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