[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdebase/workspace
From:       Aaron J. Seigo <aseigo () kde ! org>
Date:       2011-01-25 1:59:41
Message-ID: 20110125015941.538AAAC8B9 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1216838 by aseigo:

move all launcher config reading/saving into GroupManager

GroupManager can now have a config group provided by a subclass;
a siple set/get method pair wasn't enough as Applet::config() can
change without notice (principle: Applets should never hang on to
the results of config(), but call it, use it, then discard the value
upon returning from the method it is used in)

upsides:
* this is all in one neat, centralized place allowing launcher config
  to be used amongst multiple implementations
* less code duplication just to satisfy config
* the launcher[Added|Removed] signals are now gone, which gets rid of the
  somewhat ugly implementation detail that there were multiple ways to
  find out when a launcher was added, some more direct than others

also, adds a configChanged signal which allows launchers to be saved
immediately to the config, safe(r) against interuptions / crashes


 M  +125 -16   libs/taskmanager/groupmanager.cpp  
 M  +16 -5     libs/taskmanager/groupmanager.h  
 M  +0 -2      plasma/desktop/applets/tasks/taskitemlayout.h  
 M  +23 -42    plasma/desktop/applets/tasks/tasks.cpp  
 M  +7 -5      plasma/desktop/applets/tasks/tasks.h  


--- trunk/KDE/kdebase/workspace/libs/taskmanager/groupmanager.cpp #1216837:1216838
@@ -23,6 +23,7 @@
 
 #include "groupmanager.h"
 
+#include <QBuffer>
 #include <QList>
 #include <QStack>
 #include <QTimer>
@@ -64,7 +65,8 @@
           showOnlyCurrentScreen(false),
           showOnlyMinimized(false),
           onlyGroupWhenFull(false),
-          changingGroupingStrategy(false)
+          changingGroupingStrategy(false),
+          readingLauncherConfig(false)
     {
     }
 
@@ -89,6 +91,10 @@
     void removeStartup(StartupPtr);
     void launcherVisibilityChange();
     void checkLauncherVisibility(LauncherItem *launcher);
+    void saveLauncher(LauncherItem *launcher);
+    void saveLauncher(LauncherItem *launcher, KConfigGroup &group);
+    void unsaveLauncher(LauncherItem *launcher);
+    KConfigGroup launcherConfig(const KConfigGroup &config = KConfigGroup());
 
     TaskGroup *currentRootGroup();
 
@@ -105,18 +111,20 @@
     QTimer checkIfFullTimer;
     QSet<Task *> geometryTasks;
     int groupIsFullLimit;
+    QUuid configToken;
+
+    QHash<QString, QHash<int, TaskGroup*> > rootGroups; //container for groups
+    QHash<KUrl, LauncherItem *> launchers;
+    int currentDesktop;
+    QString currentActivity;
+
     bool showOnlyCurrentDesktop : 1;
     bool showOnlyCurrentActivity : 1;
     bool showOnlyCurrentScreen : 1;
     bool showOnlyMinimized : 1;
     bool onlyGroupWhenFull : 1;
     bool changingGroupingStrategy : 1;
-    QUuid configToken;
-
-    QHash<QString, QHash<int, TaskGroup*> > rootGroups; //container for groups
-    QHash<KUrl, LauncherItem *> launchers;
-    int currentDesktop;
-    QString currentActivity;
+    bool readingLauncherConfig : 1;
 };
 
 
@@ -145,7 +153,6 @@
     d->checkIfFullTimer.setSingleShot(true);
     d->checkIfFullTimer.setInterval(0);
     connect(&d->checkIfFullTimer, SIGNAL(timeout()), this, \
                SLOT(actuallyCheckIfFull()));
-
 }
 
 GroupManager::~GroupManager()
