1 /***************************************************************************
4 * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
20 ***************************************************************************/
24 #include <QtCore/QSet>
25 #include <QtGui/QApplication>
26 #include <QtGui/QGraphicsLinearLayout>
27 #include <QtGui/QWidget> // QWIDGETSIZE_MAX
31 #include <Plasma/IconWidget>
33 #include "../core/manager.h"
34 #include "../core/task.h"
37 #include "compactlayout.h"
44 class TaskArea::Private
47 Private(SystemTray::Applet
*h
)
50 topLayout(new QGraphicsLinearLayout(Qt::Horizontal
)),
51 taskLayout(new CompactLayout()),
55 hasHiddenTasks(false),
56 hasTasksThatCanHide(false)
60 SystemTray::Applet
*host
;
61 Plasma::IconWidget
*unhider
;
62 QGraphicsLinearLayout
*topLayout
;
63 CompactLayout
*taskLayout
;
64 //This item gives a bit of extra margin that separes the last items and the "normal" ones
65 QGraphicsWidget
*lastItemMargin
;
67 QSet
<QString
> hiddenTypes
;
69 bool showingHidden
: 1;
70 bool hasHiddenTasks
: 1;
71 bool hasTasksThatCanHide
: 1;
75 TaskArea::TaskArea(SystemTray::Applet
*parent
)
76 : QGraphicsWidget(parent
),
77 d(new Private(parent
))
79 setLayout(d
->topLayout
);
80 d
->topLayout
->addItem(d
->taskLayout
);
81 d
->topLayout
->setContentsMargins(0, 0, 0, 0);
91 void TaskArea::setHiddenTypes(const QStringList
&hiddenTypes
)
93 d
->hiddenTypes
= QSet
<QString
>::fromList(hiddenTypes
);
96 bool TaskArea::isHiddenType(const QString
&typeId
, bool always
) const
99 return !d
->showingHidden
&& d
->hiddenTypes
.contains(typeId
);
101 return d
->hiddenTypes
.contains(typeId
);
105 void TaskArea::syncTasks(const QList
<SystemTray::Task
*> &tasks
)
107 d
->hasTasksThatCanHide
= false;
108 d
->hasHiddenTasks
= false;
109 foreach (Task
*task
, tasks
) {
110 kDebug() << "checking" << task
->name() << d
->showingHidden
;
111 addWidgetForTask(task
);
115 d
->topLayout
->invalidate();
116 emit
sizeHintChanged(Qt::PreferredSize
);
119 void TaskArea::addTask(Task
*task
)
121 addWidgetForTask(task
);
123 emit
sizeHintChanged(Qt::PreferredSize
);
126 void TaskArea::addWidgetForTask(SystemTray::Task
*task
)
128 QGraphicsWidget
*widget
= findWidget(task
);
129 if (!task
->isEmbeddable() && !widget
) {
130 kDebug() << "task is not embeddable, so FAIL" << task
->name();
134 d
->hasTasksThatCanHide
= d
->hasTasksThatCanHide
|| isHiddenType(task
->typeId(), false);
136 if (isHiddenType(task
->typeId())) {
137 kDebug() << "is a hidden type";
138 d
->hasHiddenTasks
= true;
140 kDebug() << "just hiding the widget";
144 kDebug() << "widget already exists!";
147 widget
= task
->widget(d
->host
);
150 switch (task
->order()) {
151 case SystemTray::Task::First
:
152 d
->taskLayout
->insertItem(0, widget
);
154 case SystemTray::Task::Normal
:
155 d
->taskLayout
->insertItem(d
->taskLayout
->count() - d
->lastItemCount
, widget
);
157 case SystemTray::Task::Last
:
158 /*on the first added "last" task add also a little separator: the size depends from the applet margins,
159 in order to make the background of the last items look "balanced"*/
160 if (d
->lastItemCount
== 0) {
161 QGraphicsWidget
*applet
= dynamic_cast<QGraphicsWidget
*>(parentItem());
164 qreal left
, top
, right
, bottom
;
165 applet
->getContentsMargins(&left
, &top
, &right
, &bottom
);
166 d
->lastItemMargin
= new QGraphicsWidget();
168 d
->lastItemMargin
->setMinimumSize(right
, bottom
);
172 d
->taskLayout
->addItem(widget
);
179 void TaskArea::checkSizes()
181 d
->taskLayout
->updateGeometry();
182 d
->topLayout
->updateGeometry();
184 // this bit of braindamage is due to the "quirks" of QGrahics[Linear]Layout
185 QSizeF s
= d
->taskLayout
->effectiveSizeHint(Qt::PreferredSize
);
187 if (d
->topLayout
->orientation() == Qt::Horizontal
) {
188 s
.setWidth(s
.width() + d
->unhider
->size().width());
190 s
.setHeight(s
.height() + d
->unhider
->size().height());
197 void TaskArea::removeTask(Task
*task
)
199 foreach (QGraphicsWidget
*widget
, task
->associatedWidgets()) {
200 if (d
->taskLayout
->containsItem(widget
)) {
201 if (task
->order() == Task::Last
) {
203 //we have removed the last item, remove also the spacer
204 if (d
->lastItemCount
== 0 && d
->lastItemMargin
) {
205 d
->taskLayout
->removeItem(d
->lastItemMargin
);
206 d
->lastItemMargin
->deleteLater();
207 d
->lastItemMargin
= 0;
211 d
->taskLayout
->removeItem(widget
);
212 d
->topLayout
->invalidate();
213 emit
sizeHintChanged(Qt::PreferredSize
);
219 int TaskArea::leftEasement() const
224 if (d
->topLayout
->orientation() == Qt::Horizontal
) {
225 return d
->unhider
->size().width() / 2 + cheat
;
227 return d
->unhider
->size().height() / 2 + cheat
;
234 int TaskArea::rightEasement() const
237 if (d
->lastItemMargin
) {
238 extraMargin
= qMin(d
->lastItemMargin
->size().width(), d
->lastItemMargin
->size().height());
240 return d
->lastItemCount
* 24 + int(qreal(extraMargin
)/2.0);
243 bool TaskArea::hasHiddenTasks() const
245 return d
->hasHiddenTasks
;
248 void TaskArea::setOrientation(Qt::Orientation o
)
250 d
->topLayout
->setOrientation(o
);
253 d
->unhider
->setOrientation(o
);
254 if (d
->topLayout
->orientation() == Qt::Horizontal
) {
255 d
->unhider
->setMaximumSize(26, QWIDGETSIZE_MAX
);
256 d
->unhider
->setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Expanding
);
258 d
->unhider
->setMaximumSize(QWIDGETSIZE_MAX
, 26);
259 d
->unhider
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Minimum
);
262 updateUnhideToolIcon();
265 void TaskArea::initUnhideTool()
271 d
->unhider
= new Plasma::IconWidget(this);
272 d
->unhider
->setMinimumSize(16, 16);
273 updateUnhideToolIcon();
275 if (d
->topLayout
->orientation() == Qt::Horizontal
) {
276 d
->unhider
->setMaximumSize(22, QWIDGETSIZE_MAX
);
277 d
->unhider
->setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Expanding
);
279 d
->unhider
->setMaximumSize(QWIDGETSIZE_MAX
, 22);
280 d
->unhider
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Minimum
);
283 d
->topLayout
->removeItem(d
->taskLayout
);
284 //d->topLayout->insertItem(0, d->unhider);
285 d
->topLayout
->addItem(d
->unhider
);
286 d
->topLayout
->addItem(d
->taskLayout
);
287 connect(d
->unhider
, SIGNAL(clicked()), this, SLOT(toggleHiddenItems()));
289 emit
sizeHintChanged(Qt::PreferredSize
);
292 void TaskArea::updateUnhideToolIcon()
298 if (!d
->showingHidden
&& d
->topLayout
->orientation() == Qt::Vertical
) {
299 d
->unhider
->setSvg("widgets/systemtray", "expander-up");
300 } else if(d
->showingHidden
&& d
->topLayout
->orientation() == Qt::Vertical
){
301 d
->unhider
->setSvg("widgets/systemtray", "expander-down");
302 }else if (d
->showingHidden
|| QApplication::layoutDirection() == Qt::RightToLeft
) {
303 d
->unhider
->setSvg("widgets/systemtray", "expander-right");
305 d
->unhider
->setSvg("widgets/systemtray", "expander-left");
309 void TaskArea::toggleHiddenItems()
311 d
->showingHidden
= !d
->showingHidden
;
312 updateUnhideToolIcon();
313 syncTasks(d
->host
->manager()->tasks());
314 emit
sizeHintChanged(Qt::PreferredSize
);
317 void TaskArea::checkUnhideTool()
319 if (d
->hasTasksThatCanHide
) {
322 // hide the show tool
323 d
->topLayout
->removeItem(d
->unhider
);
324 d
->unhider
->deleteLater();
329 QGraphicsWidget
* TaskArea::findWidget(Task
*task
)
331 foreach (QGraphicsWidget
*widget
, task
->associatedWidgets()) {
332 if (d
->taskLayout
->containsItem(widget
)) {
343 #include "taskarea.moc"