• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kfontchooser.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 1996 Bernd Johannes Wuebben  <wuebben@kde.org>
00003 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
00004 Copyright (c) 1999 Mario Weilguni <mweilguni@kde.org>
00005 
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Library General Public
00008 License as published by the Free Software Foundation; either
00009 version 2 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Library General Public License for more details.
00015 
00016 You should have received a copy of the GNU Library General Public License
00017 along with this library; see the file COPYING.LIB.  If not, write to
00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019 Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kfontchooser.h"
00023 #include "fonthelpers_p.h"
00024 #include "sampleedit_p.h"
00025 
00026 #include <QtGui/QCheckBox>
00027 #include <QtGui/QLabel>
00028 #include <QtGui/QLayout>
00029 #include <QtGui/QSplitter>
00030 #include <QtGui/QScrollBar>
00031 #include <QtGui/QFontDatabase>
00032 #include <QtGui/QGroupBox>
00033 #include <kcharsets.h>
00034 #include <kconfig.h>
00035 #include <kdialog.h>
00036 #include <kglobal.h>
00037 #include <kglobalsettings.h>
00038 #include <klineedit.h>
00039 #include <klistwidget.h>
00040 #include <klocale.h>
00041 #include <kstandarddirs.h>
00042 #include <kdebug.h>
00043 #include <knuminput.h>
00044 #include <kconfiggroup.h>
00045 
00046 // When message extraction needs to be avoided.
00047 #define I18NC_NOX i18nc
00048 
00049 static int minimumListWidth( const QListWidget *list )
00050 {
00051     int w=0;
00052     for( int i=0; i<list->count(); i++ )
00053     {
00054         int itemWidth = list->visualItemRect(list->item(i)).width();
00055         // ...and add a space on both sides for not too tight look.
00056         itemWidth += list->fontMetrics().width(' ') * 2;
00057         w = qMax(w,itemWidth);
00058     }
00059     if( w == 0 ) { w = 40; }
00060     w += list->frameWidth() * 2;
00061     w += list->verticalScrollBar()->sizeHint().width();
00062     return w;
00063 }
00064 
00065 static int minimumListHeight( const QListWidget *list, int numVisibleEntry )
00066 {
00067     int w = list->count() > 0 ? list->visualItemRect(list->item(0)).height() :
00068             list->fontMetrics().lineSpacing();
00069 
00070     if( w < 0 ) { w = 10; }
00071     if( numVisibleEntry <= 0 ) { numVisibleEntry = 4; }
00072     return ( w * numVisibleEntry + 2 * list->frameWidth() );
00073 }
00074 
00075 class KFontChooser::Private
00076 {
00077 public:
00078     Private( KFontChooser* qq )
00079         : q( qq )
00080     {
00081         m_palette.setColor(QPalette::Active, QPalette::Text, Qt::black);
00082         m_palette.setColor(QPalette::Active, QPalette::Base, Qt::white);
00083         signalsAllowed = true;
00084         selectedSize = -1;
00085         customSizeRow = -1;
00086     }
00087 
00088     // pointer to an optinally supplied list of fonts to
00089     // inserted into the fontdialog font-family combo-box
00090 //    QStringList  fontList;
00091 
00092     void setFamilyBoxItems(const QStringList &fonts);
00093     void fillFamilyListBox(bool onlyFixedFonts = false);
00094     int nearestSizeRow(int val, bool customize);
00095     int fillSizeList(const QList<int> &sizes = QList<int>());
00096     int setupSizeListBox(const QString& family, const QString& style);
00097 
00098     void setupDisplay();
00099 
00100     void _k_toggled_checkbox();
00101     void _k_family_chosen_slot(const QString&);
00102     void _k_size_chosen_slot(const QString&);
00103     void _k_style_chosen_slot(const QString&);
00104     void _k_displaySample(const QFont &font);
00105     void _k_showXLFDArea(bool);
00106     void _k_size_value_slot(int);
00107 
00108     KFontChooser *q;
00109 
00110     QPalette m_palette;
00111     bool signalsAllowed:1;
00112 
00113     bool usingFixed:1;
00114 
00115     KIntNumInput *sizeOfFont;
00116 
00117     SampleEdit   *sampleEdit;
00118     KLineEdit    *xlfdEdit;
00119 
00120     QLabel       *familyLabel;
00121     QLabel       *styleLabel;
00122     QCheckBox    *familyCheckbox;
00123     QCheckBox    *styleCheckbox;
00124     QCheckBox    *sizeCheckbox;
00125     QLabel       *sizeLabel;
00126     KListWidget     *familyListBox;
00127     KListWidget     *styleListBox;
00128     KListWidget     *sizeListBox;
00129     QCheckBox    *sizeIsRelativeCheckBox;
00130 
00131     QFont        selFont;
00132 
00133     QString      selectedStyle;
00134     int          selectedSize;
00135 
00136     int          customSizeRow;
00137     QString      standardSizeAtCustom;
00138 
00139     // Mappings of translated to Qt originated family and style strings.
00140     QHash<QString, QString> qtFamilies;
00141     QHash<QString, QString> qtStyles;
00142 
00143 };
00144 
00145 
00146 KFontChooser::KFontChooser( QWidget *parent,
00147                             const DisplayFlags& flags,
00148                             const QStringList &fontList,
00149                             int visibleListSize,
00150                             Qt::CheckState *sizeIsRelativeState )
00151     : QWidget(parent),
00152       d( new KFontChooser::Private( this ) )
00153 {
00154     d->usingFixed = flags & FixedFontsOnly;
00155     setWhatsThis(i18nc("@info:whatsthis", "Here you can choose the font to be used." ));
00156 
00157     // The top layout is divided vertically into a splitter with font
00158     // attribute widgets and preview on the top, and XLFD data at the bottom.
00159     QVBoxLayout *topLayout = new QVBoxLayout( this );
00160     topLayout->setMargin( 0 );
00161     topLayout->setSpacing( KDialog::spacingHint() );
00162     int checkBoxGap = KDialog::spacingHint() / 2;
00163 
00164     // The splitter contains font attribute widgets in the top part,
00165     // and the font preview in the bottom part.
00166     // The splitter is there to allow the user to resize the font preview.
00167     QSplitter *splitter = new QSplitter(Qt::Vertical, this);
00168     splitter->setChildrenCollapsible(false);
00169     topLayout->addWidget(splitter);
00170 
00171     // Build the grid of font attribute widgets for the upper splitter part.
00172     //
00173     QWidget *page;
00174     QGridLayout *gridLayout;
00175     int row = 0;
00176     if( flags & DisplayFrame )
00177     {
00178         page = new QGroupBox( i18n("Requested Font"), this );
00179         splitter->addWidget(page);
00180         gridLayout = new QGridLayout( page );
00181         gridLayout->setMargin( KDialog::marginHint() );
00182         gridLayout->setSpacing( KDialog::spacingHint() );
00183         row = 1;
00184     }
00185     else
00186     {
00187         page = new QWidget( this );
00188         splitter->addWidget(page);
00189         gridLayout = new QGridLayout( page );
00190         gridLayout->setMargin( 0 );
00191         gridLayout->setSpacing( KDialog::spacingHint() );
00192     }
00193 
00194     //
00195     // first, create the labels across the top
00196     //
00197     QHBoxLayout *familyLayout = new QHBoxLayout();
00198     familyLayout->addSpacing( checkBoxGap );
00199     if ( flags & ShowDifferences ) {
00200         d->familyCheckbox = new QCheckBox(i18nc("@option:check","Font"), page);
00201         connect(d->familyCheckbox, SIGNAL(toggled(bool)),
00202                 this, SLOT(_k_toggled_checkbox()));
00203         familyLayout->addWidget(d->familyCheckbox, 0, Qt::AlignLeft);
00204         d->familyCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font family settings."));
00205         d->familyCheckbox->setToolTip(i18nc("@info:tooltip","Change font family?") );
00206         d->familyLabel = 0;
00207     } else {
00208         d->familyCheckbox = 0;
00209         d->familyLabel = new QLabel( i18nc("@label","Font:"), page );
00210         familyLayout->addWidget(d->familyLabel, 1, Qt::AlignLeft);
00211     }
00212     gridLayout->addLayout(familyLayout, row, 0 );
00213 
00214     QHBoxLayout *styleLayout = new QHBoxLayout();
00215     if ( flags & ShowDifferences ) {
00216         d->styleCheckbox = new QCheckBox(i18nc("@option:check","Font style"), page);
00217         connect(d->styleCheckbox, SIGNAL(toggled(bool)),
00218                 this, SLOT(_k_toggled_checkbox()));
00219         styleLayout->addWidget(d->styleCheckbox, 0, Qt::AlignLeft);
00220         d->styleCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font style settings."));
00221         d->styleCheckbox->setToolTip(i18nc("@info:tooltip","Change font style?"));
00222         d->styleLabel = 0;
00223     } else {
00224         d->styleCheckbox = 0;
00225         d->styleLabel = new QLabel(i18n("Font style:"), page );
00226         styleLayout->addWidget(d->styleLabel, 1, Qt::AlignLeft);
00227     }
00228     styleLayout->addSpacing( checkBoxGap );
00229     gridLayout->addLayout(styleLayout, row, 1 );
00230 
00231     QHBoxLayout *sizeLayout = new QHBoxLayout();
00232     if ( flags & ShowDifferences ) {
00233         d->sizeCheckbox = new QCheckBox(i18nc("@option:check","Size"),page);
00234         connect(d->sizeCheckbox, SIGNAL(toggled(bool)),
00235                 this, SLOT(_k_toggled_checkbox()));
00236         sizeLayout->addWidget(d->sizeCheckbox, 0, Qt::AlignLeft);
00237         d->sizeCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font size settings."));
00238         d->sizeCheckbox->setToolTip(i18nc("@info:tooltip","Change font size?"));
00239         d->sizeLabel = 0;
00240     } else {
00241         d->sizeCheckbox = 0;
00242         d->sizeLabel = new QLabel(i18nc("@label:listbox Font size", "Size:"), page );
00243         sizeLayout->addWidget(d->sizeLabel, 1, Qt::AlignLeft);
00244     }
00245     sizeLayout->addSpacing( checkBoxGap );
00246     sizeLayout->addSpacing( checkBoxGap ); // prevent label from eating border
00247     gridLayout->addLayout(sizeLayout, row, 2 );
00248 
00249     row ++;
00250 
00251     //
00252     // now create the actual boxes that hold the info
00253     //
00254     d->familyListBox = new KListWidget( page );
00255     d->familyListBox->setEnabled( flags ^ ShowDifferences );
00256     gridLayout->addWidget( d->familyListBox, row, 0 );
00257     QString fontFamilyWhatsThisText (
00258         i18nc("@info:whatsthis","Here you can choose the font family to be used." ));
00259     d->familyListBox->setWhatsThis(fontFamilyWhatsThisText );
00260 
00261     if ( flags & ShowDifferences ) {
00262         d->familyCheckbox->setWhatsThis(fontFamilyWhatsThisText );
00263     } else {
00264         d->familyLabel->setWhatsThis(fontFamilyWhatsThisText );
00265     }
00266 
00267     connect(d->familyListBox, SIGNAL(currentTextChanged(const QString &)),
00268             this, SLOT(_k_family_chosen_slot(const QString &)));
00269     if ( !fontList.isEmpty() ) {
00270         d->setFamilyBoxItems(fontList);
00271     }
00272     else
00273     {
00274         d->fillFamilyListBox( flags & FixedFontsOnly );
00275     }
00276 
00277     d->familyListBox->setMinimumWidth( minimumListWidth( d->familyListBox ) );
00278     d->familyListBox->setMinimumHeight(
00279         minimumListHeight( d->familyListBox, visibleListSize  ) );
00280 
00281     d->styleListBox = new KListWidget( page );
00282     d->styleListBox->setEnabled( flags ^ ShowDifferences );
00283     gridLayout->addWidget(d->styleListBox, row, 1);
00284     d->styleListBox->setWhatsThis(i18nc("@info:whatsthis","Here you can choose the font style to be used." ));
00285     if ( flags & ShowDifferences ) {
00286         ((QWidget *)d->styleCheckbox)->setWhatsThis(fontFamilyWhatsThisText );
00287     } else {
00288         ((QWidget *)d->styleLabel)->setWhatsThis( fontFamilyWhatsThisText );
00289     }
00290     // Populate usual styles, to determine minimum list width;
00291     // will be replaced later with correct styles.
00292     d->styleListBox->addItem(i18nc("@item font","Regular"));
00293     d->styleListBox->addItem(i18nc("@item font","Italic"));
00294     d->styleListBox->addItem(i18nc("@item font","Oblique"));
00295     d->styleListBox->addItem(i18nc("@item font","Bold"));
00296     d->styleListBox->addItem(i18nc("@item font","Bold Italic"));
00297     d->styleListBox->setMinimumWidth( minimumListWidth( d->styleListBox ) );
00298     d->styleListBox->setMinimumHeight(
00299         minimumListHeight( d->styleListBox, visibleListSize  ) );
00300 
00301     connect(d->styleListBox, SIGNAL(currentTextChanged(const QString &)),
00302             this, SLOT(_k_style_chosen_slot(const QString &)));
00303 
00304 
00305     d->sizeListBox = new KListWidget( page );
00306     d->sizeOfFont = new KIntNumInput(page);
00307     d->sizeOfFont->setMinimum(4);
00308     d->sizeOfFont->setMaximum(999);
00309     d->sizeOfFont->setSliderEnabled(false);
00310 
00311     d->sizeListBox->setEnabled( flags ^ ShowDifferences );
00312     d->sizeOfFont->setEnabled( flags ^ ShowDifferences );
00313     if( sizeIsRelativeState ) {
00314         QString sizeIsRelativeCBText =
00315             i18nc("@item font size","Relative");
00316         QString sizeIsRelativeCBToolTipText =
00317             i18n("Font size<br /><i>fixed</i> or <i>relative</i><br />to environment");
00318         QString sizeIsRelativeCBWhatsThisText =
00319             i18n("Here you can switch between fixed font size and font size "
00320                  "to be calculated dynamically and adjusted to changing "
00321                  "environment (e.g. widget dimensions, paper size)." );
00322         d->sizeIsRelativeCheckBox = new QCheckBox( sizeIsRelativeCBText,
00323                                                 page );
00324         d->sizeIsRelativeCheckBox->setTristate( flags & ShowDifferences );
00325         QGridLayout *sizeLayout2 = new QGridLayout();
00326         sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
00327         gridLayout->addLayout(sizeLayout2, row, 2);
00328         sizeLayout2->setColumnStretch( 1, 1 ); // to prevent text from eating the right border
00329         sizeLayout2->addWidget( d->sizeOfFont, 0, 0, 1, 2);
00330         sizeLayout2->addWidget(d->sizeListBox, 1,0, 1,2);
00331         sizeLayout2->addWidget(d->sizeIsRelativeCheckBox, 2, 0, Qt::AlignLeft);
00332         d->sizeIsRelativeCheckBox->setWhatsThis(sizeIsRelativeCBWhatsThisText );
00333         d->sizeIsRelativeCheckBox->setToolTip( sizeIsRelativeCBToolTipText );
00334     }
00335     else {
00336         d->sizeIsRelativeCheckBox = 0L;
00337         QGridLayout *sizeLayout2 = new QGridLayout();
00338         sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
00339         gridLayout->addLayout(sizeLayout2, row, 2);
00340         sizeLayout2->addWidget( d->sizeOfFont, 0, 0);
00341         sizeLayout2->addWidget(d->sizeListBox, 1,0);
00342     }
00343     QString fontSizeWhatsThisText =
00344         i18n("Here you can choose the font size to be used." );
00345     d->sizeListBox->setWhatsThis(fontSizeWhatsThisText );
00346 
00347     if ( flags & ShowDifferences ) {
00348         ((QWidget *)d->sizeCheckbox)->setWhatsThis(fontSizeWhatsThisText );
00349     } else {
00350         ((QWidget *)d->sizeLabel)->setWhatsThis( fontSizeWhatsThisText );
00351     }
00352 
00353     // Populate with usual sizes, to determine minimum list width;
00354     // will be replaced later with correct sizes.
00355     d->fillSizeList();
00356     d->sizeListBox->setMinimumWidth( minimumListWidth(d->sizeListBox) +
00357                                   d->sizeListBox->fontMetrics().maxWidth() );
00358     d->sizeListBox->setMinimumHeight(
00359         minimumListHeight( d->sizeListBox, visibleListSize  ) );
00360 
00361     connect( d->sizeOfFont, SIGNAL( valueChanged(int) ),
00362              this, SLOT(_k_size_value_slot(int)));
00363 
00364     connect( d->sizeListBox, SIGNAL(currentTextChanged(const QString&)),
00365              this, SLOT(_k_size_chosen_slot(const QString&)) );
00366 
00367     row ++;
00368     //
00369     // Completed the font attribute grid.
00370 
00371     // Add the font preview into the lower part of the splitter.
00372     //
00373     d->sampleEdit = new SampleEdit(page);
00374     d->sampleEdit->setAcceptRichText(false);
00375     QFont tmpFont( KGlobalSettings::generalFont().family(), 64, QFont::Black );
00376     d->sampleEdit->setFont(tmpFont);
00377     d->sampleEdit->setMinimumHeight( d->sampleEdit->fontMetrics().lineSpacing() );
00378     // i18n: A classical test phrase, with all letters of the English alphabet.
00379     // Replace it with a sample text in your language, such that it is
00380     // representative of language's writing system.
00381     // If you wish, you can input several lines of text separated by \n.
00382     setSampleText(i18n("The Quick Brown Fox Jumps Over The Lazy Dog"));
00383     QString sampleEditWhatsThisText =
00384         i18n("This sample text illustrates the current settings. "
00385              "You may edit it to test special characters." );
00386     d->sampleEdit->setWhatsThis(sampleEditWhatsThisText );
00387 
00388     connect(this, SIGNAL(fontSelected(const QFont &)),
00389             this, SLOT(_k_displaySample(const QFont &)));
00390 
00391     splitter->addWidget(d->sampleEdit);
00392     //
00393     // Finished setting up the splitter.
00394 
00395     // Add XLFD data below the font attributes/preview splitter.
00396     //
00397     QVBoxLayout *vbox;
00398     if( flags & DisplayFrame )
00399     {
00400         page = new QGroupBox( i18n("Actual Font"), this );
00401         topLayout->addWidget(page);
00402         vbox = new QVBoxLayout( page );
00403         vbox->setSpacing( KDialog::spacingHint() );
00404         vbox->addSpacing( fontMetrics().lineSpacing() );
00405     }
00406     else
00407     {
00408         page = new QWidget( this );
00409         topLayout->addWidget(page);
00410         vbox = new QVBoxLayout( page );
00411         vbox->setMargin( 0 );
00412         vbox->setSpacing( KDialog::spacingHint() );
00413         QLabel *label = new QLabel( i18n("Actual Font"), page );
00414         vbox->addWidget( label );
00415     }
00416 
00417     d->xlfdEdit = new KLineEdit( page );
00418     vbox->addWidget( d->xlfdEdit );
00419     //
00420     // Finished setting up the chooser layout.
00421 
00422     // lets initialize the display if possible
00423     setFont( KGlobalSettings::generalFont(), d->usingFixed );
00424 
00425     // check or uncheck or gray out the "relative" checkbox
00426     if( sizeIsRelativeState && d->sizeIsRelativeCheckBox )
00427         setSizeIsRelative( *sizeIsRelativeState );
00428 
00429     KConfigGroup cg(KGlobal::config(), QLatin1String("General"));
00430     d->_k_showXLFDArea(cg.readEntry(QLatin1String("fontSelectorShowXLFD"), false));
00431 
00432     // Set focus to the size list as this is the most commonly changed property
00433     d->sizeListBox->setFocus();
00434 }
00435 
00436 KFontChooser::~KFontChooser()
00437 {
00438     delete d;
00439 }
00440 
00441 void KFontChooser::setColor( const QColor & col )
00442 {
00443     d->m_palette.setColor( QPalette::Active, QPalette::Text, col );
00444     QPalette pal = d->sampleEdit->palette();
00445     pal.setColor( QPalette::Active, QPalette::Text, col );
00446     d->sampleEdit->setPalette( pal );
00447 }
00448 
00449 QColor KFontChooser::color() const
00450 {
00451     return d->m_palette.color( QPalette::Active, QPalette::Text );
00452 }
00453 
00454 void KFontChooser::setBackgroundColor( const QColor & col )
00455 {
00456     d->m_palette.setColor( QPalette::Active, QPalette::Base, col );
00457     QPalette pal = d->sampleEdit->palette();
00458     pal.setColor( QPalette::Active, QPalette::Base, col );
00459     d->sampleEdit->setPalette( pal );
00460 }
00461 
00462 QColor KFontChooser::backgroundColor() const
00463 {
00464     return d->m_palette.color( QPalette::Active, QPalette::Base );
00465 }
00466 
00467 void KFontChooser::setSizeIsRelative( Qt::CheckState relative )
00468 {
00469     // check or uncheck or gray out the "relative" checkbox
00470     if( d->sizeIsRelativeCheckBox ) {
00471         if( Qt::PartiallyChecked == relative )
00472             d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked);
00473         else
00474             d->sizeIsRelativeCheckBox->setCheckState(  (Qt::Checked == relative )  ? Qt::Checked : Qt::Unchecked);
00475     }
00476 }
00477 
00478 Qt::CheckState KFontChooser::sizeIsRelative() const
00479 {
00480     return d->sizeIsRelativeCheckBox
00481         ? d->sizeIsRelativeCheckBox->checkState()
00482         : Qt::PartiallyChecked;
00483 }
00484 
00485 QString KFontChooser::sampleText() const
00486 {
00487     return d->sampleEdit->toPlainText();
00488 }
00489 
00490 void KFontChooser::setSampleText( const QString &text )
00491 {
00492     d->sampleEdit->setPlainText(text);
00493 }
00494 
00495 void KFontChooser::setSampleBoxVisible( bool visible )
00496 {
00497     d->sampleEdit->setVisible( visible );
00498 }
00499 
00500 QSize KFontChooser::sizeHint( void ) const
00501 {
00502     return minimumSizeHint();
00503 }
00504 
00505 
00506 void KFontChooser::enableColumn( int column, bool state )
00507 {
00508     if( column & FamilyList )
00509     {
00510         d->familyListBox->setEnabled(state);
00511     }
00512     if( column & StyleList )
00513     {
00514         d->styleListBox->setEnabled(state);
00515     }
00516     if( column & SizeList )
00517     {
00518         d->sizeListBox->setEnabled(state);
00519     }
00520 }
00521 
00522 
00523 void KFontChooser::setFont( const QFont& aFont, bool onlyFixed )
00524 {
00525     d->selFont = aFont;
00526     d->selectedSize=aFont.pointSize();
00527     if (d->selectedSize == -1)
00528         d->selectedSize = QFontInfo(aFont).pointSize();
00529 
00530     if( onlyFixed != d->usingFixed)
00531     {
00532         d->usingFixed = onlyFixed;
00533         d->fillFamilyListBox(d->usingFixed);
00534     }
00535     d->setupDisplay();
00536 }
00537 
00538 
00539 KFontChooser::FontDiffFlags KFontChooser::fontDiffFlags() const
00540 {
00541     FontDiffFlags diffFlags = NoFontDiffFlags;
00542 
00543     if ( d->familyCheckbox && d->familyCheckbox->isChecked() ) {
00544         diffFlags |= FontDiffFamily;
00545     }
00546 
00547     if ( d->styleCheckbox && d->styleCheckbox->isChecked() ) {
00548         diffFlags |= FontDiffStyle;
00549     }
00550 
00551     if ( d->sizeCheckbox && d->sizeCheckbox->isChecked() ) {
00552         diffFlags |= FontDiffSize;
00553     }
00554 
00555     return diffFlags;
00556 }
00557 
00558 QFont KFontChooser::font() const
00559 {
00560     return d->selFont;
00561 }
00562 
00563 void KFontChooser::Private::_k_toggled_checkbox()
00564 {
00565     familyListBox->setEnabled( familyCheckbox->isChecked() );
00566     styleListBox->setEnabled( styleCheckbox->isChecked() );
00567     sizeListBox->setEnabled( sizeCheckbox->isChecked() );
00568     sizeOfFont->setEnabled( sizeCheckbox->isChecked() );
00569 }
00570 
00571 void KFontChooser::Private::_k_family_chosen_slot(const QString& family)
00572 {
00573     if ( !signalsAllowed ) {
00574         return;
00575     }
00576     signalsAllowed = false;
00577 
00578     QString currentFamily;
00579     if (family.isEmpty()) {
00580         Q_ASSERT( familyListBox->currentItem() );
00581         if (familyListBox->currentItem()) {
00582           currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00583         }
00584     }
00585     else {
00586         currentFamily = qtFamilies[family];
00587     }
00588 
00589     // Get the list of styles available in this family.
00590     QFontDatabase dbase;
00591     QStringList styles = dbase.styles(currentFamily);
00592     if (styles.isEmpty()) {
00593         // Avoid extraction, its in kdeqt.po
00594         styles.append(I18NC_NOX("QFontDatabase", "Normal"));
00595     }
00596 
00597     // Filter style strings and add to the listbox.
00598     QString pureFamily;
00599     splitFontString(family, &pureFamily);
00600     QStringList filteredStyles;
00601     qtStyles.clear();
00602     foreach (const QString &style, styles) {
00603         // Sometimes the font database will report an invalid style,
00604         // that falls back back to another when set.
00605         // Remove such styles, by checking set/get round-trip.
00606         if (dbase.styleString(dbase.font(currentFamily, style, 10)) != style) {
00607             styles.removeAll(style);
00608             continue;
00609         }
00610 
00611         // We don't like Qt's name for some styles.
00612         QString styleMod = style;
00613         if (style == I18NC_NOX("QFontDatabase", "Normal"))
00614             styleMod = i18nc("@item font", "Regular");
00615 
00616         // i18n: Filtering message, so that translators can script the
00617         // style string according to the font family name (e.g. may need
00618         // noun-adjective congruence wrt. gender of the family name).
00619         // The message provides the dynamic context 'family', which is
00620         // the family name to which the style string corresponds.
00621         QString fstyle = ki18nc("@item Font style", "%1").subs(styleMod).inContext("family", pureFamily).toString();
00622         if (!filteredStyles.contains(fstyle)) {
00623             filteredStyles.append(fstyle);
00624             qtStyles.insert(fstyle, style);
00625         }
00626     }
00627     styleListBox->clear();
00628     styleListBox->addItems(filteredStyles);
00629 
00630     // Try to set the current style in the listbox to that previous.
00631     int listPos = styles.indexOf(selectedStyle);
00632     if (listPos < 0) {
00633         // Make extra effort to have Italic selected when Oblique was chosen,
00634         // and vice versa, as that is what the user would probably want.
00635         QString styleIt = i18nc("@item font", "Italic");
00636         QString styleOb = i18nc("@item font", "Oblique");
00637         for (int i = 0; i < 2; ++i) {
00638             int pos = selectedStyle.indexOf(styleIt);
00639             if (pos >= 0) {
00640                 QString style = selectedStyle;
00641                 style.replace(pos, styleIt.length(), styleOb);
00642                 listPos = styles.indexOf(style);
00643                 if (listPos >= 0) break;
00644             }
00645             qSwap(styleIt, styleOb);
00646         }
00647     }
00648     styleListBox->setCurrentRow(listPos >= 0 ? listPos : 0);
00649     QString currentStyle = qtStyles[styleListBox->currentItem()->text()];
00650 
00651     // Recompute the size listbox for this family/style.
00652     int currentSize = setupSizeListBox(currentFamily, currentStyle);
00653     sizeOfFont->setValue(currentSize);
00654 
00655     selFont = dbase.font(currentFamily, currentStyle, currentSize);
00656     emit q->fontSelected(selFont);
00657 
00658     signalsAllowed = true;
00659 }
00660 
00661 void KFontChooser::Private::_k_style_chosen_slot(const QString& style)
00662 {
00663     if ( !signalsAllowed ) {
00664         return;
00665     }
00666     signalsAllowed = false;
00667 
00668     QFontDatabase dbase;
00669     QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00670     QString currentStyle;
00671     if (style.isEmpty()) {
00672         currentStyle = qtStyles[styleListBox->currentItem()->text()];
00673     } else {
00674         currentStyle = qtStyles[style];
00675     }
00676 
00677     // Recompute the size listbox for this family/style.
00678     int currentSize = setupSizeListBox(currentFamily, currentStyle);
00679     sizeOfFont->setValue(currentSize);
00680 
00681     selFont = dbase.font(currentFamily, currentStyle, currentSize);
00682     emit q->fontSelected(selFont);
00683 
00684     if (!style.isEmpty()) {
00685         selectedStyle = currentStyle;
00686     }
00687 
00688     signalsAllowed = true;
00689 }
00690 
00691 void KFontChooser::Private::_k_size_chosen_slot(const QString& size)
00692 {
00693     if ( !signalsAllowed ) {
00694         return;
00695     }
00696 
00697     signalsAllowed = false;
00698 
00699     int currentSize;
00700     if (size.isEmpty()) {
00701         currentSize = sizeListBox->currentItem()->text().toInt();
00702     } else {
00703         currentSize = size.toInt();
00704     }
00705 
00706     // Reset the customized size slot in the list if not needed.
00707     if (customSizeRow >= 0 && selFont.pointSize() != currentSize) {
00708         sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
00709         customSizeRow = -1;
00710     }
00711 
00712     sizeOfFont->setValue(currentSize);
00713     selFont.setPointSize(currentSize);
00714     emit q->fontSelected(selFont);
00715 
00716     if (!size.isEmpty()) {
00717         selectedSize = currentSize;
00718     }
00719 
00720     signalsAllowed = true;
00721 }
00722 
00723 void KFontChooser::Private::_k_size_value_slot(int val)
00724 {
00725     if ( !signalsAllowed ) {
00726         return;
00727     }
00728     signalsAllowed = false;
00729 
00730     QFontDatabase dbase;
00731     QString family = qtFamilies[familyListBox->currentItem()->text()];
00732     QString style = qtStyles[styleListBox->currentItem()->text()];
00733 
00734     // Reset current size slot in list if it was customized.
00735     if (sizeListBox->currentRow() == customSizeRow) {
00736         sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
00737         customSizeRow = -1;
00738     }
00739 
00740     bool canCustomize = true;
00741 
00742     // For Qt-bad-sizes workaround: skip this block unconditionally
00743     if (!dbase.isSmoothlyScalable(family, style)) {
00744         // Bitmap font, allow only discrete sizes.
00745         // Determine the nearest in the direction of change.
00746         canCustomize = false;
00747         int nrows = sizeListBox->count();
00748         int row = sizeListBox->currentRow();
00749         int nrow;
00750         if (val - selFont.pointSize() > 0) {
00751             for (nrow = row + 1; nrow < nrows; ++nrow)
00752                 if (sizeListBox->item(nrow)->text().toInt() >= val)
00753                     break;
00754         }
00755         else {
00756             for (nrow = row - 1; nrow >= 0; --nrow)
00757                 if (sizeListBox->item(nrow)->text().toInt() <= val)
00758                     break;
00759         }
00760         // Make sure the new row is not out of bounds.
00761         nrow = nrow < 0 ? 0 : nrow >= nrows ? nrows - 1 : nrow;
00762         // Get the size from the new row and set the spinbox to that size.
00763         val = sizeListBox->item(nrow)->text().toInt();
00764         sizeOfFont->setValue(val);
00765     }
00766 
00767     // Set the current size in the size listbox.
00768     int row = nearestSizeRow(val, canCustomize);
00769     sizeListBox->setCurrentRow(row);
00770 
00771     selectedSize = val;
00772     selFont.setPointSize(val);
00773     emit q->fontSelected( selFont );
00774 
00775     signalsAllowed = true;
00776 }
00777 
00778 void KFontChooser::Private::_k_displaySample( const QFont& font )
00779 {
00780     sampleEdit->setFont(font);
00781     //sampleEdit->setCursorPosition(0);
00782 
00783     xlfdEdit->setText(font.rawName());
00784     xlfdEdit->setCursorPosition(0);
00785 
00786     //QFontInfo a = QFontInfo(font);
00787     //kDebug() << "font: " << a.family () << ", " << a.pointSize ();
00788     //kDebug() << "      (" << font.toString() << ")\n";
00789 }
00790 
00791 int KFontChooser::Private::nearestSizeRow (int val, bool customize)
00792 {
00793     int diff = 1000;
00794     int row = 0;
00795     for (int r = 0; r < sizeListBox->count(); ++r) {
00796         int cval = sizeListBox->item(r)->text().toInt();
00797         if (qAbs(cval - val) < diff) {
00798             diff = qAbs(cval - val);
00799             row = r;
00800         }
00801     }
00802     // For Qt-bad-sizes workaround: ignore value of customize, use true
00803     if (customize && diff > 0) {
00804         customSizeRow = row;
00805         standardSizeAtCustom = sizeListBox->item(row)->text();
00806         sizeListBox->item(row)->setText(QString::number(val));
00807     }
00808     return row;
00809 }
00810 
00811 int KFontChooser::Private::fillSizeList (const QList<int> &sizes_)
00812 {
00813     if ( !sizeListBox ) {
00814         return 0; //assertion.
00815     }
00816 
00817     QList<int> sizes = sizes_;
00818     bool canCustomize = false;
00819     if (sizes.count() == 0) {
00820         static const int c[] = {
00821             4,  5,  6,  7,
00822             8,  9,  10, 11,
00823             12, 13, 14, 15,
00824             16, 17, 18, 19,
00825             20, 22, 24, 26,
00826             28, 32, 48, 64,
00827             72, 80, 96, 128,
00828             0
00829         };
00830         for (int i = 0; c[i]; ++i) {
00831             sizes.append(c[i]);
00832         }
00833         // Since sizes were not supplied, this is a vector font,
00834         // and size slot customization is allowed.
00835         canCustomize = true;
00836     }
00837 
00838     // Insert sizes into the listbox.
00839     sizeListBox->clear();
00840     qSort(sizes);
00841     foreach (int size, sizes) {
00842         sizeListBox->addItem(QString::number(size));
00843     }
00844 
00845     // Return the nearest to selected size.
00846     // If the font is vector, the nearest size is always same as selected,
00847     // thus size slot customization is allowed.
00848     // If the font is bitmap, the nearest size need not be same as selected,
00849     // thus size slot customization is not allowed.
00850     customSizeRow = -1;
00851     int row = nearestSizeRow(selectedSize, canCustomize);
00852     return sizeListBox->item(row)->text().toInt();
00853 }
00854 
00855 int KFontChooser::Private::setupSizeListBox (const QString& family, const QString& style)
00856 {
00857     QFontDatabase dbase;
00858     QList<int> sizes;
00859     if (dbase.isSmoothlyScalable(family, style)) {
00860         // A vector font.
00861         //>sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO
00862     }
00863     else {
00864         // A bitmap font.
00865         //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO
00866         sizes = dbase.smoothSizes(family, style);
00867     }
00868 
00869     // Fill the listbox (uses default list of sizes if the given is empty).
00870     // Collect the best fitting size to selected size, to use if not smooth.
00871     int bestFitSize = fillSizeList(sizes);
00872 
00873     // Set the best fit size as current in the listbox if available.
00874     const QList<QListWidgetItem*> selectedSizeList =
00875         sizeListBox->findItems( QString::number(bestFitSize),
00876                                 Qt::MatchExactly );
00877     if ( !selectedSizeList.isEmpty() ) {
00878         sizeListBox->setCurrentItem(selectedSizeList.first());
00879     }
00880     //TODO - KDE4 : sizeListBox->scrollTo(sizeListBox->currentItem());
00881 
00882     return bestFitSize;
00883 }
00884 
00885 void KFontChooser::Private::setupDisplay()
00886 {
00887     QFontDatabase dbase;
00888     QString family = selFont.family().toLower();
00889     QString style = dbase.styleString(selFont).toLower();
00890     int size = selFont.pointSize();
00891     if (size == -1)
00892         size = QFontInfo( selFont ).pointSize();
00893 
00894     int numEntries, i;
00895 
00896     // Direct family match.
00897     numEntries = familyListBox->count();
00898     for (i = 0; i < numEntries; i++) {
00899         if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
00900             familyListBox->setCurrentRow(i);
00901             break;
00902         }
00903     }
00904 
00905     // 1st family fallback.
00906     if ( (i == numEntries) )
00907     {
00908         if (family.contains('['))
00909         {
00910             family = family.left(family.indexOf('[')).trimmed();
00911             for (i = 0; i < numEntries; i++) {
00912                 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
00913                     familyListBox->setCurrentRow(i);
00914                     break;
00915                 }
00916             }
00917         }
00918     }
00919 
00920     // 2nd family fallback.
00921     if ( (i == numEntries) )
00922     {
00923         QString fallback = family+" [";
00924         for (i = 0; i < numEntries; i++) {
00925             if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(fallback)) {
00926                 familyListBox->setCurrentRow(i);
00927                 break;
00928             }
00929         }
00930     }
00931 
00932     // 3rd family fallback.
00933     if ( (i == numEntries) )
00934     {
00935         for (i = 0; i < numEntries; i++) {
00936             if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(family)) {
00937                 familyListBox->setCurrentRow(i);
00938                 break;
00939             }
00940         }
00941     }
00942 
00943     // Family fallback in case nothing matched. Otherwise, diff doesn't work
00944     if ( i == numEntries ) {
00945         familyListBox->setCurrentRow( 0 );
00946     }
00947 
00948     // By setting the current item in the family box, the available
00949     // styles and sizes for that family have been collected.
00950     // Try now to set the current items in the style and size boxes.
00951 
00952     // Set current style in the listbox.
00953     numEntries = styleListBox->count();
00954     for (i = 0; i < numEntries; i++) {
00955         if (style == qtStyles[styleListBox->item(i)->text()].toLower()) {
00956             styleListBox->setCurrentRow(i);
00957             break;
00958         }
00959     }
00960     if (i == numEntries) {
00961         // Style not found, fallback.
00962         styleListBox->setCurrentRow(0);
00963     }
00964 
00965     // Set current size in the listbox.
00966     // If smoothly scalable, allow customizing one of the standard size slots,
00967     // otherwise just select the nearest available size.
00968     QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00969     QString currentStyle = qtFamilies[styleListBox->currentItem()->text()];
00970     bool canCustomize = dbase.isSmoothlyScalable(currentFamily, currentStyle);
00971     sizeListBox->setCurrentRow(nearestSizeRow(size, canCustomize));
00972 
00973     // Set current size in the spinbox.
00974     sizeOfFont->setValue(sizeListBox->currentItem()->text().toInt());
00975 }
00976 
00977 
00978 void KFontChooser::getFontList( QStringList &list, uint fontListCriteria)
00979 {
00980     QFontDatabase dbase;
00981     QStringList lstSys(dbase.families());
00982 
00983     // if we have criteria; then check fonts before adding
00984     if (fontListCriteria)
00985     {
00986         QStringList lstFonts;
00987         for (QStringList::Iterator it = lstSys.begin(); it != lstSys.end(); ++it)
00988         {
00989             if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) continue;
00990             if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) &&
00991                 !dbase.isBitmapScalable(*it)) continue;
00992             if ((fontListCriteria & SmoothScalableFonts) > 0 && !dbase.isSmoothlyScalable(*it)) continue;
00993             lstFonts.append(*it);
00994         }
00995 
00996         if((fontListCriteria & FixedWidthFonts) > 0) {
00997             // Fallback.. if there are no fixed fonts found, it's probably a
00998             // bug in the font server or Qt.  In this case, just use 'fixed'
00999             if (lstFonts.count() == 0)
01000                 lstFonts.append("fixed");
01001         }
01002 
01003         lstSys = lstFonts;
01004     }
01005 
01006     lstSys.sort();
01007 
01008     list = lstSys;
01009 }
01010 
01011 void KFontChooser::Private::setFamilyBoxItems(const QStringList &fonts)
01012 {
01013     signalsAllowed = false;
01014 
01015     QStringList trfonts = translateFontNameList(fonts, &qtFamilies);
01016     familyListBox->clear();
01017     familyListBox->addItems(trfonts);
01018 
01019     signalsAllowed = true;
01020 }
01021 
01022 void KFontChooser::Private::fillFamilyListBox(bool onlyFixedFonts)
01023 {
01024     QStringList fontList;
01025     getFontList(fontList, onlyFixedFonts?FixedWidthFonts:0);
01026     setFamilyBoxItems(fontList);
01027 }
01028 
01029 void KFontChooser::Private::_k_showXLFDArea(bool show)
01030 {
01031     if( show )
01032     {
01033         xlfdEdit->parentWidget()->show();
01034     }
01035     else
01036     {
01037         xlfdEdit->parentWidget()->hide();
01038     }
01039 }
01040 
01041 #include "kfontchooser.moc"
01042 #include "sampleedit_p.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal