00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <tqfontdatabase.h>
00021 #include <tqlistbox.h>
00022 #include <tqpainter.h>
00023 #include <tqregexp.h>
00024
00025 #include <kcharsets.h>
00026 #include <tdeconfig.h>
00027 #include <tdeglobal.h>
00028 #include <tdefontdialog.h>
00029
00030 #include "tdefontcombo.h"
00031 #include "tdefontcombo.moc"
00032
00033 #include <ft2build.h>
00034 #include <fontconfig/fontconfig.h>
00035 #include <X11/Xlib.h>
00036 #include <X11/Xatom.h>
00037 #include <X11/Intrinsic.h>
00038 #include <X11/StringDefs.h>
00039 #include <X11/Shell.h>
00040
00041 #include <X11/Xft/Xft.h>
00042
00043
00044 struct TDEFontComboPrivate
00045 {
00046 TDEFontComboPrivate()
00047 : bold(false),
00048 italic(false),
00049 underline(false),
00050 strikeOut(false),
00051 modified(false),
00052 size(0),
00053 lineSpacing(0)
00054 {
00055 }
00056
00057 bool bold : 1;
00058 bool italic : 1;
00059 bool underline : 1;
00060 bool strikeOut : 1;
00061 bool displayFonts : 1;
00062 bool modified : 1;
00063 int size;
00064 int lineSpacing;
00065 TQString defaultFamily;
00066 };
00067
00068 class TDEFontListItem : public TQListBoxItem
00069 {
00070 public:
00071 TDEFontListItem(const TQString &fontName, TDEFontCombo *combo);
00072 virtual ~TDEFontListItem();
00073
00074 virtual int width(const TQListBox *) const;
00075 virtual int height(const TQListBox *) const;
00076
00077 void updateFont();
00078
00079 protected:
00080 virtual void paint(TQPainter *p);
00081
00082 private:
00083 void createFont();
00084
00085 private:
00086 TDEFontCombo *m_combo;
00087 TQString m_fontName;
00088 TQFont *m_font;
00089 bool m_canPaintName;
00090 };
00091
00092 TDEFontListItem::TDEFontListItem(const TQString &fontName, TDEFontCombo *combo)
00093 : TQListBoxItem(combo->listBox()),
00094 m_combo(combo),
00095 m_fontName(fontName),
00096 m_font(0),
00097 m_canPaintName(true)
00098 {
00099 setText(fontName);
00100 }
00101
00102 TDEFontListItem::~TDEFontListItem()
00103 {
00104 delete m_font;
00105 }
00106
00107 int TDEFontListItem::width(const TQListBox *lb) const
00108 {
00109 if (m_font)
00110 return TQFontMetrics(*m_font).width(text()) + 6;
00111 return lb->fontMetrics().width(text()) + 6;
00112 }
00113
00114 int TDEFontListItem::height(const TQListBox *lb) const
00115 {
00116 if (m_combo->d->displayFonts)
00117 return m_combo->d->lineSpacing + 2;
00118 TQFontMetrics fm(lb->fontMetrics());
00119 return fm.lineSpacing() + 2;
00120 }
00121
00122 void TDEFontListItem::paint(TQPainter *p)
00123 {
00124 if (m_combo->d->displayFonts)
00125 {
00126 if (!m_font)
00127 createFont();
00128
00129 TQString t = m_fontName;
00130 if (p->device() != m_combo)
00131 {
00132 if (m_canPaintName)
00133 p->setFont(*m_font);
00134 else
00135 t = TQString::fromLatin1("(%1)").arg(m_fontName);
00136 }
00137 TQFontMetrics fm(p->fontMetrics());
00138 p->drawText(3, (m_combo->d->lineSpacing + fm.ascent() + fm.leading() / 2) / 2, t);
00139 }
00140 else
00141 {
00142 TQFontMetrics fm(p->fontMetrics());
00143 p->drawText(3, fm.ascent() + fm.leading() / 2, m_fontName);
00144 }
00145 }
00146
00147 void TDEFontListItem::updateFont()
00148 {
00149 if (!m_font)
00150 return;
00151
00152 m_font->setBold(m_combo->d->bold);
00153 m_font->setItalic(m_combo->d->italic);
00154 m_font->setUnderline(m_combo->d->underline);
00155 m_font->setStrikeOut(m_combo->d->strikeOut);
00156 m_font->setPointSize(m_combo->d->size);
00157 }
00158
00159 void TDEFontListItem::createFont()
00160 {
00161 if (m_font)
00162 return;
00163
00164 m_font = new TQFont(m_fontName);
00165 TQFontMetrics fm(*m_font);
00166 for (unsigned int i = 0; i < m_fontName.length(); ++i)
00167 if (!fm.inFont(m_fontName[i]))
00168 {
00169 m_canPaintName = false;
00170 break;
00171 }
00172 updateFont();
00173 }
00174
00175 TDEFontCombo::TDEFontCombo(TQWidget *parent, const char *name)
00176 : KComboBox(true, parent, name)
00177 {
00178 init();
00179 TQStringList families;
00180 TDEFontChooser::getFontList(families, 0);
00181 setFonts(families);
00182 }
00183
00184 TDEFontCombo::TDEFontCombo(const TQStringList &fonts, TQWidget *parent, const char *name)
00185 : KComboBox(true, parent, name)
00186 {
00187 init();
00188 setFonts(fonts);
00189 }
00190
00191 void TDEFontCombo::setFonts(const TQStringList &fonts)
00192 {
00193 clear();
00194 for (TQStringList::ConstIterator it = fonts.begin(); it != fonts.end(); ++it)
00195 new TDEFontListItem(*it, this);
00196 }
00197
00198
00199
00200
00201 void TDEFontCombo::setCurrentFont(const TQString &family)
00202 {
00203 TQString lowerName = family.lower();
00204 int c = count();
00205 for(int i = 0; i < c; i++)
00206 {
00207 if (text(i).lower() == lowerName)
00208 {
00209 setCurrentItem(i);
00210 d->defaultFamily = text(i);
00211 d->modified = false;
00212 return;
00213 }
00214 }
00215 int x = lowerName.find(" [");
00216 if (x>-1)
00217 {
00218 lowerName = lowerName.left(x);
00219 for(int i = 0; i < c; i++)
00220 {
00221 if (text(i).lower() == lowerName)
00222 {
00223 setCurrentItem(i);
00224 d->defaultFamily = text(i);
00225 d->modified = false;
00226 return;
00227 }
00228 }
00229 }
00230
00231 lowerName += " [";
00232 for(int i = 0; i < c; i++)
00233 {
00234 if (text(i).lower().startsWith(lowerName))
00235 {
00236 setCurrentItem(i);
00237 d->defaultFamily = text(i);
00238 d->modified = false;
00239 return;
00240 }
00241 }
00242
00243
00244
00245 FcPattern *pattern = NULL;
00246 FcConfig *config = NULL;
00247 FcResult result;
00248 TQString realFamily;
00249 TQRegExp regExp("[-:]");
00250 pattern = FcNameParse( (unsigned char*) family.ascii() );
00251 FcDefaultSubstitute(pattern);
00252 FcConfigSubstitute (config, pattern, FcMatchPattern);
00253 pattern = FcFontMatch(NULL, pattern, &result);
00254 realFamily = (char*)FcNameUnparse(pattern);
00255 realFamily.remove(realFamily.find(regExp), realFamily.length());
00256
00257 if ( !realFamily.isEmpty() && realFamily != family )
00258 setCurrentFont( realFamily );
00259 }
00260
00261 void TDEFontCombo::slotModified( int )
00262 {
00263 d->modified = 1;
00264 }
00265
00266 TQString TDEFontCombo::currentFont() const
00267 {
00268 if (d->modified)
00269 return currentText();
00270 return d->defaultFamily;
00271 }
00272
00273 void TDEFontCombo::setCurrentItem(int i)
00274 {
00275 d->modified = true;
00276 TQComboBox::setCurrentItem(i);
00277 }
00278
00279 void TDEFontCombo::init()
00280 {
00281 d = new TDEFontComboPrivate;
00282 d->displayFonts = displayFonts();
00283 setInsertionPolicy(NoInsertion);
00284 setAutoCompletion(true);
00285 setSize(12);
00286 connect( this, TQT_SIGNAL(highlighted(int)), TQT_SLOT(slotModified(int)));
00287 }
00288
00289 TDEFontCombo::~TDEFontCombo()
00290 {
00291 delete d;
00292 }
00293
00294 void TDEFontCombo::setBold(bool bold)
00295 {
00296 if (d->bold == bold)
00297 return;
00298 d->bold = bold;
00299 updateFonts();
00300 }
00301
00302 bool TDEFontCombo::bold() const
00303 {
00304 return d->bold;
00305 }
00306
00307 void TDEFontCombo::setItalic(bool italic)
00308 {
00309 if (d->italic == italic)
00310 return;
00311 d->italic = italic;
00312 updateFonts();
00313 }
00314
00315 bool TDEFontCombo::italic() const
00316 {
00317 return d->italic;
00318 }
00319
00320 void TDEFontCombo::setUnderline(bool underline)
00321 {
00322 if (d->underline == underline)
00323 return;
00324 d->underline = underline;
00325 updateFonts();
00326 }
00327
00328 bool TDEFontCombo::underline() const
00329 {
00330 return d->underline;
00331 }
00332
00333 void TDEFontCombo::setStrikeOut(bool strikeOut)
00334 {
00335 if (d->strikeOut == strikeOut)
00336 return;
00337 d->strikeOut = strikeOut;
00338 updateFonts();
00339 }
00340
00341 bool TDEFontCombo::strikeOut() const
00342 {
00343 return d->strikeOut;
00344 }
00345
00346 void TDEFontCombo::setSize(int size)
00347 {
00348 if (d->size == size)
00349 return;
00350 d->size = size;
00351 TQFont f;
00352 f.setPointSize(size);
00353 TQFontMetrics fm(f);
00354 d->lineSpacing = fm.lineSpacing();
00355 updateFonts();
00356 }
00357
00358 int TDEFontCombo::size() const
00359 {
00360 return d->size;
00361 }
00362
00363 void TDEFontCombo::updateFonts()
00364 {
00365 if (!d->displayFonts)
00366 return;
00367
00368 for (unsigned int i = 0; i < listBox()->count(); ++i)
00369 {
00370 TDEFontListItem *item = static_cast<TDEFontListItem *>(listBox()->item(i));
00371 item->updateFont();
00372 }
00373 }
00374
00375 bool TDEFontCombo::displayFonts()
00376 {
00377 TDEConfigGroupSaver saver(TDEGlobal::config(), "KDE");
00378 return TDEGlobal::config()->readBoolEntry("DisplayFontItems", true);
00379 }
00380
00381 void TDEFontCombo::virtual_hook( int id, void* data )
00382 { KComboBox::virtual_hook( id, data ); }
00383