1 /***************************************************************************
2 * Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
3 * Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
19 ***************************************************************************/
22 #include "taskgroupitem.h"
23 #include "layoutwidget.h"
24 #include "windowtaskitem.h"
25 #include "tasksmenu.h"
28 #include <QGraphicsSceneContextMenuEvent>
29 #include <QStyleOptionGraphicsItem>
30 #include <QGraphicsView>
32 #include <QApplication>
33 #include <QGraphicsLinearLayout>
34 #include <QInputDialog>
37 #include <KAuthorized>
40 #include <KLocalizedString>
41 #include <KGlobalSettings>
42 #include <KIconLoader>
44 #include <taskmanager/taskactions.h>
45 #include <taskmanager/taskmanager.h>
46 #include <taskmanager/taskgroup.h>
47 #include <taskmanager/abstractgroupingstrategy.h>
49 #include <Plasma/Theme>
50 #include <Plasma/FrameSvg>
51 #include <Plasma/ToolTipManager>
52 #include <Plasma/Corona>
53 #include <Plasma/Containment>
56 #include "layoutwidget.h"
58 TaskGroupItem::TaskGroupItem(QGraphicsWidget
*parent
, Tasks
*applet
, const bool showTooltip
)
59 : AbstractTaskItem(parent
, applet
, showTooltip
),
68 m_parentSplitGroup(0),
75 bool TaskGroupItem::isSplit()
77 return m_childSplitGroup
!= 0;
80 void TaskGroupItem::setSplitGroup(TaskGroup
*group
)
83 m_parentSplitGroup
= dynamic_cast<TaskGroupItem
*>(parentWidget());
84 if (!m_parentSplitGroup
) {
85 kDebug() << "no parentSplit Group";
91 //FIXME verify if this really works correctly
92 void TaskGroupItem::unsplitGroup()
95 if (!m_childSplitGroup
) {
98 m_childSplitGroup
->deleteLater();
99 m_childSplitGroup
= 0;
105 TaskGroupItem
* TaskGroupItem::splitGroup()
107 return m_childSplitGroup
;
110 void TaskGroupItem::setSplitIndex(int position
)
112 //kDebug() << position;
113 Q_ASSERT(m_expandedLayout
);
114 Q_ASSERT(m_parentSplitGroup
);
116 for (int i
= position
; i
< m_parentSplitGroup
->group()->members().size() ; i
++) {
117 //kDebug() << "add item to childSplitGroup" << i;
118 AbstractGroupableItem
*item
= m_parentSplitGroup
->group()->members().at(i
);
119 if (!m_groupMembers
.contains(item
)) {
120 m_groupMembers
.insert(item
, m_parentSplitGroup
->abstractItem(item
));
122 m_expandedLayout
->addTaskItem(abstractItem(item
));
124 m_splitPosition
= position
;
127 TaskGroupItem
* TaskGroupItem::splitGroup(int newSplitPosition
)
129 //kDebug() << "split position" << newSplitPosition;
130 Q_ASSERT(m_expandedLayout
);
132 //remove all items which move to the splitgroup from the expandedLayout
133 for (int i
= newSplitPosition
; i
< m_groupMembers
.size() ; i
++) {
134 AbstractGroupableItem
*item
= group()->members().at(i
);
135 m_expandedLayout
->removeTaskItem(abstractItem(item
));
136 //kDebug() << "remove from parentSplitGroup" << i;
138 //add items which arent in the splitgroup anymore and should be displayed again
139 if (m_splitPosition
) { //if 0 is the init value and shouldn't happen otherwise
140 for (int i
= m_splitPosition
; i
< newSplitPosition
; i
++) {
141 AbstractGroupableItem
*item
= group()->members().at(i
);
142 m_expandedLayout
->addTaskItem(abstractItem(item
));
143 //kDebug() << "add Item to parentSplitGroup" << i;
147 if (!m_childSplitGroup
) {
148 //kDebug() << "Normal scene " << scene();
149 m_childSplitGroup
= new TaskGroupItem(this, m_applet
, true);
150 m_childSplitGroup
->setSplitGroup(m_group
);
153 m_childSplitGroup
->setSplitIndex(newSplitPosition
);
154 m_splitPosition
= newSplitPosition
;
155 return m_childSplitGroup
;
158 //scroll through items on every click
159 void TaskGroupItem::activate()
161 /*m_activeTaskIndex++;
162 if (m_activeTaskIndex >= m_groupMembers.size()) {
163 m_activeTaskIndex = 0;
166 // kDebug() << "Wheel event m_activeTaskIndex: " << m_activeTaskIndex << " of " << numberOfItems();
167 AbstractTaskItem *item = m_groupMembers.at(m_activeTaskIndex);
171 }//TODO: exclude group items? */
175 void TaskGroupItem::close()
177 // m_applet->removeGroupTask(m_group);
182 void TaskGroupItem::updateTask(::TaskManager::TaskChanges changes
)
186 bool needsUpdate
= false;
188 TaskFlags flags
= m_flags
;
189 if (m_group
->isActive()) {
190 flags
|= TaskHasFocus
;
191 emit
activated(this);
193 flags
&= ~TaskHasFocus
;
196 if (m_group
->demandsAttention()) {
197 flags
|= TaskWantsAttention
;
199 flags
&= ~TaskWantsAttention
;
202 if (m_group
->isMinimized()) {
203 flags
|= TaskIsMinimized
;
205 flags
&= ~TaskIsMinimized
;
208 if (flags
!= m_flags
) {
213 // basic title and icon
214 if (changes
& TaskManager::IconChanged
) {
216 setIcon(m_group
->icon());
219 if (changes
& TaskManager::NameChanged
) {
221 setText(m_group
->name());
224 if (m_showingTooltip
&&
225 (changes
& TaskManager::IconChanged
||
226 changes
& TaskManager::NameChanged
||
227 changes
& TaskManager::DesktopChanged
)) {
237 void TaskGroupItem::updateToolTip()
243 Plasma::ToolTipContent
data(m_group
->name(),
244 i18nc("Which virtual desktop a window is currently on", "On %1",
245 KWindowSystem::desktopName(m_group
->desktop())));
246 // data.image = m_group->icon().pixmap(QSize::small);
247 // data.windowToPreview = m_task->window();
249 Plasma::ToolTipManager::self()->setContent(this, data
);
253 void TaskGroupItem::reload()
256 QList
<AbstractItemPtr
> itemsToRemove
= m_groupMembers
.keys();
258 foreach (AbstractItemPtr item
, group()->members()) {
260 kDebug() << "invalid Item";
263 itemsToRemove
.removeAll(item
);
266 if (item
->isGroupItem()) {
267 TaskGroupItem
*group
= qobject_cast
<TaskGroupItem
*>(abstractItem(item
));
273 foreach (AbstractItemPtr item
, itemsToRemove
) { //remove unused items
275 kDebug() << "invalid Item";
282 void TaskGroupItem::setGroup(TaskManager::GroupPtr group
)
286 m_abstractItem
= qobject_cast
<AbstractItemPtr
>(group
);
287 if (!m_abstractItem
) {
291 connect(m_group
, SIGNAL(itemRemoved(AbstractItemPtr
)), this, SLOT(itemRemoved(AbstractItemPtr
)));
292 connect(m_group
, SIGNAL(itemAdded(AbstractItemPtr
)), this, SLOT(itemAdded(AbstractItemPtr
)));
294 //connect(m_group, SIGNAL(destroyed()), this, SLOT(close()));
296 connect(m_group
, SIGNAL(changed(::TaskManager::TaskChanges
)),
297 this, SLOT(updateTask(::TaskManager::TaskChanges
)));
299 connect(m_group
, SIGNAL(itemPositionChanged(AbstractItemPtr
)), this, SLOT(itemPositionChanged(AbstractItemPtr
)));
300 connect(m_group
, SIGNAL(groupEditRequest()), this, SLOT(editGroup()));
302 //Add already existing items
304 updateTask(::TaskManager::EverythingChanged
);
306 //kDebug() << "Task added, isActive = " << task->isActive();
309 TaskManager::GroupPtr
TaskGroupItem::group() const
314 void TaskGroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent
*e
)
317 if (!KAuthorized::authorizeKAction("kwin_rmb") || !m_group
) {
318 QGraphicsWidget::contextMenuEvent(e
);
322 //we are the master group item
323 if (m_applet
== parentWidget()) {
330 if (m_expandedLayout
) {
331 a
= new QAction(i18n("Collapse Group"), this);
332 connect(a
, SIGNAL(triggered()), this, SLOT(collapse()));
334 a
= new QAction(i18n("Expand Group"), this);
335 connect(a
, SIGNAL(triggered()), this, SLOT(expand()));
338 QList
<QAction
*> actionList
;
339 actionList
.append(a
);
341 TaskManager::BasicMenu
menu(qobject_cast
<QWidget
*>(this), m_group
, &m_applet
->groupManager(), actionList
);
344 Q_ASSERT(m_applet
->containment());
345 Q_ASSERT(m_applet
->containment()->corona());
346 menu
.exec(m_applet
->containment()->corona()->popupPosition(this, menu
.size()));
349 QList
<AbstractTaskItem
*> TaskGroupItem::memberList() const
351 return m_groupMembers
.values();
354 AbstractTaskItem
*TaskGroupItem::createAbstractItem(TaskManager::AbstractItemPtr groupableItem
)
356 //kDebug() << "item to create" << groupableItem << endl;
357 AbstractTaskItem
*item
= 0;
359 if (m_groupMembers
.contains(groupableItem
)) {
360 //kDebug() << "existing item found";
361 return m_groupMembers
.value(groupableItem
);
364 if (groupableItem
->isGroupItem()) {
365 TaskGroupItem
*groupItem
= new TaskGroupItem(this, m_applet
, m_applet
->showTooltip());
366 groupItem
->setGroup(static_cast<TaskManager::TaskGroup
*>(groupableItem
));
368 } else { //it's a window task
369 WindowTaskItem
*windowItem
= new WindowTaskItem(this, m_applet
, m_applet
->showTooltip());
370 windowItem
->setTask(static_cast<TaskManager::TaskItem
*>(groupableItem
));
375 kDebug() << "invalid Item";
384 void TaskGroupItem::itemAdded(TaskManager::AbstractItemPtr groupableItem
)
388 kDebug() << "No applet";
392 //returns the corresponding item or creates a new one
393 AbstractTaskItem
*item
= createAbstractItem(groupableItem
);
396 kDebug() << "invalid Item";
400 m_groupMembers
[groupableItem
] = item
;
401 item
->setParentItem(this);
405 QRect rect
= iconGeometry();
406 item
->publishIconGeometry(rect
);
407 } else if (isSplit()) {
408 splitGroup(m_splitPosition
);
410 //m_childSplitGroup->reload();
412 m_expandedLayout
->addTaskItem(item
);
415 if (item
->isActive()) {
416 //kDebug() << "item is Active" ;
417 m_activeTaskIndex
= indexOf(item
);
418 } else if (m_group
->members().size() == 1) {
419 m_activeTaskIndex
= 0;
422 connect(item
, SIGNAL(activated(AbstractTaskItem
*)),
423 this, SLOT(updateActive(AbstractTaskItem
*)));
427 void TaskGroupItem::itemRemoved(TaskManager::AbstractItemPtr groupableItem
)
431 kDebug() << "No Applet";
434 AbstractTaskItem
*item
= m_groupMembers
.take(groupableItem
);;
437 kDebug() << "Item not found";
441 disconnect(item
, 0, 0, 0);
443 if (m_expandedLayout
) {
444 m_expandedLayout
->removeTaskItem(item
);
452 bool TaskGroupItem::isWindowItem() const
457 bool TaskGroupItem::isActive() const
459 kDebug() << "Not Implemented";
463 void TaskGroupItem::mousePressEvent(QGraphicsSceneMouseEvent
*event
)
464 { //TODO add delay so we can still drag group items
465 if (event
->buttons() & Qt::LeftButton
) {
466 if (m_applet
->groupManager().sortingStrategy() == TaskManager::GroupManager::ManualSorting
||
467 m_applet
->groupManager().groupingStrategy() == TaskManager::GroupManager::ManualGrouping
) {
468 if (!m_popupMenuTimer
) {
469 m_popupMenuTimer
= new QTimer(this);
470 m_popupMenuTimer
->setSingleShot(true);
471 m_popupMenuTimer
->setInterval(300);
472 connect(m_popupMenuTimer
, SIGNAL(timeout()), this, SLOT(popupMenu()));
474 m_popupMenuTimer
->start(300);
483 void TaskGroupItem::mouseReleaseEvent(QGraphicsSceneMouseEvent
*event
)
485 if (event
->button() == Qt::MidButton
) {
489 if (m_popupMenuTimer
) {
490 if (m_popupMenuTimer
->isActive()) {
491 // clicked, released, didn't move -> show the popup!
494 m_popupMenuTimer
->stop();
497 AbstractTaskItem::mouseReleaseEvent(event
);
500 void TaskGroupItem::popupMenu()
502 if (!m_expandedLayout
) {
503 TaskManager::TasksMenu
menu(qobject_cast
<QWidget
*>(this), m_group
, &m_applet
->groupManager(), m_applet
);
505 Q_ASSERT(m_applet
->containment());
506 Q_ASSERT(m_applet
->containment()->corona());
507 menu
.exec(m_applet
->containment()->corona()->popupPosition(this, menu
.size()));
511 void TaskGroupItem::mouseMoveEvent(QGraphicsSceneMouseEvent
*event
)
513 if (QPoint(event
->screenPos() - event
->buttonDownScreenPos(Qt::LeftButton
)).manhattanLength() < QApplication::startDragDistance()) {
515 } //Wait a bit before starting drag
518 if (m_popupMenuTimer
) {
519 m_popupMenuTimer
->stop();
520 } //Wait a bit before starting drag
521 AbstractTaskItem::mouseMoveEvent(event
);
524 void TaskGroupItem::expand()
526 if (m_expandedLayout
) {
527 //kDebug() << "already expanded";
532 m_expandedLayout
= new LayoutWidget(this, m_applet
);
533 m_expandedLayout
->setMaximumRows(m_maximumRows
);
534 m_expandedLayout
->setForceRows(m_forceRows
);
536 //setLayout(m_expandedLayout);
538 connect(m_applet
, SIGNAL(constraintsChanged(Plasma::Constraints
)), m_expandedLayout
, SLOT(constraintsChanged(Plasma::Constraints
)));
539 connect(m_expandedLayout
, SIGNAL(sizeHintChanged(Qt::SizeHint
)), this, SLOT(updatePreferredSize()));
540 updatePreferredSize();
543 //kDebug() << "expanded";
547 LayoutWidget
*TaskGroupItem::layoutWidget()
549 return m_expandedLayout
;
552 void TaskGroupItem::collapse()
554 //kDebug() << (int)this;
555 if (!m_expandedLayout
) {
556 //kDebug() << "already collapsed";
560 if (m_parentSplitGroup
) {
561 m_parentSplitGroup
->collapse();
566 foreach (AbstractTaskItem
*member
, m_groupMembers
) {
567 m_expandedLayout
->removeTaskItem(member
);
571 //delete m_expandedLayout;
572 m_expandedLayout
= 0;
573 updatePreferredSize();
579 bool TaskGroupItem::collapsed() const
581 return m_expandedLayout
== 0;
584 void TaskGroupItem::updatePreferredSize()
587 setPreferredSize(layout()->preferredSize());
588 layout()->invalidate();
589 //kDebug() << "expanded group" << layout()->preferredSize();
591 //FIXME: copypaste from abstracttaskitem: to be done better with proper sizeHint()
592 setPreferredSize(basicPreferredSize());
594 //kDebug() << preferredSize();
595 emit
sizeHintChanged(Qt::PreferredSize
);
600 AbstractTaskItem
*TaskGroupItem::directMember(AbstractTaskItem
*item
)
604 TaskManager::AbstractItemPtr directMember
= m_group
->directMember(item
->abstractItem());
606 kDebug() << "Error" << item
->abstractItem();
608 return abstractItem(directMember
);
611 void TaskGroupItem::paint(QPainter
*painter
,
612 const QStyleOptionGraphicsItem
*option
,
615 if (!m_expandedLayout
) {
616 AbstractTaskItem::paint(painter
,option
,widget
);
619 //painter->fillRect(geometry(), m_group->color());
623 //kDebug() << "painter()";
624 //painter->setBrush(QBrush(background));
628 // TODO provide a way to edit all group properties
629 void TaskGroupItem::editGroup()
631 //it could look like the popup of the device notifier or the calendar of the clock..
635 if (m_applet
->groupManager().taskGrouper()->editableGroupProperties() & TaskManager::AbstractGroupingStrategy::Name
) {
637 QString text
= QInputDialog::getText(qobject_cast
<QWidget
*>(this), tr("Edit Group"),
638 tr("New Group Name: "), QLineEdit::Normal
,
639 m_group
->name(), &ok
);
640 if (ok
&& !text
.isEmpty()) {
641 m_group
->setName(text
);
647 void TaskGroupItem::itemPositionChanged(AbstractItemPtr item
)
650 if (!m_expandedLayout
) {
656 if (item
->isGroupItem()) {
657 TaskGroupItem
*groupItem
= static_cast<TaskGroupItem
*>(abstractItem(item
));
659 groupItem
->unsplitGroup();
663 AbstractTaskItem
*taskItem
= abstractItem(item
);
665 m_expandedLayout
->removeTaskItem(taskItem
);
666 m_expandedLayout
->insert(m_group
->members().indexOf(item
), taskItem
);
670 void TaskGroupItem::dragEnterEvent(QGraphicsSceneDragDropEvent
*event
)
672 //kDebug()<<"Drag enter";
673 if (!m_expandedLayout
&&
674 (event
->mimeData()->hasFormat(TaskManager::Task::mimetype()) ||
675 event
->mimeData()->hasFormat(TaskManager::Task::groupMimetype()))) {
676 event
->acceptProposedAction();
677 //kDebug()<<"Drag enter accepted";
680 if (!m_popupMenuTimer
) {
681 m_popupMenuTimer
= new QTimer(this);
682 m_popupMenuTimer
->setSingleShot(true);
683 m_popupMenuTimer
->setInterval(300);
684 connect(m_popupMenuTimer
, SIGNAL(timeout()), this, SLOT(popupMenu()));
686 m_popupMenuTimer
->start(300);
690 AbstractTaskItem
*TaskGroupItem::taskItemForWId(WId id
)
692 QHashIterator
<AbstractItemPtr
, AbstractTaskItem
*> it(m_groupMembers
);
694 while (it
.hasNext()) {
696 AbstractTaskItem
*item
= it
.value();
697 TaskGroupItem
*group
= qobject_cast
<TaskGroupItem
*>(item
);
700 item
= group
->taskItemForWId(id
);
705 TaskManager::TaskItem
*task
= qobject_cast
<TaskManager::TaskItem
*>(it
.key());
706 if (task
&& task
->task() && task
->task()->window() == id
) {
715 void TaskGroupItem::dropEvent(QGraphicsSceneDragDropEvent
*event
)
717 //kDebug() << "LayoutWidget dropEvent";
718 if (event
->mimeData()->hasFormat(TaskManager::Task::mimetype()) ||
719 event
->mimeData()->hasFormat(TaskManager::Task::groupMimetype())) {
721 QList
<WId
> ids
= TaskManager::Task::idsFromMimeData(event
->mimeData(), &ok
);
724 //kDebug() << "FAIL!";
729 AbstractTaskItem
*targetTask
= dynamic_cast<AbstractTaskItem
*>(scene()->itemAt(mapToScene(event
->pos())));
730 // kDebug() << "Pos: " << event->pos() << mapToScene(event->pos()) << "item" << scene()->itemAt(mapToScene(event->pos())) << "target Task " << dynamic_cast<QGraphicsItem *>(targetTask);
732 //kDebug() << "got" << ids.count() << "windows";
733 foreach (WId id
, ids
) {
734 handleDroppedId(id
, targetTask
, event
);
737 //kDebug() << "LayoutWidget dropEvent done";
738 event
->acceptProposedAction();
744 void TaskGroupItem::handleDroppedId(WId id
, AbstractTaskItem
*targetTask
, QGraphicsSceneDragDropEvent
*event
)
746 AbstractTaskItem
*taskItem
= m_applet
->rootGroupItem()->taskItemForWId(id
);
749 //kDebug() << "Invalid TaskItem";
753 if (!taskItem
->parentGroup()) {
754 //kDebug() << "group invalid";
758 TaskManager::GroupPtr group
= taskItem
->parentGroup()->group();
760 //kDebug() << id << taskItem->text() << (QObject*)targetTask;
762 // kDebug() << "first item: " << dynamic_cast<QGraphicsItem*>(m_taskItems.first()) << "layout widget" << dynamic_cast<QGraphicsItem*>(this);
764 if ((event
->modifiers() == m_applet
->groupModifierKey()) &&
765 m_applet
->groupManager().groupingStrategy() == TaskManager::GroupManager::ManualGrouping
) {
766 //kDebug() << "groupModifiaction";
769 //add item to this group
770 m_applet
->groupManager().manualGroupingRequest(taskItem
->abstractItem(), m_group
);
771 } else if (targetTask
->isWindowItem() && (group
== m_group
)) { //Both Items in same group
772 //Group Items together
773 int targetIndex
= m_group
->members().indexOf(targetTask
->abstractItem());
774 int sourceIndex
= m_group
->members().indexOf(taskItem
->abstractItem());
775 TaskManager::ItemList members
;
776 members
.append(targetTask
->abstractItem());
777 members
.append(taskItem
->abstractItem());
779 if (m_applet
->groupManager().manualGroupingRequest(members
)) {
780 if (sourceIndex
< targetIndex
) {
781 //fix because the taskItem is removed so the index of the group should be targetIndex - 1
785 //move group to appropriate index if possible
786 m_applet
->groupManager().manualSortingRequest(taskItem
->abstractItem()->parentGroup(), targetIndex
);
787 //kDebug() << "Group Created";
789 //kDebug() << "Couldn't create Group";
791 } else if (!targetTask
->isWindowItem()) {
792 //Drop on collapsed group item
793 //kDebug() << "Add item to Group";
794 m_applet
->groupManager().manualGroupingRequest(taskItem
->abstractItem(), dynamic_cast<TaskManager::GroupPtr
>(targetTask
->abstractItem()));
796 } else if (m_applet
->groupManager().sortingStrategy() == TaskManager::GroupManager::ManualSorting
) {
798 if (group
== m_group
) { //same group
799 //kDebug() << "Drag within group";
800 layoutTaskItem(taskItem
, event
->pos());
801 } else { //task item was dragged outside of group -> group move
802 AbstractTaskItem
*directMember
= abstractItem(m_group
->directMember(group
));
804 layoutTaskItem(directMember
, event
->pos()); //we need to get the group right under the receiver group
810 void TaskGroupItem::layoutTaskItem(AbstractTaskItem
* item
, const QPointF
&pos
)
812 if (!m_expandedLayout
) {
816 int insertIndex
= m_expandedLayout
->insertionIndexAt(pos
);
817 // kDebug() << "Item inserting at: " << insertIndex << "of: " << numberOfItems();
818 if (insertIndex
== -1) {
819 m_applet
->groupManager().manualSortingRequest(item
->abstractItem(), -1);
821 if (!m_parentSplitGroup
) {
822 m_applet
->groupManager().manualSortingRequest(item
->abstractItem(), insertIndex
);
824 m_applet
->groupManager().manualSortingRequest(item
->abstractItem(), insertIndex
+
825 m_parentSplitGroup
->m_groupMembers
.size());
831 void TaskGroupItem::updateActive(AbstractTaskItem
*task
)
833 if (!m_expandedLayout
) {
837 m_activeTaskIndex
= indexOf(task
);
840 int TaskGroupItem::indexOf(AbstractTaskItem
*task
)
842 if (!m_group
|| !task
) {
843 //kDebug() << "Error";
849 foreach (AbstractGroupableItem
*item
, group()->members()) {
850 AbstractTaskItem
*taskItem
= abstractItem(item
);
852 if (task
== taskItem
) {
853 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(taskItem
);
855 return index
+ groupItem
->indexOf(groupItem
->activeSubTask());
861 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(taskItem
);
863 int subIndex
= groupItem
->indexOf(task
);
865 index
+= groupItem
->memberList().count();
867 return index
+subIndex
;
877 AbstractTaskItem
* TaskGroupItem::activeSubTask()
879 foreach(AbstractGroupableItem
*item
, group()->members()) {
880 AbstractTaskItem
*taskItem
= abstractItem(item
);
882 if(taskItem
->isActive()) {
883 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(taskItem
);
885 return groupItem
->activeSubTask();
894 int TaskGroupItem::totalSubTasks()
898 foreach(AbstractGroupableItem
*item
, group()->members()) {
899 AbstractTaskItem
*taskItem
= abstractItem(item
);
901 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(taskItem
);
903 count
+= groupItem
->memberList().count();
913 AbstractTaskItem
* TaskGroupItem::selectSubTask(int index
)
915 foreach(AbstractGroupableItem
*item
, group()->members()) {
916 AbstractTaskItem
*taskItem
= abstractItem(item
);
918 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(taskItem
);
920 if (index
< groupItem
->memberList().count()) {
921 return groupItem
->abstractItem(groupItem
->group()->members().at(index
));
923 index
-= groupItem
->memberList().count();
925 } else if (index
== 0) {
935 void TaskGroupItem::wheelEvent(QGraphicsSceneWheelEvent
*event
)
937 int subTasks
= totalSubTasks();
938 //zero or one tasks don't cycle
944 if (event
->delta() < 0) {
946 if (m_activeTaskIndex
>= subTasks
) {
947 m_activeTaskIndex
= 0;
952 if (m_activeTaskIndex
< 0) {
953 m_activeTaskIndex
= subTasks
- 1; //last item is a spacer
957 //kDebug() << "Wheel event m_activeTaskIndex: " << m_activeTaskIndex << " of " << subTasks;
958 AbstractTaskItem
*taskItem
= selectSubTask(m_activeTaskIndex
);
960 taskItem
->activate();
964 int TaskGroupItem::maxRows()
966 return m_maximumRows
;
969 void TaskGroupItem::setMaxRows(int rows
)
971 m_maximumRows
= rows
;
972 if (m_expandedLayout
) {
973 m_expandedLayout
->setMaximumRows(m_maximumRows
);
977 bool TaskGroupItem::forceRows()
982 void TaskGroupItem::setForceRows(bool forceRows
)
984 m_forceRows
= forceRows
;
985 if (m_expandedLayout
) {
986 m_expandedLayout
->setForceRows(m_forceRows
);
990 int TaskGroupItem::optimumCapacity()
992 if (m_expandedLayout
) {
993 return m_expandedLayout
->maximumRows() * m_expandedLayout
->preferredColumns();
999 AbstractTaskItem
* TaskGroupItem::abstractItem(AbstractItemPtr item
)
1001 if (m_groupMembers
.contains(item
)) {
1002 return m_groupMembers
.value(item
);
1004 //kDebug() << "item not found";
1008 void TaskGroupItem::setAdditionalMimeData(QMimeData
* mimeData
)
1011 m_group
->addMimeData(mimeData
);
1015 void TaskGroupItem::publishIconGeometry() const
1017 // only do this if we are a collapsed group, with a GroupPtr and members
1018 if (m_expandedLayout
|| !m_group
|| m_groupMembers
.isEmpty()) {
1022 QRect rect
= iconGeometry();
1023 publishIconGeometry(rect
);
1026 void TaskGroupItem::publishIconGeometry(const QRect
&rect
) const
1028 foreach (AbstractTaskItem
*item
, m_groupMembers
) {
1029 WindowTaskItem
*windowItem
= qobject_cast
<WindowTaskItem
*>(item
);
1031 windowItem
->publishIconGeometry(rect
);
1035 TaskGroupItem
*groupItem
= qobject_cast
<TaskGroupItem
*>(item
);
1037 groupItem
->publishIconGeometry(rect
);
1042 #include "taskgroupitem.moc"