add more spacing
[personal-kdebase.git] / runtime / kcontrol / icons / icons.cpp
blob92a076f583378a9534123d88b4375a85f85f28fa
1 /* vi: ts=8 sts=4 sw=4
3 * This file is part of the KDE project, module kcmdisplay.
4 * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
5 * with minor additions and based on ideas from
6 * Torsten Rahn <torsten@kde.org> *
8 * You can Freely distribute this program under the GNU General Public
9 * License. See the file "COPYING" for the exact licensing terms.
12 #include <stdlib.h>
14 #include <QCheckBox>
15 #include <QComboBox>
16 #include <QLabel>
17 #include <QLayout>
18 #include <QSlider>
19 #include <QGroupBox>
20 //Added by qt3to4:
21 #include <QPixmap>
22 #include <QGridLayout>
23 #include <QBoxLayout>
24 #include <QVBoxLayout>
25 #include <QListWidget>
26 #include <KApplication>
27 #include <kcolorbutton.h>
28 #include <kconfig.h>
29 #include <kdebug.h>
30 #include <kiconeffect.h>
31 #include <kiconloader.h>
32 #include <klocale.h>
33 #include <kseparator.h>
34 #include <kglobalsettings.h>
36 #include "icons.h"
38 /**** KIconConfig ****/
40 KIconConfig::KIconConfig(const KComponentData &inst, QWidget *parent)
41 : KCModule(inst, parent)
44 QGridLayout *top = new QGridLayout(this );
45 top->setMargin( KDialog::marginHint() );
46 top->setSpacing( KDialog::spacingHint() );
47 top->setColumnStretch(0, 1);
48 top->setColumnStretch(1, 1);
50 // Use of Icon at (0,0) - (1, 0)
51 QGroupBox *gbox = new QGroupBox(i18n("Use of Icon"), this);
52 top->addWidget(gbox, 0, 0, 2, 1);
53 QBoxLayout *g_vlay = new QVBoxLayout(gbox);
54 g_vlay->setSpacing(KDialog::spacingHint());
55 mpUsageList = new QListWidget(gbox);
56 connect(mpUsageList, SIGNAL(currentRowChanged(int)), SLOT(slotUsage(int)));
57 g_vlay->addWidget(mpUsageList);
59 KSeparator *sep = new KSeparator( Qt::Horizontal, this );
60 top->addWidget(sep, 1, 1);
61 // Preview at (2,0) - (2, 1)
62 QGridLayout *g_lay = new QGridLayout();
63 g_lay->setMargin( KDialog::marginHint() );
64 g_lay->setSpacing( 0);
65 top->addLayout(g_lay, 2, 0, 1, 2 );
66 g_lay->addItem(new QSpacerItem(0, fontMetrics().lineSpacing()), 0, 0);
68 QPushButton *push;
70 push = addPreviewIcon(0, i18nc("@label The icon rendered by default", "Default"), this, g_lay);
71 connect(push, SIGNAL(clicked()), SLOT(slotEffectSetup0()));
72 push = addPreviewIcon(1, i18nc("@label The icon rendered as active", "Active"), this, g_lay);
73 connect(push, SIGNAL(clicked()), SLOT(slotEffectSetup1()));
74 push = addPreviewIcon(2, i18nc("@label The icon rendered as disabled", "Disabled"), this, g_lay);
75 connect(push, SIGNAL(clicked()), SLOT(slotEffectSetup2()));
77 m_pTab1 = new QWidget(this);
78 m_pTab1->setObjectName("General Tab");
79 top->addWidget(m_pTab1, 0, 1);
81 QGridLayout *grid = new QGridLayout(m_pTab1);
82 grid->setSpacing(10);
83 grid->setMargin(10);
84 grid->setColumnStretch(1, 1);
85 grid->setColumnStretch(2, 1);
88 // Size
89 QLabel *lbl = new QLabel(i18n("Size:"), m_pTab1);
90 lbl->setFixedSize(lbl->sizeHint());
91 grid->addWidget(lbl, 0, 0, Qt::AlignLeft);
92 mpSizeBox = new QComboBox(m_pTab1);
93 connect(mpSizeBox, SIGNAL(activated(int)), SLOT(slotSize(int)));
94 lbl->setBuddy(mpSizeBox);
95 grid->addWidget(mpSizeBox, 0, 1, Qt::AlignLeft);
97 mpAnimatedCheck = new QCheckBox(i18n("Animate icons"), m_pTab1);
98 connect(mpAnimatedCheck, SIGNAL(toggled(bool)), SLOT(slotAnimatedCheck(bool)));
99 grid->addWidget(mpAnimatedCheck, 2, 0, 1, 2, Qt::AlignLeft);
100 grid->setRowStretch(3, 10);
102 top->activate();
104 init();
105 read();
106 apply();
107 preview();
110 KIconConfig::~KIconConfig()
112 delete mpEffect;
115 QPushButton *KIconConfig::addPreviewIcon(int i, const QString &str, QWidget *parent, QGridLayout *lay)
117 QLabel *lab = new QLabel(str, parent);
118 lay->addWidget(lab, 1, i, Qt::AlignCenter);
119 mpPreview[i] = new QLabel(parent);
120 mpPreview[i]->setAlignment(Qt::AlignCenter);
121 mpPreview[i]->setMinimumSize(105, 105);
122 lay->addWidget(mpPreview[i], 2, i);
123 QPushButton *push = new QPushButton(i18n("Set Effect..."), parent);
124 lay->addWidget(push, 3, i, Qt::AlignCenter);
125 return push;
128 void KIconConfig::init()
130 mpLoader = KIconLoader::global();
131 mpConfig = KGlobal::config();
132 mpEffect = new KIconEffect;
133 mUsage = 0;
134 for (int i=0; i<KIconLoader::LastGroup; i++)
135 mbChanged[i] = false;
137 // Fill list/checkboxen
138 mpUsageList->addItem(i18n("Desktop"));
139 mpUsageList->addItem(i18n("Toolbar"));
140 mpUsageList->addItem(i18n("Main Toolbar"));
141 mpUsageList->addItem(i18n("Small Icons"));
142 mpUsageList->addItem(i18n("Panel"));
143 mpUsageList->addItem(i18n("All Icons"));
145 // For reading the configuration
146 mGroups += "Desktop";
147 mGroups += "Toolbar";
148 mGroups += "MainToolbar";
149 mGroups += "Small";
150 mGroups += "Panel";
152 mStates += "Default";
153 mStates += "Active";
154 mStates += "Disabled";
157 void KIconConfig::initDefaults()
159 mDefaultEffect[0].type = KIconEffect::NoEffect;
160 mDefaultEffect[1].type = KIconEffect::NoEffect;
161 mDefaultEffect[2].type = KIconEffect::ToGray;
162 mDefaultEffect[0].transparent = false;
163 mDefaultEffect[1].transparent = false;
164 mDefaultEffect[2].transparent = true;
165 mDefaultEffect[0].value = 1.0;
166 mDefaultEffect[1].value = 1.0;
167 mDefaultEffect[2].value = 1.0;
168 mDefaultEffect[0].color = QColor(144,128,248);
169 mDefaultEffect[1].color = QColor(169,156,255);
170 mDefaultEffect[2].color = QColor(34,202,0);
171 mDefaultEffect[0].color2 = QColor(0,0,0);
172 mDefaultEffect[1].color2 = QColor(0,0,0);
173 mDefaultEffect[2].color2 = QColor(0,0,0);
175 const int defDefSizes[] = { 32, 22, 22, 16, 32 };
177 KIconLoader::Group i;
178 QStringList::ConstIterator it;
179 for(it=mGroups.constBegin(), i=KIconLoader::FirstGroup; it!=mGroups.constEnd(); ++it, i++)
181 mbChanged[i] = true;
182 mbAnimated[i] = false;
183 if (mpLoader->theme())
184 mSizes[i] = mpLoader->theme()->defaultSize(i);
185 else
186 mSizes[i] = defDefSizes[i];
188 mEffects[i][0] = mDefaultEffect[0];
189 mEffects[i][1] = mDefaultEffect[1];
190 mEffects[i][2] = mDefaultEffect[2];
192 // Animate desktop icons by default
193 int group = mGroups.indexOf( "Desktop" );
194 if ( group != -1 )
195 mbAnimated[group] = true;
197 // This is the new default in KDE 2.2, in sync with the kiconeffect of kdelibs Nolden 2001/06/11
198 int activeState = mStates.indexOf( "Active" );
199 if ( activeState != -1 )
201 int group = mGroups.indexOf( "Desktop" );
202 if ( group != -1 )
204 mEffects[ group ][ activeState ].type = KIconEffect::ToGamma;
205 mEffects[ group ][ activeState ].value = 0.7;
208 group = mGroups.indexOf( "Panel" );
209 if ( group != -1 )
211 mEffects[ group ][ activeState ].type = KIconEffect::ToGamma;
212 mEffects[ group ][ activeState ].value = 0.7;
217 void KIconConfig::read()
219 if (mpLoader->theme())
221 for (KIconLoader::Group i=KIconLoader::FirstGroup; i<KIconLoader::LastGroup; i++)
222 mAvSizes[i] = mpLoader->theme()->querySizes(i);
224 mTheme = mpLoader->theme()->current();
225 mExample = mpLoader->theme()->example();
227 else
229 for (KIconLoader::Group i=KIconLoader::FirstGroup; i<KIconLoader::LastGroup; i++)
230 mAvSizes[i] = QList<int>();
232 mTheme.clear();
233 mExample.clear();
236 initDefaults();
238 int i, j, effect;
239 QStringList::ConstIterator it, it2;
240 for (it=mGroups.constBegin(), i=0; it!=mGroups.constEnd(); ++it, i++)
242 mbChanged[i] = false;
244 KConfigGroup iconGroup(mpConfig, *it + "Icons");
245 mSizes[i] = iconGroup.readEntry("Size", mSizes[i]);
246 mbAnimated[i] = iconGroup.readEntry("Animated", mbAnimated[i]);
248 for (it2=mStates.constBegin(), j=0; it2!=mStates.constEnd(); ++it2, j++)
250 QString tmp = iconGroup.readEntry(*it2 + "Effect", QString());
251 if (tmp == "togray")
252 effect = KIconEffect::ToGray;
253 else if (tmp == "colorize")
254 effect = KIconEffect::Colorize;
255 else if (tmp == "togamma")
256 effect = KIconEffect::ToGamma;
257 else if (tmp == "desaturate")
258 effect = KIconEffect::DeSaturate;
259 else if (tmp == "tomonochrome")
260 effect = KIconEffect::ToMonochrome;
261 else if (tmp == "none")
262 effect = KIconEffect::NoEffect;
263 else continue;
264 mEffects[i][j].type = effect;
265 mEffects[i][j].value = iconGroup.readEntry(*it2 + "Value", 0.0);
266 mEffects[i][j].color = iconGroup.readEntry(*it2 + "Color",QColor());
267 mEffects[i][j].color2 = iconGroup.readEntry(*it2 + "Color2", QColor());
268 mEffects[i][j].transparent = iconGroup.readEntry(*it2 + "SemiTransparent", false);
273 void KIconConfig::apply()
275 mpUsageList->setCurrentRow(mUsage);
277 int delta = 1000, dw, index = -1, size = 0, i;
278 QList<int>::Iterator it;
279 mpSizeBox->clear();
280 if (mUsage < KIconLoader::LastGroup) {
281 for (it=mAvSizes[mUsage].begin(), i=0; it!=mAvSizes[mUsage].end(); ++it, i++)
283 mpSizeBox->addItem(QString().setNum(*it));
284 dw = abs(mSizes[mUsage] - *it);
285 if (dw < delta)
287 delta = dw;
288 index = i;
289 size = *it;
293 if (index != -1)
295 mpSizeBox->setCurrentIndex(index);
296 mSizes[mUsage] = size; // best or exact match
298 mpAnimatedCheck->setChecked(mbAnimated[mUsage]);
302 void KIconConfig::preview(int i)
304 // Apply effects ourselves because we don't want to sync
305 // the configuration every preview.
307 int viewedGroup = (mUsage == KIconLoader::LastGroup) ? KIconLoader::FirstGroup : mUsage;
309 QPixmap pm = mpLoader->loadIcon(mExample, KIconLoader::NoGroup, mSizes[viewedGroup]);
310 QImage img = pm.toImage();
312 Effect &effect = mEffects[viewedGroup][i];
314 img = mpEffect->apply(img, effect.type,
315 effect.value, effect.color, effect.color2, effect.transparent);
316 pm = QPixmap::fromImage(img);
317 mpPreview[i]->setPixmap(pm);
320 void KIconConfig::preview()
322 preview(0);
323 preview(1);
324 preview(2);
327 void KIconConfig::load()
329 read();
330 apply();
331 emit changed(false);
332 for (int i=0; i<KIconLoader::LastGroup; i++)
333 mbChanged[i] = false;
334 preview();
338 void KIconConfig::save()
340 int i, j;
341 QStringList::ConstIterator it, it2;
342 for (it=mGroups.constBegin(), i=0; it!=mGroups.constEnd(); ++it, i++)
344 KConfigGroup cg(mpConfig, *it + "Icons");
345 cg.writeEntry("Size", mSizes[i], KConfig::Normal|KConfig::Global);
346 cg.writeEntry("Animated", mbAnimated[i], KConfig::Normal|KConfig::Global);
347 for (it2=mStates.constBegin(), j=0; it2!=mStates.constEnd(); ++it2, j++)
349 QString tmp;
350 switch (mEffects[i][j].type)
352 case KIconEffect::ToGray:
353 tmp = "togray";
354 break;
355 case KIconEffect::ToGamma:
356 tmp = "togamma";
357 break;
358 case KIconEffect::Colorize:
359 tmp = "colorize";
360 break;
361 case KIconEffect::DeSaturate:
362 tmp = "desaturate";
363 break;
364 case KIconEffect::ToMonochrome:
365 tmp = "tomonochrome";
366 break;
367 default:
368 tmp = "none";
369 break;
371 cg.writeEntry(*it2 + "Effect", tmp, KConfig::Normal|KConfig::Global);
372 cg.writeEntry(*it2 + "Value", mEffects[i][j].value, KConfig::Normal|KConfig::Global);
373 cg.writeEntry(*it2 + "Color", mEffects[i][j].color, KConfig::Normal|KConfig::Global);
374 cg.writeEntry(*it2 + "Color2", mEffects[i][j].color2, KConfig::Normal|KConfig::Global);
375 cg.writeEntry(*it2 + "SemiTransparent", mEffects[i][j].transparent, KConfig::Normal|KConfig::Global);
379 mpConfig->sync();
381 emit changed(false);
383 // Emit KIPC change message.
384 for (int i=0; i<KIconLoader::LastGroup; i++)
386 if (mbChanged[i])
388 KGlobalSettings::self()->emitChange(KGlobalSettings::IconChanged, i);
389 mbChanged[i] = false;
394 void KIconConfig::defaults()
396 initDefaults();
397 apply();
398 preview();
399 emit changed(true);
402 void KIconConfig::slotUsage(int index)
404 if (index == -1)
405 return;
407 mUsage = index;
408 if ( mUsage == KIconLoader::Panel || mUsage == KIconLoader::LastGroup )
410 mpSizeBox->setEnabled(false);
411 mpAnimatedCheck->setEnabled( mUsage == KIconLoader::Panel );
413 else
415 mpSizeBox->setEnabled(true);
416 mpAnimatedCheck->setEnabled( mUsage == KIconLoader::Desktop );
419 apply();
420 preview();
423 void KIconConfig::EffectSetup(int state)
425 int viewedGroup = (mUsage == KIconLoader::LastGroup) ? KIconLoader::FirstGroup : mUsage;
427 QPixmap pm = mpLoader->loadIcon(mExample, KIconLoader::NoGroup, mSizes[viewedGroup]);
428 QImage img = pm.toImage();
430 QString caption;
431 switch (state)
433 case 0 : caption = i18n("Setup Default Icon Effect"); break;
434 case 1 : caption = i18n("Setup Active Icon Effect"); break;
435 case 2 : caption = i18n("Setup Disabled Icon Effect"); break;
438 KIconEffectSetupDialog dlg(mEffects[viewedGroup][state], mDefaultEffect[state], caption, img, this);
440 if (dlg.exec() == QDialog::Accepted)
442 if (mUsage == KIconLoader::LastGroup) {
443 for (int i=0; i<KIconLoader::LastGroup; i++)
444 mEffects[i][state] = dlg.effect();
445 } else {
446 mEffects[mUsage][state] = dlg.effect();
449 // AK - can this call be moved therefore removing
450 // code duplication?
452 emit changed(true);
454 if (mUsage == KIconLoader::LastGroup) {
455 for (int i=0; i<KIconLoader::LastGroup; i++)
456 mbChanged[i] = true;
457 } else {
458 mbChanged[mUsage] = true;
461 preview(state);
464 void KIconConfig::slotSize(int index)
466 Q_ASSERT(mUsage < KIconLoader::LastGroup);
467 mSizes[mUsage] = mAvSizes[mUsage][index];
468 preview();
469 emit changed(true);
470 mbChanged[mUsage] = true;
473 void KIconConfig::slotAnimatedCheck(bool check)
475 Q_ASSERT(mUsage < KIconLoader::LastGroup);
476 if (mbAnimated[mUsage] != check)
478 mbAnimated[mUsage] = check;
479 emit changed(true);
480 mbChanged[mUsage] = true;
484 KIconEffectSetupDialog::KIconEffectSetupDialog(const Effect &effect,
485 const Effect &defaultEffect,
486 const QString &caption, const QImage &image,
487 QWidget *parent, char *name)
488 : KDialog( parent ),
489 mEffect(effect),
490 mDefaultEffect(defaultEffect),
491 mExample(image)
493 setObjectName( name );
494 setModal( true );
495 setCaption( caption );
496 setButtons( Default|Ok|Cancel );
497 showButtonSeparator( true );
499 mpEffect = new KIconEffect;
501 QLabel *lbl;
502 QGroupBox *frame;
503 QGridLayout *grid;
505 QWidget *page = new QWidget(this);
506 setMainWidget(page);
508 QGridLayout *top = new QGridLayout(page);
509 top->setSpacing(spacingHint());
510 top->setMargin(0);
511 top->setColumnStretch(0,1);
512 top->addItem(new QSpacerItem(10, 0), 0, 1);
513 top->setColumnStretch(2,2);
514 top->setRowStretch(1,1);
516 lbl = new QLabel(i18n("&Effect:"), page);
517 lbl->setFixedSize(lbl->sizeHint());
518 top->addWidget(lbl, 0, 0, Qt::AlignLeft);
519 mpEffectBox = new QListWidget(page);
520 mpEffectBox->addItem(i18n("No Effect"));
521 mpEffectBox->addItem(i18n("To Gray"));
522 mpEffectBox->addItem(i18n("Colorize"));
523 mpEffectBox->addItem(i18n("Gamma"));
524 mpEffectBox->addItem(i18n("Desaturate"));
525 mpEffectBox->addItem(i18n("To Monochrome"));
526 mpEffectBox->setMinimumWidth( 100 );
527 connect(mpEffectBox, SIGNAL(currentRowChanged(int)), SLOT(slotEffectType(int)));
528 top->addWidget(mpEffectBox, 1, 0, 2, 1, Qt::AlignLeft);
529 lbl->setBuddy(mpEffectBox);
531 mpSTCheck = new QCheckBox(i18n("&Semi-transparent"), page);
532 connect(mpSTCheck, SIGNAL(toggled(bool)), SLOT(slotSTCheck(bool)));
533 top->addWidget(mpSTCheck, 3, 0, Qt::AlignLeft);
535 frame = new QGroupBox(i18n("Preview"), page);
536 top->addWidget(frame, 0, 1, 2, 1);
537 grid = new QGridLayout(frame);
538 grid->setSpacing(spacingHint());
539 grid->setMargin(marginHint());
540 grid->addItem(new QSpacerItem(0, fontMetrics().lineSpacing()), 0, 0);
541 grid->setRowStretch(1, 1);
543 mpPreview = new QLabel(frame);
544 mpPreview->setAlignment(Qt::AlignCenter);
545 mpPreview->setMinimumSize(105, 105);
546 grid->addWidget(mpPreview, 1, 0);
548 mpEffectGroup = new QGroupBox(i18n("Effect Parameters"), page);
549 top->addWidget(mpEffectGroup, 2, 1, 2, 1);
550 grid = new QGridLayout(mpEffectGroup);
551 grid->setSpacing(spacingHint());
552 grid->setMargin(marginHint());
553 grid->addItem(new QSpacerItem(0, fontMetrics().lineSpacing()), 0, 0);
555 mpEffectLabel = new QLabel(i18n("&Amount:"), mpEffectGroup);
556 grid->addWidget(mpEffectLabel, 1, 0);
557 mpEffectSlider = new QSlider(Qt::Horizontal, mpEffectGroup);
558 mpEffectSlider->setMinimum(0);
559 mpEffectSlider->setMaximum(100);
560 mpEffectSlider->setPageStep(5);
561 mpEffectLabel->setBuddy( mpEffectSlider );
562 connect(mpEffectSlider, SIGNAL(valueChanged(int)), SLOT(slotEffectValue(int)));
563 grid->addWidget(mpEffectSlider, 1, 1);
565 mpEffectColor = new QLabel(i18n("Co&lor:"), mpEffectGroup);
566 grid->addWidget(mpEffectColor, 2, 0);
567 mpEColButton = new KColorButton(mpEffectGroup);
568 mpEffectColor->setBuddy( mpEColButton );
569 connect(mpEColButton, SIGNAL(changed(const QColor &)),
570 SLOT(slotEffectColor(const QColor &)));
571 grid->addWidget(mpEColButton, 2, 1);
573 mpEffectColor2 = new QLabel(i18n("&Second color:"), mpEffectGroup);
574 grid->addWidget(mpEffectColor2, 3, 0);
575 mpECol2Button = new KColorButton(mpEffectGroup);
576 mpEffectColor2->setBuddy( mpECol2Button );
577 connect(mpECol2Button, SIGNAL(changed(const QColor &)),
578 SLOT(slotEffectColor2(const QColor &)));
579 grid->addWidget(mpECol2Button, 3, 1);
581 init();
582 preview();
585 KIconEffectSetupDialog::~KIconEffectSetupDialog()
587 delete mpEffect;
590 void KIconEffectSetupDialog::init()
592 mpEffectBox->setCurrentRow(mEffect.type);
593 mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
594 mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type == KIconEffect::ToMonochrome);
595 mpECol2Button->setEnabled(mEffect.type == KIconEffect::ToMonochrome);
596 mpEffectSlider->setValue((int) (100.0 * mEffect.value + 0.5));
597 mpEColButton->setColor(mEffect.color);
598 mpECol2Button->setColor(mEffect.color2);
599 mpSTCheck->setChecked(mEffect.transparent);
602 void KIconEffectSetupDialog::slotEffectValue(int value)
604 mEffect.value = 0.01 * value;
605 preview();
608 void KIconEffectSetupDialog::slotEffectColor(const QColor &col)
610 mEffect.color = col;
611 preview();
614 void KIconEffectSetupDialog::slotEffectColor2(const QColor &col)
616 mEffect.color2 = col;
617 preview();
620 void KIconEffectSetupDialog::slotEffectType(int type)
622 if (type == -1)
623 return;
625 mEffect.type = type;
626 mpEffectGroup->setEnabled(mEffect.type != KIconEffect::NoEffect);
627 mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
628 mpEffectColor->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type == KIconEffect::ToMonochrome);
629 mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type == KIconEffect::ToMonochrome);
630 mpEffectColor2->setEnabled(mEffect.type == KIconEffect::ToMonochrome);
631 mpECol2Button->setEnabled(mEffect.type == KIconEffect::ToMonochrome);
632 preview();
635 void KIconEffectSetupDialog::slotSTCheck(bool b)
637 mEffect.transparent = b;
638 preview();
641 void KIconEffectSetupDialog::slotDefault()
643 mEffect = mDefaultEffect;
644 init();
645 preview();
648 void KIconEffectSetupDialog::preview()
650 QPixmap pm;
651 QImage img = mExample.copy();
652 img = mpEffect->apply(img, mEffect.type,
653 mEffect.value, mEffect.color, mEffect.color2, mEffect.transparent);
654 pm = QPixmap::fromImage(img);
655 mpPreview->setPixmap(pm);
658 #include "icons.moc"