@@ -535,7 +542,7 @@
 
 void GroupManager::reconnect()
 {
-    kDebug();
+    //kDebug();
     disconnect(TaskManager::self(), SIGNAL(desktopChanged(int)),
                this, SLOT(currentDesktopChanged(int)));
     disconnect(TaskManager::self(), SIGNAL(activityChanged(QString)),
@@ -566,6 +573,11 @@
     d->reloadTasks();
 }
 
+KConfigGroup GroupManager::config() const
+{
+    return KConfigGroup();
+}
+
 bool GroupManager::addLauncher(const KUrl &url, QIcon icon, QString name, QString \
genericName)  {
     if (url.isEmpty()) {
@@ -605,7 +617,7 @@
         d->launchers.insert(url, launcher);
         connect(launcher, SIGNAL(show(bool)), this, \
SLOT(launcherVisibilityChange()));  d->checkLauncherVisibility(launcher);
-        emit launcherAdded(launcher);
+        d->saveLauncher(launcher);
     }
 
     return launcher;
@@ -627,7 +639,7 @@
         }
     }
 
-    emit launcherRemoved(launcher);
+    d->unsaveLauncher(launcher);
     launcher->deleteLater();
 }
 
@@ -638,7 +650,6 @@
 
 void GroupManagerPrivate::checkLauncherVisibility(LauncherItem *launcher)
 {
-    kDebug() << "booyah, bitches!" << launcher;
     if (!launcher) {
         return;
     }
@@ -660,10 +671,18 @@
     return d->launchers.value(url);
 }
 
