Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / kcontrol / kdm / background / bgsettings.cpp
blobd15f8babe889f8b87b970562e9d2310cf729f7b5
1 /* vi: ts=8 sts=4 sw=4
2 * kate: space-indent on; indent-width 4; indent-mode cstyle;
4 * This file is part of the KDE project, module kdesktop.
5 * Copyright (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl>
7 * You can Freely distribute this program under the GNU Library General
8 * Public License. See the file "COPYING.LIB" for the exact licensing terms.
9 */
11 #include <netwm.h>
12 #include <time.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <QtDBus/QtDBus>
16 // Clean up after X.h/Xlib.h
17 #undef Bool
18 #undef Unsorted
20 #include <QDir>
21 #include <QPixmap>
22 //Added by qt3to4:
23 #include <QByteArray>
25 #include <kapplication.h>
26 #include <kdebug.h>
27 #include <KColorScheme>
28 #include <kdesktopfile.h>
29 #include <kconfiggroup.h>
30 #include <kstandarddirs.h>
31 #include <krandomsequence.h>
33 #include "bgdefaults.h"
34 #include "bgsettings.h"
35 #include <QX11Info>
37 #define DEFAULT_TEXTWIDTH 0
38 #define DEFAULT_TEXTHEIGHT 2
42 * QString -> int hash. From Qt's QGDict::hashKeyString().
45 static int BGHash(const QString &key)
47 int g, h = 0;
48 const QChar *p = key.unicode();
49 for (int i=0; i < key.length(); i++) {
50 h = (h << 4) + p[i].cell();
51 if ((g = (h & 0xf0000000)))
52 h ^= (g >> 24);
53 h &= ~g;
55 return h;
59 /**** KBackgroundPattern ****/
62 KBackgroundPattern::KBackgroundPattern(bool _kdmMode, const QString &name)
64 dirty = false;
65 hashdirty = true;
66 m_kdmMode = _kdmMode;
68 m_pDirs = KGlobal::dirs();
69 m_pDirs->addResourceType("dtop_pattern", "data", "kdesktop/patterns");
70 m_pConfig = 0L;
72 m_Name = name;
73 if (m_Name.isEmpty())
74 return;
76 init();
77 readSettings();
81 KBackgroundPattern::~KBackgroundPattern()
83 delete m_pConfig;
86 void KBackgroundPattern::copyConfig(const KBackgroundPattern *settings)
88 dirty = hashdirty = true;
89 m_Name = settings->m_Name;
90 m_Comment = settings->m_Comment;
91 m_Pattern = settings->m_Pattern;
92 m_File = settings->m_File;
95 void KBackgroundPattern::load(const QString &name)
97 m_Name = name;
98 init();
99 readSettings();
103 void KBackgroundPattern::init(bool force_rw)
105 delete m_pConfig;
107 m_File = m_pDirs->findResource("dtop_pattern", m_Name + ".desktop");
108 if (force_rw || m_File.isEmpty()) {
109 m_File = m_pDirs->saveLocation("dtop_pattern") + m_Name + ".desktop";
110 m_pConfig = new KDesktopFile(m_File);
111 } else
112 m_pConfig = new KDesktopFile(m_File);
114 QFileInfo fi(m_File);
115 m_bReadOnly = !fi.isWritable();
119 void KBackgroundPattern::setComment(const QString &comment)
121 if (m_Comment == comment)
122 return;
123 dirty = true;
124 m_Comment = comment;
128 void KBackgroundPattern::setPattern(const QString &pattern)
130 if (m_Pattern == pattern)
131 return;
132 dirty = hashdirty = true;
133 m_Pattern = pattern;
137 void KBackgroundPattern::readSettings()
139 dirty = false;
140 hashdirty = true;
142 const KConfigGroup group = m_pConfig->group("KDE Desktop Pattern");
144 m_Pattern = m_kdmMode ? group.readEntry("File") : group.readPathEntry("File", QString());
145 m_Comment = group.readEntry("Comment");
146 if (m_Comment.isEmpty())
147 m_Comment = m_File.mid(m_File.lastIndexOf('/')+1);
151 void KBackgroundPattern::writeSettings()
153 if (!dirty)
154 return;
155 if (m_bReadOnly)
156 init(true);
158 if ( !m_pConfig )
159 return; // better safe than sorry
161 KConfigGroup group = m_pConfig->group("KDE Desktop Pattern");
162 if (m_kdmMode)
163 group.writeEntry("File", m_Pattern);
164 else
165 group.writePathEntry("File", m_Pattern);
166 group.writeEntry("Comment", m_Comment);
167 m_pConfig->sync();
168 dirty = false;
172 bool KBackgroundPattern::isAvailable()
174 if (m_Pattern.isEmpty())
175 return false;
176 QString file = m_Pattern;
177 if (file.at(0) != '/')
178 file = m_pDirs->findResource("dtop_pattern", file);
179 QFileInfo fi(file);
180 return (fi.exists());
184 bool KBackgroundPattern::remove()
186 if (m_bReadOnly)
187 return false;
188 return !unlink(QFile::encodeName(m_File));
192 QString KBackgroundPattern::fingerprint()
194 return m_File;
198 int KBackgroundPattern::hash()
200 if (hashdirty) {
201 m_Hash = BGHash(fingerprint());
202 hashdirty = false;
204 return m_Hash;
208 /* static */
209 QStringList KBackgroundPattern::list()
211 KStandardDirs *dirs = KGlobal::dirs();
212 dirs->addResourceType("dtop_pattern", "data", "kdesktop/patterns");
213 QStringList lst = dirs->findAllResources("dtop_pattern", "*.desktop",
214 KStandardDirs::NoDuplicates);
215 QStringList::Iterator it;
216 for (it=lst.begin(); it!=lst.end(); ++it) {
217 // Strip path and suffix
218 int pos = (*it).lastIndexOf('/');
219 if (pos != -1)
220 (*it) = (*it).mid(pos+1);
221 pos = (*it).lastIndexOf('.');
222 if (pos != -1)
223 (*it) = (*it).left(pos);
225 return lst;
229 /**** KBackgroundProgram ****/
232 KBackgroundProgram::KBackgroundProgram(bool _kdmMode, const QString &name)
234 dirty = false;
235 hashdirty = true;
236 m_kdmMode = _kdmMode;
238 m_pDirs = KGlobal::dirs();
239 m_pDirs->addResourceType("dtop_program", "data", "kdesktop/programs");
240 m_pConfig = 0L;
242 // prevent updates when just constructed.
243 m_LastChange = (int) time(0L);
245 m_Name = name;
246 if (m_Name.isEmpty())
247 return;
249 init();
250 readSettings();
254 KBackgroundProgram::~KBackgroundProgram()
256 delete m_pConfig;
259 void KBackgroundProgram::copyConfig(const KBackgroundProgram *settings)
261 dirty = hashdirty = true;
262 m_Refresh = settings->m_Refresh;
263 m_LastChange = settings->m_LastChange;
264 m_Name = settings->m_Name;
265 m_Command = settings->m_Command;
266 m_PreviewCommand = settings->m_PreviewCommand;
267 m_Comment = settings->m_Comment;
268 m_Executable = settings->m_Executable;
269 m_File = settings->m_File;
273 void KBackgroundProgram::init(bool force_rw)
275 delete m_pConfig;
277 m_File = m_pDirs->findResource("dtop_program", m_Name + ".desktop");
278 if (force_rw || m_File.isEmpty()) {
279 m_File = m_pDirs->saveLocation("dtop_program") + m_Name + ".desktop";
280 m_pConfig = new KDesktopFile(m_File);
281 m_bReadOnly = false;
282 } else {
283 m_pConfig = new KDesktopFile(m_File);
284 m_bReadOnly = (m_File != KStandardDirs::locateLocal("dtop_program", m_Name + ".desktop"));
289 void KBackgroundProgram::load(const QString &name)
291 m_Name = name;
292 init();
293 readSettings();
297 void KBackgroundProgram::setComment(const QString &comment)
299 if (m_Comment == comment)
300 return;
301 dirty = true;
302 m_Comment = comment;
306 void KBackgroundProgram::setExecutable(const QString &executable)
308 if (m_Executable == executable)
309 return;
310 dirty = true;
311 m_Executable = executable;
315 void KBackgroundProgram::setCommand(const QString &command)
317 if (m_Command == command)
318 return;
319 dirty = hashdirty = true;
320 m_Command = command;
324 void KBackgroundProgram::setPreviewCommand(const QString &command)
326 if (m_PreviewCommand == command)
327 return;
328 dirty = true;
329 m_PreviewCommand = command;
333 void KBackgroundProgram::setRefresh(int refresh)
335 if (m_Refresh == refresh)
336 return;
337 dirty = hashdirty = true;
338 m_Refresh = refresh;
342 void KBackgroundProgram::readSettings()
344 dirty = false;
345 hashdirty = true;
347 const KConfigGroup group = m_pConfig->group("KDE Desktop Program");
348 m_Comment = group.readEntry("Comment");
349 if (m_kdmMode) {
350 m_Executable = group.readEntry("Executable");
351 m_Command = group.readEntry("Command");
352 m_PreviewCommand = group.readEntry("PreviewCommand", m_Command);
353 } else {
354 m_Executable = group.readPathEntry("Executable", QString());
355 m_Command = group.readPathEntry("Command", QString());
356 m_PreviewCommand = group.readPathEntry("PreviewCommand", m_Command);
358 m_Refresh = group.readEntry("Refresh", 300);
362 void KBackgroundProgram::writeSettings()
364 if (!dirty)
365 return;
366 if (m_bReadOnly)
367 init(true);
369 if ( !m_pConfig )
370 return; // better safe than sorry
372 KConfigGroup group = m_pConfig->group("KDE Desktop Program");
373 group.writeEntry("Comment", m_Comment);
374 if (m_kdmMode) {
375 group.writeEntry("Executable", m_Executable);
376 group.writeEntry("Command", m_Command);
377 group.writeEntry("PreviewCommand", m_PreviewCommand);
378 } else {
379 group.writePathEntry("Executable", m_Executable);
380 group.writePathEntry("Command", m_Command);
381 group.writePathEntry("PreviewCommand", m_PreviewCommand);
383 group.writeEntry("Refresh", m_Refresh);
384 m_pConfig->sync();
385 dirty = false;
389 bool KBackgroundProgram::isAvailable()
391 return !m_pDirs->findExe(m_Executable).isEmpty();
395 bool KBackgroundProgram::remove()
397 if (m_bReadOnly)
398 return false;
399 return !unlink(QFile::encodeName(m_File));
403 bool KBackgroundProgram::needUpdate()
405 return (m_LastChange + 60*m_Refresh <= time(0L));
409 void KBackgroundProgram::update()
411 m_LastChange = (int) time(0L);
415 QString KBackgroundProgram::fingerprint()
417 return QString("co:%1;re:%2").arg(m_Command).arg(m_Refresh);
421 int KBackgroundProgram::hash()
423 if (hashdirty) {
424 m_Hash = BGHash(fingerprint());
425 hashdirty = false;
427 return m_Hash;
431 /* static */
432 QStringList KBackgroundProgram::list()
434 KStandardDirs *dirs = KGlobal::dirs();
435 dirs->addResourceType("dtop_program", "data", "kdesktop/programs");
436 QStringList lst = dirs->findAllResources("dtop_program", "*.desktop",
437 KStandardDirs::NoDuplicates);
438 QStringList::Iterator it;
439 for (it=lst.begin(); it!=lst.end(); ++it) {
440 // Strip path and suffix
441 int pos = (*it).lastIndexOf('/');
442 if (pos != -1)
443 (*it) = (*it).mid(pos+1);
444 pos = (*it).lastIndexOf('.');
445 if (pos != -1)
446 (*it) = (*it).left(pos);
448 return lst;
452 /**** KBackgroundSettings ****/
455 KBackgroundSettings::KBackgroundSettings(int desk, int screen, bool drawBackgroundPerScreen, const KSharedConfigPtr &config, bool _kdmMode)
456 : KBackgroundPattern(_kdmMode),
457 KBackgroundProgram(_kdmMode)
459 dirty = false; hashdirty = true;
460 m_bDrawBackgroundPerScreen = drawBackgroundPerScreen;
461 m_Desk = desk;
462 m_Screen = screen;
463 m_bEnabled = true;
464 m_kdmMode = _kdmMode;
466 // Default values.
467 defColorA = _defColorA;
468 defColorB = _defColorB;
469 if (QPixmap::defaultDepth() > 8)
470 defBackgroundMode = _defBackgroundMode;
471 else
472 defBackgroundMode = Flat;
473 defWallpaperMode = _defWallpaperMode;
474 defMultiMode = _defMultiMode;
475 defBlendMode = _defBlendMode;
476 defBlendBalance = _defBlendBalance;
477 defReverseBlending = _defReverseBlending;
479 m_MinOptimizationDepth = _defMinOptimizationDepth;
480 m_bShm = _defShm;
482 // Background modes
483 #define ADD_STRING(ID) m_BMMap[#ID] = ID; m_BMRevMap[ID] = (char *) #ID;
484 ADD_STRING(Flat)
485 ADD_STRING(Pattern)
486 ADD_STRING(Program)
487 ADD_STRING(HorizontalGradient)
488 ADD_STRING(VerticalGradient)
489 ADD_STRING(PyramidGradient)
490 ADD_STRING(PipeCrossGradient)
491 ADD_STRING(EllipticGradient)
492 #undef ADD_STRING
494 // Blend modes
495 #define ADD_STRING(ID) m_BlMMap[#ID] = ID; m_BlMRevMap[ID] = (char *) #ID;
496 ADD_STRING(NoBlending)
497 ADD_STRING(FlatBlending)
498 ADD_STRING(HorizontalBlending)
499 ADD_STRING(VerticalBlending)
500 ADD_STRING(PyramidBlending)
501 ADD_STRING(PipeCrossBlending)
502 ADD_STRING(EllipticBlending)
503 ADD_STRING(IntensityBlending)
504 ADD_STRING(SaturateBlending)
505 ADD_STRING(ContrastBlending)
506 ADD_STRING(HueShiftBlending)
507 #undef ADD_STRING
509 // Wallpaper modes
510 #define ADD_STRING(ID) m_WMMap[#ID] = ID; m_WMRevMap[ID] = (char *) #ID;
511 ADD_STRING(NoWallpaper)
512 ADD_STRING(Centred)
513 ADD_STRING(Tiled)
514 ADD_STRING(CenterTiled)
515 ADD_STRING(CentredMaxpect)
516 ADD_STRING(TiledMaxpect)
517 ADD_STRING(Scaled)
518 ADD_STRING(CentredAutoFit)
519 ADD_STRING(ScaleAndCrop)
520 #undef ADD_STRING
522 // Multiple wallpaper modes
523 #define ADD_STRING(ID) m_MMMap[#ID] = ID; m_MMRevMap[ID] = (char *) #ID;
524 ADD_STRING(NoMulti)
525 ADD_STRING(InOrder)
526 ADD_STRING(Random)
527 ADD_STRING(NoMultiRandom)
528 #undef ADD_STRING
530 m_pDirs = KGlobal::dirs();
532 if (!config) {
533 int screen_number = 0;
534 if (QX11Info::display())
535 screen_number = DefaultScreen(QX11Info::display());
536 QString configname;
537 if (screen_number == 0)
538 configname = "kdesktoprc";
539 else
540 configname.sprintf("kdesktop-screen-%drc", screen_number);
542 m_pConfig = KSharedConfig::openConfig(configname, KConfig::NoGlobals);
543 } else {
544 m_pConfig = config;
547 if (m_Desk == -1)
548 return;
550 readSettings();
554 KBackgroundSettings::~KBackgroundSettings()
558 void KBackgroundSettings::copyConfig(const KBackgroundSettings *settings)
560 dirty = true;
561 hashdirty = true;
563 m_ColorA = settings->m_ColorA;
564 m_ColorB = settings->m_ColorB;
565 m_Wallpaper = settings->m_Wallpaper;
566 m_WallpaperList = settings->m_WallpaperList;
567 m_WallpaperFiles = settings->m_WallpaperFiles;
569 m_BackgroundMode = settings->m_BackgroundMode;
570 m_WallpaperMode = settings->m_WallpaperMode;
571 m_BlendMode = settings->m_BlendMode;
572 m_BlendBalance = settings->m_BlendBalance;
573 m_ReverseBlending = settings->m_ReverseBlending;
574 m_MinOptimizationDepth = settings->m_MinOptimizationDepth;
575 m_bShm = settings->m_bShm;
576 m_MultiMode = settings->m_MultiMode;
577 m_Interval = settings->m_Interval;
578 m_CurrentWallpaper = settings->m_CurrentWallpaper;
579 m_CurrentWallpaperName = settings->m_CurrentWallpaperName;
581 KBackgroundPattern::copyConfig(settings);
582 KBackgroundProgram::copyConfig(settings);
586 void KBackgroundSettings::load(int desk, int screen, bool drawBackgroundPerScreen, bool reparseConfig)
588 m_Desk = desk;
589 m_Screen = screen;
590 m_bDrawBackgroundPerScreen = drawBackgroundPerScreen;
591 readSettings(reparseConfig);
595 void KBackgroundSettings::setColorA(const QColor& color)
597 if (m_ColorA == color)
598 return;
599 dirty = hashdirty = true;
600 m_ColorA = color;
604 void KBackgroundSettings::setColorB(const QColor& color)
606 if (m_ColorB == color)
607 return;
608 dirty = hashdirty = true;
609 m_ColorB = color;
613 void KBackgroundSettings::setPatternName(const QString &name)
615 int ohash = KBackgroundPattern::hash();
616 KBackgroundPattern::load(name);
617 if (ohash == KBackgroundPattern::hash())
618 return;
620 dirty = hashdirty = true;
621 return;
625 void KBackgroundSettings::setProgram(const QString &name)
627 int ohash = KBackgroundProgram::hash();
628 KBackgroundProgram::load(name);
629 if (ohash == KBackgroundProgram::hash())
630 return;
632 dirty = hashdirty = true;
633 return;
637 void KBackgroundSettings::setBackgroundMode(int mode)
639 if (m_BackgroundMode == mode)
640 return;
641 dirty = hashdirty = true;
642 m_BackgroundMode = mode;
645 void KBackgroundSettings::setBlendMode(int mode)
647 if (m_BlendMode == mode)
648 return;
649 dirty = hashdirty = true;
650 m_BlendMode = mode;
653 void KBackgroundSettings::setBlendBalance(int value)
655 if (m_BlendBalance == value)
656 return;
657 dirty = hashdirty = true;
658 m_BlendBalance = value;
661 void KBackgroundSettings::setReverseBlending(bool value)
663 if (m_ReverseBlending == value)
664 return;
665 dirty = hashdirty = true;
666 m_ReverseBlending = value;
670 void KBackgroundSettings::setWallpaper(const QString &wallpaper)
672 if (m_Wallpaper == wallpaper)
673 return;
674 dirty = hashdirty = true;
675 m_Wallpaper = wallpaper;
679 void KBackgroundSettings::setWallpaperMode(int mode)
681 if (m_WallpaperMode == mode)
682 return;
683 dirty = hashdirty = true;
684 m_WallpaperMode = mode;
688 void KBackgroundSettings::setWallpaperList(const QStringList &list)
690 KStandardDirs *d = KGlobal::dirs();
691 if (m_WallpaperList == list)
692 return;
694 dirty = hashdirty = true;
695 m_WallpaperList.clear();
696 for(QStringList::ConstIterator it = list.begin();
697 it != list.end(); ++it)
699 QString rpath = d->relativeLocation("wallpaper", *it);
700 m_WallpaperList.append( !rpath.isEmpty() ? rpath : *it );
702 updateWallpaperFiles();
703 // Try to keep the current wallpaper (-1 to set position to one before it)
704 m_CurrentWallpaper = m_WallpaperFiles.indexOf(m_CurrentWallpaperName) - 1;
705 changeWallpaper(m_CurrentWallpaper < 0);
709 void KBackgroundSettings::setWallpaperChangeInterval(int interval)
711 if (m_Interval == interval)
712 return;
713 dirty = hashdirty = true;
714 m_Interval = interval;
718 void KBackgroundSettings::setMultiWallpaperMode(int mode)
720 if (m_MultiMode == mode)
721 return;
722 dirty = hashdirty = true;
723 m_MultiMode = mode;
724 changeWallpaper(true);
728 void KBackgroundSettings::setMinOptimizationDepth(int mode)
730 if (m_MinOptimizationDepth == mode)
731 return;
732 dirty = hashdirty = true;
733 m_MinOptimizationDepth = mode;
736 bool KBackgroundSettings::optimize() const
738 switch( m_MinOptimizationDepth )
740 case AlwaysOpt :
741 return true;
742 case Opt16bpp :
743 return QPixmap::defaultDepth() >= 16;
744 case Opt15bpp :
745 return QPixmap::defaultDepth() >= 15;
746 case NeverOpt :
747 default :
748 return false;
752 void KBackgroundSettings::setUseShm(bool use)
754 if (m_bShm == use)
755 return;
756 dirty = hashdirty = true;
757 m_bShm = use;
760 QString KBackgroundSettings::configGroupName() const
762 QString screenName;
763 if (m_bDrawBackgroundPerScreen)
764 screenName = QString("Screen%1").arg(QString::number(m_Screen));
765 return QString("Desktop%1%2").arg(m_Desk).arg(screenName);
768 void KBackgroundSettings::readSettings(bool reparse)
770 if (reparse)
771 m_pConfig->reparseConfiguration();
773 KConfigGroup cg = m_pConfig->group(configGroupName());
775 // Background mode (Flat, div. Gradients, Pattern or Program)
776 m_ColorA = cg.readEntry("Color1", defColorA);
777 m_ColorB = cg.readEntry("Color2", defColorB);
779 QString s = m_kdmMode ? cg.readEntry("Pattern") : cg.readPathEntry("Pattern", QString());
780 if (!s.isEmpty())
781 KBackgroundPattern::load(s);
783 s = m_kdmMode ? cg.readEntry("Program") : cg.readPathEntry("Program", QString());
784 if (!s.isEmpty())
785 KBackgroundProgram::load(s);
787 m_BackgroundMode = defBackgroundMode;
788 s = cg.readEntry("BackgroundMode", "invalid");
790 if (m_BMMap.contains(s)) {
791 int mode = m_BMMap[s];
792 // consistency check
793 if ( ((mode != Pattern) && (mode != Program)) ||
794 ((mode == Pattern) && !pattern().isEmpty()) ||
795 ((mode == Program) && !command().isEmpty())
797 m_BackgroundMode = mode;
800 m_BlendMode = defBlendMode;
801 s = cg.readEntry("BlendMode", "invalid");
802 if (m_BlMMap.contains(s)) {
803 m_BlendMode = m_BlMMap[s];
806 m_BlendBalance = defBlendBalance;
807 int value = cg.readEntry( "BlendBalance", defBlendBalance);
808 if (value > -201 && value < 201)
809 m_BlendBalance = value;
811 m_ReverseBlending = cg.readEntry( "ReverseBlending", defReverseBlending );
813 // Multiple wallpaper config
814 m_WallpaperList = cg.readPathEntry("WallpaperList", QStringList());
816 m_Interval = cg.readEntry("ChangeInterval", 60);
817 m_LastChange = cg.readEntry("LastChange", 0);
818 m_CurrentWallpaper = cg.readEntry("CurrentWallpaper", 0);
819 m_CurrentWallpaperName = cg.readEntry("CurrentWallpaperName");
821 m_MultiMode = defMultiMode;
822 s = cg.readEntry("MultiWallpaperMode");
823 if (m_MMMap.contains(s)) {
824 int mode = m_MMMap[s];
825 m_MultiMode = mode;
828 updateWallpaperFiles();
829 if( !m_CurrentWallpaperName.isEmpty())
830 m_CurrentWallpaper = m_WallpaperFiles.indexOf(m_CurrentWallpaperName);
831 if(m_CurrentWallpaper < 0)
832 m_CurrentWallpaper = 0;
834 // Wallpaper mode (NoWallpaper, div. tilings)
835 m_WallpaperMode = defWallpaperMode;
836 m_Wallpaper = m_kdmMode ? cg.readEntry("Wallpaper") : cg.readPathEntry("Wallpaper", QString());
837 s = cg.readEntry("WallpaperMode", "invalid");
838 if (m_WMMap.contains(s)) {
839 int mode = m_WMMap[s];
840 // consistency check.
841 if ((mode == NoWallpaper) || !m_Wallpaper.isEmpty() || (m_MultiMode == InOrder || m_MultiMode == Random))
842 m_WallpaperMode = mode;
845 m_MinOptimizationDepth = cg.readEntry( "MinOptimizationDepth",
846 _defMinOptimizationDepth );
847 m_bShm = cg.readEntry( "UseSHM", _defShm );
849 dirty = false; hashdirty = true;
853 void KBackgroundSettings::writeSettings()
855 KBackgroundPattern::writeSettings();
856 KBackgroundProgram::writeSettings();
858 if (!dirty)
859 return;
861 KConfigGroup conf(m_pConfig, configGroupName());
862 conf.writeEntry("Color1", m_ColorA);
863 conf.writeEntry("Color2", m_ColorB);
864 conf.writeEntry("Program", KBackgroundProgram::name());
865 conf.writeEntry("BackgroundMode", QString(m_BMRevMap[m_BackgroundMode]));
866 conf.writeEntry("WallpaperMode", QString(m_WMRevMap[m_WallpaperMode]));
867 conf.writeEntry("MultiWallpaperMode", QString(m_MMRevMap[m_MultiMode]));
868 conf.writeEntry("BlendMode", QString(m_BlMRevMap[m_BlendMode]));
869 conf.writeEntry("BlendBalance", m_BlendBalance);
870 conf.writeEntry("ReverseBlending", m_ReverseBlending);
871 conf.writeEntry("MinOptimizationDepth", m_MinOptimizationDepth);
872 conf.writeEntry("UseSHM", m_bShm);
873 if (m_kdmMode) {
874 conf.writeEntry("Pattern", KBackgroundPattern::name());
875 conf.writeEntry("Wallpaper", m_Wallpaper);
876 conf.writeEntry("WallpaperList", m_WallpaperList);
877 } else {
878 conf.writePathEntry("Pattern", KBackgroundPattern::name());
879 conf.writePathEntry("Wallpaper", m_Wallpaper);
880 conf.writePathEntry("WallpaperList", m_WallpaperList);
882 conf.writeEntry("ChangeInterval", m_Interval);
883 conf.writeEntry("LastChange", m_LastChange);
884 conf.deleteEntry("CurrentWallpaper"); // obsolete, remember name
885 conf.writeEntry("CurrentWallpaperName", m_CurrentWallpaperName);
887 m_pConfig->sync();
889 dirty = false;
893 * (re)Build m_WallpaperFiles from m_WallpaperList
895 void KBackgroundSettings::updateWallpaperFiles()
897 QStringList::Iterator it;
898 m_WallpaperFiles.clear();
899 for (it=m_WallpaperList.begin(); it!=m_WallpaperList.end(); ++it) {
900 QString file = KStandardDirs::locate("wallpaper", *it);
901 if (file.isEmpty())
902 continue;
903 QFileInfo fi(file);
904 if (!fi.exists())
905 continue;
906 if (fi.isFile() && fi.isReadable())
907 m_WallpaperFiles.append(file);
908 if (fi.isDir()) {
909 QDir dir(file);
910 QStringList lst = dir.entryList(QDir::Files | QDir::Readable);
911 QStringList::Iterator it;
912 for (it=lst.begin(); it!=lst.end(); ++it)
914 file = dir.absoluteFilePath(*it);
915 QFileInfo fi(file);
916 if (fi.isFile() && fi.isReadable())
917 m_WallpaperFiles.append(file);
922 if (m_MultiMode == Random)
923 randomizeWallpaperFiles();
926 // Randomize the m_WallpaperFiles in a non-repeating method.
927 void KBackgroundSettings::randomizeWallpaperFiles()
929 if (m_WallpaperFiles.count() < 4)
930 return;
932 KRandomSequence rseq;
933 QStringList tmpList = m_WallpaperFiles;
934 QStringList randomList;
935 randomList.append(tmpList.front());
936 tmpList.pop_front();
937 while(tmpList.count())
939 long t = rseq.getLong(randomList.count()+1);
940 randomList.insert(t, tmpList.front());
941 tmpList.pop_front();
943 m_WallpaperFiles = randomList;
946 QStringList KBackgroundSettings::wallpaperList() const
948 if ( m_WallpaperMode == NoWallpaper )
949 return QStringList();
950 if ( m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom )
951 return QStringList(m_Wallpaper);
952 return m_WallpaperList;
955 QStringList KBackgroundSettings::wallpaperFiles() const
957 if ( m_WallpaperMode == NoWallpaper )
958 return QStringList();
959 if ( m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom )
960 return QStringList(m_Wallpaper);
961 return m_WallpaperFiles;
965 * Select a new wallpaper from the list.
967 void KBackgroundSettings::changeWallpaper(bool init)
969 if (m_WallpaperFiles.count() == 0) {
970 if( init ) {
971 m_CurrentWallpaper = 0;
972 m_CurrentWallpaperName = QString();
974 return;
977 switch (m_MultiMode) {
978 case InOrder:
979 m_CurrentWallpaper++;
980 if (init || (m_CurrentWallpaper >= (int) m_WallpaperFiles.count()))
981 m_CurrentWallpaper = 0;
982 break;
984 case Random:
985 // Random: m_WallpaperFiles is randomized in a non-repeating
986 // method. Hence we just increment the index.
987 m_CurrentWallpaper++;
988 if (init || (m_CurrentWallpaper >= (int) m_WallpaperFiles.count())) {
989 m_CurrentWallpaper = 0;
990 randomizeWallpaperFiles(); // Get a new random-ordered list.
992 break;
993 default:
994 break;
997 m_CurrentWallpaperName = m_WallpaperFiles[ m_CurrentWallpaper ];
998 m_LastChange = (int) time(0L);
999 KConfigGroup conf(m_pConfig, configGroupName());
1000 conf.deleteEntry("CurrentWallpaper"); // obsolete, remember name
1001 conf.writeEntry("CurrentWallpaperName", m_CurrentWallpaperName);
1002 conf.writeEntry("LastChange", m_LastChange);
1003 m_pConfig->sync();
1005 hashdirty = true;
1009 QString KBackgroundSettings::currentWallpaper() const
1011 if ( m_WallpaperMode == NoWallpaper )
1012 return QString();
1013 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
1014 return m_Wallpaper;
1015 if (m_CurrentWallpaper >= 0 && m_CurrentWallpaper < (int) m_WallpaperFiles.count())
1016 return m_WallpaperFiles[m_CurrentWallpaper];
1017 return QString();
1020 bool KBackgroundSettings::discardCurrentWallpaper()
1022 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
1024 return false;
1026 m_WallpaperFiles.removeAll(m_WallpaperFiles.at(m_CurrentWallpaper));
1027 --m_CurrentWallpaper;
1028 changeWallpaper();
1030 return true;
1034 bool KBackgroundSettings::needWallpaperChange()
1036 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
1037 return false;
1039 return ((m_LastChange + 60*m_Interval) <= time(0L));
1044 * Create a fingerprint string for this config. Be somewhat (overly) carefull
1045 * that only a different final result will give a different fingerprint.
1048 QString KBackgroundSettings::fingerprint()
1050 QString s = QString("bm:%1;en:%2").arg(m_BackgroundMode).arg(m_bEnabled);
1051 switch (m_BackgroundMode) {
1052 case Flat:
1053 s += QString("ca:%1;").arg(m_ColorA.rgb());
1054 break;
1055 case Program:
1056 s += QString("pr:%1;").arg(KBackgroundProgram::hash());
1057 break;
1058 case Pattern:
1059 s += QString("ca:%1;cb:%2;pt:%3;").arg(m_ColorA.rgb())
1060 .arg(m_ColorB.rgb()).arg(KBackgroundPattern::hash());
1061 break;
1062 default:
1063 s += QString("ca:%1;cb:%2;").arg(m_ColorA.rgb()).arg(m_ColorB.rgb());
1064 break;
1067 s += QString("wm:%1;").arg(m_WallpaperMode);
1068 if (m_WallpaperMode != NoWallpaper)
1070 quint32 rh = KGlobal::dirs()->calcResourceHash("wallpaper", currentWallpaper(), false);
1071 s += QString("wp:%2:%1;").arg(rh).arg(currentWallpaper());
1074 s += QString("blm:%1;").arg(m_BlendMode);
1075 if (m_BlendMode != NoBlending) {
1076 s += QString("blb:%1;").arg(m_BlendBalance);
1077 s += QString("rbl:%1;").arg(int(m_ReverseBlending));
1079 s += QString::number( m_bShm );
1080 s += QString::number( m_MinOptimizationDepth );
1082 return s;
1086 int KBackgroundSettings::hash()
1088 if (hashdirty) {
1089 m_Hash = BGHash(fingerprint());
1090 hashdirty = false;
1092 return m_Hash;
1095 void KBackgroundSettings::setEnabled(const bool enable)
1097 if (m_bEnabled == enable)
1098 return;
1100 m_bEnabled= enable;
1101 hashdirty = true;
1104 /**** KGlobalBackgroundSettings ****/
1106 KGlobalBackgroundSettings::KGlobalBackgroundSettings(const KSharedConfigPtr &_config)
1108 m_pConfig = _config;
1110 readSettings();
1114 QString KGlobalBackgroundSettings::deskName(int desk)
1116 return m_Names[desk];
1121 void KGlobalBackgroundSettings::setDeskName(int desk, QString name)
1123 if (name == m_Names[desk])
1124 return;
1125 dirty = true;
1126 m_Names[desk] = name;
1131 void KGlobalBackgroundSettings::setCacheSize(int size)
1133 if (size == m_CacheSize)
1134 return;
1135 dirty = true;
1136 m_CacheSize = size;
1140 void KGlobalBackgroundSettings::setLimitCache(bool limit)
1142 if (limit == m_bLimitCache)
1143 return;
1144 dirty = true;
1145 m_bLimitCache = limit;
1149 bool KGlobalBackgroundSettings::drawBackgroundPerScreen(int desk) const
1151 if ( desk > int(m_bDrawBackgroundPerScreen.size()) )
1152 return _defDrawBackgroundPerScreen;
1153 return m_bDrawBackgroundPerScreen[desk];
1157 void KGlobalBackgroundSettings::setDrawBackgroundPerScreen(int desk, bool perScreen)
1159 if ( desk >= int(m_bDrawBackgroundPerScreen.size()) )
1160 return;
1162 if ( m_bDrawBackgroundPerScreen[desk] == perScreen )
1163 return;
1165 dirty = true;
1166 m_bDrawBackgroundPerScreen[desk] = perScreen;
1170 void KGlobalBackgroundSettings::setCommonScreenBackground(bool common)
1172 if (common == m_bCommonScreen)
1173 return;
1174 dirty = true;
1175 m_bCommonScreen = common;
1179 void KGlobalBackgroundSettings::setCommonDeskBackground(bool common)
1181 if (common == m_bCommonDesk)
1182 return;
1183 dirty = true;
1184 m_bCommonDesk = common;
1188 void KGlobalBackgroundSettings::setDockPanel(bool dock)
1190 if (dock == m_bDock)
1191 return;
1192 dirty = true;
1193 m_bDock = dock;
1197 void KGlobalBackgroundSettings::setExportBackground(bool _export)
1199 if (_export == m_bExport)
1200 return;
1201 dirty = true;
1202 m_bExport = _export;
1205 void KGlobalBackgroundSettings::setTextColor(const QColor &_color)
1207 if (_color == m_TextColor)
1208 return;
1209 dirty = true;
1210 m_TextColor = _color;
1213 void KGlobalBackgroundSettings::setTextBackgroundColor(const QColor &_color)
1215 if (_color == m_TextBackgroundColor)
1216 return;
1217 dirty = true;
1218 m_TextBackgroundColor = _color;
1221 void KGlobalBackgroundSettings::setShadowEnabled(bool enabled)
1223 if (enabled == m_shadowEnabled)
1224 return;
1225 dirty = true;
1226 m_shadowEnabled = enabled;
1229 void KGlobalBackgroundSettings::setTextLines(int lines)
1231 if (lines == m_textLines)
1232 return;
1233 dirty = true;
1234 m_textLines = lines;
1237 void KGlobalBackgroundSettings::setTextWidth(int width)
1239 if (width == m_textWidth)
1240 return;
1241 dirty = true;
1242 m_textWidth = width;
1245 void KGlobalBackgroundSettings::readSettings()
1247 const KConfigGroup common = m_pConfig->group( "Background Common");
1249 m_bCommonScreen = common.readEntry("CommonScreen", _defCommonScreen);
1250 m_bCommonDesk = common.readEntry("CommonDesktop", _defCommonDesk);
1251 m_bDock = common.readEntry("Dock", _defDock);
1252 m_bExport = common.readEntry("Export", _defExport);
1253 m_bLimitCache = common.readEntry("LimitCache", _defLimitCache);
1254 m_CacheSize = common.readEntry("CacheSize", _defCacheSize);
1256 NETRootInfo info( QX11Info::display(), NET::DesktopNames | NET::NumberOfDesktops );
1257 m_bDrawBackgroundPerScreen.resize(info.numberOfDesktops());
1258 for ( int i = 0 ; i < info.numberOfDesktops() ; ++i )
1259 m_bDrawBackgroundPerScreen[i] = common.readEntry( QString("DrawBackgroundPerScreen_%1").arg(i), _defDrawBackgroundPerScreen );
1261 // OK to use explicit QPalette::Active here, desktop icons can ignore state
1262 // ### But, aren't desktop icons gone in KDE4?
1263 m_TextColor = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color();
1264 const KConfigGroup fmSettings = m_pConfig->group("FMSettings");
1265 m_TextColor = fmSettings.readEntry("NormalTextColor", m_TextColor);
1266 m_TextBackgroundColor = fmSettings.readEntry("ItemTextBackground");
1267 m_shadowEnabled = fmSettings.readEntry("ShadowEnabled", true);
1268 m_textLines = fmSettings.readEntry("TextHeight", DEFAULT_TEXTHEIGHT);
1269 m_textWidth = fmSettings.readEntry("TextWidth", DEFAULT_TEXTWIDTH);
1271 m_Names.clear();
1272 for ( int i = 0 ; i < info.numberOfDesktops() ; ++i )
1273 m_Names.append( QString::fromUtf8(info.desktopName(i+1)) );
1275 dirty = false;
1278 void KGlobalBackgroundSettings::writeSettings()
1280 if (!dirty)
1281 return;
1283 KConfigGroup common = m_pConfig->group( "Background Common");
1284 common.writeEntry("CommonScreen", m_bCommonScreen);
1285 common.writeEntry("CommonDesktop", m_bCommonDesk);
1286 common.writeEntry("Dock", m_bDock);
1287 common.writeEntry("Export", m_bExport);
1288 common.writeEntry("LimitCache", m_bLimitCache);
1289 common.writeEntry("CacheSize", m_CacheSize);
1291 for ( int i = 0 ; i < m_bDrawBackgroundPerScreen.size() ; ++i )
1292 common.writeEntry(QString("DrawBackgroundPerScreen_%1").arg(i), m_bDrawBackgroundPerScreen[i] );
1294 KConfigGroup fmSettings = m_pConfig->group("FMSettings");
1295 fmSettings.writeEntry("NormalTextColor", m_TextColor);
1296 fmSettings.writeEntry("ItemTextBackground", m_TextBackgroundColor);
1297 fmSettings.writeEntry("ShadowEnabled", m_shadowEnabled);
1298 fmSettings.writeEntry("TextHeight", m_textLines);
1299 fmSettings.writeEntry("TextWidth", m_textWidth);
1301 m_pConfig->sync();
1302 dirty = false;
1304 // tell kdesktop to get it's butt in gear and pick up the new settings
1305 QDBusInterface kdesktop("org.kde.kdesktop", "/Background", "org.kde.kdesktop.Background");
1306 kdesktop.call("configure");