not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kcontrol / kdm / background / bgsettings.cpp
blobfeb6158874ca551103c6818568f6d08c5bd9fc79
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 // Clean up after X.h/Xlib.h
16 #undef Bool
17 #undef Unsorted
19 #include <QDir>
20 #include <QPixmap>
21 //Added by qt3to4:
22 #include <QByteArray>
24 #include <kapplication.h>
25 #include <kdebug.h>
26 #include <KColorScheme>
27 #include <kdesktopfile.h>
28 #include <kconfiggroup.h>
29 #include <kstandarddirs.h>
30 #include <krandomsequence.h>
32 #include "bgdefaults.h"
33 #include "bgsettings.h"
34 #include <QX11Info>
38 * QString -> int hash. From Qt's QGDict::hashKeyString().
41 static int BGHash(const QString &key)
43 int g, h = 0;
44 const QChar *p = key.unicode();
45 for (int i=0; i < key.length(); i++) {
46 h = (h << 4) + p[i].cell();
47 if ((g = (h & 0xf0000000)))
48 h ^= (g >> 24);
49 h &= ~g;
51 return h;
55 /**** KBackgroundPattern ****/
58 KBackgroundPattern::KBackgroundPattern(const QString &name)
60 dirty = false;
61 hashdirty = true;
63 m_pDirs = KGlobal::dirs();
64 m_pDirs->addResourceType("dtop_pattern", "data", "kdm/patterns");
65 m_pConfig = 0L;
67 m_Name = name;
68 if (m_Name.isEmpty())
69 return;
71 init();
72 readSettings();
76 KBackgroundPattern::~KBackgroundPattern()
78 delete m_pConfig;
81 void KBackgroundPattern::copyConfig(const KBackgroundPattern *settings)
83 dirty = hashdirty = true;
84 m_Name = settings->m_Name;
85 m_Comment = settings->m_Comment;
86 m_Pattern = settings->m_Pattern;
87 m_File = settings->m_File;
90 void KBackgroundPattern::load(const QString &name)
92 m_Name = name;
93 init();
94 readSettings();
98 void KBackgroundPattern::init(bool force_rw)
100 delete m_pConfig;
102 m_File = m_pDirs->findResource("dtop_pattern", m_Name + ".desktop");
103 if (force_rw || m_File.isEmpty()) {
104 m_File = m_pDirs->saveLocation("dtop_pattern") + m_Name + ".desktop";
105 m_pConfig = new KDesktopFile(m_File);
106 } else
107 m_pConfig = new KDesktopFile(m_File);
109 QFileInfo fi(m_File);
110 m_bReadOnly = !fi.isWritable();
114 void KBackgroundPattern::setComment(const QString &comment)
116 if (m_Comment == comment)
117 return;
118 dirty = true;
119 m_Comment = comment;
123 void KBackgroundPattern::setPattern(const QString &pattern)
125 if (m_Pattern == pattern)
126 return;
127 dirty = hashdirty = true;
128 m_Pattern = pattern;
132 void KBackgroundPattern::readSettings()
134 dirty = false;
135 hashdirty = true;
137 const KConfigGroup group = m_pConfig->group("KDE Desktop Pattern");
139 m_Pattern = group.readEntry("File");
140 m_Comment = group.readEntry("Comment");
141 if (m_Comment.isEmpty())
142 m_Comment = m_File.mid(m_File.lastIndexOf('/')+1);
146 void KBackgroundPattern::writeSettings()
148 if (!dirty)
149 return;
150 if (m_bReadOnly)
151 init(true);
153 if ( !m_pConfig )
154 return; // better safe than sorry
156 KConfigGroup group = m_pConfig->group("KDE Desktop Pattern");
157 group.writeEntry("File", m_Pattern);
158 group.writeEntry("Comment", m_Comment);
159 m_pConfig->sync();
160 dirty = false;
164 bool KBackgroundPattern::isAvailable()
166 if (m_Pattern.isEmpty())
167 return false;
168 QString file = m_Pattern;
169 if (file.at(0) != '/')
170 file = m_pDirs->findResource("dtop_pattern", file);
171 QFileInfo fi(file);
172 return (fi.exists());
176 bool KBackgroundPattern::remove()
178 if (m_bReadOnly)
179 return false;
180 return !unlink(QFile::encodeName(m_File));
184 QString KBackgroundPattern::fingerprint()
186 return m_File;
190 int KBackgroundPattern::hash()
192 if (hashdirty) {
193 m_Hash = BGHash(fingerprint());
194 hashdirty = false;
196 return m_Hash;
200 /* static */
201 QStringList KBackgroundPattern::list()
203 KStandardDirs *dirs = KGlobal::dirs();
204 dirs->addResourceType("dtop_pattern", "data", "kdm/patterns");
205 QStringList lst = dirs->findAllResources("dtop_pattern", "*.desktop",
206 KStandardDirs::NoDuplicates);
207 QStringList::Iterator it;
208 for (it=lst.begin(); it!=lst.end(); ++it) {
209 // Strip path and suffix
210 int pos = (*it).lastIndexOf('/');
211 if (pos != -1)
212 (*it) = (*it).mid(pos+1);
213 pos = (*it).lastIndexOf('.');
214 if (pos != -1)
215 (*it) = (*it).left(pos);
217 return lst;
221 /**** KBackgroundProgram ****/
224 KBackgroundProgram::KBackgroundProgram(const QString &name)
226 dirty = false;
227 hashdirty = true;
229 m_pDirs = KGlobal::dirs();
230 m_pDirs->addResourceType("dtop_program", "data", "kdm/programs");
231 m_pConfig = 0L;
233 // prevent updates when just constructed.
234 m_LastChange = (int) time(0L);
236 m_Name = name;
237 if (m_Name.isEmpty())
238 return;
240 init();
241 readSettings();
245 KBackgroundProgram::~KBackgroundProgram()
247 delete m_pConfig;
250 void KBackgroundProgram::copyConfig(const KBackgroundProgram *settings)
252 dirty = hashdirty = true;
253 m_Refresh = settings->m_Refresh;
254 m_LastChange = settings->m_LastChange;
255 m_Name = settings->m_Name;
256 m_Command = settings->m_Command;
257 m_PreviewCommand = settings->m_PreviewCommand;
258 m_Comment = settings->m_Comment;
259 m_Executable = settings->m_Executable;
260 m_File = settings->m_File;
264 void KBackgroundProgram::init(bool force_rw)
266 delete m_pConfig;
268 m_File = m_pDirs->findResource("dtop_program", m_Name + ".desktop");
269 if (force_rw || m_File.isEmpty()) {
270 m_File = m_pDirs->saveLocation("dtop_program") + m_Name + ".desktop";
271 m_pConfig = new KDesktopFile(m_File);
272 m_bReadOnly = false;
273 } else {
274 m_pConfig = new KDesktopFile(m_File);
275 m_bReadOnly = (m_File != KStandardDirs::locateLocal("dtop_program", m_Name + ".desktop"));
280 void KBackgroundProgram::load(const QString &name)
282 m_Name = name;
283 init();
284 readSettings();
288 void KBackgroundProgram::setComment(const QString &comment)
290 if (m_Comment == comment)
291 return;
292 dirty = true;
293 m_Comment = comment;
297 void KBackgroundProgram::setExecutable(const QString &executable)
299 if (m_Executable == executable)
300 return;
301 dirty = true;
302 m_Executable = executable;
306 void KBackgroundProgram::setCommand(const QString &command)
308 if (m_Command == command)
309 return;
310 dirty = hashdirty = true;
311 m_Command = command;
315 void KBackgroundProgram::setPreviewCommand(const QString &command)
317 if (m_PreviewCommand == command)
318 return;
319 dirty = true;
320 m_PreviewCommand = command;
324 void KBackgroundProgram::setRefresh(int refresh)
326 if (m_Refresh == refresh)
327 return;
328 dirty = hashdirty = true;
329 m_Refresh = refresh;
333 void KBackgroundProgram::readSettings()
335 dirty = false;
336 hashdirty = true;
338 const KConfigGroup group = m_pConfig->group("KDE Desktop Program");
339 m_Comment = group.readEntry("Comment");
340 m_Executable = group.readEntry("Executable");
341 m_Command = group.readEntry("Command");
342 m_PreviewCommand = group.readEntry("PreviewCommand", m_Command);
343 m_Refresh = group.readEntry("Refresh", 300);
347 void KBackgroundProgram::writeSettings()
349 if (!dirty)
350 return;
351 if (m_bReadOnly)
352 init(true);
354 if ( !m_pConfig )
355 return; // better safe than sorry
357 KConfigGroup group = m_pConfig->group("KDE Desktop Program");
358 group.writeEntry("Comment", m_Comment);
359 group.writeEntry("Executable", m_Executable);
360 group.writeEntry("Command", m_Command);
361 group.writeEntry("PreviewCommand", m_PreviewCommand);
362 group.writeEntry("Refresh", m_Refresh);
363 m_pConfig->sync();
364 dirty = false;
368 bool KBackgroundProgram::isAvailable()
370 return !m_pDirs->findExe(m_Executable).isEmpty();
374 bool KBackgroundProgram::remove()
376 if (m_bReadOnly)
377 return false;
378 return !unlink(QFile::encodeName(m_File));
382 bool KBackgroundProgram::needUpdate()
384 return (m_LastChange + 60*m_Refresh <= time(0L));
388 void KBackgroundProgram::update()
390 m_LastChange = (int) time(0L);
394 QString KBackgroundProgram::fingerprint()
396 return QString("co:%1;re:%2").arg(m_Command).arg(m_Refresh);
400 int KBackgroundProgram::hash()
402 if (hashdirty) {
403 m_Hash = BGHash(fingerprint());
404 hashdirty = false;
406 return m_Hash;
410 /* static */
411 QStringList KBackgroundProgram::list()
413 KStandardDirs *dirs = KGlobal::dirs();
414 dirs->addResourceType("dtop_program", "data", "kdm/programs");
415 QStringList lst = dirs->findAllResources("dtop_program", "*.desktop",
416 KStandardDirs::NoDuplicates);
417 QStringList::Iterator it;
418 for (it=lst.begin(); it!=lst.end(); ++it) {
419 // Strip path and suffix
420 int pos = (*it).lastIndexOf('/');
421 if (pos != -1)
422 (*it) = (*it).mid(pos+1);
423 pos = (*it).lastIndexOf('.');
424 if (pos != -1)
425 (*it) = (*it).left(pos);
427 return lst;
431 /**** KBackgroundSettings ****/
434 KBackgroundSettings::KBackgroundSettings(int screen, bool drawBackgroundPerScreen, const KSharedConfigPtr &config)
435 : KBackgroundPattern(),
436 KBackgroundProgram()
438 dirty = false; hashdirty = true;
439 m_bDrawBackgroundPerScreen = drawBackgroundPerScreen;
440 m_Screen = screen;
441 m_bEnabled = true;
443 // Default values.
444 defColorA = _defColorA;
445 defColorB = _defColorB;
446 if (QPixmap::defaultDepth() > 8)
447 defBackgroundMode = _defBackgroundMode;
448 else
449 defBackgroundMode = Flat;
450 defWallpaperMode = _defWallpaperMode;
451 defMultiMode = _defMultiMode;
452 defBlendMode = _defBlendMode;
453 defBlendBalance = _defBlendBalance;
454 defReverseBlending = _defReverseBlending;
456 m_MinOptimizationDepth = _defMinOptimizationDepth;
457 m_bShm = _defShm;
459 // Background modes
460 #define ADD_STRING(ID) m_BMMap[#ID] = ID; m_BMRevMap[ID] = (char *) #ID;
461 ADD_STRING(Flat)
462 ADD_STRING(Pattern)
463 ADD_STRING(Program)
464 ADD_STRING(HorizontalGradient)
465 ADD_STRING(VerticalGradient)
466 ADD_STRING(PyramidGradient)
467 ADD_STRING(PipeCrossGradient)
468 ADD_STRING(EllipticGradient)
469 #undef ADD_STRING
471 // Blend modes
472 #define ADD_STRING(ID) m_BlMMap[#ID] = ID; m_BlMRevMap[ID] = (char *) #ID;
473 ADD_STRING(NoBlending)
474 ADD_STRING(FlatBlending)
475 ADD_STRING(HorizontalBlending)
476 ADD_STRING(VerticalBlending)
477 ADD_STRING(PyramidBlending)
478 ADD_STRING(PipeCrossBlending)
479 ADD_STRING(EllipticBlending)
480 ADD_STRING(IntensityBlending)
481 ADD_STRING(SaturateBlending)
482 ADD_STRING(ContrastBlending)
483 ADD_STRING(HueShiftBlending)
484 #undef ADD_STRING
486 // Wallpaper modes
487 #define ADD_STRING(ID) m_WMMap[#ID] = ID; m_WMRevMap[ID] = (char *) #ID;
488 ADD_STRING(NoWallpaper)
489 ADD_STRING(Centred)
490 ADD_STRING(Tiled)
491 ADD_STRING(CenterTiled)
492 ADD_STRING(CentredMaxpect)
493 ADD_STRING(TiledMaxpect)
494 ADD_STRING(Scaled)
495 ADD_STRING(CentredAutoFit)
496 ADD_STRING(ScaleAndCrop)
497 #undef ADD_STRING
499 // Multiple wallpaper modes
500 #define ADD_STRING(ID) m_MMMap[#ID] = ID; m_MMRevMap[ID] = (char *) #ID;
501 ADD_STRING(NoMulti)
502 ADD_STRING(InOrder)
503 ADD_STRING(Random)
504 ADD_STRING(NoMultiRandom)
505 #undef ADD_STRING
507 m_pDirs = KGlobal::dirs();
508 m_pConfig = config;
510 readSettings();
514 KBackgroundSettings::~KBackgroundSettings()
518 void KBackgroundSettings::copyConfig(const KBackgroundSettings *settings)
520 dirty = true;
521 hashdirty = true;
523 m_ColorA = settings->m_ColorA;
524 m_ColorB = settings->m_ColorB;
525 m_Wallpaper = settings->m_Wallpaper;
526 m_WallpaperList = settings->m_WallpaperList;
527 m_WallpaperFiles = settings->m_WallpaperFiles;
529 m_BackgroundMode = settings->m_BackgroundMode;
530 m_WallpaperMode = settings->m_WallpaperMode;
531 m_BlendMode = settings->m_BlendMode;
532 m_BlendBalance = settings->m_BlendBalance;
533 m_ReverseBlending = settings->m_ReverseBlending;
534 m_MinOptimizationDepth = settings->m_MinOptimizationDepth;
535 m_bShm = settings->m_bShm;
536 m_MultiMode = settings->m_MultiMode;
537 m_Interval = settings->m_Interval;
538 m_CurrentWallpaper = settings->m_CurrentWallpaper;
539 m_CurrentWallpaperName = settings->m_CurrentWallpaperName;
541 KBackgroundPattern::copyConfig(settings);
542 KBackgroundProgram::copyConfig(settings);
546 void KBackgroundSettings::load(int screen, bool drawBackgroundPerScreen, bool reparseConfig)
548 m_Screen = screen;
549 m_bDrawBackgroundPerScreen = drawBackgroundPerScreen;
550 readSettings(reparseConfig);
554 void KBackgroundSettings::setColorA(const QColor& color)
556 if (m_ColorA == color)
557 return;
558 dirty = hashdirty = true;
559 m_ColorA = color;
563 void KBackgroundSettings::setColorB(const QColor& color)
565 if (m_ColorB == color)
566 return;
567 dirty = hashdirty = true;
568 m_ColorB = color;
572 void KBackgroundSettings::setPatternName(const QString &name)
574 int ohash = KBackgroundPattern::hash();
575 KBackgroundPattern::load(name);
576 if (ohash == KBackgroundPattern::hash())
577 return;
579 dirty = hashdirty = true;
580 return;
584 void KBackgroundSettings::setProgram(const QString &name)
586 int ohash = KBackgroundProgram::hash();
587 KBackgroundProgram::load(name);
588 if (ohash == KBackgroundProgram::hash())
589 return;
591 dirty = hashdirty = true;
592 return;
596 void KBackgroundSettings::setBackgroundMode(int mode)
598 if (m_BackgroundMode == mode)
599 return;
600 dirty = hashdirty = true;
601 m_BackgroundMode = mode;
604 void KBackgroundSettings::setBlendMode(int mode)
606 if (m_BlendMode == mode)
607 return;
608 dirty = hashdirty = true;
609 m_BlendMode = mode;
612 void KBackgroundSettings::setBlendBalance(int value)
614 if (m_BlendBalance == value)
615 return;
616 dirty = hashdirty = true;
617 m_BlendBalance = value;
620 void KBackgroundSettings::setReverseBlending(bool value)
622 if (m_ReverseBlending == value)
623 return;
624 dirty = hashdirty = true;
625 m_ReverseBlending = value;
629 void KBackgroundSettings::setWallpaper(const QString &wallpaper)
631 if (m_Wallpaper == wallpaper)
632 return;
633 dirty = hashdirty = true;
634 m_Wallpaper = wallpaper;
638 void KBackgroundSettings::setWallpaperMode(int mode)
640 if (m_WallpaperMode == mode)
641 return;
642 dirty = hashdirty = true;
643 m_WallpaperMode = mode;
647 void KBackgroundSettings::setWallpaperList(const QStringList &list)
649 KStandardDirs *d = KGlobal::dirs();
650 if (m_WallpaperList == list)
651 return;
653 dirty = hashdirty = true;
654 m_WallpaperList.clear();
655 for(QStringList::ConstIterator it = list.begin();
656 it != list.end(); ++it)
658 QString rpath = d->relativeLocation("wallpaper", *it);
659 m_WallpaperList.append( !rpath.isEmpty() ? rpath : *it );
661 updateWallpaperFiles();
662 // Try to keep the current wallpaper (-1 to set position to one before it)
663 m_CurrentWallpaper = m_WallpaperFiles.indexOf(m_CurrentWallpaperName) - 1;
664 changeWallpaper(m_CurrentWallpaper < 0);
668 void KBackgroundSettings::setWallpaperChangeInterval(int interval)
670 if (m_Interval == interval)
671 return;
672 dirty = hashdirty = true;
673 m_Interval = interval;
677 void KBackgroundSettings::setMultiWallpaperMode(int mode)
679 if (m_MultiMode == mode)
680 return;
681 dirty = hashdirty = true;
682 m_MultiMode = mode;
683 changeWallpaper(true);
687 void KBackgroundSettings::setMinOptimizationDepth(int mode)
689 if (m_MinOptimizationDepth == mode)
690 return;
691 dirty = hashdirty = true;
692 m_MinOptimizationDepth = mode;
695 bool KBackgroundSettings::optimize() const
697 switch( m_MinOptimizationDepth )
699 case AlwaysOpt :
700 return true;
701 case Opt16bpp :
702 return QPixmap::defaultDepth() >= 16;
703 case Opt15bpp :
704 return QPixmap::defaultDepth() >= 15;
705 case NeverOpt :
706 default :
707 return false;
711 void KBackgroundSettings::setUseShm(bool use)
713 if (m_bShm == use)
714 return;
715 dirty = hashdirty = true;
716 m_bShm = use;
719 QString KBackgroundSettings::configGroupName() const
721 QString screenName;
722 if (m_bDrawBackgroundPerScreen)
723 screenName = QString("Screen%1").arg(QString::number(m_Screen));
724 return QString("Desktop0%1").arg(screenName);
727 void KBackgroundSettings::readSettings(bool reparse)
729 if (reparse)
730 m_pConfig->reparseConfiguration();
732 KConfigGroup cg = m_pConfig->group(configGroupName());
734 // Background mode (Flat, div. Gradients, Pattern or Program)
735 m_ColorA = cg.readEntry("Color1", defColorA);
736 m_ColorB = cg.readEntry("Color2", defColorB);
738 QString s = cg.readEntry("Pattern");
739 if (!s.isEmpty())
740 KBackgroundPattern::load(s);
742 s = cg.readEntry("Program");
743 if (!s.isEmpty())
744 KBackgroundProgram::load(s);
746 m_BackgroundMode = defBackgroundMode;
747 s = cg.readEntry("BackgroundMode", "invalid");
749 if (m_BMMap.contains(s)) {
750 int mode = m_BMMap[s];
751 // consistency check
752 if ( ((mode != Pattern) && (mode != Program)) ||
753 ((mode == Pattern) && !pattern().isEmpty()) ||
754 ((mode == Program) && !command().isEmpty())
756 m_BackgroundMode = mode;
759 m_BlendMode = defBlendMode;
760 s = cg.readEntry("BlendMode", "invalid");
761 if (m_BlMMap.contains(s)) {
762 m_BlendMode = m_BlMMap[s];
765 m_BlendBalance = defBlendBalance;
766 int value = cg.readEntry( "BlendBalance", defBlendBalance);
767 if (value > -201 && value < 201)
768 m_BlendBalance = value;
770 m_ReverseBlending = cg.readEntry( "ReverseBlending", defReverseBlending );
772 // Multiple wallpaper config
773 m_WallpaperList = cg.readPathEntry("WallpaperList", QStringList());
775 m_Interval = cg.readEntry("ChangeInterval", 60);
776 m_LastChange = cg.readEntry("LastChange", 0);
777 m_CurrentWallpaper = cg.readEntry("CurrentWallpaper", 0);
778 m_CurrentWallpaperName = cg.readEntry("CurrentWallpaperName");
780 m_MultiMode = defMultiMode;
781 s = cg.readEntry("MultiWallpaperMode");
782 if (m_MMMap.contains(s)) {
783 int mode = m_MMMap[s];
784 m_MultiMode = mode;
787 updateWallpaperFiles();
788 if( !m_CurrentWallpaperName.isEmpty())
789 m_CurrentWallpaper = m_WallpaperFiles.indexOf(m_CurrentWallpaperName);
790 if(m_CurrentWallpaper < 0)
791 m_CurrentWallpaper = 0;
793 // Wallpaper mode (NoWallpaper, div. tilings)
794 m_WallpaperMode = defWallpaperMode;
795 m_Wallpaper = cg.readEntry("Wallpaper");
796 s = cg.readEntry("WallpaperMode", "invalid");
797 if (m_WMMap.contains(s)) {
798 int mode = m_WMMap[s];
799 // consistency check.
800 if ((mode == NoWallpaper) || !m_Wallpaper.isEmpty() || (m_MultiMode == InOrder || m_MultiMode == Random))
801 m_WallpaperMode = mode;
804 m_MinOptimizationDepth = cg.readEntry( "MinOptimizationDepth",
805 _defMinOptimizationDepth );
806 m_bShm = cg.readEntry( "UseSHM", _defShm );
808 dirty = false; hashdirty = true;
812 void KBackgroundSettings::writeSettings()
814 KBackgroundPattern::writeSettings();
815 KBackgroundProgram::writeSettings();
817 if (!dirty)
818 return;
820 KConfigGroup conf(m_pConfig, configGroupName());
821 conf.writeEntry("Color1", m_ColorA);
822 conf.writeEntry("Color2", m_ColorB);
823 conf.writeEntry("Program", KBackgroundProgram::name());
824 conf.writeEntry("BackgroundMode", QString(m_BMRevMap[m_BackgroundMode]));
825 conf.writeEntry("WallpaperMode", QString(m_WMRevMap[m_WallpaperMode]));
826 conf.writeEntry("MultiWallpaperMode", QString(m_MMRevMap[m_MultiMode]));
827 conf.writeEntry("BlendMode", QString(m_BlMRevMap[m_BlendMode]));
828 conf.writeEntry("BlendBalance", m_BlendBalance);
829 conf.writeEntry("ReverseBlending", m_ReverseBlending);
830 conf.writeEntry("MinOptimizationDepth", m_MinOptimizationDepth);
831 conf.writeEntry("UseSHM", m_bShm);
832 conf.writeEntry("Pattern", KBackgroundPattern::name());
833 conf.writeEntry("Wallpaper", m_Wallpaper);
834 conf.writeEntry("WallpaperList", m_WallpaperList);
835 conf.writeEntry("ChangeInterval", m_Interval);
836 conf.writeEntry("LastChange", m_LastChange);
837 conf.deleteEntry("CurrentWallpaper"); // obsolete, remember name
838 conf.writeEntry("CurrentWallpaperName", m_CurrentWallpaperName);
840 m_pConfig->sync();
842 dirty = false;
846 * (re)Build m_WallpaperFiles from m_WallpaperList
848 void KBackgroundSettings::updateWallpaperFiles()
850 QStringList::Iterator it;
851 m_WallpaperFiles.clear();
852 for (it=m_WallpaperList.begin(); it!=m_WallpaperList.end(); ++it) {
853 QString file = KStandardDirs::locate("wallpaper", *it);
854 if (file.isEmpty())
855 continue;
856 QFileInfo fi(file);
857 if (!fi.exists())
858 continue;
859 if (fi.isFile() && fi.isReadable())
860 m_WallpaperFiles.append(file);
861 if (fi.isDir()) {
862 QDir dir(file);
863 QStringList lst = dir.entryList(QDir::Files | QDir::Readable);
864 QStringList::Iterator it;
865 for (it=lst.begin(); it!=lst.end(); ++it)
867 file = dir.absoluteFilePath(*it);
868 QFileInfo fi(file);
869 if (fi.isFile() && fi.isReadable())
870 m_WallpaperFiles.append(file);
875 if (m_MultiMode == Random)
876 randomizeWallpaperFiles();
879 // Randomize the m_WallpaperFiles in a non-repeating method.
880 void KBackgroundSettings::randomizeWallpaperFiles()
882 if (m_WallpaperFiles.count() < 4)
883 return;
885 KRandomSequence rseq;
886 QStringList tmpList = m_WallpaperFiles;
887 QStringList randomList;
888 randomList.append(tmpList.front());
889 tmpList.pop_front();
890 while(tmpList.count())
892 long t = rseq.getLong(randomList.count()+1);
893 randomList.insert(t, tmpList.front());
894 tmpList.pop_front();
896 m_WallpaperFiles = randomList;
899 QStringList KBackgroundSettings::wallpaperList() const
901 if ( m_WallpaperMode == NoWallpaper )
902 return QStringList();
903 if ( m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom )
904 return QStringList(m_Wallpaper);
905 return m_WallpaperList;
908 QStringList KBackgroundSettings::wallpaperFiles() const
910 if ( m_WallpaperMode == NoWallpaper )
911 return QStringList();
912 if ( m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom )
913 return QStringList(m_Wallpaper);
914 return m_WallpaperFiles;
918 * Select a new wallpaper from the list.
920 void KBackgroundSettings::changeWallpaper(bool init)
922 if (m_WallpaperFiles.count() == 0) {
923 if( init ) {
924 m_CurrentWallpaper = 0;
925 m_CurrentWallpaperName = QString();
927 return;
930 switch (m_MultiMode) {
931 case InOrder:
932 m_CurrentWallpaper++;
933 if (init || (m_CurrentWallpaper >= (int) m_WallpaperFiles.count()))
934 m_CurrentWallpaper = 0;
935 break;
937 case Random:
938 // Random: m_WallpaperFiles is randomized in a non-repeating
939 // method. Hence we just increment the index.
940 m_CurrentWallpaper++;
941 if (init || (m_CurrentWallpaper >= (int) m_WallpaperFiles.count())) {
942 m_CurrentWallpaper = 0;
943 randomizeWallpaperFiles(); // Get a new random-ordered list.
945 break;
946 default:
947 break;
950 m_CurrentWallpaperName = m_WallpaperFiles[ m_CurrentWallpaper ];
951 m_LastChange = (int) time(0L);
952 KConfigGroup conf(m_pConfig, configGroupName());
953 conf.deleteEntry("CurrentWallpaper"); // obsolete, remember name
954 conf.writeEntry("CurrentWallpaperName", m_CurrentWallpaperName);
955 conf.writeEntry("LastChange", m_LastChange);
956 m_pConfig->sync();
958 hashdirty = true;
962 QString KBackgroundSettings::currentWallpaper() const
964 if ( m_WallpaperMode == NoWallpaper )
965 return QString();
966 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
967 return m_Wallpaper;
968 if (m_CurrentWallpaper >= 0 && m_CurrentWallpaper < (int) m_WallpaperFiles.count())
969 return m_WallpaperFiles[m_CurrentWallpaper];
970 return QString();
973 bool KBackgroundSettings::discardCurrentWallpaper()
975 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
977 return false;
979 m_WallpaperFiles.removeAll(m_WallpaperFiles.at(m_CurrentWallpaper));
980 --m_CurrentWallpaper;
981 changeWallpaper();
983 return true;
987 bool KBackgroundSettings::needWallpaperChange()
989 if (m_MultiMode == NoMulti || m_MultiMode == NoMultiRandom)
990 return false;
992 return ((m_LastChange + 60*m_Interval) <= time(0L));
997 * Create a fingerprint string for this config. Be somewhat (overly) carefull
998 * that only a different final result will give a different fingerprint.
1001 QString KBackgroundSettings::fingerprint()
1003 QString s = QString("bm:%1;en:%2").arg(m_BackgroundMode).arg(m_bEnabled);
1004 switch (m_BackgroundMode) {
1005 case Flat:
1006 s += QString("ca:%1;").arg(m_ColorA.rgb());
1007 break;
1008 case Program:
1009 s += QString("pr:%1;").arg(KBackgroundProgram::hash());
1010 break;
1011 case Pattern:
1012 s += QString("ca:%1;cb:%2;pt:%3;").arg(m_ColorA.rgb())
1013 .arg(m_ColorB.rgb()).arg(KBackgroundPattern::hash());
1014 break;
1015 default:
1016 s += QString("ca:%1;cb:%2;").arg(m_ColorA.rgb()).arg(m_ColorB.rgb());
1017 break;
1020 s += QString("wm:%1;").arg(m_WallpaperMode);
1021 if (m_WallpaperMode != NoWallpaper)
1023 quint32 rh = KGlobal::dirs()->calcResourceHash("wallpaper", currentWallpaper(), false);
1024 s += QString("wp:%2:%1;").arg(rh).arg(currentWallpaper());
1027 s += QString("blm:%1;").arg(m_BlendMode);
1028 if (m_BlendMode != NoBlending) {
1029 s += QString("blb:%1;").arg(m_BlendBalance);
1030 s += QString("rbl:%1;").arg(int(m_ReverseBlending));
1032 s += QString::number( m_bShm );
1033 s += QString::number( m_MinOptimizationDepth );
1035 return s;
1039 int KBackgroundSettings::hash()
1041 if (hashdirty) {
1042 m_Hash = BGHash(fingerprint());
1043 hashdirty = false;
1045 return m_Hash;
1048 void KBackgroundSettings::setEnabled(const bool enable)
1050 if (m_bEnabled == enable)
1051 return;
1053 m_bEnabled= enable;
1054 hashdirty = true;
1057 /**** KGlobalBackgroundSettings ****/
1059 KGlobalBackgroundSettings::KGlobalBackgroundSettings(const KSharedConfigPtr &_config)
1061 m_pConfig = _config;
1063 readSettings();
1067 void KGlobalBackgroundSettings::setCacheSize(int size)
1069 if (size == m_CacheSize)
1070 return;
1071 dirty = true;
1072 m_CacheSize = size;
1076 void KGlobalBackgroundSettings::setLimitCache(bool limit)
1078 if (limit == m_bLimitCache)
1079 return;
1080 dirty = true;
1081 m_bLimitCache = limit;
1085 bool KGlobalBackgroundSettings::drawBackgroundPerScreen() const
1087 return m_bDrawBackgroundPerScreen;
1091 void KGlobalBackgroundSettings::setDrawBackgroundPerScreen(bool perScreen)
1093 if ( m_bDrawBackgroundPerScreen == perScreen )
1094 return;
1096 dirty = true;
1097 m_bDrawBackgroundPerScreen = perScreen;
1101 void KGlobalBackgroundSettings::setCommonScreenBackground(bool common)
1103 if (common == m_bCommonScreen)
1104 return;
1105 dirty = true;
1106 m_bCommonScreen = common;
1109 void KGlobalBackgroundSettings::readSettings()
1111 const KConfigGroup common = m_pConfig->group( "Background Common");
1113 m_bCommonScreen = common.readEntry("CommonScreen", _defCommonScreen);
1114 m_bLimitCache = common.readEntry("LimitCache", _defLimitCache);
1115 m_CacheSize = common.readEntry("CacheSize", _defCacheSize);
1116 m_bDrawBackgroundPerScreen = common.readEntry("DrawBackgroundPerScreen_0", _defDrawBackgroundPerScreen);
1118 dirty = false;
1121 void KGlobalBackgroundSettings::writeSettings()
1123 if (!dirty)
1124 return;
1126 KConfigGroup common = m_pConfig->group( "Background Common");
1127 common.writeEntry("CommonScreen", m_bCommonScreen);
1128 common.writeEntry("LimitCache", m_bLimitCache);
1129 common.writeEntry("CacheSize", m_CacheSize);
1130 common.writeEntry("DrawBackgroundPerScreen_0", m_bDrawBackgroundPerScreen);
1132 m_pConfig->sync();
1133 dirty = false;