• Skip to content
  • Skip to link menu
KDE 4.2 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     d->sampleEdit->setTextCursor(QTextCursor(d->sampleEdit->document()));
00384     QString sampleEditWhatsThisText =
00385         i18n("This sample text illustrates the current settings. "
00386              "You may edit it to test special characters." );
00387     d->sampleEdit->setWhatsThis(sampleEditWhatsThisText );
00388 
00389     connect(this, SIGNAL(fontSelected(const QFont &)),
00390             this, SLOT(_k_displaySample(const QFont &)));
00391 
00392     splitter->addWidget(d->sampleEdit);
00393     //
00394     // Finished setting up the splitter.
00395 
00396     // Add XLFD data below the font attributes/preview splitter.
00397     //
00398     QVBoxLayout *vbox;
00399     if( flags & DisplayFrame )
00400     {
00401         page = new QGroupBox( i18n("Actual Font"), this );
00402         topLayout->addWidget(page);
00403         vbox = new QVBoxLayout( page );
00404         vbox->setSpacing( KDialog::spacingHint() );
00405         vbox->addSpacing( fontMetrics().lineSpacing() );
00406     }
00407     else
00408     {
00409         page = new QWidget( this );
00410         topLayout->addWidget(page);
00411         vbox = new QVBoxLayout( page );
00412         vbox->setMargin( 0 );
00413         vbox->setSpacing( KDialog::spacingHint() );
00414         QLabel *label = new QLabel( i18n("Actual Font"), page );
00415         vbox->addWidget( label );
00416     }
00417 
00418     d->xlfdEdit = new KLineEdit( page );
00419     vbox->addWidget( d->xlfdEdit );
00420     //
00421     // Finished setting up the chooser layout.
00422 
00423     // lets initialize the display if possible
00424     setFont( KGlobalSettings::generalFont(), d->usingFixed );
00425 
00426     // check or uncheck or gray out the "relative" checkbox
00427     if( sizeIsRelativeState && d->sizeIsRelativeCheckBox )
00428         setSizeIsRelative( *sizeIsRelativeState );
00429 
00430     KConfigGroup cg(KGlobal::config(), QLatin1String("General"));
00431     d->_k_showXLFDArea(cg.readEntry(QLatin1String("fontSelectorShowXLFD"), false));
00432 
00433     // Set focus to the size list as this is the most commonly changed property
00434     d->sizeListBox->setFocus();
00435 }
00436 
00437 KFontChooser::~KFontChooser()
00438 {
00439     delete d;
00440 }
00441 
00442 void KFontChooser::setColor( const QColor & col )
00443 {
00444     d->m_palette.setColor( QPalette::Active, QPalette::Text, col );
00445     QPalette pal = d->sampleEdit->palette();
00446     pal.setColor( QPalette::Active, QPalette::Text, col );
00447     d->sampleEdit->setPalette( pal );
00448     QTextCursor cursor = d->sampleEdit->textCursor();
00449     d->sampleEdit->selectAll();
00450     d->sampleEdit->setTextColor( col );
00451     d->sampleEdit->setTextCursor( cursor );
00452 }
00453 
00454 QColor KFontChooser::color() const
00455 {
00456     return d->m_palette.color( QPalette::Active, QPalette::Text );
00457 }
00458 
00459 void KFontChooser::setBackgroundColor( const QColor & col )
00460 {
00461     d->m_palette.setColor( QPalette::Active, QPalette::Base, col );
00462     QPalette pal = d->sampleEdit->palette();
00463     pal.setColor( QPalette::Active, QPalette::Base, col );
00464     d->sampleEdit->setPalette( pal );
00465 }
00466 
00467 QColor KFontChooser::backgroundColor() const
00468 {
00469     return d->m_palette.color( QPalette::Active, QPalette::Base );
00470 }
00471 
00472 void KFontChooser::setSizeIsRelative( Qt::CheckState relative )
00473 {
00474     // check or uncheck or gray out the "relative" checkbox
00475     if( d->sizeIsRelativeCheckBox ) {
00476         if( Qt::PartiallyChecked == relative )
00477             d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked);
00478         else
00479             d->sizeIsRelativeCheckBox->setCheckState(  (Qt::Checked == relative )  ? Qt::Checked : Qt::Unchecked);
00480     }
00481 }
00482 
00483 Qt::CheckState KFontChooser::sizeIsRelative() const
00484 {
00485     return d->sizeIsRelativeCheckBox
00486         ? d->sizeIsRelativeCheckBox->checkState()
00487         : Qt::PartiallyChecked;
00488 }
00489 
00490 QString KFontChooser::sampleText() const
00491 {
00492     return d->sampleEdit->toPlainText();
00493 }
00494 
00495 void KFontChooser::setSampleText( const QString &text )
00496 {
00497     d->sampleEdit->setPlainText(text);
00498 }
00499 
00500 void KFontChooser::setSampleBoxVisible( bool visible )
00501 {
00502     d->sampleEdit->setVisible( visible );
00503 }
00504 
00505 QSize KFontChooser::sizeHint( void ) const
00506 {
00507     return minimumSizeHint();
00508 }
00509 
00510 
00511 void KFontChooser::enableColumn( int column, bool state )
00512 {
00513     if( column & FamilyList )
00514     {
00515         d->familyListBox->setEnabled(state);
00516     }
00517     if( column & StyleList )
00518     {
00519         d->styleListBox->setEnabled(state);
00520     }
00521     if( column & SizeList )
00522     {
00523         d->sizeListBox->setEnabled(state);
00524     }
00525 }
00526 
00527 
00528 void KFontChooser::setFont( const QFont& aFont, bool onlyFixed )
00529 {
00530     d->selFont = aFont;
00531     d->selectedSize=aFont.pointSize();
00532     if (d->selectedSize == -1)
00533         d->selectedSize = QFontInfo(aFont).pointSize();
00534 
00535     if( onlyFixed != d->usingFixed)
00536     {
00537         d->usingFixed = onlyFixed;
00538         d->fillFamilyListBox(d->usingFixed);
00539     }
00540     d->setupDisplay();
00541 }
00542 
00543 
00544 KFontChooser::FontDiffFlags KFontChooser::fontDiffFlags() const
00545 {
00546     FontDiffFlags diffFlags = NoFontDiffFlags;
00547 
00548     if ( d->familyCheckbox && d->familyCheckbox->isChecked() ) {
00549         diffFlags |= FontDiffFamily;
00550     }
00551 
00552     if ( d->styleCheckbox && d->styleCheckbox->isChecked() ) {
00553         diffFlags |= FontDiffStyle;
00554     }
00555 
00556     if ( d->sizeCheckbox && d->sizeCheckbox->isChecked() ) {
00557         diffFlags |= FontDiffSize;
00558     }
00559 
00560     return diffFlags;
00561 }
00562 
00563 QFont KFontChooser::font() const
00564 {
00565     return d->selFont;
00566 }
00567 
00568 void KFontChooser::Private::_k_toggled_checkbox()
00569 {
00570     familyListBox->setEnabled( familyCheckbox->isChecked() );
00571     styleListBox->setEnabled( styleCheckbox->isChecked() );
00572     sizeListBox->setEnabled( sizeCheckbox->isChecked() );
00573     sizeOfFont->setEnabled( sizeCheckbox->isChecked() );
00574 }
00575 
00576 void KFontChooser::Private::_k_family_chosen_slot(const QString& family)
00577 {
00578     if ( !signalsAllowed ) {
00579         return;
00580     }
00581     signalsAllowed = false;
00582 
00583     QString currentFamily;
00584     if (family.isEmpty()) {
00585         Q_ASSERT( familyListBox->currentItem() );
00586         if (familyListBox->currentItem()) {
00587           currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00588         }
00589     }
00590     else {
00591         currentFamily = qtFamilies[family];
00592     }
00593 
00594     // Get the list of styles available in this family.
00595     QFontDatabase dbase;
00596     QStringList styles = dbase.styles(currentFamily);
00597     if (styles.isEmpty()) {
00598         // Avoid extraction, its in kdeqt.po
00599         styles.append(I18NC_NOX("QFontDatabase", "Normal"));
00600     }
00601 
00602     // Filter style strings and add to the listbox.
00603     QString pureFamily;
00604     splitFontString(family, &pureFamily);
00605     QStringList filteredStyles;
00606     qtStyles.clear();
00607     foreach (const QString &style, styles) {
00608         // Sometimes the font database will report an invalid style,
00609         // that falls back back to another when set.
00610         // Remove such styles, by checking set/get round-trip.
00611         if (dbase.styleString(dbase.font(currentFamily, style, 10)) != style) {
00612             styles.removeAll(style);
00613             continue;
00614         }
00615 
00616         // We don't like Qt's name for some styles.
00617         QString styleMod = style;
00618         if (style == I18NC_NOX("QFontDatabase", "Normal"))
00619             styleMod = i18nc("@item font", "Regular");
00620 
00621         // i18n: Filtering message, so that translators can script the
00622         // style string according to the font family name (e.g. may need
00623         // noun-adjective congruence wrt. gender of the family name).
00624         // The message provides the dynamic context 'family', which is
00625         // the family name to which the style string corresponds.
00626         QString fstyle = ki18nc("@item Font style", "%1").subs(styleMod).inContext("family", pureFamily).toString();
00627         if (!filteredStyles.contains(fstyle)) {
00628             filteredStyles.append(fstyle);
00629             qtStyles.insert(fstyle, style);
00630         }
00631     }
00632     styleListBox->clear();
00633     styleListBox->addItems(filteredStyles);
00634 
00635     // Try to set the current style in the listbox to that previous.
00636     int listPos = styles.indexOf(selectedStyle);
00637     if (listPos < 0) {
00638         // Make extra effort to have Italic selected when Oblique was chosen,
00639         // and vice versa, as that is what the user would probably want.
00640         QString styleIt = i18nc("@item font", "Italic");
00641         QString styleOb = i18nc("@item font", "Oblique");
00642         for (int i = 0; i < 2; ++i) {
00643             int pos = selectedStyle.indexOf(styleIt);
00644             if (pos >= 0) {
00645                 QString style = selectedStyle;
00646                 style.replace(pos, styleIt.length(), styleOb);
00647                 listPos = styles.indexOf(style);
00648                 if (listPos >= 0) break;
00649             }
00650             qSwap(styleIt, styleOb);
00651         }
00652     }
00653     styleListBox->setCurrentRow(listPos >= 0 ? listPos : 0);
00654     QString currentStyle = qtStyles[styleListBox->currentItem()->text()];
00655 
00656     // Recompute the size listbox for this family/style.
00657     int currentSize = setupSizeListBox(currentFamily, currentStyle);
00658     sizeOfFont->setValue(currentSize);
00659 
00660     selFont = dbase.font(currentFamily, currentStyle, currentSize);
00661     emit q->fontSelected(selFont);
00662 
00663     signalsAllowed = true;
00664 }
00665 
00666 void KFontChooser::Private::_k_style_chosen_slot(const QString& style)
00667 {
00668     if ( !signalsAllowed ) {
00669         return;
00670     }
00671     signalsAllowed = false;
00672 
00673     QFontDatabase dbase;
00674     QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00675     QString currentStyle;
00676     if (style.isEmpty()) {
00677         currentStyle = qtStyles[styleListBox->currentItem()->text()];
00678     } else {
00679         currentStyle = qtStyles[style];
00680     }
00681 
00682     // Recompute the size listbox for this family/style.
00683     int currentSize = setupSizeListBox(currentFamily, currentStyle);
00684     sizeOfFont->setValue(currentSize);
00685 
00686     selFont = dbase.font(currentFamily, currentStyle, currentSize);
00687     emit q->fontSelected(selFont);
00688 
00689     if (!style.isEmpty()) {
00690         selectedStyle = currentStyle;
00691     }
00692 
00693     signalsAllowed = true;
00694 }
00695 
00696 void KFontChooser::Private::_k_size_chosen_slot(const QString& size)
00697 {
00698     if ( !signalsAllowed ) {
00699         return;
00700     }
00701 
00702     signalsAllowed = false;
00703 
00704     int currentSize;
00705     if (size.isEmpty()) {
00706         currentSize = sizeListBox->currentItem()->text().toInt();
00707     } else {
00708         currentSize = size.toInt();
00709     }
00710 
00711     // Reset the customized size slot in the list if not needed.
00712     if (customSizeRow >= 0 && selFont.pointSize() != currentSize) {
00713         sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
00714         customSizeRow = -1;
00715     }
00716 
00717     sizeOfFont->setValue(currentSize);
00718     selFont.setPointSize(currentSize);
00719     emit q->fontSelected(selFont);
00720 
00721     if (!size.isEmpty()) {
00722         selectedSize = currentSize;
00723     }
00724 
00725     signalsAllowed = true;
00726 }
00727 
00728 void KFontChooser::Private::_k_size_value_slot(int val)
00729 {
00730     if ( !signalsAllowed ) {
00731         return;
00732     }
00733     signalsAllowed = false;
00734 
00735     QFontDatabase dbase;
00736     QString family = qtFamilies[familyListBox->currentItem()->text()];
00737     QString style = qtStyles[styleListBox->currentItem()->text()];
00738 
00739     // Reset current size slot in list if it was customized.
00740     if (sizeListBox->currentRow() == customSizeRow) {
00741         sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
00742         customSizeRow = -1;
00743     }
00744 
00745     bool canCustomize = true;
00746 
00747     // For Qt-bad-sizes workaround: skip this block unconditionally
00748     if (!dbase.isSmoothlyScalable(family, style)) {
00749         // Bitmap font, allow only discrete sizes.
00750         // Determine the nearest in the direction of change.
00751         canCustomize = false;
00752         int nrows = sizeListBox->count();
00753         int row = sizeListBox->currentRow();
00754         int nrow;
00755         if (val - selFont.pointSize() > 0) {
00756             for (nrow = row + 1; nrow < nrows; ++nrow)
00757                 if (sizeListBox->item(nrow)->text().toInt() >= val)
00758                     break;
00759         }
00760         else {
00761             for (nrow = row - 1; nrow >= 0; --nrow)
00762                 if (sizeListBox->item(nrow)->text().toInt() <= val)
00763                     break;
00764         }
00765         // Make sure the new row is not out of bounds.
00766         nrow = nrow < 0 ? 0 : nrow >= nrows ? nrows - 1 : nrow;
00767         // Get the size from the new row and set the spinbox to that size.
00768         val = sizeListBox->item(nrow)->text().toInt();
00769         sizeOfFont->setValue(val);
00770     }
00771 
00772     // Set the current size in the size listbox.
00773     int row = nearestSizeRow(val, canCustomize);
00774     sizeListBox->setCurrentRow(row);
00775 
00776     selectedSize = val;
00777     selFont.setPointSize(val);
00778     emit q->fontSelected( selFont );
00779 
00780     signalsAllowed = true;
00781 }
00782 
00783 void KFontChooser::Private::_k_displaySample( const QFont& font )
00784 {
00785     sampleEdit->setFont(font);
00786     //sampleEdit->setCursorPosition(0);
00787 
00788     xlfdEdit->setText(font.rawName());
00789     xlfdEdit->setCursorPosition(0);
00790 
00791     //QFontInfo a = QFontInfo(font);
00792     //kDebug() << "font: " << a.family () << ", " << a.pointSize ();
00793     //kDebug() << "      (" << font.toString() << ")\n";
00794 }
00795 
00796 int KFontChooser::Private::nearestSizeRow (int val, bool customize)
00797 {
00798     int diff = 1000;
00799     int row = 0;
00800     for (int r = 0; r < sizeListBox->count(); ++r) {
00801         int cval = sizeListBox->item(r)->text().toInt();
00802         if (qAbs(cval - val) < diff) {
00803             diff = qAbs(cval - val);
00804             row = r;
00805         }
00806     }
00807     // For Qt-bad-sizes workaround: ignore value of customize, use true
00808     if (customize && diff > 0) {
00809         customSizeRow = row;
00810         standardSizeAtCustom = sizeListBox->item(row)->text();
00811         sizeListBox->item(row)->setText(QString::number(val));
00812     }
00813     return row;
00814 }
00815 
00816 int KFontChooser::Private::fillSizeList (const QList<int> &sizes_)
00817 {
00818     if ( !sizeListBox ) {
00819         return 0; //assertion.
00820     }
00821 
00822     QList<int> sizes = sizes_;
00823     bool canCustomize = false;
00824     if (sizes.count() == 0) {
00825         static const int c[] = {
00826             4,  5,  6,  7,
00827             8,  9,  10, 11,
00828             12, 13, 14, 15,
00829             16, 17, 18, 19,
00830             20, 22, 24, 26,
00831             28, 32, 48, 64,
00832             72, 80, 96, 128,
00833             0
00834         };
00835         for (int i = 0; c[i]; ++i) {
00836             sizes.append(c[i]);
00837         }
00838         // Since sizes were not supplied, this is a vector font,
00839         // and size slot customization is allowed.
00840         canCustomize = true;
00841     }
00842 
00843     // Insert sizes into the listbox.
00844     sizeListBox->clear();
00845     qSort(sizes);
00846     foreach (int size, sizes) {
00847         sizeListBox->addItem(QString::number(size));
00848     }
00849 
00850     // Return the nearest to selected size.
00851     // If the font is vector, the nearest size is always same as selected,
00852     // thus size slot customization is allowed.
00853     // If the font is bitmap, the nearest size need not be same as selected,
00854     // thus size slot customization is not allowed.
00855     customSizeRow = -1;
00856     int row = nearestSizeRow(selectedSize, canCustomize);
00857     return sizeListBox->item(row)->text().toInt();
00858 }
00859 
00860 int KFontChooser::Private::setupSizeListBox (const QString& family, const QString& style)
00861 {
00862     QFontDatabase dbase;
00863     QList<int> sizes;
00864     if (dbase.isSmoothlyScalable(family, style)) {
00865         // A vector font.
00866         //>sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO
00867     }
00868     else {
00869         // A bitmap font.
00870         //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO
00871         sizes = dbase.smoothSizes(family, style);
00872     }
00873 
00874     // Fill the listbox (uses default list of sizes if the given is empty).
00875     // Collect the best fitting size to selected size, to use if not smooth.
00876     int bestFitSize = fillSizeList(sizes);
00877 
00878     // Set the best fit size as current in the listbox if available.
00879     const QList<QListWidgetItem*> selectedSizeList =
00880         sizeListBox->findItems( QString::number(bestFitSize),
00881                                 Qt::MatchExactly );
00882     if ( !selectedSizeList.isEmpty() ) {
00883         sizeListBox->setCurrentItem(selectedSizeList.first());
00884     }
00885     //TODO - KDE4 : sizeListBox->scrollTo(sizeListBox->currentItem());
00886 
00887     return bestFitSize;
00888 }
00889 
00890 void KFontChooser::Private::setupDisplay()
00891 {
00892     QFontDatabase dbase;
00893     QString family = selFont.family().toLower();
00894     QString style = dbase.styleString(selFont).toLower();
00895     int size = selFont.pointSize();
00896     if (size == -1)
00897         size = QFontInfo( selFont ).pointSize();
00898 
00899     int numEntries, i;
00900 
00901     // Direct family match.
00902     numEntries = familyListBox->count();
00903     for (i = 0; i < numEntries; i++) {
00904         if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
00905             familyListBox->setCurrentRow(i);
00906             break;
00907         }
00908     }
00909 
00910     // 1st family fallback.
00911     if ( (i == numEntries) )
00912     {
00913         if (family.contains('['))
00914         {
00915             family = family.left(family.indexOf('[')).trimmed();
00916             for (i = 0; i < numEntries; i++) {
00917                 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
00918                     familyListBox->setCurrentRow(i);
00919                     break;
00920                 }
00921             }
00922         }
00923     }
00924 
00925     // 2nd family fallback.
00926     if ( (i == numEntries) )
00927     {
00928         QString fallback = family+" [";
00929         for (i = 0; i < numEntries; i++) {
00930             if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(fallback)) {
00931                 familyListBox->setCurrentRow(i);
00932                 break;
00933             }
00934         }
00935     }
00936 
00937     // 3rd family fallback.
00938     if ( (i == numEntries) )
00939     {
00940         for (i = 0; i < numEntries; i++) {
00941             if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(family)) {
00942                 familyListBox->setCurrentRow(i);
00943                 break;
00944             }
00945         }
00946     }
00947 
00948     // Family fallback in case nothing matched. Otherwise, diff doesn't work
00949     if ( i == numEntries ) {
00950         familyListBox->setCurrentRow( 0 );
00951     }
00952 
00953     // By setting the current item in the family box, the available
00954     // styles and sizes for that family have been collected.
00955     // Try now to set the current items in the style and size boxes.
00956 
00957     // Set current style in the listbox.
00958     numEntries = styleListBox->count();
00959     for (i = 0; i < numEntries; i++) {
00960         if (style == qtStyles[styleListBox->item(i)->text()].toLower()) {
00961             styleListBox->setCurrentRow(i);
00962             break;
00963         }
00964     }
00965     if (i == numEntries) {
00966         // Style not found, fallback.
00967         styleListBox->setCurrentRow(0);
00968     }
00969 
00970     // Set current size in the listbox.
00971     // If smoothly scalable, allow customizing one of the standard size slots,
00972     // otherwise just select the nearest available size.
00973     QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
00974     QString currentStyle = qtFamilies[styleListBox->currentItem()->text()];
00975     bool canCustomize = dbase.isSmoothlyScalable(currentFamily, currentStyle);
00976     sizeListBox->setCurrentRow(nearestSizeRow(size, canCustomize));
00977 
00978     // Set current size in the spinbox.
00979     sizeOfFont->setValue(sizeListBox->currentItem()->text().toInt());
00980 }
00981 
00982 
00983 void KFontChooser::getFontList( QStringList &list, uint fontListCriteria)
00984 {
00985     QFontDatabase dbase;
00986     QStringList lstSys(dbase.families());
00987 
00988     // if we have criteria; then check fonts before adding
00989     if (fontListCriteria)
00990     {
00991         QStringList lstFonts;
00992         for (QStringList::const_iterator it = lstSys.constBegin(); it != lstSys.constEnd(); ++it)
00993         {
00994             if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) continue;
00995             if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) &&
00996                 !dbase.isBitmapScalable(*it)) continue;
00997             if ((fontListCriteria & SmoothScalableFonts) > 0 && !dbase.isSmoothlyScalable(*it)) continue;
00998             lstFonts.append(*it);
00999         }
01000 
01001         if((fontListCriteria & FixedWidthFonts) > 0) {
01002             // Fallback.. if there are no fixed fonts found, it's probably a
01003             // bug in the font server or Qt.  In this case, just use 'fixed'
01004             if (lstFonts.count() == 0)
01005                 lstFonts.append("fixed");
01006         }
01007 
01008         lstSys = lstFonts;
01009     }
01010 
01011     lstSys.sort();
01012 
01013     list = lstSys;
01014 }
01015 
01016 void KFontChooser::Private::setFamilyBoxItems(const QStringList &fonts)
01017 {
01018     signalsAllowed = false;
01019 
01020     QStringList trfonts = translateFontNameList(fonts, &qtFamilies);
01021     familyListBox->clear();
01022     familyListBox->addItems(trfonts);
01023 
01024     signalsAllowed = true;
01025 }
01026 
01027 void KFontChooser::Private::fillFamilyListBox(bool onlyFixedFonts)
01028 {
01029     QStringList fontList;
01030     getFontList(fontList, onlyFixedFonts?FixedWidthFonts:0);
01031     setFamilyBoxItems(fontList);
01032 }
01033 
01034 void KFontChooser::Private::_k_showXLFDArea(bool show)
01035 {
01036     if( show )
01037     {
01038         xlfdEdit->parentWidget()->show();
01039     }
01040     else
01041     {
01042         xlfdEdit->parentWidget()->hide();
01043     }
01044 }
01045 
01046 #include "kfontchooser.moc"
01047 #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
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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