~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/taskmanager/strategies/programgroupingstrategy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************** Copyright 2008 Christian Mollekopf <chrigi_1@hotmail.com>
 
2
Permission is hereby granted, free of charge, to any person obtaining a copy
 
3
of this software and associated documentation files (the "Software"), to deal
 
4
in the Software without restriction, including without limitation the rights
 
5
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
6
copies of the Software, and to permit persons to whom the Software is
 
7
furnished to do so, subject to the following conditions:
 
8
 
 
9
The above copyright notice and this permission notice shall be included in
 
10
all copies or substantial portions of the Software.
 
11
 
 
12
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
13
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
14
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
15
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
16
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
17
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
18
 
 
19
******************************************************************/
 
20
 
 
21
#include "programgroupingstrategy.h"
 
22
 
 
23
#include <QAction>
 
24
#include <QWeakPointer>
 
25
 
 
26
#include <KDebug>
 
27
#include <KLocale>
 
28
#include <KConfig>
 
29
#include <KConfigGroup>
 
30
 
 
31
#include "abstractgroupingstrategy.h"
 
32
#include "groupmanager.h"
 
33
 
 
34
namespace TaskManager
 
35
{
 
36
 
 
37
class ProgramGroupingStrategy::Private
 
38
{
 
39
public:
 
40
    Private()
 
41
        :editableGroupProperties(AbstractGroupingStrategy::None)
 
42
    {
 
43
    }
 
44
 
 
45
    AbstractGroupingStrategy::EditableGroupProperties editableGroupProperties;
 
46
    QWeakPointer<AbstractGroupableItem> tempItem;
 
47
    QStringList blackList; //Programs in this list should not be grouped
 
48
};
 
49
 
 
50
 
 
51
ProgramGroupingStrategy::ProgramGroupingStrategy(GroupManager *groupManager)
 
52
    :AbstractGroupingStrategy(groupManager),
 
53
     d(new Private)
 
54
{
 
55
    setType(GroupManager::ProgramGrouping);
 
56
 
 
57
    KConfig groupBlacklist( "taskbargroupblacklistrc", KConfig::NoGlobals );
 
58
    KConfigGroup blackGroup( &groupBlacklist, "Blacklist" );
 
59
    d->blackList = blackGroup.readEntry( "Applications", QStringList() );
 
60
}
 
61
 
 
62
ProgramGroupingStrategy::~ProgramGroupingStrategy()
 
63
{
 
64
    delete d;
 
65
}
 
66
 
 
67
QList<QAction*> ProgramGroupingStrategy::strategyActions(QObject *parent, AbstractGroupableItem *item)
 
68
{
 
69
    QAction *a = new QAction(parent);
 
70
    QString name = className(item);
 
71
    if (d->blackList.contains(name)) {
 
72
        a->setText(i18n("Allow this program to be grouped"));
 
73
    } else {
 
74
        a->setText(i18n("Do not allow this program to be grouped"));
 
75
    }
 
76
    connect(a, SIGNAL(triggered()), this, SLOT(toggleGrouping()));
 
77
 
 
78
    QList<QAction*> actionList;
 
79
    actionList.append(a);
 
80
    d->tempItem = item;
 
81
    return actionList;
 
82
}
 
83
 
 
84
QString ProgramGroupingStrategy::className(AbstractGroupableItem *item)
 
85
{
 
86
    QString name;
 
87
    if (item->itemType() == GroupItemType) { //maybe add the condition that the subgroup was created by programGrouping
 
88
        TaskGroup *group = qobject_cast<TaskGroup*>(item);
 
89
        TaskItem *task = qobject_cast<TaskItem*>(group->members().first()); //There are only TaskItems in programGrouping groups
 
90
        return task->task()->classClass();
 
91
    }
 
92
 
 
93
        return (qobject_cast<TaskItem*>(item))->task()->classClass();
 
94
}
 
95
 
 
96
 
 
97
void ProgramGroupingStrategy::toggleGrouping()
 
98
{
 
99
    AbstractGroupableItem *tempItem = d->tempItem.data();
 
100
    if (!tempItem) {
 
101
        return;
 
102
    }
 
103
 
 
104
    QString name = className(tempItem);
 
105
 
 
106
    if (d->blackList.contains(name)) {
 
107
        d->blackList.removeAll(name);
 
108
        if (tempItem->itemType() == GroupItemType) {
 
109
            foreach (AbstractGroupableItem *item, (qobject_cast<TaskGroup*>(tempItem))->members()) {
 
110
                handleItem(item);
 
111
            }
 
112
        } else {
 
113
            handleItem(tempItem);
 
114
        }
 
115
    } else {
 
116
        d->blackList.append(name);
 
117
        GroupPtr root = rootGroup();
 
118
        if (tempItem->itemType() == GroupItemType) {
 
119
            closeGroup(qobject_cast<TaskGroup*>(tempItem));
 
120
        } else if (root) {
 
121
            root->add(tempItem);
 
122
        }
 
123
 
 
124
        if (root) {
 
125
            foreach (AbstractGroupableItem *item, root->members()) {
 
126
                if (item->itemType() == GroupItemType) {
 
127
                    untoggleGroupingOn(static_cast<TaskGroup*>(item), name);
 
128
                }
 
129
            }
 
130
        }
 
131
    }
 
132
 
 
133
    d->tempItem.clear();
 
134
 
 
135
    // Save immediately. Much better than saving in the destructor,
 
136
    // since this class is deleted at every change of virtual desktop (!)
 
137
    // So when doing it from the destructor we were constantly sync'ing
 
138
    // (and triggering KDirWatch) even when the blacklist hadn't changed at all...
 
139
    KConfig groupBlacklist("taskbargroupblacklistrc", KConfig::NoGlobals);
 
140
    KConfigGroup blackGroup(&groupBlacklist, "Blacklist");
 
141
    blackGroup.writeEntry("Applications", d->blackList);
 
142
    blackGroup.config()->sync();
 
143
}
 
144
 
 
145
void ProgramGroupingStrategy::untoggleGroupingOn(TaskGroup *group, const QString &name)
 
146
{
 
147
    if (!group->parentGroup()) {
 
148
        return;
 
149
    }
 
150
 
 
151
    foreach (AbstractGroupableItem *item, group->members()) {
 
152
        if (item->itemType() == GroupItemType) {
 
153
            untoggleGroupingOn(static_cast<TaskGroup*>(item), name);
 
154
        }
 
155
    }
 
156
 
 
157
    foreach (AbstractGroupableItem *item, group->members()) {
 
158
        if (!item->itemType() == GroupItemType && name == static_cast<TaskItem *>(item)->task()->classClass())  {
 
159
            if (group->parentGroup()) {
 
160
                group->parentGroup()->add(item);
 
161
            }
 
162
        }
 
163
    }
 
164
 
 
165
    if (group->members().isEmpty()) {
 
166
        closeGroup(group);
 
167
    }
 
168
}
 
169
 
 
170
void ProgramGroupingStrategy::handleItem(AbstractGroupableItem *item)
 
171
{
 
172
    GroupPtr root = rootGroup();
 
173
 
 
174
    if (!root) {
 
175
        return;
 
176
    }
 
177
 
 
178
    if (item->itemType() == GroupItemType) {
 
179
        //kDebug() << item->name() << "item is groupitem";
 
180
        root->add(item);
 
181
        return;
 
182
    } else if (d->blackList.contains((static_cast<TaskItem*>(item))->task()->classClass())) {
 
183
        //kDebug() << item->name() << "item is in blacklist";
 
184
        root->add(item);
 
185
        return;
 
186
    }
 
187
 
 
188
    TaskItem *task = dynamic_cast<TaskItem*>(item);
 
189
    if (task && !programGrouping(task, root)) {
 
190
        //kDebug() << item->name() << "joined rootGroup ";
 
191
        root->add(item);
 
192
    }
 
193
}
 
194
 
 
195
bool ProgramGroupingStrategy::programGrouping(TaskItem* taskItem, TaskGroup* groupItem)
 
196
{
 
197
    //kDebug() << "===== Task:" << taskItem->name() << " <=> Group:" << groupItem->name() << "=====";
 
198
    QList<AbstractGroupableItem *> list;
 
199
    QString name = taskItem->task()->classClass();
 
200
 
 
201
    //search for an existing group
 
202
    foreach (AbstractGroupableItem *item, groupItem->members()) {
 
203
        if (item->itemType() == GroupItemType) {
 
204
            //TODO: maybe add the condition that the subgroup was created by programGrouping?
 
205
            if (programGrouping(taskItem, static_cast<TaskGroup*>(item))) {
 
206
                //kDebug() << "    joined subGroup";
 
207
                return true;
 
208
            }
 
209
        } else {
 
210
            TaskItem *task = static_cast<TaskItem*>(item);
 
211
            //kDebug() << "    testing" << (task->task() ? task->task()->classClass() : "No task!") << "==" << name;
 
212
            if (task != taskItem && task->task() && task->task()->classClass() == name) { //omit startup tasks
 
213
                list.append(item);
 
214
            }
 
215
        }
 
216
    }
 
217
 
 
218
    if (!list.isEmpty()) {
 
219
        if (groupItem->isRootGroup()) {
 
220
            //kDebug() << "    create Group root group";
 
221
            QIcon icon = taskItem->icon();
 
222
            list.append(taskItem);
 
223
            TaskGroup* group = createGroup(list);
 
224
            group->setName(name);
 
225
            group->setColor(Qt::red);
 
226
            group->setIcon(icon);
 
227
            connect(group, SIGNAL(checkIcon(TaskGroup*)), this, SLOT(updateIcon(TaskGroup*)));
 
228
        } else {
 
229
            //kDebug() << "    joined this Group";
 
230
            groupItem->add(taskItem);
 
231
        }
 
232
 
 
233
        return true;
 
234
    }
 
235
 
 
236
    //kDebug() << "    failed";
 
237
    return false;
 
238
}
 
239
 
 
240
void ProgramGroupingStrategy::checkGroup()
 
241
{
 
242
    TaskGroup *group = qobject_cast<TaskGroup*>(sender());
 
243
    if (group) {
 
244
        if (group->members().size() < 2) {
 
245
            closeGroup(group);
 
246
        } else {
 
247
            updateIcon(group);
 
248
        }
 
249
    }
 
250
}
 
251
 
 
252
void ProgramGroupingStrategy::updateIcon(TaskGroup *group)
 
253
{
 
254
    foreach (AbstractGroupableItem *taskItem, group->members()) {
 
255
        if (!taskItem->icon().isNull()) {
 
256
            QIcon icon = taskItem->icon();
 
257
            group->setIcon(icon);
 
258
            break;
 
259
        }
 
260
    }
 
261
}
 
262
 
 
263
}//namespace
 
264
 
 
265
#include "programgroupingstrategy.moc"
 
266