• Skip to content
  • Skip to link menu
KDE 4.3 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     int checkBoxGap = KDialog::spacingHint() / 2;
00162 
00163     // The splitter contains font attribute widgets in the top part,
00164     // and the font preview in the bottom part.
00165     // The splitter is there to allow the user to resize the font preview.
00166     QSplitter *splitter = new QSplitter(Qt::Vertical, this);
00167     splitter->setChildrenCollapsible(false);
00168     topLayout->addWidget(splitter);
00169 
00170     // Build the grid of font attribute widgets for the upper splitter part.
00171     //
00172     QWidget *page;
00173     QGridLayout *gridLayout;
00174     int row = 0;
00175     if( flags & DisplayFrame )
00176     {
00177         page = new QGroupBox( i18n("Requested Font"), this );
00178         splitter->addWidget(page);
00179         gridLayout = new QGridLayout( page );
00180         row = 1;
00181     }
00182     else
00183     {
00184         page = new QWidget( this );
00185         splitter->addWidget(page);
00186         gridLayout = new QGridLayout( page );
00187         gridLayout->setMargin( 0 );
00188     }
00189 
00190     //
00191     // first, create the labels across the top
00192     //
00193     QHBoxLayout *familyLayout = new QHBoxLayout();
00194     familyLayout->addSpacing( checkBoxGap );
00195     if ( flags & ShowDifferences ) {
00196         d->familyCheckbox = new QCheckBox(i18nc("@option:check","Font"), page);
00197         connect(d->familyCheckbox, SIGNAL(toggled(bool)),
00198                 this, SLOT(_k_toggled_checkbox()));
00199         familyLayout->addWidget(d->familyCheckbox, 0, Qt::AlignLeft);
00200         d->familyCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font family settings."));
00201         d->familyCheckbox->setToolTip(i18nc("@info:tooltip","Change font family?") );
00202         d->familyLabel = 0;
00203     } else {
00204         d->familyCheckbox = 0;
00205         d->familyLabel = new QLabel( i18nc("@label","Font:"), page );
00206         familyLayout->addWidget(d->familyLabel, 1, Qt::AlignLeft);
00207     }
00208     gridLayout->addLayout(familyLayout, row, 0 );
00209 
00210     QHBoxLayout *styleLayout = new QHBoxLayout();
00211     if ( flags & ShowDifferences ) {
00212         d->styleCheckbox = new QCheckBox(i18nc("@option:check","Font style"), page);
00213         connect(d->styleCheckbox, SIGNAL(toggled(bool)),
00214                 this, SLOT(_k_toggled_checkbox()));
00215         styleLayout->addWidget(d->styleCheckbox, 0, Qt::AlignLeft);
00216         d->styleCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font style settings."));
00217         d->styleCheckbox->setToolTip(i18nc("@info:tooltip","Change font style?"));
00218         d->styleLabel = 0;
00219     } else {
00220         d->styleCheckbox = 0;
00221         d->styleLabel = new QLabel(i18n("Font style:"), page );
00222         styleLayout->addWidget(d->styleLabel, 1, Qt::AlignLeft);
00223     }
00224     styleLayout->addSpacing( checkBoxGap );
00225     gridLayout->addLayout(styleLayout, row, 1 );
00226 
00227     QHBoxLayout *sizeLayout = new QHBoxLayout();
00228     if ( flags & ShowDifferences ) {
00229         d->sizeCheckbox = new QCheckBox(i18nc("@option:check","Size"),page);
00230         connect(d->sizeCheckbox, SIGNAL(toggled(bool)),
00231                 this, SLOT(_k_toggled_checkbox()));
00232         sizeLayout->addWidget(d->sizeCheckbox, 0, Qt::AlignLeft);
00233         d->sizeCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font size settings."));
00234         d->sizeCheckbox->setToolTip(i18nc("@info:tooltip","Change font size?"));
00235         d->sizeLabel = 0;
00236     } else {
00237         d->sizeCheckbox = 0;
00238         d->sizeLabel = new QLabel(i18nc("@label:listbox Font size", "Size:"), page );
00239         sizeLayout->addWidget(d->sizeLabel, 1, Qt::AlignLeft);
00240     }
00241     sizeLayout->addSpacing( checkBoxGap );
00242     sizeLayout->addSpacing( checkBoxGap ); // prevent label from eating border
00243     gridLayout->addLayout(sizeLayout, row, 2 );
00244 
00245     row ++;
00246 
00247     //
00248     // now create the actual boxes that hold the info
00249     //
00250     d->familyListBox = new KListWidget( page );
00251     d->familyListBox->setEnabled( flags ^ ShowDifferences );
00252     gridLayout->addWidget( d->familyListBox, row, 0 );
00253     QString fontFamilyWhatsThisText (
00254         i18nc("@info:whatsthis","Here you can choose the font family to be used." ));
00255     d->familyListBox->setWhatsThis(fontFamilyWhatsThisText );
00256 
00257     if ( flags & ShowDifferences ) {
00258         d->familyCheckbox->setWhatsThis(fontFamilyWhatsThisText );
00259     } else {
00260         d->familyLabel->setWhatsThis(fontFamilyWhatsThisText );
00261     }
00262 
00263     connect(d->familyListBox, SIGNAL(currentTextChanged(const QString &)),
00264             this, SLOT(_k_family_chosen_slot(const QString &)));
00265     if ( !fontList.isEmpty() ) {
00266         d->setFamilyBoxItems(fontList);
00267     }
00268     else
00269     {
00270         d->fillFamilyListBox( flags & FixedFontsOnly );
00271     }
00272 
00273     d->familyListBox->setMinimumWidth( minimumListWidth( d->familyListBox ) );
00274     d->familyListBox->setMinimumHeight(
00275         minimumListHeight( d->familyListBox, visibleListSize  ) );
00276 
00277     d->styleListBox = new KListWidget( page );
00278     d->styleListBox->setEnabled( flags ^ ShowDifferences );
00279     gridLayout->addWidget(d->styleListBox, row, 1);
00280     d->styleListBox->setWhatsThis(i18nc("@info:whatsthis","Here you can choose the font style to be used." ));
00281     if ( flags & ShowDifferences ) {
00282         ((QWidget *)d->styleCheckbox)->setWhatsThis(fontFamilyWhatsThisText );
00283     } else {
00284         ((QWidget *)d->styleLabel)->setWhatsThis( fontFamilyWhatsThisText );
00285     }
00286     // Populate usual styles, to determine minimum list width;
00287     // will be replaced later with correct styles.
00288     d->styleListBox->addItem(i18nc("@item font","Regular"));
00289     d->styleListBox->addItem(i18nc("@item font","Italic"));
00290     d->styleListBox->addItem(i18nc("@item font","Oblique"));
00291     d->styleListBox->addItem(i18nc("@item font","Bold"));
00292     d->styleListBox->addItem(i18nc("@item font","Bold Italic"));
00293     d->styleListBox->setMinimumWidth( minimumListWidth( d->styleListBox ) );
00294     d->styleListBox->setMinimumHeight(
00295         minimumListHeight( d->styleListBox, visibleListSize  ) );
00296 
00297     connect(d->styleListBox, SIGNAL(currentTextChanged(const QString &)),
00298             this, SLOT(_k_style_chosen_slot(const QString &)));
00299 
00300 
00301     d->sizeListBox = new KListWidget( page );
00302     d->sizeOfFont = new KIntNumInput(page);
00303     d->sizeOfFont->setMinimum(4);
00304     d->sizeOfFont->setMaximum(999);
00305     d->sizeOfFont->setSliderEnabled(false);
00306 
00307     d->sizeListBox->setEnabled( flags ^ ShowDifferences );
00308     d->sizeOfFont->setEnabled( flags ^ ShowDifferences );
00309     if( sizeIsRelativeState ) {
00310         QString sizeIsRelativeCBText =
00311             i18nc("@item font size","Relative");
00312         QString sizeIsRelativeCBToolTipText =
00313             i18n("Font size<br /><i>fixed</i> or <i>relative</i><br />to environment");
00314         QString sizeIsRelativeCBWhatsThisText =
00315             i18n("Here you can switch between fixed font size and font size "
00316                  "to be calculated dynamically and adjusted to changing "
00317                  "environment (e.g. widget dimensions, paper size)." );
00318         d->sizeIsRelativeCheckBox = new QCheckBox( sizeIsRelativeCBText,
00319                                                 page );
00320         d->sizeIsRelativeCheckBox->setTristate( flags & ShowDifferences );
00321         QGridLayout *sizeLayout2 = new QGridLayout();
00322         sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
00323         gridLayout->addLayout(sizeLayout2, row, 2);
00324         sizeLayout2->setColumnStretch( 1, 1 ); // to prevent text from eating the right border
00325         sizeLayout2->addWidget( d->sizeOfFont, 0, 0, 1, 2);
00326         sizeLayout2->addWidget(d->sizeListBox, 1,0, 1,2);
00327         sizeLayout2->addWidget(d->sizeIsRelativeCheckBox, 2, 0, Qt::AlignLeft);
00328         d->sizeIsRelativeCheckBox->setWhatsThis(sizeIsRelativeCBWhatsThisText );
00329         d->sizeIsRelativeCheckBox->setToolTip( sizeIsRelativeCBToolTipText );
00330     }
00331     else {
00332         d->sizeIsRelativeCheckBox = 0L;
00333         QGridLayout *sizeLayout2 = new QGridLayout();
00334         sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
00335         gridLayout->addLayout(sizeLayout2, row, 2);
00336         sizeLayout2->addWidget( d->sizeOfFont, 0, 0);
00337         sizeLayout2->addWidget(d->sizeListBox, 1,0);
00338     }
00339     QString fontSizeWhatsThisText =
00340         i18n("Here you can choose the font size to be used." );
00341     d->sizeListBox->setWhatsThis(fontSizeWhatsThisText );
00342 
00343     if ( flags & ShowDifferences ) {
00344         ((QWidget *)d->sizeCheckbox)->setWhatsThis(fontSizeWhatsThisText );
00345     } else {
00346         ((QWidget *)d->sizeLabel)->setWhatsThis( fontSizeWhatsThisText );
00347     }
00348 
00349     // Populate with usual sizes, to determine minimum list width;
00350     // will be replaced later with correct sizes.
00351     d->fillSizeList();
00352     d->sizeListBox->setMinimumWidth( minimumListWidth(d->sizeListBox) +
00353                                   d->sizeListBox->fontMetrics().maxWidth() );
00354     d->sizeListBox->setMinimumHeight(
00355         minimumListHeight( d->sizeListBox, visibleListSize  ) );
00356 
00357     connect( d->sizeOfFont, SIGNAL( valueChanged(int) ),
00358              this, SLOT(_k_size_value_slot(int)));
00359 
00360     connect( d->sizeListBox, SIGNAL(currentTextChanged(const QString&)),
00361              this, SLOT(_k_size_chosen_slot(const QString&)) );
00362 
00363     row ++;
00364     //
00365     // Completed the font attribute grid.
00366 
00367     // Add the font preview into the lower part of the splitter.
00368     //
00369     d->sampleEdit = new SampleEdit(page);
00370     d->sampleEdit->setAcceptRichText(false);
00371     QFont tmpFont( KGlobalSettings::generalFont().family(), 64, QFont::Black );
00372     d->sampleEdit->setFont(tmpFont);
00373     d->sampleEdit->setMinimumHeight( d->sampleEdit->fontMetrics().lineSpacing() );
00374     // i18n: A classical test phrase, with all letters of the English alphabet.
00375     // Replace it with a sample text in your language, such that it is
00376     // representative of language's writing system.
00377     // If you wish, you can input several lines of text separated by \n.
00378     setSampleText(i18n("The Quick Brown Fox Jumps Over The Lazy Dog"));
00379     d->sampleEdit->setTextCursor(QTextCursor(d->sampleEdit->document()));
00380     QString sampleEditWhatsThisText =
00381         i18n("This sample text illustrates the current settings. "
00382              "You may edit it to test special characters." );
00383     d->sampleEdit->setWhatsThis(sampleEditWhatsThisText );
00384 
00385     connect(this, SIGNAL(fontSelected(const QFont &)),
00386             this, SLOT(_k_displaySample(const QFont &)));
00387 
00388     splitter->addWidget(d->sampleEdit);
00389     //
00390     // Finished setting up the splitter.
00391 
00392     // Add XLFD data below the font attributes/preview splitter.
00393     //
00394     QVBoxLayout *vbox;
00395     if( flags & DisplayFrame )
00396     {
00397         page = new QGroupBox( i18n("Actual Font"), this );
00398         topLayout->addWidget(page);
00399         vbox = new QVBoxLayout( page );
00400         vbox->addSpacing( fontMetrics().lineSpacing() );
00401     }
00402     else
00403     {
00404         page = new QWidget( this );
00405         topLayout->addWidget(page);
00406         vbox = new QVBoxLayout( page );
00407         vbox->setMargin( 0 );
00408         QLabel *label = new QLabel( i18n("Actual Font"), page );
00409         vbox->addWidget( label );
00410     }
00411 
00412     d->xlfdEdit = new KLineEdit( page );
00413     vbox->addWidget( d->xlfdEdit );
00414     //
00415     // Finished setting up the chooser layout.
00416 
00417     // lets initialize the display if possible
00418     setFont( KGlobalSettings::generalFont(), d->usingFixed );
00419 
00420     // check or uncheck or gray out the "relative" checkbox
00421     if( sizeIsRelativeState && d->sizeIsRelativeCheckBox )
00422         setSizeIsRelative( *sizeIsRelativeState );
00423 
00424     KConfigGroup cg(KGlobal::config(), QLatin1String("General"));
00425     d->_k_showXLFDArea(cg.readEntry(QLatin1String("fontSelectorShowXLFD"), false));
00426 
00427     // Set focus to the size list as this is the most commonly changed property
00428     d->sizeListBox->setFocus();
00429 }
00430 
00431 KFontChooser::~KFontChooser()
00432 {
00433     delete d;
00434 }
00435 
00436 void KFontChooser::setColor( const QColor & col )
00437 {
00438     d->m_palette.setColor( QPalette::Active, QPalette::Text, col );
00439     QPalette pal = d->sampleEdit->palette();
00440     pal.setColor( QPalette::Active, QPalette::Text, col );
00441     d->sampleEdit->setPalette( pal );
00442     QTextCursor cursor = d->sampleEdit->textCursor();
00443     d->sampleEdit->selectAll();
00444     d->sampleEdit->setTextColor( col );
00445     d->sampleEdit->setTextCursor( cursor );
00446 }
00447 
00448 QColor KFontChooser::color() const
00449 {
00450     return d->m_palette.color( QPalette::Active, QPalette::Text );
00451 }
00452 
00453 void KFontChooser::setBackgroundColor( const QColor & col )
00454 {
00455     d->m_palette.setColor( QPalette::Active, QPalette::Base, col );
00456     QPalette pal = d->sampleEdit->palette();
00457     pal.setColor( QPalette::Active, QPalette::Base, col );
00458     d->sampleEdit->setPalette( pal );
00459 }
00460 
00461 QColor KFontChooser::backgroundColor() const
00462 {
00463     return d->m_palette.color( QPalette::Active, QPalette::Base );
00464 }
00465 
00466 void KFontChooser::setSizeIsRelative( Qt::CheckState relative )
00467 {
00468     // check or uncheck or gray out the "relative" checkbox
00469     if( d->sizeIsRelativeCheckBox ) {
00470         if( Qt::PartiallyChecked == relative )
00471             d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked);
00472         else
00473             d->sizeIsRelativeCheckBox->setCheckState(  (Qt::Checked == relative )  ? Qt::Checked : Qt::Unchecked);
00474     }
00475 }
00476 
00477 Qt::CheckState KFontChooser::sizeIsRelative() const
00478 {
00479     return d->sizeIsRelativeCheckBox
00480         ? d->sizeIsRelativeCheckBox->checkState()
00481         : Qt::PartiallyChecked;
00482 }
00483 
00484 QString KFontChooser::sampleText() const
00485 {
00486     return d->sampleEdit->toPlainText();
00487 }
00488 
00489 void KFontChooser::setSampleText( const QString &text )
00490 {
00491     d->sampleEdit->setPlainText(text);
00492 }
00493 
00494 void KFontChooser::setSampleBoxVisible( bool visible )
00495 {
00496     d->sampleEdit->setVisible( visible );
00497 }
00498 
00499 QSize KFontChooser::sizeHint( void ) const
00500 {
00501     return minimumSizeHint();
00502 }
00503 
00504 
00505 void KFontChooser::enableColumn( int column, bool state )
00506 {
00507     if( column & FamilyList )
00508     {
00509         d->familyListBox->setEnabled(state);
00510     }
00511     if( column & StyleList )
00512     {
00513         d->styleListBox->setEnabled(state);
00514     }
00515     if( column & SizeList )
00516     {
00517         d->sizeListBox->setEnabled(state);
00518         d->sizeOfFont->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, it is 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::const_iterator it = lstSys.constBegin(); it != lstSys.constEnd(); ++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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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