-void GroupManager::readLauncherConfig(const KConfigGroup &config)
+void GroupManager::readLauncherConfig(const KConfigGroup &cg)
 {
-    foreach (const QString &key, config.keyList()) {
-        QStringList item = config.readEntry(key, QStringList());
+    KConfigGroup conf = d->launcherConfig(cg);
+    if (!conf.isValid()) {
+        return;
+    }
+
+    // prevents re-writing the results out
+    d->readingLauncherConfig = true;
+    QSet<KUrl> urls;
+    foreach (const QString &key, conf.keyList()) {
+        QStringList item = conf.readEntry(key, QStringList());
         if (item.length() >= 4) {
             KUrl url(item.at(0));
             KIcon icon;
@@ -677,11 +696,101 @@
             }
             QString name(item.at(2));
             QString genericName(item.at(3));
-            addLauncher(url, icon, name, genericName);
+
+            if (addLauncher(url, icon, name, genericName)) {
+                urls << url;
         }
     }
 }
 
+    d->readingLauncherConfig = false;
+
+    // a bit paranoiac, perhaps, but we check the removals first and then
+    // remove the launchers after that scan because Qt's iterators operate
+    // on a copy of the list and/or don't like multiple iterators messing
+    // with the same list. we might get away with just calling removeLauncher
+    // immediately without the removals KUrl::List, but this is known safe
+    // and not a performance bottleneck
+    KUrl::List removals;
+    foreach (LauncherItem *launcher, d->launchers) {
+        if (!urls.contains(launcher->launcherUrl())) {
+            removals << launcher->launcherUrl();
+        }
+    }
+
+    foreach (const KUrl &url, removals) {
+        removeLauncher(url);
+    }
+}
+
+void GroupManager::exportLauncherConfig(const KConfigGroup &cg)
+{
+    KConfigGroup conf = d->launcherConfig(cg);
+    if (!conf.isValid()) {
+        return;
+    }
+
+    foreach (LauncherItem *launcher, d->launchers) {
+        d->saveLauncher(launcher, conf);
+    }
+}
+
+KConfigGroup GroupManagerPrivate::launcherConfig(const KConfigGroup &config)
+{
+    KConfigGroup cg = config.isValid() ? config : q->config();
+    if (!cg.isValid()) {
+        return cg;
+    }
+
+    return KConfigGroup(&cg, "Launchers");
+}
+
+void GroupManagerPrivate::saveLauncher(LauncherItem *launcher)
+{
+    if (readingLauncherConfig) {
+        return;
+    }
+
+    KConfigGroup cg = launcherConfig();
+    if (!cg.isValid()) {
+        return;
+    }
+
+    saveLauncher(launcher, cg);
+    emit q->configChanged();
+}
+
+void GroupManagerPrivate::saveLauncher(LauncherItem *launcher, KConfigGroup &cg)
+{
+    QVariantList launcherProperties;
+    launcherProperties.append(launcher->launcherUrl().url());
+    launcherProperties.append(launcher->icon().name());
+    launcherProperties.append(launcher->name());
+    launcherProperties.append(launcher->genericName());
+
+    if (launcher->icon().name().isEmpty()) {
+        QPixmap pixmap = launcher->icon().pixmap(QSize(64,64));
+        QByteArray bytes;
+        QBuffer buffer(&bytes);
+        buffer.open(QIODevice::WriteOnly);
+        pixmap.save(&buffer, "PNG");
+        launcherProperties.append(bytes.toBase64());
+    }
+
+    cg.writeEntry(launcher->name(), launcherProperties);
+}
+
+void GroupManagerPrivate::unsaveLauncher(LauncherItem *launcher)
+{
+    KConfigGroup cg = launcherConfig();
+    if (!cg.isValid()) {
+        return;
+    }
+
+    cg.deleteEntry(launcher->name());
+    emit q->configChanged();
+}
+
 bool GroupManager::onlyGroupWhenFull() const
 {
     return d->onlyGroupWhenFull;
--- trunk/KDE/kdebase/workspace/libs/taskmanager/groupmanager.h #1216837:1216838
@@ -132,21 +132,32 @@
 
     /** Adds a Launcher for the executable/.desktop-file at url and returns a \
                reference to the launcher*/
     bool addLauncher(const KUrl &url, QIcon icon = QIcon(), QString name = \
QString(), QString genericName = QString()); +
     /** Removes the given launcher*/
     void removeLauncher(const KUrl &url);
+
     /** @return true if there is a matching launcher */
     bool launcherExists(const KUrl &url) const;
     bool launcherExistsForUrl(const KUrl &url) const;
-    void readLauncherConfig(const KConfigGroup &config);
 
+    /** call when the launcher config should be read or re-read */
+    void readLauncherConfig(const KConfigGroup &config = KConfigGroup());
+
+    /** exports the launcher config to a given config group; usually not needed
+        if config() is reimplemented to provide a valid config group */
+    void exportLauncherConfig(const KConfigGroup &config);
+
+protected:
+    // reimplement to provide a config group to read/write settings to
+    virtual KConfigGroup config() const;
+
 Q_SIGNALS:
     /** Signal that the rootGroup has to be reloaded in the visualization */
     void reload();
-    /** Signal that a Launcher has been added*/
-    void launcherAdded(LauncherItem*);
-    /** Signal that a Launcher has been removed*/
-    void launcherRemoved(LauncherItem*);
 
+    /** Signal that the configuration writen to the config file has changed */
+    void configChanged();
+
 private:
     Q_PRIVATE_SLOT(d, void currentDesktopChanged(int))
     Q_PRIVATE_SLOT(d, void currentActivityChanged(QString))
--- trunk/KDE/kdebase/workspace/plasma/desktop/applets/tasks/taskitemlayout.h \
#1216837:1216838 @@ -34,9 +34,7 @@
 
 using TaskManager::StartupPtr;
 using TaskManager::TaskPtr;
-using TaskManager::GroupManager;
 
-
 /**
  * A Layout for the expanded group
  */
--- trunk/KDE/kdebase/workspace/plasma/desktop/applets/tasks/tasks.cpp \
#1216837:1216838 @@ -25,6 +25,7 @@
 #include "ui_tasksConfig.h"
 
 //Taskmanager
+#include <taskmanager/groupmanager.h>
 #include <taskmanager/taskgroup.h>
 #include <taskmanager/taskitem.h>
 
@@ -44,6 +45,25 @@
 #include <Plasma/FrameSvg>
 #include <Plasma/Theme>
 
+class GroupManager : public TaskManager::GroupManager
+{
+public:
+    GroupManager(Plasma::Applet *applet)
+        : TaskManager::GroupManager(applet),
+          m_applet(applet)
+    {
+    }
+
+protected:
+    KConfigGroup config() const
+    {
+        return m_applet->config();
+    }
+
+private:
+    Plasma::Applet *m_applet;
+};
+
 Tasks::Tasks(QObject* parent, const QVariantList &arguments)
      : Plasma::Applet(parent, arguments),
        m_showTooltip(false),
@@ -79,18 +99,14 @@
 
 void Tasks::init()
 {
-    m_groupManager = new TaskManager::GroupManager(this);
+    m_groupManager = new GroupManager(this);
     Plasma::Containment* appletContainment = containment();
     if (appletContainment) {
         m_groupManager->setScreen(appletContainment->screen());
     }
 
-    //FIXME: the order of creation and setting of items in this method is both \
                fragile (from
-    // personal experience tinking with it) and convoluted. It should be possible to
-    // set up the GroupManager firt, and *then* create the root TaskGroupItem.
-
     connect(m_groupManager, SIGNAL(reload()), this, SLOT(reload()));
-    //connect(this, SIGNAL(settingsChanged()), m_groupManager, SLOT(reconnect()));
+    connect(m_groupManager, SIGNAL(configChanged()), this, \
SIGNAL(configNeedsSaving()));  
     m_rootGroupItem = new TaskGroupItem(this, this);
     m_rootGroupItem->expand();
@@ -105,18 +121,14 @@
     connect(m_rootGroupItem, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, \
SLOT(changeSizeHint(Qt::SizeHint)));  
     setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
-    //like in Qt's designer
-    //TODO : Qt's bug??
     setMaximumSize(INT_MAX,INT_MAX);
 
     layout = new QGraphicsLinearLayout(this);
     layout->setContentsMargins(0,0,0,0);
     layout->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
                
-    //TODO : Qt's bug??
     layout->setMaximumSize(INT_MAX,INT_MAX);
     layout->setOrientation(Qt::Vertical);
     layout->addItem(m_rootGroupItem);
-
     setLayout(layout);
 
     configChanged();
@@ -201,8 +213,7 @@
         changed = true;
     }
 
-    KConfigGroup launcherCg(&cg, "Launchers");
-    m_groupManager->readLauncherConfig(launcherCg);
+    m_groupManager->readLauncherConfig();
 
     if (changed) {
         emit settingsChanged();
@@ -210,36 +221,6 @@
     }
 }
 
-void Tasks::launcherAdded(LauncherItem *launcher)
-{
-    KConfigGroup cg = config();
-    KConfigGroup launcherCg(&cg, "Launchers");
-
-    QVariantList launcherProperties;
-    launcherProperties.append(launcher->launcherUrl().url());
-    launcherProperties.append(launcher->icon().name());
-    launcherProperties.append(launcher->name());
-    launcherProperties.append(launcher->genericName());
-
-    if (launcher->icon().name().isEmpty()) {
-        QPixmap pixmap = launcher->icon().pixmap(QSize(64,64));
-        QByteArray bytes;
-        QBuffer buffer(&bytes);
-        buffer.open(QIODevice::WriteOnly);
-        pixmap.save(&buffer, "PNG");
-        launcherProperties.append(bytes.toBase64());
-    }
-
-    launcherCg.writeEntry(launcher->name(), launcherProperties);
-}
-
-void Tasks::launcherRemoved(LauncherItem *launcher )
-{
-    KConfigGroup cg = config();
-    KConfigGroup launcherCg(&cg, "Launchers");
-    launcherCg.deleteEntry(launcher->name());
-}
-
 void Tasks::reload()
 {
     TaskGroup *newGroup = m_groupManager->rootGroup();
--- trunk/KDE/kdebase/workspace/plasma/desktop/applets/tasks/tasks.h #1216837:1216838
@@ -48,18 +48,23 @@
     class FrameSvg;
 } // namespace Plasma
 
-class TaskGroupItem;
+namespace TaskManager
+{
+    class GroupManager;
+} // namespace TaskManager
 
 using TaskManager::StartupPtr;
 using TaskManager::TaskPtr;
 using TaskManager::StartupPtr;
 using TaskManager::GroupPtr;
 using TaskManager::AbstractGroupableItem;
-using TaskManager::GroupManager;
 using TaskManager::TaskItem;
 using TaskManager::TaskGroup;
 using TaskManager::LauncherItem;
 
+class TaskGroupItem;
+class GroupManager;
+
 /**
  * An applet which provides a visual representation of running
  * graphical tasks (ie. tasks that have some form of visual interface),
@@ -95,7 +100,6 @@
         void resizeItemBackground(const QSizeF &newSize);
 
         TaskGroupItem*  rootGroupItem();
-
         TaskManager::GroupManager &groupManager() const;
 
         Qt::KeyboardModifiers groupModifierKey() const;
@@ -135,8 +139,6 @@
         void reload();
         void changeSizeHint(Qt::SizeHint which);
         void dialogGroupingChanged(int index);
-        void launcherAdded(LauncherItem *launcher);
-        void launcherRemoved(LauncherItem *launcher);
 
 private:
         bool m_showTooltip;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic