• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Applets

taskgroupitem.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 *   Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>          *
00003 *   Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>           *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU General Public License as published by  *
00007 *   the Free Software Foundation; either version 2 of the License, or     *
00008 *   (at your option) any later version.                                   *
00009 *                                                                         *
00010 *   This program is distributed in the hope that it will be useful,       *
00011 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013 *   GNU General Public License for more details.                          *
00014 *                                                                         *
00015 *   You should have received a copy of the GNU General Public License     *
00016 *   along with this program; if not, write to the                         *
00017 *   Free Software Foundation, Inc.,                                       *
00018 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
00019 ***************************************************************************/
00020 
00021 // Own
00022 #include "taskgroupitem.h"
00023 #include "layoutwidget.h"
00024 #include "windowtaskitem.h"
00025 #include "tasksmenu.h"
00026 
00027 // Qt
00028 #include <QGraphicsSceneContextMenuEvent>
00029 #include <QStyleOptionGraphicsItem>
00030 #include <QGraphicsView>
00031 #include <QTimer>
00032 #include <QApplication>
00033 #include <QGraphicsLinearLayout>
00034 #include <QInputDialog>
00035 
00036 // KDE
00037 #include <KAuthorized>
00038 #include <KDebug>
00039 #include <KIcon>
00040 #include <KLocalizedString>
00041 #include <KGlobalSettings>
00042 #include <KIconLoader>
00043 
00044 #include <taskmanager/taskactions.h>
00045 #include <taskmanager/taskmanager.h>
00046 #include <taskmanager/taskgroup.h>
00047 #include <taskmanager/abstractgroupingstrategy.h>
00048 
00049 #include <Plasma/Theme>
00050 #include <Plasma/FrameSvg>
00051 #include <Plasma/ToolTipManager>
00052 #include <Plasma/Corona>
00053 #include <Plasma/Containment>
00054 
00055 #include "tasks.h"
00056 #include "layoutwidget.h"
00057 
00058 TaskGroupItem::TaskGroupItem(QGraphicsWidget *parent, Tasks *applet, const bool showTooltip)
00059     : AbstractTaskItem(parent, applet, showTooltip),
00060       m_group(0),
00061       m_expandedLayout(0),
00062       m_popupMenuTimer(0),
00063       m_lastActivated(-1),
00064       m_activeTaskIndex(0),
00065       m_maximumRows(1),
00066       m_forceRows(false),
00067       m_splitPosition(0),
00068       m_parentSplitGroup(0),
00069       m_childSplitGroup(0)
00070 {
00071     setAcceptDrops(true);
00072 }
00073 
00074 
00075 bool TaskGroupItem::isSplit()
00076 {
00077     return m_childSplitGroup != 0;
00078 }
00079 
00080 void TaskGroupItem::setSplitGroup(TaskGroup *group)
00081 {
00082     m_group = group;
00083     m_parentSplitGroup = dynamic_cast<TaskGroupItem*>(parentWidget());
00084     if (!m_parentSplitGroup) {
00085         kDebug() << "no parentSplit Group";
00086         return;
00087     }
00088     expand();
00089 }
00090 
00091 //FIXME verify if this really works correctly
00092 void TaskGroupItem::unsplitGroup()
00093 {
00094     //kDebug();
00095     if (!m_childSplitGroup) {
00096         return;
00097     }
00098     m_childSplitGroup->deleteLater();
00099     m_childSplitGroup = 0;
00100     m_splitPosition = 0;
00101     reload();
00102 }
00103 
00104 
00105 TaskGroupItem * TaskGroupItem::splitGroup()
00106 {
00107     return m_childSplitGroup;
00108 }
00109 
00110 void TaskGroupItem::setSplitIndex(int position)
00111 {
00112     //kDebug() << position;
00113     Q_ASSERT(m_expandedLayout);
00114     Q_ASSERT(m_parentSplitGroup);
00115 
00116     for (int i = position ; i < m_parentSplitGroup->group()->members().size() ; i++) {
00117         //kDebug() << "add item to childSplitGroup" << i;
00118         AbstractGroupableItem *item = m_parentSplitGroup->group()->members().at(i);
00119         if (!m_groupMembers.contains(item)) {
00120             m_groupMembers.insert(item, m_parentSplitGroup->abstractItem(item));
00121         }
00122         m_expandedLayout->addTaskItem(abstractItem(item));
00123     }
00124     m_splitPosition = position;
00125 }
00126 
00127 TaskGroupItem * TaskGroupItem::splitGroup(int newSplitPosition)
00128 {
00129     //kDebug() << "split position" << newSplitPosition;
00130     Q_ASSERT(m_expandedLayout);
00131 
00132     //remove all items which move to the splitgroup from the expandedLayout
00133     for (int i = newSplitPosition ; i < m_groupMembers.size() ; i++) {
00134         AbstractGroupableItem *item = group()->members().at(i);
00135         m_expandedLayout->removeTaskItem(abstractItem(item));
00136         //kDebug() << "remove from parentSplitGroup" << i;
00137     }
00138     //add items which arent in the splitgroup anymore and should be displayed again
00139     if (m_splitPosition) { //if 0 is the init value and shouldn't happen otherwise
00140         for (int i = m_splitPosition ; i < newSplitPosition ; i++) {
00141             AbstractGroupableItem *item = group()->members().at(i);
00142             m_expandedLayout->addTaskItem(abstractItem(item));
00143             //kDebug() << "add Item to parentSplitGroup" << i;
00144         }
00145     }
00146 
00147     if (!m_childSplitGroup) {
00148         //kDebug() << "Normal scene " << scene();
00149         m_childSplitGroup = new  TaskGroupItem(this, m_applet, true);
00150         m_childSplitGroup->setSplitGroup(m_group);
00151     }
00152 
00153     m_childSplitGroup->setSplitIndex(newSplitPosition);
00154     m_splitPosition = newSplitPosition;
00155     return m_childSplitGroup;
00156 }
00157 
00158 //scroll through items on every click
00159 void TaskGroupItem::activate()
00160 {
00161     /*m_activeTaskIndex++;
00162     if (m_activeTaskIndex >= m_groupMembers.size()) {
00163     m_activeTaskIndex = 0;
00164     }
00165 
00166     //    kDebug() << "Wheel event m_activeTaskIndex: " << m_activeTaskIndex << " of " << numberOfItems();
00167     AbstractTaskItem *item = m_groupMembers.at(m_activeTaskIndex);
00168 
00169     if (item) {
00170     item->activate();
00171     }//TODO: exclude group items? */
00172 
00173 }
00174 
00175 void TaskGroupItem::close()
00176 {
00177 //  m_applet->removeGroupTask(m_group);
00178     m_group = 0;
00179 }
00180 
00181 
00182 void TaskGroupItem::updateTask(::TaskManager::TaskChanges changes)
00183 {
00184     Q_ASSERT(m_group);
00185 
00186     bool needsUpdate = false;
00187     // task flags
00188     TaskFlags flags = m_flags;
00189     if (m_group->isActive()) {
00190         flags |= TaskHasFocus;
00191         emit activated(this);
00192     } else {
00193         flags &= ~TaskHasFocus;
00194     }
00195 
00196     if (m_group->demandsAttention()) {
00197         flags |= TaskWantsAttention;
00198     } else {
00199         flags &= ~TaskWantsAttention;
00200     }
00201 
00202     if (m_group->isMinimized()) {
00203         flags |= TaskIsMinimized;
00204     } else {
00205         flags &= ~TaskIsMinimized;
00206     }
00207 
00208     if (flags != m_flags) {
00209         needsUpdate = true;
00210         setTaskFlags(flags);
00211     }
00212 
00213     // basic title and icon
00214     if (changes & TaskManager::IconChanged) {
00215         needsUpdate = true;
00216         setIcon(m_group->icon());
00217     }
00218 
00219     if (changes & TaskManager::NameChanged) {
00220         needsUpdate = true;
00221         setText(m_group->name());
00222     }
00223 
00224     if (m_showingTooltip &&
00225         (changes & TaskManager::IconChanged ||
00226         changes & TaskManager::NameChanged ||
00227         changes & TaskManager::DesktopChanged)) {
00228         updateToolTip();
00229     }
00230 
00231     if (needsUpdate) {
00232         //redraw
00233         queueUpdate();
00234     }
00235 }
00236 
00237 void TaskGroupItem::updateToolTip()
00238 {
00239     if (!m_group) {
00240         return;
00241     }
00242 
00243     Plasma::ToolTipContent data(m_group->name(),
00244                                 i18nc("Which virtual desktop a window is currently on", "On %1",
00245                                     KWindowSystem::desktopName(m_group->desktop())));
00246 //    data.image = m_group->icon().pixmap(QSize::small);
00247 //    data.windowToPreview = m_task->window();
00248 
00249     Plasma::ToolTipManager::self()->setContent(this, data);
00250 }
00251 
00252 
00253 void TaskGroupItem::reload()
00254 {
00255     kDebug();
00256     QList <AbstractItemPtr> itemsToRemove = m_groupMembers.keys();
00257 
00258     foreach (AbstractItemPtr item, group()->members()) {
00259         if (!item) {
00260             kDebug() << "invalid Item";
00261             continue;
00262         }
00263         itemsToRemove.removeAll(item);
00264         itemAdded(item);
00265 
00266         if (item->isGroupItem()) {
00267             TaskGroupItem *group = qobject_cast<TaskGroupItem *>(abstractItem(item));
00268             if (group) {
00269                 group->reload();
00270             }
00271         }
00272     }
00273     foreach (AbstractItemPtr item, itemsToRemove) { //remove unused items
00274         if (!item) {
00275             kDebug() << "invalid Item";
00276             continue;
00277         }
00278         itemRemoved(item);
00279     }
00280 }
00281 
00282 void TaskGroupItem::setGroup(TaskManager::GroupPtr group)
00283 {
00284     //kDebug();
00285     m_group = group;
00286     m_abstractItem = qobject_cast<AbstractItemPtr>(group);
00287     if (!m_abstractItem) {
00288         kDebug() << "error";
00289     }
00290 
00291     connect(m_group, SIGNAL(itemRemoved(AbstractItemPtr)), this, SLOT(itemRemoved(AbstractItemPtr)));
00292     connect(m_group, SIGNAL(itemAdded(AbstractItemPtr)), this, SLOT(itemAdded(AbstractItemPtr)));
00293 
00294     //connect(m_group, SIGNAL(destroyed()), this, SLOT(close()));
00295 
00296     connect(m_group, SIGNAL(changed(::TaskManager::TaskChanges)),
00297             this, SLOT(updateTask(::TaskManager::TaskChanges)));
00298 
00299     connect(m_group, SIGNAL(itemPositionChanged(AbstractItemPtr)), this, SLOT(itemPositionChanged(AbstractItemPtr)));
00300     connect(m_group, SIGNAL(groupEditRequest()), this, SLOT(editGroup()));
00301 
00302     //Add already existing items
00303     reload();
00304     updateTask(::TaskManager::EverythingChanged);
00305 
00306     //kDebug() << "Task added, isActive = " << task->isActive();
00307 }
00308 
00309 TaskManager::GroupPtr TaskGroupItem::group() const
00310 {
00311     return m_group;
00312 }
00313 
00314 void TaskGroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *e)
00315 {
00316     //kDebug();
00317     if (!KAuthorized::authorizeKAction("kwin_rmb") || !m_group) {
00318         QGraphicsWidget::contextMenuEvent(e);
00319         return;
00320     }
00321     Q_ASSERT(m_applet);
00322     //we are the master group item
00323     if (m_applet == parentWidget()) {
00324         e->ignore();
00325         return;
00326     }
00327 
00328     QAction *a;
00329 
00330     if (m_expandedLayout) {
00331         a = new QAction(i18n("Collapse Group"), this);
00332         connect(a, SIGNAL(triggered()), this, SLOT(collapse()));
00333     } else {
00334         a = new QAction(i18n("Expand Group"), this);
00335         connect(a, SIGNAL(triggered()), this, SLOT(expand()));
00336     }
00337 
00338     QList <QAction*> actionList;
00339     actionList.append(a);
00340 
00341     TaskManager::BasicMenu menu(qobject_cast<QWidget*>(this), m_group, &m_applet->groupManager(), actionList);
00342     menu.adjustSize();
00343 
00344     Q_ASSERT(m_applet->containment());
00345     Q_ASSERT(m_applet->containment()->corona());
00346     menu.exec(m_applet->containment()->corona()->popupPosition(this, menu.size()));
00347 }
00348 
00349 QList<AbstractTaskItem*> TaskGroupItem::memberList() const
00350 {
00351     return m_groupMembers.values();
00352 }
00353 
00354 AbstractTaskItem *TaskGroupItem::createAbstractItem(TaskManager::AbstractItemPtr groupableItem)
00355 {
00356     //kDebug() << "item to create" << groupableItem << endl;
00357     AbstractTaskItem *item = 0;
00358 
00359     if (m_groupMembers.contains(groupableItem)) {
00360         //kDebug() << "existing item found";
00361         return m_groupMembers.value(groupableItem);
00362     }
00363 
00364     if (groupableItem->isGroupItem()) {
00365         TaskGroupItem *groupItem = new TaskGroupItem(this, m_applet, m_applet->showTooltip());
00366         groupItem->setGroup(static_cast<TaskManager::TaskGroup*>(groupableItem));
00367         item = groupItem;
00368     } else { //it's a window task
00369         WindowTaskItem *windowItem = new WindowTaskItem(this, m_applet, m_applet->showTooltip());
00370         windowItem->setTask(static_cast<TaskManager::TaskItem*>(groupableItem));
00371         item = windowItem;
00372     }
00373 
00374     if (!item) {
00375         kDebug() << "invalid Item";
00376         return 0;
00377     }
00378 
00379     return item;
00380 }
00381 
00382 
00383 
00384 void TaskGroupItem::itemAdded(TaskManager::AbstractItemPtr groupableItem)
00385 {
00386     //kDebug();
00387     if (!m_applet) {
00388         kDebug() << "No applet";
00389         return;
00390     }
00391 
00392     //returns the corresponding item or creates a new one
00393     AbstractTaskItem *item = createAbstractItem(groupableItem);
00394 
00395     if (!item) {
00396         kDebug() << "invalid Item";
00397         return;
00398     }
00399 
00400     m_groupMembers[groupableItem] = item;
00401     item->setParentItem(this);
00402 
00403     if (collapsed()) {
00404         item->hide();
00405         QRect rect = iconGeometry();
00406         item->publishIconGeometry(rect);
00407     } else if (isSplit()) {
00408         splitGroup(m_splitPosition);
00409         //emit changed();
00410         //m_childSplitGroup->reload();
00411     } else {
00412         m_expandedLayout->addTaskItem(item);
00413     }
00414 
00415     if (item->isActive()) {
00416         //kDebug() << "item is Active" ;
00417         m_activeTaskIndex = indexOf(item);
00418     } else if (m_group->members().size() == 1) {
00419         m_activeTaskIndex = 0;
00420     }
00421 
00422     connect(item, SIGNAL(activated(AbstractTaskItem*)),
00423             this, SLOT(updateActive(AbstractTaskItem*)));
00424 
00425 }
00426 
00427 void TaskGroupItem::itemRemoved(TaskManager::AbstractItemPtr groupableItem)
00428 {
00429     //kDebug();
00430     if (!m_applet) {
00431         kDebug() << "No Applet";
00432         return;
00433     }
00434     AbstractTaskItem *item = m_groupMembers.take(groupableItem);;
00435 
00436     if (!item) {
00437         kDebug() << "Item not found";
00438         return;
00439     }
00440 
00441     disconnect(item, 0, 0, 0);
00442 
00443     if (m_expandedLayout) {
00444         m_expandedLayout->removeTaskItem(item);
00445     }
00446 
00447     item->close();
00448     item->deleteLater();
00449 }
00450 
00451 
00452 bool TaskGroupItem::isWindowItem() const
00453 {
00454     return false;
00455 }
00456 
00457 bool TaskGroupItem::isActive() const
00458 {
00459     kDebug() << "Not Implemented";
00460     return false;
00461 }
00462 
00463 void TaskGroupItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
00464 { //TODO add delay so we can still drag group items
00465     if (event->buttons() & Qt::LeftButton) {
00466         if (m_applet->groupManager().sortingStrategy() == TaskManager::GroupManager::ManualSorting ||
00467             m_applet->groupManager().groupingStrategy() == TaskManager::GroupManager::ManualGrouping) {
00468             if (!m_popupMenuTimer) {
00469                 m_popupMenuTimer = new QTimer(this);
00470                 m_popupMenuTimer->setSingleShot(true);
00471                 m_popupMenuTimer->setInterval(300);
00472                 connect(m_popupMenuTimer, SIGNAL(timeout()), this, SLOT(popupMenu()));
00473             }
00474             m_popupMenuTimer->start(300);
00475         } else {
00476             popupMenu();
00477         }
00478     }
00479 
00480     event->accept();
00481 }
00482 
00483 void TaskGroupItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00484 {
00485     if (event->button() == Qt::MidButton) {
00486         expand();
00487     }
00488 
00489     if (m_popupMenuTimer) {
00490         if (m_popupMenuTimer->isActive()) {
00491             // clicked, released, didn't move -> show the popup!
00492             popupMenu();
00493         }
00494         m_popupMenuTimer->stop();
00495     }
00496 
00497     AbstractTaskItem::mouseReleaseEvent(event);
00498 }
00499 
00500 void TaskGroupItem::popupMenu()
00501 {
00502     if (!m_expandedLayout) {
00503         TaskManager::TasksMenu menu(qobject_cast<QWidget*>(this), m_group,  &m_applet->groupManager(), m_applet);
00504         menu.adjustSize();
00505         Q_ASSERT(m_applet->containment());
00506         Q_ASSERT(m_applet->containment()->corona());
00507         menu.exec(m_applet->containment()->corona()->popupPosition(this, menu.size()));
00508     }
00509 }
00510 
00511 void TaskGroupItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00512 {
00513     if (QPoint(event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance()) {
00514         return;
00515     } //Wait a bit before starting drag
00516 
00517     //kDebug();
00518     if (m_popupMenuTimer) {
00519         m_popupMenuTimer->stop();
00520     } //Wait a bit before starting drag
00521     AbstractTaskItem::mouseMoveEvent(event);
00522 }
00523 
00524 void TaskGroupItem::expand()
00525 {
00526     if (m_expandedLayout) {
00527         //kDebug() << "already expanded";
00528         return;
00529     }
00530 
00531     //kDebug();
00532     m_expandedLayout = new LayoutWidget(this, m_applet);
00533     m_expandedLayout->setMaximumRows(m_maximumRows);
00534     m_expandedLayout->setForceRows(m_forceRows);
00535 
00536     //setLayout(m_expandedLayout);
00537 
00538     connect(m_applet, SIGNAL(constraintsChanged(Plasma::Constraints)), m_expandedLayout, SLOT(constraintsChanged(Plasma::Constraints)));
00539     connect(m_expandedLayout, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(updatePreferredSize()));
00540     updatePreferredSize();
00541     emit changed();
00542     checkSettings();
00543     //kDebug() << "expanded";
00544 
00545 }
00546 
00547 LayoutWidget *TaskGroupItem::layoutWidget()
00548 {
00549     return m_expandedLayout;
00550 }
00551 
00552 void TaskGroupItem::collapse()
00553 {
00554     //kDebug() << (int)this;
00555     if (!m_expandedLayout) {
00556         //kDebug() << "already collapsed";
00557         return;
00558     }
00559 
00560     if (m_parentSplitGroup) {
00561         m_parentSplitGroup->collapse();
00562     }
00563 
00564     //kDebug();
00565     unsplitGroup();
00566     foreach (AbstractTaskItem *member, m_groupMembers) {
00567         m_expandedLayout->removeTaskItem(member);
00568     }
00569     setLayout(0);
00570     //kDebug();
00571     //delete m_expandedLayout;
00572     m_expandedLayout = 0;
00573     updatePreferredSize();
00574     //kDebug();
00575     emit changed();
00576     checkSettings();
00577 }
00578 
00579 bool TaskGroupItem::collapsed() const
00580 {
00581     return m_expandedLayout == 0;
00582 }
00583 
00584 void TaskGroupItem::updatePreferredSize()
00585 {
00586     if (layout()) {
00587         setPreferredSize(layout()->preferredSize());
00588         layout()->invalidate();
00589         //kDebug() << "expanded group" << layout()->preferredSize();
00590     } else {
00591         //FIXME: copypaste from abstracttaskitem: to be done better with proper sizeHint()
00592         setPreferredSize(basicPreferredSize());
00593     }
00594     //kDebug() << preferredSize();
00595     emit sizeHintChanged(Qt::PreferredSize);
00596 }
00597 
00598 
00599 
00600 AbstractTaskItem *TaskGroupItem::directMember(AbstractTaskItem *item)
00601 {
00602     Q_ASSERT(item);
00603     Q_ASSERT(m_group);
00604     TaskManager::AbstractItemPtr directMember = m_group->directMember(item->abstractItem());
00605     if (!directMember) {
00606         kDebug() << "Error" << item->abstractItem();
00607     }
00608     return abstractItem(directMember);
00609 }
00610 
00611 void TaskGroupItem::paint(QPainter *painter,
00612                             const QStyleOptionGraphicsItem *option,
00613                             QWidget *widget)
00614 {
00615     if (!m_expandedLayout) {
00616         AbstractTaskItem::paint(painter,option,widget);
00617     }/* else {
00618         if (m_group) {
00619             //painter->fillRect(geometry(), m_group->color());
00620         }
00621     }*/
00622 
00623     //kDebug() << "painter()";
00624     //painter->setBrush(QBrush(background));
00625 }
00626 
00627 
00628 // TODO provide a way to edit all group properties
00629 void TaskGroupItem::editGroup()
00630 {
00631     //it could look like the popup of the device notifier or the calendar of the clock..
00632     //kDebug();
00633     Q_ASSERT(m_group);
00634     Q_ASSERT(m_applet);
00635     if (m_applet->groupManager().taskGrouper()->editableGroupProperties() & TaskManager::AbstractGroupingStrategy::Name) {
00636         bool ok;
00637         QString text = QInputDialog::getText(qobject_cast<QWidget*>(this), tr("Edit Group"),
00638                                             tr("New Group Name: "), QLineEdit::Normal,
00639                                             m_group->name(), &ok);
00640         if (ok && !text.isEmpty()) {
00641             m_group->setName(text);
00642         }
00643     }
00644 }
00645 
00646 
00647 void  TaskGroupItem::itemPositionChanged(AbstractItemPtr item)
00648 {
00649     //kDebug();
00650     if (!m_expandedLayout) {
00651         return;
00652     }
00653 
00654     Q_ASSERT(item);
00655 
00656     if (item->isGroupItem()) {
00657         TaskGroupItem *groupItem = static_cast<TaskGroupItem*>(abstractItem(item));
00658         if (groupItem) {
00659             groupItem->unsplitGroup();
00660         }
00661     }
00662 
00663     AbstractTaskItem *taskItem = abstractItem(item);
00664 
00665     m_expandedLayout->removeTaskItem(taskItem);
00666     m_expandedLayout->insert(m_group->members().indexOf(item), taskItem);
00667 }
00668 
00669 
00670 void TaskGroupItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
00671 {
00672     //kDebug()<<"Drag enter";
00673     if (!m_expandedLayout &&
00674         (event->mimeData()->hasFormat(TaskManager::Task::mimetype()) ||
00675          event->mimeData()->hasFormat(TaskManager::Task::groupMimetype()))) {
00676         event->acceptProposedAction();
00677         //kDebug()<<"Drag enter accepted";
00678     } else {
00679         event->accept();
00680         if (!m_popupMenuTimer) {
00681             m_popupMenuTimer = new QTimer(this);
00682             m_popupMenuTimer->setSingleShot(true);
00683             m_popupMenuTimer->setInterval(300);
00684             connect(m_popupMenuTimer, SIGNAL(timeout()), this, SLOT(popupMenu()));
00685         }
00686         m_popupMenuTimer->start(300);
00687     }
00688 }
00689 
00690 AbstractTaskItem *TaskGroupItem::taskItemForWId(WId id)
00691 {
00692     QHashIterator<AbstractItemPtr, AbstractTaskItem*> it(m_groupMembers);
00693 
00694     while (it.hasNext()) {
00695         it.next();
00696         AbstractTaskItem *item = it.value();
00697         TaskGroupItem *group = qobject_cast<TaskGroupItem*>(item);
00698 
00699         if (group) {
00700             item = group->taskItemForWId(id);
00701             if (item) {
00702                 return item;
00703             }
00704         } else {
00705             TaskManager::TaskItem *task = qobject_cast<TaskManager::TaskItem*>(it.key());
00706             if (task && task->task() && task->task()->window() == id) {
00707                 return item;
00708             }
00709         }
00710     }
00711 
00712     return 0;
00713 }
00714 
00715 void TaskGroupItem::dropEvent(QGraphicsSceneDragDropEvent *event)
00716 {
00717     //kDebug() << "LayoutWidget dropEvent";
00718     if (event->mimeData()->hasFormat(TaskManager::Task::mimetype()) ||
00719         event->mimeData()->hasFormat(TaskManager::Task::groupMimetype())) {
00720         bool ok;
00721         QList<WId> ids = TaskManager::Task::idsFromMimeData(event->mimeData(), &ok);
00722 
00723         if (!ok) {
00724             //kDebug() << "FAIL!";
00725             event->ignore();
00726             return;
00727         }
00728 
00729         AbstractTaskItem *targetTask = dynamic_cast<AbstractTaskItem *>(scene()->itemAt(mapToScene(event->pos())));
00730         //  kDebug() << "Pos: " << event->pos() << mapToScene(event->pos()) << "item" << scene()->itemAt(mapToScene(event->pos())) << "target Task " << dynamic_cast<QGraphicsItem *>(targetTask);
00731 
00732         //kDebug() << "got" << ids.count() << "windows";
00733         foreach (WId id, ids) {
00734             handleDroppedId(id, targetTask, event);
00735         }
00736 
00737         //kDebug() << "LayoutWidget dropEvent done";
00738         event->acceptProposedAction();
00739     } else {
00740         event->ignore();
00741     }
00742 }
00743 
00744 void TaskGroupItem::handleDroppedId(WId id, AbstractTaskItem *targetTask, QGraphicsSceneDragDropEvent *event)
00745 {
00746     AbstractTaskItem *taskItem = m_applet->rootGroupItem()->taskItemForWId(id);
00747 
00748     if (!taskItem) {
00749         //kDebug() << "Invalid TaskItem";
00750         return;
00751     }
00752 
00753     if (!taskItem->parentGroup()) {
00754         //kDebug() << "group invalid";
00755         return;
00756     }
00757 
00758     TaskManager::GroupPtr group = taskItem->parentGroup()->group();
00759 
00760     //kDebug() << id << taskItem->text() << (QObject*)targetTask;
00761 
00762     // kDebug() << "first item: " << dynamic_cast<QGraphicsItem*>(m_taskItems.first()) << "layout widget" << dynamic_cast<QGraphicsItem*>(this);
00763 
00764     if ((event->modifiers() == m_applet->groupModifierKey()) &&
00765         m_applet->groupManager().groupingStrategy() == TaskManager::GroupManager::ManualGrouping) {
00766         //kDebug() << "groupModifiaction";
00767 
00768         if (!targetTask) {
00769             //add item to this group
00770             m_applet->groupManager().manualGroupingRequest(taskItem->abstractItem(), m_group);
00771         } else if (targetTask->isWindowItem() && (group == m_group)) { //Both Items in same group
00772             //Group Items together
00773             int targetIndex = m_group->members().indexOf(targetTask->abstractItem());
00774             int sourceIndex = m_group->members().indexOf(taskItem->abstractItem());
00775             TaskManager::ItemList members;
00776             members.append(targetTask->abstractItem());
00777             members.append(taskItem->abstractItem());
00778 
00779             if (m_applet->groupManager().manualGroupingRequest(members)) {
00780                 if (sourceIndex < targetIndex) {
00781                     //fix because the taskItem is removed so the index of the group should be targetIndex - 1
00782                     targetIndex--;
00783                 }
00784 
00785                 //move group to appropriate index if possible
00786                 m_applet->groupManager().manualSortingRequest(taskItem->abstractItem()->parentGroup(), targetIndex);
00787                 //kDebug() << "Group Created";
00788             } else {
00789                 //kDebug() << "Couldn't create Group";
00790             }
00791         } else if (!targetTask->isWindowItem()) {
00792             //Drop on collapsed group item
00793             //kDebug() << "Add item to Group";
00794             m_applet->groupManager().manualGroupingRequest(taskItem->abstractItem(), dynamic_cast<TaskManager::GroupPtr>(targetTask->abstractItem()));
00795         }
00796     } else if (m_applet->groupManager().sortingStrategy() == TaskManager::GroupManager::ManualSorting) {
00797         //Move action 
00798         if (group == m_group) { //same group
00799             //kDebug() << "Drag within group";
00800             layoutTaskItem(taskItem, event->pos());
00801         } else { //task item was dragged outside of group -> group move
00802             AbstractTaskItem *directMember = abstractItem(m_group->directMember(group));
00803             if (directMember) {
00804                 layoutTaskItem(directMember, event->pos()); //we need to get the group right under the receiver group
00805             }
00806         }
00807     }
00808 }
00809 
00810 void TaskGroupItem::layoutTaskItem(AbstractTaskItem* item, const QPointF &pos)
00811 {
00812     if (!m_expandedLayout) {
00813         return;
00814     }
00815 
00816     int insertIndex = m_expandedLayout->insertionIndexAt(pos);
00817     // kDebug() << "Item inserting at: " << insertIndex << "of: " << numberOfItems();
00818     if (insertIndex == -1) {
00819         m_applet->groupManager().manualSortingRequest(item->abstractItem(), -1);
00820     } else {
00821         if (!m_parentSplitGroup) {
00822             m_applet->groupManager().manualSortingRequest(item->abstractItem(), insertIndex);
00823         } else {
00824             m_applet->groupManager().manualSortingRequest(item->abstractItem(), insertIndex +
00825                     m_parentSplitGroup->m_groupMembers.size());
00826         }
00827     }
00828 }
00829 
00830 
00831 void TaskGroupItem::updateActive(AbstractTaskItem *task)
00832 {
00833     if (!m_expandedLayout) {
00834         return;
00835     }
00836 
00837     m_activeTaskIndex = indexOf(task);
00838 }
00839 
00840 int TaskGroupItem::indexOf(AbstractTaskItem *task)
00841 {
00842     if (!m_group || !task) {
00843         //kDebug() << "Error";
00844         return -1;
00845     }
00846 
00847     int index = 0;
00848 
00849     foreach (AbstractGroupableItem *item, group()->members()) {
00850         AbstractTaskItem *taskItem = abstractItem(item);
00851         if (taskItem) {
00852             if (task == taskItem) {
00853                 TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(taskItem);
00854                 if (groupItem) {
00855                     return index + groupItem->indexOf(groupItem->activeSubTask());
00856                 }
00857 
00858                 return index;
00859             }
00860 
00861             TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(taskItem);
00862             if (groupItem) {
00863                 int subIndex = groupItem->indexOf(task);
00864                 if(subIndex == -1) {
00865                     index += groupItem->memberList().count();
00866                 } else {
00867                     return index+subIndex;
00868                 }
00869             } else {
00870                 index++;
00871             }
00872         }
00873     }
00874     return -1;
00875 }
00876 
00877 AbstractTaskItem * TaskGroupItem::activeSubTask()
00878 {
00879     foreach(AbstractGroupableItem *item, group()->members()) {
00880         AbstractTaskItem *taskItem = abstractItem(item);
00881         if (taskItem) {
00882             if(taskItem->isActive()) {
00883                 TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(taskItem);
00884                 if (groupItem) {
00885                     return groupItem->activeSubTask();
00886                 }
00887                 return taskItem;
00888             }
00889         }
00890     }
00891     return NULL;
00892 }
00893 
00894 int TaskGroupItem::totalSubTasks()
00895 {
00896     int count = 0;
00897 
00898     foreach(AbstractGroupableItem *item, group()->members()) {
00899         AbstractTaskItem *taskItem = abstractItem(item);
00900         if (taskItem) {
00901             TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(taskItem);
00902             if (groupItem) {
00903                 count += groupItem->memberList().count();
00904             } else {
00905                 count++;
00906             }
00907         }
00908     }
00909     return count;
00910 }
00911 
00912 
00913 AbstractTaskItem * TaskGroupItem::selectSubTask(int index)
00914 {
00915     foreach(AbstractGroupableItem *item, group()->members()) {
00916         AbstractTaskItem *taskItem = abstractItem(item);
00917         if (taskItem) {
00918             TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(taskItem);
00919             if (groupItem) {
00920                 if (index < groupItem->memberList().count()) {
00921                    return groupItem->abstractItem(groupItem->group()->members().at(index));
00922                 } else {
00923                    index -= groupItem->memberList().count();
00924                 }
00925             } else if (index == 0) {
00926                 return taskItem;
00927             } else {
00928                 --index;
00929             }
00930         }
00931     }
00932     return NULL;
00933 }
00934 
00935 void TaskGroupItem::wheelEvent(QGraphicsSceneWheelEvent *event)
00936 {
00937     int subTasks = totalSubTasks();
00938     //zero or one tasks don't cycle
00939     if (subTasks < 1) {
00940         return;
00941     }
00942 
00943     //mouse wheel down
00944     if (event->delta() < 0) {
00945         m_activeTaskIndex++;
00946         if (m_activeTaskIndex >= subTasks) {
00947             m_activeTaskIndex = 0;
00948         }
00949         //mouse wheel up
00950     } else {
00951         m_activeTaskIndex--;
00952         if (m_activeTaskIndex < 0) {
00953             m_activeTaskIndex = subTasks - 1; //last item is a spacer
00954         }
00955     }
00956 
00957     //kDebug() << "Wheel event m_activeTaskIndex: " << m_activeTaskIndex << " of " << subTasks;
00958     AbstractTaskItem *taskItem = selectSubTask(m_activeTaskIndex);
00959     if (taskItem) {
00960         taskItem->activate();
00961     }
00962 }
00963 
00964 int TaskGroupItem::maxRows()
00965 {
00966     return m_maximumRows;
00967 }
00968 
00969 void TaskGroupItem::setMaxRows(int rows)
00970 {
00971     m_maximumRows = rows;
00972     if (m_expandedLayout) {
00973         m_expandedLayout->setMaximumRows(m_maximumRows);
00974     }
00975 }
00976 
00977 bool TaskGroupItem::forceRows()
00978 {
00979     return m_forceRows;
00980 }
00981 
00982 void TaskGroupItem::setForceRows(bool forceRows)
00983 {
00984     m_forceRows = forceRows;
00985     if (m_expandedLayout) {
00986         m_expandedLayout->setForceRows(m_forceRows);
00987     }
00988 }
00989 
00990 int TaskGroupItem::optimumCapacity()
00991 {
00992     if (m_expandedLayout) {
00993         return m_expandedLayout->maximumRows() * m_expandedLayout->preferredColumns();
00994     }
00995 
00996     return 1;
00997 }
00998 
00999 AbstractTaskItem* TaskGroupItem::abstractItem(AbstractItemPtr item)
01000 {
01001     if (m_groupMembers.contains(item)) {
01002         return m_groupMembers.value(item);
01003     }
01004     //kDebug() << "item not found";
01005     return 0;
01006 }
01007 
01008 void TaskGroupItem::setAdditionalMimeData(QMimeData* mimeData)
01009 {
01010     if (m_group) {
01011         m_group->addMimeData(mimeData);
01012     }
01013 }
01014 
01015 void TaskGroupItem::publishIconGeometry() const
01016 {
01017     // only do this if we are a collapsed group, with a GroupPtr and members
01018     if (m_expandedLayout || !m_group || m_groupMembers.isEmpty()) {
01019         return;
01020     }
01021 
01022     QRect rect = iconGeometry();
01023     publishIconGeometry(rect);
01024 }
01025 
01026 void TaskGroupItem::publishIconGeometry(const QRect &rect) const
01027 {
01028     foreach (AbstractTaskItem *item, m_groupMembers) {
01029         WindowTaskItem *windowItem = qobject_cast<WindowTaskItem *>(item);
01030         if (windowItem) {
01031             windowItem->publishIconGeometry(rect);
01032             continue;
01033         }
01034 
01035         TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(item);
01036         if (groupItem) {
01037             groupItem->publishIconGeometry(rect);
01038         }
01039     }
01040 }
01041 
01042 #include "taskgroupitem.moc"
01043 

Applets

Skip menu "Applets"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal