00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "manualgroupingstrategy.h"
00025
00026 #include <QAction>
00027
00028 #include <KDebug>
00029 #include <KLocale>
00030
00031 #include "abstractgroupingstrategy.h"
00032 #include "groupmanager.h"
00033 #include "taskmanager.h"
00034
00035
00036 namespace TaskManager
00037 {
00038
00039 class ManualGroupingStrategy::Private
00040 {
00041 public:
00042 Private()
00043 : currentTemplate(0),
00044 editableGroupProperties(AbstractGroupingStrategy::All),
00045 tempItem(0),
00046 tempGroup(0),
00047 oldDesktop(TaskManager::self()->currentDesktop())
00048 {
00049 }
00050
00051 GroupManager *groupManager;
00052 QHash<int, TaskGroupTemplate*> templateTrees;
00053 TaskGroupTemplate* currentTemplate;
00054 QList<TaskGroup*> protectedGroups;
00055 AbstractGroupingStrategy::EditableGroupProperties editableGroupProperties;
00056 AbstractGroupableItem *tempItem;
00057 TaskGroup *tempGroup;
00058 int oldDesktop;
00059 };
00060
00061
00062
00063 ManualGroupingStrategy::ManualGroupingStrategy(GroupManager *groupManager)
00064 :AbstractGroupingStrategy(groupManager),
00065 d(new Private)
00066 {
00067 d->groupManager = groupManager;
00068 setType(GroupManager::ManualGrouping);
00069 }
00070
00071 ManualGroupingStrategy::~ManualGroupingStrategy()
00072 {
00073 delete d;
00074 }
00075
00076 AbstractGroupingStrategy::EditableGroupProperties ManualGroupingStrategy::editableGroupProperties()
00077 {
00078 return d->editableGroupProperties;
00079 }
00080
00081 QList<QAction*> ManualGroupingStrategy::strategyActions(QObject *parent, AbstractGroupableItem *item)
00082 {
00083 QList<QAction*> actionList;
00084
00085 if (item->isGrouped()) {
00086 QAction *a = new QAction(i18n("Leave Group"), parent);
00087 connect(a, SIGNAL(triggered()), this, SLOT(leaveGroup()));
00088 actionList.append(a);
00089 d->tempItem = item;
00090 }
00091
00092 if (item->isGroupItem()) {
00093 QAction *a = new QAction(i18n("Remove Group"), parent);
00094 connect(a, SIGNAL(triggered()), this, SLOT(removeGroup()));
00095 actionList.append(a);
00096 d->tempGroup = dynamic_cast<TaskGroup*>(item);
00097 }
00098
00099 return actionList;
00100 }
00101
00102 void ManualGroupingStrategy::leaveGroup()
00103 {
00104 Q_ASSERT(d->tempItem);
00105 if (d->tempItem->isGrouped()) {
00106 d->tempItem->parentGroup()->parentGroup()->add(d->tempItem);
00107 }
00108 d->tempItem = 0;
00109 }
00110
00111 void ManualGroupingStrategy::removeGroup()
00112 {
00113 Q_ASSERT(d->tempGroup);
00114 if (d->tempGroup->parentGroup()) {
00115 foreach (AbstractGroupableItem *item, d->tempGroup->members()) {
00116 d->tempGroup->parentGroup()->add(item);
00117 }
00118
00119 }
00120 d->tempGroup = 0;
00121 }
00122
00123 void ManualGroupingStrategy::unprotectGroup(TaskGroup *group)
00124 {
00125
00126 d->protectedGroups.removeOne(group);
00127 if (group->members().isEmpty()) {
00128 closeGroup(group);
00129 }
00130 }
00131
00132 void ManualGroupingStrategy::protectGroup(TaskGroup *group)
00133 {
00134
00135 d->protectedGroups.append(group);
00136 }
00137
00138
00139 void ManualGroupingStrategy::handleItem(AbstractItemPtr item)
00140 {
00141
00142 if (d->currentTemplate) {
00143 TaskGroupTemplate *templateGroup = d->currentTemplate;
00144
00145 if (templateGroup->hasMember(item)) {
00146
00147 while(!templateGroup->hasDirectMember(item)) {
00148
00149 TaskGroupTemplate *oldTemplateGroup = templateGroup;
00150 AbstractGroupableItem *templateItem = templateGroup->directMember(item);
00151 if (templateItem->isGroupItem()) {
00152 templateGroup = dynamic_cast<TaskGroupTemplate*>(templateItem);
00153 } else {
00154
00155 }
00156 if (templateGroup->group()) {
00157 oldTemplateGroup->group()->add(templateGroup->group());
00158 } else {
00159
00160 d->groupManager->rootGroup()->add(item);
00161 return;
00162 }
00163 }
00164
00165
00166 templateGroup->group()->add(item);
00167 templateGroup->remove(item);
00168 } else {
00169
00170 d->groupManager->rootGroup()->add(item);
00171 }
00172 } else {
00173 d->groupManager->rootGroup()->add(item);
00174 }
00175 }
00176
00177 TaskGroupTemplate *ManualGroupingStrategy::createDuplication(TaskGroup *group)
00178 {
00179 TaskGroupTemplate *templateGroup = new TaskGroupTemplate(this, group);
00180 return templateGroup;
00181 }
00182
00183
00184 void ManualGroupingStrategy::desktopChanged(int newDesktop)
00185 {
00186
00187 if (d->oldDesktop == newDesktop) {
00188 return;
00189 }
00190
00191
00192 if (d->currentTemplate) {
00193 d->currentTemplate->clear();
00194 }
00195
00196 TaskGroupTemplate *group = createDuplication(d->groupManager->rootGroup());
00197 d->templateTrees.insert(d->oldDesktop, group);
00198 if (d->templateTrees.contains(newDesktop)) {
00199
00200 d->currentTemplate = d->templateTrees.value(newDesktop);
00201 connect (d->currentTemplate, SIGNAL(destroyed()), this, SLOT(resetCurrentTemplate()));
00202 } else {
00203 d->currentTemplate = 0;
00204 }
00205 d->oldDesktop = newDesktop;
00206 }
00207
00208
00209
00210 void ManualGroupingStrategy::resetCurrentTemplate()
00211 {
00212
00213 d->currentTemplate = 0;
00214 }
00215
00216
00217 void ManualGroupingStrategy::groupChangedDesktop(int newDesktop)
00218 {
00219
00220 TaskGroup *group = qobject_cast<TaskGroup*>(sender());
00221 if (!group) {
00222 return;
00223 }
00224 if (newDesktop && (newDesktop != d->oldDesktop)) {
00225 if (group->parentGroup()) {
00226 group->parentGroup()->remove(group);
00227 }
00228 }
00229 TaskGroupTemplate *templateGroup;
00230 if (newDesktop) {
00231 if (d->templateTrees.contains(newDesktop)) {
00232
00233 templateGroup = d->templateTrees.value(newDesktop);
00234 } else {
00235
00236 templateGroup = new TaskGroupTemplate(this, 0);
00237 templateGroup->setGroup(d->groupManager->rootGroup());
00238 d->templateTrees.insert(newDesktop, templateGroup);
00239 }
00240
00241 } else {
00242 for (int i = 1; i <= TaskManager::self()->numberOfDesktops(); i++) {
00243 if (d->templateTrees.contains(newDesktop)) {
00244
00245 templateGroup = d->templateTrees.value(newDesktop);
00246 if (templateGroup->hasMember(group)) {
00247 continue;
00248 }
00249 } else {
00250
00251 templateGroup = new TaskGroupTemplate(this, 0);
00252 templateGroup->setGroup(d->groupManager->rootGroup());
00253 d->templateTrees.insert(newDesktop, templateGroup);
00254 }
00255 templateGroup->add(createDuplication(group));
00256 }
00257 }
00258
00259 }
00260
00261 bool ManualGroupingStrategy::groupItems(ItemList items)
00262 {
00263
00264 TaskGroup *group = createGroup(items);
00265 connect(group, SIGNAL(movedToDesktop(int)), this, SLOT(groupChangedDesktop(int)));
00266 setName(nameSuggestions(group).first(), group);
00267 setColor(colorSuggestions(group).first(), group);
00268 setIcon(iconSuggestions(group).first(), group);
00269 return true;
00270 }
00271
00272 void ManualGroupingStrategy::closeGroup(TaskGroup *group)
00273 {
00274
00275 if (!d->protectedGroups.contains(group)) {
00276 AbstractGroupingStrategy::closeGroup(group);
00277 } else if (group->parentGroup()) {
00278 group->parentGroup()->remove(group);
00279
00280 }
00281 }
00282
00283 class TaskGroupTemplate::Private
00284 {
00285 public:
00286 Private()
00287 : group(0),
00288 parentGroup(0),
00289 groupingStrategy(0)
00290 {
00291 }
00292
00293 ItemList members;
00294 QString name;
00295 QColor color;
00296 QIcon icon;
00297 TaskGroup *group;
00298 TaskGroupTemplate *parentGroup;
00299 ManualGroupingStrategy *groupingStrategy;
00300 };
00301
00302
00303 TaskGroupTemplate::TaskGroupTemplate(ManualGroupingStrategy *parent, TaskGroup *group)
00304 : AbstractGroupableItem(parent),
00305 d(new Private)
00306 {
00307 connect(this, SIGNAL(unprotectGroup(TaskGroup *)), parent, SLOT(unprotectGroup(TaskGroup *)));
00308 connect(this, SIGNAL(protectGroup(TaskGroup *)), parent, SLOT(protectGroup(TaskGroup *)));
00309 if (group) {
00310 d->name = group->name();
00311 d->color = group->color();
00312 d->icon = group->icon();
00313 setGroup(group);
00314 foreach (AbstractGroupableItem *item, group->members()) {
00315
00316
00317 if (item->isGroupItem()) {
00318
00319 TaskGroupTemplate *createdDuplication = new TaskGroupTemplate(parent, dynamic_cast<TaskGroup*>(item));
00320 add(createdDuplication);
00321 } else {
00322 add(item);
00323 }
00324 }
00325 }
00326
00327 }
00328
00329 TaskGroupTemplate::~TaskGroupTemplate()
00330 {
00331 emit unprotectGroup(group());
00332 emit destroyed(this);
00333
00334
00335 delete d;
00336 }
00337
00338 TaskGroup *TaskGroupTemplate::group()
00339 {
00340 return d->group;
00341 }
00342
00343 void TaskGroupTemplate::setGroup(TaskGroup *group)
00344 {
00345 if (d->group) {
00346 emit unprotectGroup(group);
00347 }
00348 if (group) {
00349 emit protectGroup(group);
00350 }
00351 d->group = group;
00352 }
00353
00354 ItemList &TaskGroupTemplate::members() const
00355 {
00356 return d->members;
00357 }
00358
00359 QIcon TaskGroupTemplate::icon() const
00360 {
00361 return d->icon;
00362 }
00363
00364 QColor TaskGroupTemplate::color() const
00365 {
00366 return d->color;
00367 }
00368
00369 QString TaskGroupTemplate::name() const
00370 {
00371 return d->name;
00372 }
00373
00375 void TaskGroupTemplate::add(AbstractItemPtr item)
00376 {
00377 if (d->members.contains(item)) {
00378 return;
00379 }
00380 d->members.append(item);
00381 if (item->isGroupItem()) {
00382 connect(item, SIGNAL(destroyed(AbstractGroupableItem *)), this, SLOT(itemDestroyed(AbstractGroupableItem *)));
00383 (dynamic_cast<TaskGroupTemplate*>(item))->setParentGroup(this);
00384 }
00385 }
00386
00388 void TaskGroupTemplate::remove(AbstractItemPtr item)
00389 {
00390 disconnect(item, 0, this, 0);
00391 disconnect(this, 0, item, 0);
00392 d->members.removeAll(item);
00393 if (item->isGroupItem()) {
00394 (dynamic_cast<TaskGroupTemplate*>(item))->setParentGroup(0);
00395 }
00396 if (d->members.isEmpty()) {
00397 closeGroup();
00398 }
00399 }
00400
00402 void TaskGroupTemplate::clear()
00403 {
00404 foreach(AbstractGroupableItem *item, d->members) {
00405 Q_ASSERT(item);
00406 if (item->isGroupItem()) {
00407 TaskGroupTemplate* templateGroup = qobject_cast<TaskGroupTemplate*>(item);
00408 Q_ASSERT(templateGroup);
00409 templateGroup->clear();
00410 } else {
00411 remove(item);
00412 }
00413 }
00414 }
00416 void TaskGroupTemplate::closeGroup()
00417 {
00418 if (parentGroup()) {
00419 foreach(AbstractGroupableItem *item, d->members) {
00420 Q_ASSERT(item);
00421 remove(item);
00422 parentGroup()->add(item);
00423 }
00424 } else {
00425 foreach(AbstractGroupableItem *item, d->members) {
00426 Q_ASSERT(item);
00427 remove(item);
00428 }
00429 }
00430 deleteLater();
00431 }
00432
00433
00434 TaskGroupTemplate *TaskGroupTemplate::parentGroup() const
00435 {
00436 return d->parentGroup;
00437 }
00438
00439 void TaskGroupTemplate::setParentGroup(TaskGroupTemplate *group)
00440 {
00441 d->parentGroup = group;
00442 }
00443
00444 void TaskGroupTemplate::addMimeData(QMimeData *mimeData) const
00445 {
00446 if (d->group) {
00447 d->group->addMimeData(mimeData);
00448 }
00449 }
00450
00452 bool TaskGroupTemplate::hasDirectMember(AbstractItemPtr item) const
00453 {
00454 return d->members.contains(item);
00455 }
00456
00458 bool TaskGroupTemplate::hasMember(AbstractItemPtr item) const
00459 {
00460
00461 if (members().contains(item)) {
00462 return true;
00463 }
00464 ItemList::const_iterator iterator = members().constBegin();
00465 while (iterator != members().constEnd()) {
00466 if ((*iterator)->isGroupItem()) {
00467 if ((dynamic_cast<TaskGroupTemplate *>(*iterator))->hasMember(item)) {
00468 return true;
00469 }
00470 }
00471 ++iterator;
00472 }
00473 return false;
00474
00475 }
00476
00478 AbstractItemPtr TaskGroupTemplate::directMember(AbstractItemPtr item) const
00479 {
00480 if (members().contains(item)) {
00481 return item;
00482 } else {
00483 ItemList::const_iterator iterator = members().constBegin();
00484 while (iterator != members().constEnd()) {
00485 if ((*iterator)->isGroupItem()) {
00486 if ((dynamic_cast<TaskGroupTemplate*>(*iterator))->hasMember(item)) {
00487
00488 return (*iterator);
00489 }
00490 }
00491 ++iterator;
00492 }
00493 }
00494 kDebug() << "item not found";
00495 return AbstractItemPtr();
00496 }
00497
00498 TaskGroupTemplate *TaskGroupTemplate::findParentGroup(AbstractItemPtr item) const
00499 {
00500 if (members().contains(item)) {
00501 return const_cast<TaskGroupTemplate*>(this);
00502 } else {
00503 ItemList::const_iterator iterator = members().constBegin();
00504 while (iterator != members().constEnd()) {
00505 if ((*iterator)->isGroupItem()) {
00506 TaskGroupTemplate *returnedGroup = (dynamic_cast<TaskGroupTemplate*>(*iterator))->findParentGroup(item);
00507 if (returnedGroup) {
00508
00509 return returnedGroup;
00510 }
00511 }
00512 ++iterator;
00513 }
00514 }
00515 kDebug() << "item not found";
00516 return 0;
00517 }
00518
00519 void TaskGroupTemplate::itemDestroyed(AbstractGroupableItem *item)
00520 {
00521 if (!item) {
00522 kDebug() << "Error";
00523 return;
00524 }
00525
00529 d->members.removeAll(item);
00530 disconnect(item, 0, this, 0);
00531 disconnect(this, 0, item, 0);
00532 if (members().isEmpty()) {
00533 closeGroup();
00534 }
00535 }
00536
00537 }
00538
00539 #include "manualgroupingstrategy.moc"
00540