kdeui Library API Documentation

kfontcombo.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (c) 2001 Malte Starostik <malte@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016    Boston, MA 02111-1307, USA.
00017 */
00018 
00019 
00020 #include <qfontdatabase.h>
00021 #include <qlistbox.h>
00022 #include <qpainter.h>
00023 #include <qregexp.h>
00024 
00025 #include <kcharsets.h>
00026 #include <kconfig.h>
00027 #include <kglobal.h>
00028 #include <kfontdialog.h>
00029 
00030 #include "kfontcombo.h"
00031 #include "kfontcombo.moc"
00032 
00033 #include <freetype/freetype.h>
00034 #include <X11/Xlib.h>
00035 #include <X11/Xatom.h>
00036 #include <X11/Intrinsic.h>
00037 #include <X11/StringDefs.h>
00038 #include <X11/Shell.h>
00039 
00040 #include <X11/Xft/Xft.h>
00041 
00042 
00043 struct KFontComboPrivate
00044 {
00045     KFontComboPrivate()
00046         : bold(false),
00047           italic(false),
00048           underline(false),
00049           strikeOut(false),
00050       modified(false),
00051           size(0),
00052           lineSpacing(0)
00053     {
00054     };
00055 
00056     bool bold : 1;
00057     bool italic : 1;
00058     bool underline : 1;
00059     bool strikeOut : 1;
00060     bool displayFonts : 1;
00061     bool modified : 1;
00062     int size;
00063     int lineSpacing;
00064     QString defaultFamily;
00065 };
00066 
00067 class KFontListItem : public QListBoxItem
00068 {
00069 public:
00070     KFontListItem(const QString &fontName, KFontCombo *combo);
00071     virtual ~KFontListItem();
00072 
00073     virtual int width(const QListBox *) const;
00074     virtual int height(const QListBox *) const;
00075 
00076     void updateFont();
00077 
00078 protected:
00079     virtual void paint(QPainter *p);
00080 
00081 private:
00082     void createFont();
00083 
00084 private:
00085     KFontCombo *m_combo;
00086     QString m_fontName;
00087     QFont *m_font;
00088     bool m_canPaintName;
00089 };
00090 
00091 KFontListItem::KFontListItem(const QString &fontName, KFontCombo *combo)
00092     : QListBoxItem(combo->listBox()),
00093       m_combo(combo),
00094       m_fontName(fontName),
00095       m_font(0),
00096       m_canPaintName(true)
00097 {
00098     setText(fontName);
00099 }
00100 
00101 KFontListItem::~KFontListItem()
00102 {
00103     delete m_font;
00104 }
00105 
00106 int KFontListItem::width(const QListBox *lb) const
00107 {
00108     if (m_font)
00109        return QFontMetrics(*m_font).width(text()) + 6;
00110     return lb->fontMetrics().width(text()) + 6;
00111 }
00112 
00113 int KFontListItem::height(const QListBox *lb) const
00114 {
00115     if (m_combo->d->displayFonts)
00116         return m_combo->d->lineSpacing + 2;
00117     QFontMetrics fm(lb->fontMetrics());
00118     return fm.lineSpacing() + 2;
00119 }
00120 
00121 void KFontListItem::paint(QPainter *p)
00122 {
00123     if (m_combo->d->displayFonts)
00124     {
00125         if (!m_font)
00126             createFont();
00127 
00128         QString t = m_fontName;
00129         if (p->device() != m_combo)
00130         {
00131             if (m_canPaintName)
00132                 p->setFont(*m_font);
00133             else
00134                 t = QString::fromLatin1("(%1)").arg(m_fontName);
00135         }
00136         QFontMetrics fm(p->fontMetrics());
00137         p->drawText(3, (m_combo->d->lineSpacing + fm.ascent() + fm.leading() / 2) / 2, t);
00138     }
00139     else
00140     {
00141         QFontMetrics fm(p->fontMetrics());
00142         p->drawText(3, fm.ascent() + fm.leading() / 2, m_fontName);
00143     }
00144 }
00145 
00146 void KFontListItem::updateFont()
00147 {
00148     if (!m_font)
00149         return;
00150 
00151     m_font->setBold(m_combo->d->bold);
00152     m_font->setItalic(m_combo->d->italic);
00153     m_font->setUnderline(m_combo->d->underline);
00154     m_font->setStrikeOut(m_combo->d->strikeOut);
00155     m_font->setPointSize(m_combo->d->size);
00156 }
00157 
00158 void KFontListItem::createFont()
00159 {
00160     if (m_font)
00161         return;
00162 
00163     m_font = new QFont(m_fontName);
00164     QFontMetrics fm(*m_font);
00165     for (unsigned int i = 0; i < m_fontName.length(); ++i)
00166         if (!fm.inFont(m_fontName[i]))
00167         {
00168             m_canPaintName = false;
00169             break;
00170         }
00171     updateFont();
00172 }
00173 
00174 KFontCombo::KFontCombo(QWidget *parent, const char *name)
00175     : KComboBox(true, parent, name)
00176 {
00177     init();
00178     QStringList families;
00179     KFontChooser::getFontList(families, 0);
00180     setFonts(families);
00181 }
00182 
00183 KFontCombo::KFontCombo(const QStringList &fonts, QWidget *parent, const char *name)
00184     : KComboBox(true, parent, name)
00185 {
00186     init();
00187     setFonts(fonts);
00188 }
00189 
00190 void KFontCombo::setFonts(const QStringList &fonts)
00191 {
00192     clear();
00193     for (QStringList::ConstIterator it = fonts.begin(); it != fonts.end(); ++it)
00194         new KFontListItem(*it, this);
00195 }
00196 
00197 /*
00198  * Maintenance note: Keep in sync with KFontAction::setFont()
00199  */
00200 void KFontCombo::setCurrentFont(const QString &family)
00201 {
00202     QString lowerName = family.lower();
00203     int c = count();
00204     for(int i = 0; i < c; i++)
00205     {
00206        if (text(i).lower() == lowerName)
00207        {
00208           setCurrentItem(i);
00209           d->defaultFamily = text(i);
00210       d->modified = false;
00211           return;
00212        }
00213     }
00214     int x = lowerName.find(" [");
00215     if (x>-1)
00216     {
00217        lowerName = lowerName.left(x);
00218        for(int i = 0; i < c; i++)
00219        {
00220           if (text(i).lower() == lowerName)
00221           {
00222              setCurrentItem(i);
00223              d->defaultFamily = text(i);
00224          d->modified = false;
00225              return;
00226           }
00227        }
00228     }
00229 
00230     lowerName += " [";
00231     for(int i = 0; i < c; i++)
00232     {
00233        if (text(i).lower().startsWith(lowerName))
00234        {
00235           setCurrentItem(i);
00236           d->defaultFamily = text(i);
00237       d->modified = false;
00238           return;
00239        }
00240     }
00241 
00242     // nothing matched yet, try a fontconfig reverse lookup and
00243     // check again to solve an alias
00244     FcPattern *pattern = NULL;
00245     FcConfig *config = NULL;
00246     QString realFamily;
00247     QRegExp regExp("[-:]");
00248     pattern = FcNameParse( (unsigned char*) family.ascii() );
00249     FcDefaultSubstitute(pattern);
00250     FcConfigSubstitute (config, pattern, FcMatchPattern);
00251     pattern = FcFontMatch(NULL, pattern, NULL);
00252     realFamily = (char*)FcNameUnparse(pattern);
00253     realFamily.remove(realFamily.find(regExp), realFamily.length());
00254 
00255     if ( !realFamily.isEmpty() && realFamily != family )
00256        setCurrentFont( realFamily );
00257 }
00258 
00259 void KFontCombo::slotModified( int )
00260 {
00261    d->modified = 1;
00262 }
00263 
00264 QString KFontCombo::currentFont() const
00265 {
00266    if (d->modified)
00267       return currentText();
00268    return d->defaultFamily;
00269 }
00270 
00271 void KFontCombo::setCurrentItem(int i)
00272 {
00273     d->modified = true;
00274     QComboBox::setCurrentItem(i);
00275 }
00276 
00277 void KFontCombo::init()
00278 {
00279     d = new KFontComboPrivate;
00280     d->displayFonts = displayFonts();
00281     setInsertionPolicy(NoInsertion);
00282     setAutoCompletion(true);
00283     setSize(12);
00284     connect( this, SIGNAL(highlighted(int)), SLOT(slotModified(int)));
00285 }
00286 
00287 KFontCombo::~KFontCombo()
00288 {
00289     delete d;
00290 }
00291 
00292 void KFontCombo::setBold(bool bold)
00293 {
00294     if (d->bold == bold)
00295         return;
00296     d->bold = bold;
00297     updateFonts();
00298 }
00299 
00300 bool KFontCombo::bold() const
00301 {
00302     return d->bold;
00303 }
00304 
00305 void KFontCombo::setItalic(bool italic)
00306 {
00307     if (d->italic == italic)
00308         return;
00309     d->italic = italic;
00310     updateFonts();
00311 }
00312 
00313 bool KFontCombo::italic() const
00314 {
00315     return d->italic;
00316 }
00317 
00318 void KFontCombo::setUnderline(bool underline)
00319 {
00320     if (d->underline == underline)
00321         return;
00322     d->underline = underline;
00323     updateFonts();
00324 }
00325 
00326 bool KFontCombo::underline() const
00327 {
00328     return d->underline;
00329 }
00330 
00331 void KFontCombo::setStrikeOut(bool strikeOut)
00332 {
00333     if (d->strikeOut == strikeOut)
00334         return;
00335     d->strikeOut = strikeOut;
00336     updateFonts();
00337 }
00338 
00339 bool KFontCombo::strikeOut() const
00340 {
00341     return d->strikeOut;
00342 }
00343 
00344 void KFontCombo::setSize(int size)
00345 {
00346     if (d->size == size)
00347         return;
00348     d->size = size;
00349     QFont f;
00350     f.setPointSize(size);
00351     QFontMetrics fm(f);
00352     d->lineSpacing = fm.lineSpacing();
00353     updateFonts();
00354 }
00355 
00356 int KFontCombo::size() const
00357 {
00358     return d->size;
00359 }
00360 
00361 void KFontCombo::updateFonts()
00362 {
00363     if (!d->displayFonts)
00364         return;
00365 
00366     for (unsigned int i = 0; i < listBox()->count(); ++i)
00367     {
00368         KFontListItem *item = static_cast<KFontListItem *>(listBox()->item(i));
00369         item->updateFont();
00370     }
00371 }
00372 
00373 bool KFontCombo::displayFonts()
00374 {
00375     KConfigGroupSaver saver(KGlobal::config(), "KDE");
00376     return KGlobal::config()->readBoolEntry("DisplayFontItems", true);
00377 }
00378 
00379 void KFontCombo::virtual_hook( int id, void* data )
00380 { KComboBox::virtual_hook( id, data ); }
00381 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Mar 22 19:48:26 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003