File indexing completed on 2024-05-19 04:49:49
0001 /**************************************************************************************** 0002 * Copyright (c) 2009 Thomas Lübking <thomas.luebking@web.de * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "LayoutEditDialog.h" 0018 0019 #include "widgets/TokenWithLayout.h" 0020 #include "widgets/TokenDropTarget.h" 0021 0022 #include <QIcon> 0023 #include <KLocalizedString> 0024 0025 #include <QButtonGroup> 0026 #include <QComboBox> 0027 #include <QDialogButtonBox> 0028 #include <QGroupBox> 0029 #include <QHBoxLayout> 0030 #include <QLabel> 0031 #include <QLineEdit> 0032 #include <QPainter> 0033 #include <QRadioButton> 0034 #include <QSlider> 0035 #include <QStyle> 0036 #include <QStyleOptionFrame> 0037 #include <QToolButton> 0038 0039 0040 class HintingLineEdit : public QLineEdit 0041 { 0042 public: 0043 HintingLineEdit( const QString &hint = QString(), QWidget *parent = nullptr ) : QLineEdit( parent ), m_hint( hint ) 0044 { } 0045 void setHint( const QString &hint ) 0046 { 0047 m_hint = hint; 0048 } 0049 protected: 0050 void paintEvent ( QPaintEvent *pe ) override 0051 { 0052 QLineEdit::paintEvent( pe ); 0053 if ( !hasFocus() && text().isEmpty() ) 0054 { 0055 QStyleOptionFrame opt; 0056 initStyleOption( &opt ); 0057 0058 QPainter p(this); 0059 QColor fg = palette().color( foregroundRole() ); 0060 fg.setAlpha( fg.alpha() / 2 ); 0061 p.setPen( fg ); 0062 0063 p.drawText( style()->subElementRect( QStyle::SE_LineEditContents, &opt, this ), 0064 alignment() | Qt::TextSingleLine | Qt::TextIncludeTrailingSpaces, 0065 m_hint ); 0066 p.end(); 0067 } 0068 } 0069 private: 0070 QString m_hint; 0071 }; 0072 0073 LayoutEditDialog::LayoutEditDialog( QWidget *parent ) : QDialog( parent ) 0074 { 0075 setWindowTitle( i18n( "Configuration for" ) ); 0076 0077 QFont boldFont = font(); 0078 boldFont.setBold( true ); 0079 QVBoxLayout *l1 = new QVBoxLayout( this ); 0080 QHBoxLayout *l2 = new QHBoxLayout; 0081 l2->addWidget( m_prefix = new HintingLineEdit( i18nc( "placeholder for a prefix", "[prefix]" ), this ) ); 0082 m_prefix->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); 0083 l2->addWidget( m_element = new QLabel( this ) ); 0084 m_element->setFont( boldFont ); 0085 l2->addWidget( m_suffix = new HintingLineEdit( i18nc( "placeholder for a suffix", "[suffix]" ), this ) ); 0086 l1->addLayout( l2 ); 0087 0088 QFrame *line = new QFrame( this ); 0089 line->setFrameStyle( QFrame::Sunken | QFrame::HLine ); 0090 l1->addWidget( line ); 0091 0092 QWidget *boxWidget = new QWidget( this ); 0093 QLabel *l; 0094 0095 #define HAVE_WIDTH_MODES 0 0096 0097 QHBoxLayout *l4 = new QHBoxLayout; 0098 l = new QLabel( i18n( "Width: " ), this ); 0099 l->setFont( boldFont ); 0100 l4->addWidget( l ); 0101 l4->addWidget( m_fixedWidth = new QRadioButton( i18n( "Custom" ), this ) ); 0102 m_fixedWidth->setToolTip( i18n( "Either a fixed (absolute) value, or a relative value (e.g. 128px or 12%)." ) ); 0103 m_fixedWidth->setChecked( true ); 0104 #if HAVE_WIDTH_MODES 0105 l4->addWidget( m_fitContent = new QRadioButton( i18n( "Fit content" ), this ) ); 0106 m_fitContent->setToolTip( i18n( "Fit the element text" ) ); 0107 #endif 0108 l4->addWidget( m_automaticWidth = new QRadioButton( i18nc( "automatic width", "Automatic" ), this ) ); 0109 m_automaticWidth->setToolTip( i18n( "Take homogeneous part of the space available to all elements with automatic width" ) ); 0110 l4->addStretch(); 0111 boxWidget->connect( m_fixedWidth, &QRadioButton::toggled, this, &LayoutEditDialog::setEnabled ); 0112 connect( m_automaticWidth, &QRadioButton::toggled, this, &LayoutEditDialog::setAutomaticWidth ); 0113 l1->addLayout( l4 ); 0114 0115 QHBoxLayout *l5 = new QHBoxLayout( boxWidget ); 0116 l5->addWidget( m_width = new QSlider( Qt::Horizontal, boxWidget ) ); 0117 m_width->setRange( 0, 100 ); 0118 l = new QLabel( boxWidget ); 0119 l5->addWidget( l ); 0120 // width->connect( sizeMode, SIGNAL(currentIndexChanged(int)), SLOT(setDisabled()) ) 0121 l->setNum( 0 ); 0122 connect( m_width, &QSlider::valueChanged, l, QOverload<int>::of(&QLabel::setNum) ); 0123 0124 #define HAVE_METRICS 0 0125 #if HAVE_METRICS 0126 QComboBox *metrics = new QComboBox( this ); 0127 metrics->setFrame( false ); 0128 metrics->addItem( "%" ); 0129 metrics->addItem( "px" ); 0130 metrics->addItem( "chars" ); 0131 l5->addWidget( metrics ); 0132 #else 0133 QLabel *metrics = new QLabel( QStringLiteral("%"), this ); 0134 l5->addWidget( metrics ); 0135 #endif 0136 0137 l1->addWidget( boxWidget ); 0138 0139 line = new QFrame( this ); 0140 line->setFrameStyle( QFrame::Sunken | QFrame::HLine ); 0141 l1->addWidget( line ); 0142 0143 QHBoxLayout *l3 = new QHBoxLayout; 0144 l = new QLabel( i18n( "Alignment: " ), this ); 0145 l->setFont( boldFont ); 0146 l3->addWidget( l ); 0147 l3->addWidget( m_alignLeft = new QToolButton( this ) ); 0148 l3->addWidget( m_alignCenter = new QToolButton( this ) ); 0149 l3->addWidget( m_alignRight = new QToolButton( this ) ); 0150 0151 l3->addSpacing( 12 ); 0152 0153 l = new QLabel( i18n( "Font: " ), this ); 0154 l->setFont( boldFont ); 0155 l3->addWidget( l ); 0156 l3->addWidget( m_bold = new QToolButton( this ) ); 0157 l3->addWidget( m_italic = new QToolButton( this ) ); 0158 l3->addWidget( m_underline = new QToolButton( this ) ); 0159 l3->addStretch(); 0160 l1->addLayout( l3 ); 0161 0162 QDialogButtonBox *box = new QDialogButtonBox(this); 0163 box->addButton( QDialogButtonBox::Cancel ); 0164 box->addButton( QDialogButtonBox::Ok ); 0165 connect( box, &QDialogButtonBox::rejected, this, &LayoutEditDialog::close ); 0166 connect( box, &QDialogButtonBox::accepted, this, &LayoutEditDialog::apply ); 0167 l1->addWidget( box ); 0168 0169 l1->addStretch(); 0170 0171 m_alignLeft->setIcon( QIcon::fromTheme( QStringLiteral("format-justify-left") ) ); 0172 m_alignLeft->setCheckable( true ); 0173 m_alignCenter->setIcon( QIcon::fromTheme( QStringLiteral("format-justify-center") ) ); 0174 m_alignCenter->setCheckable( true ); 0175 m_alignRight->setIcon( QIcon::fromTheme( QStringLiteral("format-justify-right") ) ); 0176 m_alignRight->setCheckable( true ); 0177 QButtonGroup *align = new QButtonGroup( this ); 0178 align->setExclusive( true ); 0179 align->addButton( m_alignLeft ); 0180 align->addButton( m_alignCenter ); 0181 align->addButton( m_alignRight ); 0182 0183 m_bold->setIcon( QIcon::fromTheme( QStringLiteral("format-text-bold") ) ); 0184 m_bold->setCheckable( true ); 0185 m_italic->setIcon( QIcon::fromTheme( QStringLiteral("format-text-italic") ) ); 0186 m_italic->setCheckable( true ); 0187 m_underline->setIcon( QIcon::fromTheme( QStringLiteral("format-text-underline") ) ); 0188 m_underline->setCheckable( true ); 0189 0190 } 0191 0192 void LayoutEditDialog::apply() 0193 { 0194 if( !m_token ) 0195 return; 0196 0197 m_token->setPrefix( m_prefix->text() ); 0198 m_token->setSuffix( m_suffix->text() ); 0199 m_token->setWidth( m_width->value() ); 0200 if ( m_alignLeft->isChecked() ) 0201 m_token->setAlignment( Qt::AlignLeft ); 0202 else if ( m_alignCenter->isChecked() ) 0203 m_token->setAlignment( Qt::AlignHCenter ); 0204 else if ( m_alignRight->isChecked() ) 0205 m_token->setAlignment( Qt::AlignRight ); 0206 m_token->setBold( m_bold->isChecked() ); 0207 m_token->setItalic( m_italic->isChecked() ); 0208 m_token->setUnderline( m_underline->isChecked() ); 0209 0210 // we do this here to avoid reliance on the connection order (i.e. prevent close before apply) 0211 if( sender() ) 0212 close(); 0213 } 0214 0215 void LayoutEditDialog::close() 0216 { 0217 m_token.clear(); 0218 QDialog::close(); 0219 } 0220 0221 void LayoutEditDialog::setAutomaticWidth( bool automatic ) 0222 { 0223 if( automatic ) 0224 { 0225 m_previousWidth = m_width->value(); 0226 m_width->setMinimum( 0 ); // without setting the minimum we can't set the value.. 0227 m_width->setValue( 0 ); // automatic width is represented by width == 0 0228 } 0229 else 0230 { 0231 m_width->setValue( m_previousWidth ); 0232 m_width->setMinimum( 1 ); // set minimum back to 1 since "0" means automatic 0233 } 0234 } 0235 0236 0237 void LayoutEditDialog::setToken( TokenWithLayout *t ) 0238 { 0239 setWindowTitle( i18n( "Configuration for '%1'", t->name() ) ); 0240 0241 apply(); 0242 m_token = t; 0243 if ( m_token ) 0244 { 0245 m_element->setText( m_token->name() ); 0246 m_prefix->setText( m_token->prefix() ); 0247 m_suffix->setText( m_token->suffix() ); 0248 0249 0250 // Compute the remaining space from the tokens on the same line. 0251 // this should still not be done here as it makes upward assumptions 0252 // solution(?) token->element->row->elements 0253 TokenDropTarget *editWidget = qobject_cast<TokenDropTarget*>( m_token->parentWidget() ); 0254 if( editWidget ) 0255 { 0256 qreal spareWidth = 100.0; 0257 int row = editWidget->row( m_token.data() ); 0258 if( row > -1 ) 0259 { 0260 QList<Token*> tokens = editWidget->tokensAtRow( row ); 0261 foreach ( Token *token, tokens ) 0262 { 0263 if ( token == m_token.data() ) 0264 continue; 0265 0266 if ( TokenWithLayout *twl = qobject_cast<TokenWithLayout*>( token ) ) 0267 spareWidth -= twl->width() * 100.0; 0268 } 0269 } 0270 0271 int max = qMax( spareWidth, qreal( 0.0 ) ); 0272 0273 if( max >= m_token->width() * 100.0 ) 0274 m_width->setMaximum( qMax( spareWidth, qreal( 0.0 ) ) ); 0275 else 0276 m_width->setMaximum( m_token->width() * 100.0 ); 0277 } 0278 m_width->setValue( m_token->width() * 100.0 ); 0279 m_previousWidth = m_width->value(); 0280 0281 if ( m_token->width() > 0.0 ) 0282 m_fixedWidth->setChecked( true ); 0283 else 0284 m_automaticWidth->setChecked( true ); 0285 0286 if ( m_token->alignment() & Qt::AlignLeft ) 0287 m_alignLeft->setChecked(true); 0288 else if ( m_token->alignment() & Qt::AlignHCenter ) 0289 m_alignCenter->setChecked(true); 0290 else if ( m_token->alignment() & Qt::AlignRight ) 0291 m_alignRight->setChecked(true); 0292 0293 m_bold->setChecked( m_token->bold() ); 0294 m_italic->setChecked( m_token->italic() ); 0295 m_underline->setChecked( m_token->underline() ); 0296 } 0297 } 0298