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.
22 #include <QGridLayout>
24 #include <QVBoxLayout>
25 #include <QListWidget>
26 #include <KApplication>
27 #include <kcolorbutton.h>
30 #include <kiconeffect.h>
31 #include <kiconloader.h>
33 #include <kseparator.h>
34 #include <kglobalsettings.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);
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
);
84 grid
->setColumnStretch(1, 1);
85 grid
->setColumnStretch(2, 1);
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);
110 KIconConfig::~KIconConfig()
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
);
128 void KIconConfig::init()
130 mpLoader
= KIconLoader::global();
131 mpConfig
= KGlobal::config();
132 mpEffect
= new KIconEffect
;
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";
152 mStates
+= "Default";
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
++)
182 mbAnimated
[i
] = false;
183 if (mpLoader
->theme())
184 mSizes
[i
] = mpLoader
->theme()->defaultSize(i
);
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" );
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" );
204 mEffects
[ group
][ activeState
].type
= KIconEffect::ToGamma
;
205 mEffects
[ group
][ activeState
].value
= 0.7;
208 group
= mGroups
.indexOf( "Panel" );
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();
229 for (KIconLoader::Group i
=KIconLoader::FirstGroup
; i
<KIconLoader::LastGroup
; i
++)
230 mAvSizes
[i
] = QList
<int>();
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());
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
;
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
;
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
);
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()
327 void KIconConfig::load()
332 for (int i
=0; i
<KIconLoader::LastGroup
; i
++)
333 mbChanged
[i
] = false;
338 void KIconConfig::save()
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
++)
350 switch (mEffects
[i
][j
].type
)
352 case KIconEffect::ToGray
:
355 case KIconEffect::ToGamma
:
358 case KIconEffect::Colorize
:
361 case KIconEffect::DeSaturate
:
364 case KIconEffect::ToMonochrome
:
365 tmp
= "tomonochrome";
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
);
383 // Emit KIPC change message.
384 for (int i
=0; i
<KIconLoader::LastGroup
; i
++)
388 KGlobalSettings::self()->emitChange(KGlobalSettings::IconChanged
, i
);
389 mbChanged
[i
] = false;
394 void KIconConfig::defaults()
402 void KIconConfig::slotUsage(int index
)
408 if ( mUsage
== KIconLoader::Panel
|| mUsage
== KIconLoader::LastGroup
)
410 mpSizeBox
->setEnabled(false);
411 mpAnimatedCheck
->setEnabled( mUsage
== KIconLoader::Panel
);
415 mpSizeBox
->setEnabled(true);
416 mpAnimatedCheck
->setEnabled( mUsage
== KIconLoader::Desktop
);
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();
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();
446 mEffects
[mUsage
][state
] = dlg
.effect();
449 // AK - can this call be moved therefore removing
454 if (mUsage
== KIconLoader::LastGroup
) {
455 for (int i
=0; i
<KIconLoader::LastGroup
; i
++)
458 mbChanged
[mUsage
] = true;
464 void KIconConfig::slotSize(int index
)
466 Q_ASSERT(mUsage
< KIconLoader::LastGroup
);
467 mSizes
[mUsage
] = mAvSizes
[mUsage
][index
];
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
;
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
)
490 mDefaultEffect(defaultEffect
),
493 setObjectName( name
);
495 setCaption( caption
);
496 setButtons( Default
|Ok
|Cancel
);
497 showButtonSeparator( true );
499 mpEffect
= new KIconEffect
;
505 QWidget
*page
= new QWidget(this);
508 QGridLayout
*top
= new QGridLayout(page
);
509 top
->setSpacing(spacingHint());
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);
585 KIconEffectSetupDialog::~KIconEffectSetupDialog()
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
;
608 void KIconEffectSetupDialog::slotEffectColor(const QColor
&col
)
614 void KIconEffectSetupDialog::slotEffectColor2(const QColor
&col
)
616 mEffect
.color2
= col
;
620 void KIconEffectSetupDialog::slotEffectType(int 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
);
635 void KIconEffectSetupDialog::slotSTCheck(bool b
)
637 mEffect
.transparent
= b
;
641 void KIconEffectSetupDialog::slotDefault()
643 mEffect
= mDefaultEffect
;
648 void KIconEffectSetupDialog::preview()
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
);