• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • fonts
kfontchooser.cpp
Go to the documentation of this file.
1/*
2Copyright (C) 1996 Bernd Johannes Wuebben <wuebben@kde.org>
3Copyright (c) 1999 Preston Brown <pbrown@kde.org>
4Copyright (c) 1999 Mario Weilguni <mweilguni@kde.org>
5
6This library is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11This library is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public License
17along with this library; see the file COPYING.LIB. If not, write to
18the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, MA 02110-1301, USA.
20*/
21
22#include "kfontchooser.h"
23#include "fonthelpers_p.h"
24#include "sampleedit_p.h"
25
26#include <QtGui/QCheckBox>
27#include <QtGui/QLabel>
28#include <QtGui/QLayout>
29#include <QtGui/QSplitter>
30#include <QtGui/QScrollBar>
31#include <QtGui/QFontDatabase>
32#include <QtGui/QGroupBox>
33#include <kcharsets.h>
34#include <kconfig.h>
35#include <kdialog.h>
36#include <kglobal.h>
37#include <kglobalsettings.h>
38#include <klineedit.h>
39#include <klistwidget.h>
40#include <klocale.h>
41#include <kstandarddirs.h>
42#include <kdebug.h>
43#include <knuminput.h>
44#include <kconfiggroup.h>
45
46#include <cmath>
47
48// When message extraction needs to be avoided.
49#define I18NC_NOX i18nc
50
51static int minimumListWidth( const QListWidget *list )
52{
53 int w=0;
54 for( int i=0; i<list->count(); i++ )
55 {
56 int itemWidth = list->visualItemRect(list->item(i)).width();
57 // ...and add a space on both sides for not too tight look.
58 itemWidth += list->fontMetrics().width(' ') * 2;
59 w = qMax(w,itemWidth);
60 }
61 if( w == 0 ) { w = 40; }
62 w += list->frameWidth() * 2;
63 w += list->verticalScrollBar()->sizeHint().width();
64 return w;
65}
66
67static int minimumListHeight( const QListWidget *list, int numVisibleEntry )
68{
69 int w = list->count() > 0 ? list->visualItemRect(list->item(0)).height() :
70 list->fontMetrics().lineSpacing();
71
72 if( w < 0 ) { w = 10; }
73 if( numVisibleEntry <= 0 ) { numVisibleEntry = 4; }
74 return ( w * numVisibleEntry + 2 * list->frameWidth() );
75}
76
77static QString formatFontSize(qreal size)
78{
79 return KGlobal::locale()->formatNumber(size, (size == floor(size)) ? 0 : 1);
80}
81
82class KFontChooser::Private
83{
84public:
85 Private( KFontChooser* qq )
86 : q( qq )
87 {
88 m_palette.setColor(QPalette::Active, QPalette::Text, Qt::black);
89 m_palette.setColor(QPalette::Active, QPalette::Base, Qt::white);
90 signalsAllowed = true;
91 selectedSize = -1;
92 customSizeRow = -1;
93 }
94
95 // pointer to an optinally supplied list of fonts to
96 // inserted into the fontdialog font-family combo-box
97// QStringList fontList;
98
99 void setFamilyBoxItems(const QStringList &fonts);
100 void fillFamilyListBox(bool onlyFixedFonts = false);
101 int nearestSizeRow(qreal val, bool customize);
102 qreal fillSizeList(const QList<qreal> &sizes = QList<qreal>());
103 qreal setupSizeListBox(const QString& family, const QString& style);
104
105 void setupDisplay();
106 QString styleIdentifier (const QFont &font);
107
108 void _k_toggled_checkbox();
109 void _k_family_chosen_slot(const QString&);
110 void _k_size_chosen_slot(const QString&);
111 void _k_style_chosen_slot(const QString&);
112 void _k_displaySample(const QFont &font);
113 void _k_showXLFDArea(bool);
114 void _k_size_value_slot(double);
115
116 KFontChooser *q;
117
118 QPalette m_palette;
119 bool signalsAllowed:1;
120
121 bool usingFixed:1;
122
123 KDoubleNumInput *sizeOfFont;
124
125 SampleEdit *sampleEdit;
126 KLineEdit *xlfdEdit;
127
128 QLabel *familyLabel;
129 QLabel *styleLabel;
130 QCheckBox *familyCheckbox;
131 QCheckBox *styleCheckbox;
132 QCheckBox *sizeCheckbox;
133 QLabel *sizeLabel;
134 KListWidget *familyListBox;
135 KListWidget *styleListBox;
136 KListWidget *sizeListBox;
137 QCheckBox *sizeIsRelativeCheckBox;
138
139 QFont selFont;
140
141 QString selectedStyle;
142 qreal selectedSize;
143
144 int customSizeRow;
145 QString standardSizeAtCustom;
146
147 // Mappings of translated to Qt originated family and style strings.
148 QHash<QString, QString> qtFamilies;
149 QHash<QString, QString> qtStyles;
150 // Mapping of translated style strings to internal style identifiers.
151 QHash<QString, QString> styleIDs;
152
153};
154
155
156KFontChooser::KFontChooser( QWidget *parent,
157 const DisplayFlags& flags,
158 const QStringList &fontList,
159 int visibleListSize,
160 Qt::CheckState *sizeIsRelativeState )
161 : QWidget(parent),
162 d( new KFontChooser::Private( this ) )
163{
164 d->usingFixed = flags & FixedFontsOnly;
165 setWhatsThis(i18nc("@info:whatsthis", "Here you can choose the font to be used." ));
166
167 // The top layout is divided vertically into a splitter with font
168 // attribute widgets and preview on the top, and XLFD data at the bottom.
169 QVBoxLayout *topLayout = new QVBoxLayout( this );
170 topLayout->setMargin( 0 );
171 int checkBoxGap = KDialog::spacingHint() / 2;
172
173 // The splitter contains font attribute widgets in the top part,
174 // and the font preview in the bottom part.
175 // The splitter is there to allow the user to resize the font preview.
176 QSplitter *splitter = new QSplitter(Qt::Vertical, this);
177 splitter->setChildrenCollapsible(false);
178 topLayout->addWidget(splitter);
179
180 // Build the grid of font attribute widgets for the upper splitter part.
181 //
182 QWidget *page;
183 QGridLayout *gridLayout;
184 int row = 0;
185 if( flags & DisplayFrame )
186 {
187 page = new QGroupBox( i18n("Requested Font"), this );
188 splitter->addWidget(page);
189 gridLayout = new QGridLayout( page );
190 row = 1;
191 }
192 else
193 {
194 page = new QWidget( this );
195 splitter->addWidget(page);
196 gridLayout = new QGridLayout( page );
197 gridLayout->setMargin( 0 );
198 }
199
200 //
201 // first, create the labels across the top
202 //
203 QHBoxLayout *familyLayout = new QHBoxLayout();
204 familyLayout->addSpacing( checkBoxGap );
205 if ( flags & ShowDifferences ) {
206 d->familyCheckbox = new QCheckBox(i18nc("@option:check","Font"), page);
207 connect(d->familyCheckbox, SIGNAL(toggled(bool)),
208 this, SLOT(_k_toggled_checkbox()));
209 familyLayout->addWidget(d->familyCheckbox, 0, Qt::AlignLeft);
210 d->familyCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font family settings."));
211 d->familyCheckbox->setToolTip(i18nc("@info:tooltip","Change font family?") );
212 d->familyLabel = 0;
213 } else {
214 d->familyCheckbox = 0;
215 d->familyLabel = new QLabel( i18nc("@label","Font:"), page );
216 familyLayout->addWidget(d->familyLabel, 1, Qt::AlignLeft);
217 }
218 gridLayout->addLayout(familyLayout, row, 0 );
219
220 QHBoxLayout *styleLayout = new QHBoxLayout();
221 if ( flags & ShowDifferences ) {
222 d->styleCheckbox = new QCheckBox(i18nc("@option:check","Font style"), page);
223 connect(d->styleCheckbox, SIGNAL(toggled(bool)),
224 this, SLOT(_k_toggled_checkbox()));
225 styleLayout->addWidget(d->styleCheckbox, 0, Qt::AlignLeft);
226 d->styleCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font style settings."));
227 d->styleCheckbox->setToolTip(i18nc("@info:tooltip","Change font style?"));
228 d->styleLabel = 0;
229 } else {
230 d->styleCheckbox = 0;
231 d->styleLabel = new QLabel(i18n("Font style:"), page );
232 styleLayout->addWidget(d->styleLabel, 1, Qt::AlignLeft);
233 }
234 styleLayout->addSpacing( checkBoxGap );
235 gridLayout->addLayout(styleLayout, row, 1 );
236
237 QHBoxLayout *sizeLayout = new QHBoxLayout();
238 if ( flags & ShowDifferences ) {
239 d->sizeCheckbox = new QCheckBox(i18nc("@option:check","Size"),page);
240 connect(d->sizeCheckbox, SIGNAL(toggled(bool)),
241 this, SLOT(_k_toggled_checkbox()));
242 sizeLayout->addWidget(d->sizeCheckbox, 0, Qt::AlignLeft);
243 d->sizeCheckbox->setWhatsThis(i18nc("@info:whatsthis","Enable this checkbox to change the font size settings."));
244 d->sizeCheckbox->setToolTip(i18nc("@info:tooltip","Change font size?"));
245 d->sizeLabel = 0;
246 } else {
247 d->sizeCheckbox = 0;
248 d->sizeLabel = new QLabel(i18nc("@label:listbox Font size", "Size:"), page );
249 sizeLayout->addWidget(d->sizeLabel, 1, Qt::AlignLeft);
250 }
251 sizeLayout->addSpacing( checkBoxGap );
252 sizeLayout->addSpacing( checkBoxGap ); // prevent label from eating border
253 gridLayout->addLayout(sizeLayout, row, 2 );
254
255 row ++;
256
257 //
258 // now create the actual boxes that hold the info
259 //
260 d->familyListBox = new KListWidget( page );
261 d->familyListBox->setEnabled( flags ^ ShowDifferences );
262 gridLayout->addWidget( d->familyListBox, row, 0 );
263 QString fontFamilyWhatsThisText (
264 i18nc("@info:whatsthis","Here you can choose the font family to be used." ));
265 d->familyListBox->setWhatsThis(fontFamilyWhatsThisText );
266
267 if ( flags & ShowDifferences ) {
268 d->familyCheckbox->setWhatsThis(fontFamilyWhatsThisText );
269 } else {
270 d->familyLabel->setWhatsThis(fontFamilyWhatsThisText );
271 }
272
273 connect(d->familyListBox, SIGNAL(currentTextChanged(QString)),
274 this, SLOT(_k_family_chosen_slot(QString)));
275 if ( !fontList.isEmpty() ) {
276 d->setFamilyBoxItems(fontList);
277 }
278 else
279 {
280 d->fillFamilyListBox( flags & FixedFontsOnly );
281 }
282
283 d->familyListBox->setMinimumWidth( minimumListWidth( d->familyListBox ) );
284 d->familyListBox->setMinimumHeight(
285 minimumListHeight( d->familyListBox, visibleListSize ) );
286
287 d->styleListBox = new KListWidget( page );
288 d->styleListBox->setEnabled( flags ^ ShowDifferences );
289 gridLayout->addWidget(d->styleListBox, row, 1);
290 d->styleListBox->setWhatsThis(i18nc("@info:whatsthis","Here you can choose the font style to be used." ));
291 if ( flags & ShowDifferences ) {
292 ((QWidget *)d->styleCheckbox)->setWhatsThis(fontFamilyWhatsThisText );
293 } else {
294 ((QWidget *)d->styleLabel)->setWhatsThis( fontFamilyWhatsThisText );
295 }
296 // Populate usual styles, to determine minimum list width;
297 // will be replaced later with correct styles.
298 d->styleListBox->addItem(I18NC_NOX("QFontDatabase", "Normal"));
299 d->styleListBox->addItem(i18nc("@item font","Italic"));
300 d->styleListBox->addItem(i18nc("@item font","Oblique"));
301 d->styleListBox->addItem(i18nc("@item font","Bold"));
302 d->styleListBox->addItem(i18nc("@item font","Bold Italic"));
303 d->styleListBox->setMinimumWidth( minimumListWidth( d->styleListBox ) );
304 d->styleListBox->setMinimumHeight(
305 minimumListHeight( d->styleListBox, visibleListSize ) );
306
307 connect(d->styleListBox, SIGNAL(currentTextChanged(QString)),
308 this, SLOT(_k_style_chosen_slot(QString)));
309
310
311 d->sizeListBox = new KListWidget( page );
312 d->sizeOfFont = new KDoubleNumInput(page);
313 d->sizeOfFont->setMinimum(4);
314 d->sizeOfFont->setMaximum(999);
315 d->sizeOfFont->setDecimals(1);
316 d->sizeOfFont->setSingleStep(1);
317 d->sizeOfFont->setSliderEnabled(false);
318
319 d->sizeListBox->setEnabled( flags ^ ShowDifferences );
320 d->sizeOfFont->setEnabled( flags ^ ShowDifferences );
321 if( sizeIsRelativeState ) {
322 QString sizeIsRelativeCBText =
323 i18nc("@item font size","Relative");
324 QString sizeIsRelativeCBToolTipText =
325 i18n("Font size<br /><i>fixed</i> or <i>relative</i><br />to environment");
326 QString sizeIsRelativeCBWhatsThisText =
327 i18n("Here you can switch between fixed font size and font size "
328 "to be calculated dynamically and adjusted to changing "
329 "environment (e.g. widget dimensions, paper size)." );
330 d->sizeIsRelativeCheckBox = new QCheckBox( sizeIsRelativeCBText,
331 page );
332 d->sizeIsRelativeCheckBox->setTristate( flags & ShowDifferences );
333 QGridLayout *sizeLayout2 = new QGridLayout();
334 sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
335 gridLayout->addLayout(sizeLayout2, row, 2);
336 sizeLayout2->setColumnStretch( 1, 1 ); // to prevent text from eating the right border
337 sizeLayout2->addWidget( d->sizeOfFont, 0, 0, 1, 2);
338 sizeLayout2->addWidget(d->sizeListBox, 1,0, 1,2);
339 sizeLayout2->addWidget(d->sizeIsRelativeCheckBox, 2, 0, Qt::AlignLeft);
340 d->sizeIsRelativeCheckBox->setWhatsThis(sizeIsRelativeCBWhatsThisText );
341 d->sizeIsRelativeCheckBox->setToolTip( sizeIsRelativeCBToolTipText );
342 }
343 else {
344 d->sizeIsRelativeCheckBox = 0L;
345 QGridLayout *sizeLayout2 = new QGridLayout();
346 sizeLayout2->setSpacing( KDialog::spacingHint()/2 );
347 gridLayout->addLayout(sizeLayout2, row, 2);
348 sizeLayout2->addWidget( d->sizeOfFont, 0, 0);
349 sizeLayout2->addWidget(d->sizeListBox, 1,0);
350 }
351 QString fontSizeWhatsThisText =
352 i18n("Here you can choose the font size to be used." );
353 d->sizeListBox->setWhatsThis(fontSizeWhatsThisText );
354
355 if ( flags & ShowDifferences ) {
356 ((QWidget *)d->sizeCheckbox)->setWhatsThis(fontSizeWhatsThisText );
357 } else {
358 ((QWidget *)d->sizeLabel)->setWhatsThis( fontSizeWhatsThisText );
359 }
360
361 // Populate with usual sizes, to determine minimum list width;
362 // will be replaced later with correct sizes.
363 d->fillSizeList();
364 d->sizeListBox->setMinimumWidth( minimumListWidth(d->sizeListBox) +
365 d->sizeListBox->fontMetrics().maxWidth() );
366 d->sizeListBox->setMinimumHeight(
367 minimumListHeight( d->sizeListBox, visibleListSize ) );
368
369 connect( d->sizeOfFont, SIGNAL(valueChanged(double)),
370 this, SLOT(_k_size_value_slot(double)));
371
372 connect( d->sizeListBox, SIGNAL(currentTextChanged(QString)),
373 this, SLOT(_k_size_chosen_slot(QString)) );
374
375 row ++;
376 //
377 // Completed the font attribute grid.
378
379 // Add the font preview into the lower part of the splitter.
380 //
381 d->sampleEdit = new SampleEdit(page);
382 d->sampleEdit->setAcceptRichText(false);
383 QFont tmpFont( KGlobalSettings::generalFont().family(), 64, QFont::Black );
384 d->sampleEdit->setFont(tmpFont);
385 d->sampleEdit->setMinimumHeight( d->sampleEdit->fontMetrics().lineSpacing() );
386 // i18n: A classical test phrase, with all letters of the English alphabet.
387 // Replace it with a sample text in your language, such that it is
388 // representative of language's writing system.
389 // If you wish, you can input several lines of text separated by \n.
390 setSampleText(i18n("The Quick Brown Fox Jumps Over The Lazy Dog"));
391 d->sampleEdit->setTextCursor(QTextCursor(d->sampleEdit->document()));
392 QString sampleEditWhatsThisText =
393 i18n("This sample text illustrates the current settings. "
394 "You may edit it to test special characters." );
395 d->sampleEdit->setWhatsThis(sampleEditWhatsThisText );
396
397 connect(this, SIGNAL(fontSelected(QFont)),
398 this, SLOT(_k_displaySample(QFont)));
399
400 splitter->addWidget(d->sampleEdit);
401 //
402 // Finished setting up the splitter.
403
404 // Add XLFD data below the font attributes/preview splitter.
405 //
406 QVBoxLayout *vbox;
407 if( flags & DisplayFrame )
408 {
409 page = new QGroupBox( i18n("Actual Font"), this );
410 topLayout->addWidget(page);
411 vbox = new QVBoxLayout( page );
412 vbox->addSpacing( fontMetrics().lineSpacing() );
413 }
414 else
415 {
416 page = new QWidget( this );
417 topLayout->addWidget(page);
418 vbox = new QVBoxLayout( page );
419 vbox->setMargin( 0 );
420 QLabel *label = new QLabel( i18n("Actual Font"), page );
421 vbox->addWidget( label );
422 }
423
424 d->xlfdEdit = new KLineEdit( page );
425 vbox->addWidget( d->xlfdEdit );
426 //
427 // Finished setting up the chooser layout.
428
429 // lets initialize the display if possible
430 setFont( d->usingFixed ? KGlobalSettings::fixedFont() : KGlobalSettings::generalFont(), d->usingFixed );
431
432 // check or uncheck or gray out the "relative" checkbox
433 if( sizeIsRelativeState && d->sizeIsRelativeCheckBox )
434 setSizeIsRelative( *sizeIsRelativeState );
435
436 KConfigGroup cg(KGlobal::config(), QLatin1String("General"));
437 d->_k_showXLFDArea(cg.readEntry(QLatin1String("fontSelectorShowXLFD"), false));
438
439 // Set focus to the size list as this is the most commonly changed property
440 d->sizeListBox->setFocus();
441}
442
443KFontChooser::~KFontChooser()
444{
445 delete d;
446}
447
448void KFontChooser::setColor( const QColor & col )
449{
450 d->m_palette.setColor( QPalette::Active, QPalette::Text, col );
451 QPalette pal = d->sampleEdit->palette();
452 pal.setColor( QPalette::Active, QPalette::Text, col );
453 d->sampleEdit->setPalette( pal );
454 QTextCursor cursor = d->sampleEdit->textCursor();
455 d->sampleEdit->selectAll();
456 d->sampleEdit->setTextColor( col );
457 d->sampleEdit->setTextCursor( cursor );
458}
459
460QColor KFontChooser::color() const
461{
462 return d->m_palette.color( QPalette::Active, QPalette::Text );
463}
464
465void KFontChooser::setBackgroundColor( const QColor & col )
466{
467 d->m_palette.setColor( QPalette::Active, QPalette::Base, col );
468 QPalette pal = d->sampleEdit->palette();
469 pal.setColor( QPalette::Active, QPalette::Base, col );
470 d->sampleEdit->setPalette( pal );
471}
472
473QColor KFontChooser::backgroundColor() const
474{
475 return d->m_palette.color( QPalette::Active, QPalette::Base );
476}
477
478void KFontChooser::setSizeIsRelative( Qt::CheckState relative )
479{
480 // check or uncheck or gray out the "relative" checkbox
481 if( d->sizeIsRelativeCheckBox ) {
482 if( Qt::PartiallyChecked == relative )
483 d->sizeIsRelativeCheckBox->setCheckState(Qt::PartiallyChecked);
484 else
485 d->sizeIsRelativeCheckBox->setCheckState( (Qt::Checked == relative ) ? Qt::Checked : Qt::Unchecked);
486 }
487}
488
489Qt::CheckState KFontChooser::sizeIsRelative() const
490{
491 return d->sizeIsRelativeCheckBox
492 ? d->sizeIsRelativeCheckBox->checkState()
493 : Qt::PartiallyChecked;
494}
495
496QString KFontChooser::sampleText() const
497{
498 return d->sampleEdit->toPlainText();
499}
500
501void KFontChooser::setSampleText( const QString &text )
502{
503 d->sampleEdit->setPlainText(text);
504}
505
506void KFontChooser::setSampleBoxVisible( bool visible )
507{
508 d->sampleEdit->setVisible( visible );
509}
510
511QSize KFontChooser::sizeHint( void ) const
512{
513 return minimumSizeHint();
514}
515
516
517void KFontChooser::enableColumn( int column, bool state )
518{
519 if( column & FamilyList )
520 {
521 d->familyListBox->setEnabled(state);
522 }
523 if( column & StyleList )
524 {
525 d->styleListBox->setEnabled(state);
526 }
527 if( column & SizeList )
528 {
529 d->sizeListBox->setEnabled(state);
530 d->sizeOfFont->setEnabled(state);
531 }
532}
533
534
535void KFontChooser::setFont( const QFont& aFont, bool onlyFixed )
536{
537 d->selFont = aFont;
538 d->selectedSize=aFont.pointSizeF();
539 if (d->selectedSize == -1)
540 d->selectedSize = QFontInfo(aFont).pointSizeF();
541
542 if( onlyFixed != d->usingFixed)
543 {
544 d->usingFixed = onlyFixed;
545 d->fillFamilyListBox(d->usingFixed);
546 }
547 d->setupDisplay();
548}
549
550
551KFontChooser::FontDiffFlags KFontChooser::fontDiffFlags() const
552{
553 FontDiffFlags diffFlags = NoFontDiffFlags;
554
555 if ( d->familyCheckbox && d->familyCheckbox->isChecked() ) {
556 diffFlags |= FontDiffFamily;
557 }
558
559 if ( d->styleCheckbox && d->styleCheckbox->isChecked() ) {
560 diffFlags |= FontDiffStyle;
561 }
562
563 if ( d->sizeCheckbox && d->sizeCheckbox->isChecked() ) {
564 diffFlags |= FontDiffSize;
565 }
566
567 return diffFlags;
568}
569
570QFont KFontChooser::font() const
571{
572 return d->selFont;
573}
574
575void KFontChooser::Private::_k_toggled_checkbox()
576{
577 familyListBox->setEnabled( familyCheckbox->isChecked() );
578 styleListBox->setEnabled( styleCheckbox->isChecked() );
579 sizeListBox->setEnabled( sizeCheckbox->isChecked() );
580 sizeOfFont->setEnabled( sizeCheckbox->isChecked() );
581}
582
583void KFontChooser::Private::_k_family_chosen_slot(const QString& family)
584{
585 if ( !signalsAllowed ) {
586 return;
587 }
588 signalsAllowed = false;
589
590 QString currentFamily;
591 if (family.isEmpty()) {
592 Q_ASSERT( familyListBox->currentItem() );
593 if (familyListBox->currentItem()) {
594 currentFamily = qtFamilies[familyListBox->currentItem()->text()];
595 }
596 }
597 else {
598 currentFamily = qtFamilies[family];
599 }
600
601 // Get the list of styles available in this family.
602 QFontDatabase dbase;
603 QStringList styles = dbase.styles(currentFamily);
604 if (styles.isEmpty()) {
605 // Avoid extraction, it is in kdeqt.po
606 styles.append(I18NC_NOX("QFontDatabase", "Normal"));
607 }
608
609 // Filter style strings and add to the listbox.
610 QString pureFamily;
611 splitFontString(family, &pureFamily);
612 QStringList filteredStyles;
613 qtStyles.clear();
614 styleIDs.clear();
615 foreach (const QString &style, styles) {
616 // Sometimes the font database will report an invalid style,
617 // that falls back back to another when set.
618 // Remove such styles, by checking set/get round-trip.
619 QFont testFont = dbase.font(currentFamily, style, 10);
620 if (dbase.styleString(testFont) != style) {
621 styles.removeAll(style);
622 continue;
623 }
624
625 // i18n: Filtering message, so that translators can script the
626 // style string according to the font family name (e.g. may need
627 // noun-adjective congruence wrt. gender of the family name).
628 // The message provides the dynamic context 'family', which is
629 // the family name to which the style string corresponds.
630 QString fstyle = ki18nc("@item Font style", "%1").subs(style).inContext("family", pureFamily).toString();
631 if (!filteredStyles.contains(fstyle)) {
632 filteredStyles.append(fstyle);
633 qtStyles.insert(fstyle, style);
634 styleIDs.insert(fstyle, styleIdentifier(testFont));
635 }
636 }
637 styleListBox->clear();
638 styleListBox->addItems(filteredStyles);
639
640 // Try to set the current style in the listbox to that previous.
641 int listPos = filteredStyles.indexOf(selectedStyle.isEmpty() ? I18NC_NOX("QFontDatabase", "Normal") : selectedStyle);
642 if (listPos < 0) {
643 // Make extra effort to have Italic selected when Oblique was chosen,
644 // and vice versa, as that is what the user would probably want.
645 QString styleIt = i18nc("@item font", "Italic");
646 QString styleOb = i18nc("@item font", "Oblique");
647 for (int i = 0; i < 2; ++i) {
648 int pos = selectedStyle.indexOf(styleIt);
649 if (pos >= 0) {
650 QString style = selectedStyle;
651 style.replace(pos, styleIt.length(), styleOb);
652 listPos = filteredStyles.indexOf(style);
653 if (listPos >= 0) break;
654 }
655 qSwap(styleIt, styleOb);
656 }
657 }
658 styleListBox->setCurrentRow(listPos >= 0 ? listPos : 0);
659 QString currentStyle = qtStyles[styleListBox->currentItem()->text()];
660
661 // Recompute the size listbox for this family/style.
662 qreal currentSize = setupSizeListBox(currentFamily, currentStyle);
663 sizeOfFont->setValue(currentSize);
664
665 selFont = dbase.font(currentFamily, currentStyle, int(currentSize));
666 if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) {
667 selFont.setPointSizeF(currentSize);
668 }
669 emit q->fontSelected(selFont);
670
671 signalsAllowed = true;
672}
673
674void KFontChooser::Private::_k_style_chosen_slot(const QString& style)
675{
676 if ( !signalsAllowed ) {
677 return;
678 }
679 signalsAllowed = false;
680
681 QFontDatabase dbase;
682 QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
683 QString currentStyle;
684 if (style.isEmpty()) {
685 currentStyle = qtStyles[styleListBox->currentItem()->text()];
686 } else {
687 currentStyle = qtStyles[style];
688 }
689
690 // Recompute the size listbox for this family/style.
691 qreal currentSize = setupSizeListBox(currentFamily, currentStyle);
692 sizeOfFont->setValue(currentSize);
693
694 selFont = dbase.font(currentFamily, currentStyle, int(currentSize));
695 if (dbase.isSmoothlyScalable(currentFamily, currentStyle) && selFont.pointSize() == floor(currentSize)) {
696 selFont.setPointSizeF(currentSize);
697 }
698 emit q->fontSelected(selFont);
699
700 if (!style.isEmpty()) {
701 selectedStyle = currentStyle;
702 }
703
704 signalsAllowed = true;
705}
706
707void KFontChooser::Private::_k_size_chosen_slot(const QString& size)
708{
709 if ( !signalsAllowed ) {
710 return;
711 }
712
713 signalsAllowed = false;
714
715 qreal currentSize;
716 if (size.isEmpty()) {
717 currentSize = KGlobal::locale()->readNumber(sizeListBox->currentItem()->text());
718 } else {
719 currentSize = KGlobal::locale()->readNumber(size);
720 }
721
722 // Reset the customized size slot in the list if not needed.
723 if (customSizeRow >= 0 && selFont.pointSizeF() != currentSize) {
724 sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
725 customSizeRow = -1;
726 }
727
728 sizeOfFont->setValue(currentSize);
729 selFont.setPointSizeF(currentSize);
730 emit q->fontSelected(selFont);
731
732 if (!size.isEmpty()) {
733 selectedSize = currentSize;
734 }
735
736 signalsAllowed = true;
737}
738
739void KFontChooser::Private::_k_size_value_slot(double dval)
740{
741 if ( !signalsAllowed ) {
742 return;
743 }
744 signalsAllowed = false;
745
746 // We compare with qreal, so convert for platforms where qreal != double.
747 qreal val = qreal(dval);
748
749 QFontDatabase dbase;
750 QString family = qtFamilies[familyListBox->currentItem()->text()];
751 QString style = qtStyles[styleListBox->currentItem()->text()];
752
753 // Reset current size slot in list if it was customized.
754 if (customSizeRow >= 0 && sizeListBox->currentRow() == customSizeRow) {
755 sizeListBox->item(customSizeRow)->setText(standardSizeAtCustom);
756 customSizeRow = -1;
757 }
758
759 bool canCustomize = true;
760
761 // For Qt-bad-sizes workaround: skip this block unconditionally
762 if (!dbase.isSmoothlyScalable(family, style)) {
763 // Bitmap font, allow only discrete sizes.
764 // Determine the nearest in the direction of change.
765 canCustomize = false;
766 int nrows = sizeListBox->count();
767 int row = sizeListBox->currentRow();
768 int nrow;
769 if (val - selFont.pointSizeF() > 0) {
770 for (nrow = row + 1; nrow < nrows; ++nrow)
771 if (KGlobal::locale()->readNumber(sizeListBox->item(nrow)->text()) >= val)
772 break;
773 }
774 else {
775 for (nrow = row - 1; nrow >= 0; --nrow)
776 if (KGlobal::locale()->readNumber(sizeListBox->item(nrow)->text()) <= val)
777 break;
778 }
779 // Make sure the new row is not out of bounds.
780 nrow = nrow < 0 ? 0 : nrow >= nrows ? nrows - 1 : nrow;
781 // Get the size from the new row and set the spinbox to that size.
782 val = KGlobal::locale()->readNumber(sizeListBox->item(nrow)->text());
783 sizeOfFont->setValue(val);
784 }
785
786 // Set the current size in the size listbox.
787 int row = nearestSizeRow(val, canCustomize);
788 sizeListBox->setCurrentRow(row);
789
790 selectedSize = val;
791 selFont.setPointSizeF(val);
792 emit q->fontSelected( selFont );
793
794 signalsAllowed = true;
795}
796
797void KFontChooser::Private::_k_displaySample( const QFont& font )
798{
799 sampleEdit->setFont(font);
800 //sampleEdit->setCursorPosition(0);
801
802 xlfdEdit->setText(font.rawName());
803 xlfdEdit->setCursorPosition(0);
804
805 //QFontInfo a = QFontInfo(font);
806 //kDebug() << "font: " << a.family () << ", " << a.pointSize ();
807 //kDebug() << " (" << font.toString() << ")\n";
808}
809
810int KFontChooser::Private::nearestSizeRow (qreal val, bool customize)
811{
812 qreal diff = 1000;
813 int row = 0;
814 for (int r = 0; r < sizeListBox->count(); ++r) {
815 qreal cval = KGlobal::locale()->readNumber(sizeListBox->item(r)->text());
816 if (qAbs(cval - val) < diff) {
817 diff = qAbs(cval - val);
818 row = r;
819 }
820 }
821 // For Qt-bad-sizes workaround: ignore value of customize, use true
822 if (customize && diff > 0) {
823 customSizeRow = row;
824 standardSizeAtCustom = sizeListBox->item(row)->text();
825 sizeListBox->item(row)->setText(formatFontSize(val));
826 }
827 return row;
828}
829
830qreal KFontChooser::Private::fillSizeList (const QList<qreal> &sizes_)
831{
832 if ( !sizeListBox ) {
833 return 0; //assertion.
834 }
835
836 QList<qreal> sizes = sizes_;
837 bool canCustomize = false;
838 if (sizes.count() == 0) {
839 static const int c[] = {
840 4, 5, 6, 7,
841 8, 9, 10, 11,
842 12, 13, 14, 15,
843 16, 17, 18, 19,
844 20, 22, 24, 26,
845 28, 32, 48, 64,
846 72, 80, 96, 128,
847 0
848 };
849 for (int i = 0; c[i]; ++i) {
850 sizes.append(c[i]);
851 }
852 // Since sizes were not supplied, this is a vector font,
853 // and size slot customization is allowed.
854 canCustomize = true;
855 }
856
857 // Insert sizes into the listbox.
858 sizeListBox->clear();
859 qSort(sizes);
860 foreach (qreal size, sizes) {
861 sizeListBox->addItem(formatFontSize(size));
862 }
863
864 // Return the nearest to selected size.
865 // If the font is vector, the nearest size is always same as selected,
866 // thus size slot customization is allowed.
867 // If the font is bitmap, the nearest size need not be same as selected,
868 // thus size slot customization is not allowed.
869 customSizeRow = -1;
870 int row = nearestSizeRow(selectedSize, canCustomize);
871 return KGlobal::locale()->readNumber(sizeListBox->item(row)->text());
872}
873
874qreal KFontChooser::Private::setupSizeListBox (const QString& family, const QString& style)
875{
876 QFontDatabase dbase;
877 QList<qreal> sizes;
878 if (dbase.isSmoothlyScalable(family, style)) {
879 // A vector font.
880 //>sampleEdit->setPaletteBackgroundPixmap( VectorPixmap ); // TODO
881 }
882 else {
883 // A bitmap font.
884 //sampleEdit->setPaletteBackgroundPixmap( BitmapPixmap ); // TODO
885 QList<int> smoothSizes = dbase.smoothSizes(family, style);
886 foreach (int size, smoothSizes) {
887 sizes.append(size);
888 }
889 }
890
891 // Fill the listbox (uses default list of sizes if the given is empty).
892 // Collect the best fitting size to selected size, to use if not smooth.
893 qreal bestFitSize = fillSizeList(sizes);
894
895 // Set the best fit size as current in the listbox if available.
896 const QList<QListWidgetItem*> selectedSizeList =
897 sizeListBox->findItems( formatFontSize(bestFitSize),
898 Qt::MatchExactly );
899 if ( !selectedSizeList.isEmpty() ) {
900 sizeListBox->setCurrentItem(selectedSizeList.first());
901 }
902 //TODO - KDE4 : sizeListBox->scrollTo(sizeListBox->currentItem());
903
904 return bestFitSize;
905}
906
907void KFontChooser::Private::setupDisplay()
908{
909 QFontDatabase dbase;
910 QString family = selFont.family().toLower();
911 QString styleID = styleIdentifier(selFont);
912 qreal size = selFont.pointSizeF();
913 if (size == -1)
914 size = QFontInfo( selFont ).pointSizeF();
915
916 int numEntries, i;
917
918 // Direct family match.
919 numEntries = familyListBox->count();
920 for (i = 0; i < numEntries; i++) {
921 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
922 familyListBox->setCurrentRow(i);
923 break;
924 }
925 }
926
927 // 1st family fallback.
928 if ( i == numEntries )
929 {
930 if (family.contains('['))
931 {
932 family = family.left(family.indexOf('[')).trimmed();
933 for (i = 0; i < numEntries; i++) {
934 if (family == qtFamilies[familyListBox->item(i)->text()].toLower()) {
935 familyListBox->setCurrentRow(i);
936 break;
937 }
938 }
939 }
940 }
941
942 // 2nd family fallback.
943 if ( i == numEntries )
944 {
945 QString fallback = family+" [";
946 for (i = 0; i < numEntries; i++) {
947 if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(fallback)) {
948 familyListBox->setCurrentRow(i);
949 break;
950 }
951 }
952 }
953
954 // 3rd family fallback.
955 if ( i == numEntries )
956 {
957 for (i = 0; i < numEntries; i++) {
958 if (qtFamilies[familyListBox->item(i)->text()].toLower().startsWith(family)) {
959 familyListBox->setCurrentRow(i);
960 break;
961 }
962 }
963 }
964
965 // Family fallback in case nothing matched. Otherwise, diff doesn't work
966 if ( i == numEntries ) {
967 familyListBox->setCurrentRow( 0 );
968 }
969
970 // By setting the current item in the family box, the available
971 // styles and sizes for that family have been collected.
972 // Try now to set the current items in the style and size boxes.
973
974 // Set current style in the listbox.
975 numEntries = styleListBox->count();
976 for (i = 0; i < numEntries; i++) {
977 if (styleID == styleIDs[styleListBox->item(i)->text()]) {
978 styleListBox->setCurrentRow(i);
979 break;
980 }
981 }
982 if (i == numEntries) {
983 // Style not found, fallback.
984 styleListBox->setCurrentRow(0);
985 }
986
987 // Set current size in the listbox.
988 // If smoothly scalable, allow customizing one of the standard size slots,
989 // otherwise just select the nearest available size.
990 QString currentFamily = qtFamilies[familyListBox->currentItem()->text()];
991 QString currentStyle = qtStyles[styleListBox->currentItem()->text()];
992 bool canCustomize = dbase.isSmoothlyScalable(currentFamily, currentStyle);
993 sizeListBox->setCurrentRow(nearestSizeRow(size, canCustomize));
994
995 // Set current size in the spinbox.
996 sizeOfFont->setValue(KGlobal::locale()->readNumber(sizeListBox->currentItem()->text()));
997}
998
999
1000void KFontChooser::getFontList( QStringList &list, uint fontListCriteria)
1001{
1002 QFontDatabase dbase;
1003 QStringList lstSys(dbase.families());
1004
1005 // if we have criteria; then check fonts before adding
1006 if (fontListCriteria)
1007 {
1008 QStringList lstFonts;
1009 for (QStringList::const_iterator it = lstSys.constBegin(); it != lstSys.constEnd(); ++it)
1010 {
1011 if ((fontListCriteria & FixedWidthFonts) > 0 && !dbase.isFixedPitch(*it)) continue;
1012 if (((fontListCriteria & (SmoothScalableFonts | ScalableFonts)) == ScalableFonts) &&
1013 !dbase.isBitmapScalable(*it)) continue;
1014 if ((fontListCriteria & SmoothScalableFonts) > 0 && !dbase.isSmoothlyScalable(*it)) continue;
1015 lstFonts.append(*it);
1016 }
1017
1018 if((fontListCriteria & FixedWidthFonts) > 0) {
1019 // Fallback.. if there are no fixed fonts found, it's probably a
1020 // bug in the font server or Qt. In this case, just use 'fixed'
1021 if (lstFonts.count() == 0)
1022 lstFonts.append("fixed");
1023 }
1024
1025 lstSys = lstFonts;
1026 }
1027
1028 lstSys.sort();
1029
1030 list = lstSys;
1031}
1032
1033void KFontChooser::Private::setFamilyBoxItems(const QStringList &fonts)
1034{
1035 signalsAllowed = false;
1036
1037 QStringList trfonts = translateFontNameList(fonts, &qtFamilies);
1038 familyListBox->clear();
1039 familyListBox->addItems(trfonts);
1040
1041 signalsAllowed = true;
1042}
1043
1044void KFontChooser::Private::fillFamilyListBox(bool onlyFixedFonts)
1045{
1046 QStringList fontList;
1047 getFontList(fontList, onlyFixedFonts?FixedWidthFonts:0);
1048 setFamilyBoxItems(fontList);
1049}
1050
1051void KFontChooser::Private::_k_showXLFDArea(bool show)
1052{
1053 if( show )
1054 {
1055 xlfdEdit->parentWidget()->show();
1056 }
1057 else
1058 {
1059 xlfdEdit->parentWidget()->hide();
1060 }
1061}
1062
1063// Human-readable style identifiers returned by QFontDatabase::styleString()
1064// do not always survive round trip of QFont serialization/deserialization,
1065// causing wrong style in the style box to be highlighted when
1066// the chooser dialog is opened. This will cause the style to be changed
1067// when the dialog is closed and the user did not touch the style box.
1068// Hence, construct custom style identifiers sufficient for the purpose.
1069QString KFontChooser::Private::styleIdentifier(const QFont &font)
1070{
1071 const QChar comma(QLatin1Char(','));
1072 return QString::number(font.weight()) + comma
1073 + QString::number((int)font.style()) + comma
1074 + QString::number(font.stretch());
1075}
1076
1077#include "kfontchooser.moc"
1078#include "sampleedit_p.moc"
KConfigGroup
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KDialog::spacingHint
static int spacingHint()
Returns the number of pixels that should be used between widgets inside a dialog according to the KDE...
Definition: kdialog.cpp:432
KDoubleNumInput
An input control for real numbers, consisting of a spinbox and a slider.
Definition: knuminput.h:451
KFontChooser
A font selection widget.
Definition: kfontchooser.h:48
KFontChooser::FamilyList
@ FamilyList
Definition: kfontchooser.h:62
KFontChooser::SizeList
@ SizeList
Definition: kfontchooser.h:62
KFontChooser::StyleList
@ StyleList
Definition: kfontchooser.h:62
KFontChooser::setColor
void setColor(const QColor &col)
Sets the color to use in the preview.
Definition: kfontchooser.cpp:448
KFontChooser::setBackgroundColor
void setBackgroundColor(const QColor &col)
Sets the background color to use in the preview.
Definition: kfontchooser.cpp:465
KFontChooser::setSampleBoxVisible
void setSampleBoxVisible(bool visible)
Shows or hides the sample text box.
Definition: kfontchooser.cpp:506
KFontChooser::FixedWidthFonts
@ FixedWidthFonts
Definition: kfontchooser.h:232
KFontChooser::ScalableFonts
@ ScalableFonts
Definition: kfontchooser.h:232
KFontChooser::SmoothScalableFonts
@ SmoothScalableFonts
Definition: kfontchooser.h:232
KFontChooser::DisplayFrame
@ DisplayFrame
Definition: kfontchooser.h:83
KFontChooser::ShowDifferences
@ ShowDifferences
Definition: kfontchooser.h:84
KFontChooser::FixedFontsOnly
@ FixedFontsOnly
Definition: kfontchooser.h:82
KFontChooser::~KFontChooser
virtual ~KFontChooser()
Destructs the font chooser.
Definition: kfontchooser.cpp:443
KFontChooser::getFontList
static void getFontList(QStringList &list, uint fontListCriteria)
Creates a list of font strings.
Definition: kfontchooser.cpp:1000
KFontChooser::fontSelected
void fontSelected(const QFont &font)
Emitted whenever the selected font changes.
KFontChooser::setSampleText
void setSampleText(const QString &text)
Sets the sample text.
Definition: kfontchooser.cpp:501
KFontChooser::setSizeIsRelative
void setSizeIsRelative(Qt::CheckState relative)
Sets the state of the checkbox indicating whether the font size is to be interpreted as relative size...
Definition: kfontchooser.cpp:478
KFontChooser::fontDiffFlags
FontDiffFlags fontDiffFlags() const
Definition: kfontchooser.cpp:551
KFontChooser::sampleText
QString sampleText
Definition: kfontchooser.h:54
KFontChooser::color
QColor color
Definition: kfontchooser.h:51
KFontChooser::backgroundColor
QColor backgroundColor
Definition: kfontchooser.h:52
KFontChooser::setFont
void setFont(const QFont &font, bool onlyFixed=false)
Sets the currently selected font in the chooser.
Definition: kfontchooser.cpp:535
KFontChooser::enableColumn
void enableColumn(int column, bool state)
Enables or disable a font column in the chooser.
Definition: kfontchooser.cpp:517
KFontChooser::sizeHint
virtual QSize sizeHint(void) const
Reimplemented for internal reasons.
Definition: kfontchooser.cpp:511
KFontChooser::sizeIsRelative
Qt::CheckState sizeIsRelative
Definition: kfontchooser.h:53
KFontChooser::NoFontDiffFlags
@ NoFontDiffFlags
Definition: kfontchooser.h:69
KFontChooser::FontDiffFamily
@ FontDiffFamily
Definition: kfontchooser.h:70
KFontChooser::FontDiffStyle
@ FontDiffStyle
Definition: kfontchooser.h:71
KFontChooser::FontDiffSize
@ FontDiffSize
Definition: kfontchooser.h:72
KFontChooser::KFontChooser
KFontChooser(QWidget *parent=0L, const DisplayFlags &flags=DisplayFrame, const QStringList &fontList=QStringList(), int visibleListSize=8, Qt::CheckState *sizeIsRelativeState=0L)
Constructs a font picker widget.
Definition: kfontchooser.cpp:156
KFontChooser::font
QFont font
Definition: kfontchooser.h:50
KGlobalSettings::generalFont
static QFont generalFont()
Returns the default general font.
Definition: kglobalsettings.cpp:446
KGlobalSettings::fixedFont
static QFont fixedFont()
Returns the default fixed font.
Definition: kglobalsettings.cpp:450
KLineEdit
An enhanced QLineEdit widget for inputting text.
Definition: klineedit.h:150
KListWidget
A variant of QListWidget that honors KDE's system-wide settings.
Definition: klistwidget.h:41
KLocale::formatNumber
QString formatNumber(const QString &numStr, bool round=true, int precision=-1) const
KLocale::readNumber
double readNumber(const QString &numStr, bool *ok=0) const
KLocalizedString::toString
QString toString() const
KLocalizedString::subs
KLocalizedString subs(const QString &a, int fieldWidth=0, const QChar &fillChar=QLatin1Char(' ')) const
KLocalizedString::inContext
KLocalizedString inContext(const QString &key, const QString &text) const
QGroupBox
QHash
QLabel
QListWidget
QList
QWidget
translateFontNameList
QStringList translateFontNameList(const QStringList &names, QHash< QString, QString > *trToRawNames)
Definition: fonthelpers.cpp:96
splitFontString
void splitFontString(const QString &name, QString *family, QString *foundry)
Definition: fonthelpers.cpp:42
kcharsets.h
kconfig.h
kconfiggroup.h
kdebug.h
kdialog.h
I18NC_NOX
#define I18NC_NOX
Definition: kfontchooser.cpp:49
minimumListWidth
static int minimumListWidth(const QListWidget *list)
Definition: kfontchooser.cpp:51
minimumListHeight
static int minimumListHeight(const QListWidget *list, int numVisibleEntry)
Definition: kfontchooser.cpp:67
formatFontSize
static QString formatFontSize(qreal size)
Definition: kfontchooser.cpp:77
kfontchooser.h
kglobal.h
kglobalsettings.h
klineedit.h
klistwidget.h
klocale.h
ki18nc
KLocalizedString ki18nc(const char *ctxt, const char *msg)
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
knuminput.h
kstandarddirs.h
KGlobal::locale
KLocale * locale()
KGlobal::config
KSharedConfigPtr config()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal