00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "abstracttaskitem.h"
00024
00025
00026 #include <QGraphicsSceneContextMenuEvent>
00027 #include <QStyleOptionGraphicsItem>
00028 #include <QGraphicsView>
00029 #include <QTimer>
00030 #include <QApplication>
00031 #include <QTextLayout>
00032 #include <QGraphicsLinearLayout>
00033
00034
00035 #include <KAuthorized>
00036 #include <KDebug>
00037 #include <KIcon>
00038 #include <KIconEffect>
00039 #include <KLocalizedString>
00040 #include <KGlobalSettings>
00041 #include <KIconLoader>
00042 #include <KColorUtils>
00043
00044 #include <taskmanager/task.h>
00045 #include <taskmanager/taskmanager.h>
00046 #include <taskmanager/taskgroup.h>
00047
00048 #include <Plasma/Theme>
00049 #include <Plasma/PaintUtils>
00050 #include <Plasma/FrameSvg>
00051 #include <Plasma/ToolTipManager>
00052
00053 #include "tasks.h"
00054 #include "taskgroupitem.h"
00055 #include "layoutwidget.h"
00056
00057 AbstractTaskItem::AbstractTaskItem(QGraphicsWidget *parent, Tasks *applet, const bool showTooltip)
00058 : QGraphicsWidget(parent),
00059 m_abstractItem(0),
00060 m_applet(applet),
00061 m_activateTimer(0),
00062 m_flags(0),
00063 m_animId(0),
00064 m_alpha(1),
00065 m_backgroundPrefix("normal"),
00066 m_updateTimerId(0),
00067 m_attentionTimerId(0),
00068 m_attentionTicks(0),
00069 m_fadeIn(true),
00070 m_showTooltip(showTooltip),
00071 m_showingTooltip(false)
00072 {
00073 setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
00074 setAcceptsHoverEvents(true);
00075 setAcceptDrops(true);
00076
00077 Plasma::ToolTipManager::self()->registerWidget(this);
00078 setPreferredSize(basicPreferredSize());
00079 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(syncActiveRect()));
00080 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(queueUpdate()));
00081 connect(applet, SIGNAL(settingsChanged()), this, SLOT(checkSettings()));
00082 }
00083
00084 QSize AbstractTaskItem::basicPreferredSize() const
00085 {
00086 QFontMetrics fm(KGlobalSettings::taskbarFont());
00087 QSize mSize = fm.size(0, "M");
00088 int iconsize = KIconLoader::SizeSmall;
00089
00090
00091
00092 int topMargin = m_applet->itemTopMargin();
00093 int bottomMargin = m_applet->itemBottomMargin();
00094 if (m_applet->size().height() < 44) {
00095 topMargin = 1;
00096 bottomMargin = 1;
00097 } else if (m_applet->size().height() < 64) {
00098 topMargin = qMax(1, topMargin/2);
00099 bottomMargin = qMax(1, bottomMargin/2);
00100 }
00101 return QSize(mSize.width()*12 + m_applet->itemLeftMargin() + m_applet->itemRightMargin() + KIconLoader::SizeSmall,
00102 qMax(mSize.height(), iconsize) + topMargin + bottomMargin);
00103 }
00104
00105 AbstractTaskItem::~AbstractTaskItem()
00106 {
00107 if (m_animId) {
00108 Plasma::Animator::self()->stopCustomAnimation(m_animId);
00109 }
00110
00111 Plasma::ToolTipManager::self()->unregisterWidget(this);
00112 }
00113
00114 void AbstractTaskItem::checkSettings()
00115 {
00116 TaskGroupItem *group = qobject_cast<TaskGroupItem *>(this);
00117
00118 if (group && !group->collapsed()) {
00119 m_showTooltip = false;
00120 } else if (m_showTooltip != m_applet->showTooltip()) {
00121 m_showTooltip = !m_showTooltip;
00122 }
00123 }
00124
00125 void AbstractTaskItem::setShowTooltip(const bool showit)
00126 {
00127 m_showTooltip = showit;
00128 }
00129
00130 void AbstractTaskItem::setText(const QString &text)
00131 {
00132 m_text = text;
00133 }
00134
00135 void AbstractTaskItem::setIcon(const QIcon &icon)
00136 {
00137 m_icon = icon;
00138 }
00139
00140 QIcon AbstractTaskItem::icon() const
00141 {
00142 return m_icon;
00143 }
00144
00145 QString AbstractTaskItem::text() const
00146 {
00147 return m_text;
00148 }
00149
00150 void AbstractTaskItem::setTaskFlags(const TaskFlags flags)
00151 {
00152 if (((m_flags & TaskWantsAttention) != 0) != ((flags & TaskWantsAttention) != 0)) {
00153
00154 if (flags & TaskWantsAttention) {
00155
00156 if (!m_attentionTimerId) {
00157 m_attentionTimerId = startTimer(500);
00158 }
00159 } else if (m_attentionTimerId) {
00160 killTimer(m_attentionTimerId);
00161 m_attentionTimerId = 0;
00162
00163 }
00164 }
00165
00166 m_flags = flags;
00167
00168 QString newBackground;
00169 if (m_flags & TaskIsMinimized) {
00170 newBackground = "minimized";
00171 } else if (m_flags & TaskHasFocus) {
00172 newBackground = "focus";
00173 } else {
00174 newBackground = "normal";
00175 }
00176
00177 if (newBackground != m_backgroundPrefix) {
00178 fadeBackground(newBackground, 100, true);
00179 }
00180 }
00181
00182 void AbstractTaskItem::fadeBackground(const QString &newBackground, int duration, bool fadeIn)
00183 {
00184 m_oldBackgroundPrefix = m_backgroundPrefix;
00185 m_backgroundPrefix = newBackground;
00186
00187 if (m_animId) {
00188 Plasma::Animator::self()->stopCustomAnimation(m_animId);
00189 }
00190
00191 m_fadeIn = fadeIn;
00192 m_animId = Plasma::Animator::self()->customAnimation(40 / (1000 / duration), duration,Plasma::Animator::LinearCurve, this, "animationUpdate");
00193 }
00194
00195
00196 AbstractTaskItem::TaskFlags AbstractTaskItem::taskFlags() const
00197 {
00198 return m_flags;
00199 }
00200
00201 void AbstractTaskItem::toolTipAboutToShow()
00202 {
00203 if (m_showTooltip) {
00204 m_showingTooltip = true;
00205 updateToolTip();
00206 } else {
00207 Plasma::ToolTipManager::self()->clearContent(this);
00208 }
00209 }
00210
00211 void AbstractTaskItem::toolTipHidden()
00212 {
00213 m_showingTooltip = false;
00214 Plasma::ToolTipManager::self()->clearContent(this);
00215 }
00216
00217 void AbstractTaskItem::queueUpdate()
00218 {
00219 if (m_updateTimerId || m_attentionTimerId) {
00220 return;
00221 }
00222
00223 if (m_lastUpdate.elapsed() < 200) {
00224 m_updateTimerId = startTimer(200);
00225 return;
00226 }
00227
00228 update();
00229 m_lastUpdate.restart();
00230 }
00231
00232 void AbstractTaskItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00233 {
00234 Q_UNUSED(event)
00235
00236 fadeBackground("hover", 175, true);
00237 }
00238
00239 void AbstractTaskItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00240 {
00241 Q_UNUSED(event)
00242
00243 QString backgroundPrefix;
00244
00245 if (m_flags & TaskWantsAttention) {
00246 backgroundPrefix = "attention";
00247 } else if (m_flags & TaskIsMinimized) {
00248 backgroundPrefix = "minimized";
00249 } else if (m_flags & TaskHasFocus) {
00250 backgroundPrefix = "focus";
00251 } else {
00252 backgroundPrefix = "normal";
00253 }
00254
00255 fadeBackground(backgroundPrefix, 150, false);
00256 }
00257
00258 void AbstractTaskItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00259 {
00260 if (event->button() == Qt::LeftButton) {
00261 activate();
00262 }
00263 }
00264
00265 void AbstractTaskItem::mousePressEvent(QGraphicsSceneMouseEvent *)
00266 {
00267 update();
00268 }
00269
00270 void AbstractTaskItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00271 {
00272
00273 if (QPoint(event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance()) {
00274 return;
00275 }
00276
00277
00278
00279
00280
00281 QByteArray data;
00282 data.resize(sizeof(AbstractTaskItem*));
00283 AbstractTaskItem *selfPtr = this;
00284 memcpy(data.data(), &selfPtr, sizeof(AbstractTaskItem*));
00285
00286 QMimeData* mimeData = new QMimeData();
00287 setAdditionalMimeData(mimeData);
00288
00289 QDrag *drag = new QDrag(event->widget());
00290 drag->setMimeData(mimeData);
00291 drag->setPixmap(m_icon.pixmap(20));
00292
00293 drag->exec();
00294 }
00295
00296 void AbstractTaskItem::timerEvent(QTimerEvent *event)
00297 {
00298 if (event->timerId() == m_updateTimerId) {
00299 killTimer(m_updateTimerId);
00300 update();
00301 m_updateTimerId = 0;
00302 } else if (event->timerId() == m_attentionTimerId) {
00303 ++m_attentionTicks;
00304 if (m_attentionTicks > 6) {
00305 killTimer(m_attentionTimerId);
00306 m_attentionTimerId = 0;
00307 m_attentionTicks = 0;
00308 }
00309
00310 if (m_attentionTicks % 2 == 0) {
00311 fadeBackground("attention", 100, false);
00312 } else {
00313 fadeBackground("normal", 150, false);
00314 }
00315
00316 update();
00317 }
00318 }
00319
00320 void AbstractTaskItem::paint(QPainter *painter,
00321 const QStyleOptionGraphicsItem *option,
00322 QWidget *widget)
00323 {
00324 painter->setRenderHint(QPainter::Antialiasing);
00325
00326
00327 drawBackground(painter, option, widget);
00328
00329
00330 drawTask(painter, option, widget);
00331 }
00332
00333 void AbstractTaskItem::syncActiveRect()
00334 {
00335 Plasma::FrameSvg *itemBackground = m_applet->itemBackground();
00336
00337 if (!itemBackground) {
00338 return;
00339 }
00340
00341 itemBackground->setElementPrefix("normal");
00342
00343 qreal left, top, right, bottom;
00344 itemBackground->getMargins(left, top, right, bottom);
00345
00346 itemBackground->setElementPrefix("focus");
00347 qreal activeLeft, activeTop, activeRight, activeBottom;
00348 itemBackground->getMargins(activeLeft, activeTop, activeRight, activeBottom);
00349
00350 m_activeRect = QRectF(QPointF(0, 0), size());
00351 m_activeRect.adjust(left - activeLeft, top - activeTop,
00352 -(right - activeRight), -(bottom - activeBottom));
00353
00354 itemBackground->setElementPrefix(m_backgroundPrefix);
00355 }
00356
00357 void AbstractTaskItem::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
00358 {
00359
00360 if (!option->rect.isValid()) {
00361 return;
00362 }
00363
00364
00365
00366
00367
00368 Plasma::FrameSvg *itemBackground = m_applet->itemBackground();
00369
00370 if (!itemBackground) {
00371 return;
00372 }
00373
00374
00375 if (itemBackground->size() != size().toSize() && itemBackground->size() != m_activeRect.size().toSize()) {
00376 syncActiveRect();
00377
00378 itemBackground->setElementPrefix("focus");
00379 m_applet->resizeItemBackground(m_activeRect.size().toSize());
00380 itemBackground->setElementPrefix("normal");
00381 m_applet->resizeItemBackground(size().toSize());
00382 itemBackground->setElementPrefix("minimized");
00383 m_applet->resizeItemBackground(size().toSize());
00384 itemBackground->setElementPrefix("attention");
00385 m_applet->resizeItemBackground(size().toSize());
00386 itemBackground->setElementPrefix("hover");
00387 m_applet->resizeItemBackground(m_activeRect.size().toSize());
00388
00389
00390 itemBackground->setElementPrefix(m_backgroundPrefix);
00391 }
00392
00393
00394
00395 if (!m_animId && ~option->state & QStyle::State_Sunken) {
00396 itemBackground->setElementPrefix(m_backgroundPrefix);
00397 if (itemBackground->frameSize() == m_activeRect.size().toSize()) {
00398 itemBackground->paintFrame(painter, m_activeRect.topLeft());
00399 } else {
00400 itemBackground->paintFrame(painter);
00401 }
00402
00403 return;
00404 }
00405
00406 itemBackground->setElementPrefix(m_oldBackgroundPrefix);
00407 QPixmap oldBackground;
00408
00409 if (option->state & QStyle::State_Sunken) {
00410 oldBackground = QPixmap(m_activeRect.size().toSize());
00411 oldBackground.fill(Qt::transparent);
00412 m_alpha = 0.4;
00413 } else {
00414 oldBackground = itemBackground->framePixmap();
00415 }
00416
00417 itemBackground->setElementPrefix(m_backgroundPrefix);
00418 QPixmap result = Plasma::PaintUtils::transition(oldBackground, itemBackground->framePixmap(), m_alpha);
00419
00420 if (result.size() == m_activeRect.size().toSize()) {
00421 painter->drawPixmap(m_activeRect.topLeft(), result);
00422 } else {
00423 painter->drawPixmap(QPoint(0,0), result);
00424 }
00425
00426 return;
00427 }
00428
00429 void AbstractTaskItem::drawTask(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
00430 {
00431 Q_UNUSED(option)
00432
00433 QRectF bounds = boundingRect().adjusted(m_applet->itemLeftMargin(), m_applet->itemTopMargin(), -m_applet->itemRightMargin(), -m_applet->itemBottomMargin());
00434
00435 if ((!m_animId && ~option->state & QStyle::State_MouseOver) ||
00436 (m_oldBackgroundPrefix != "hover" && m_backgroundPrefix != "hover")) {
00437 m_icon.paint(painter, iconRect(bounds).toRect());
00438 } else {
00439 KIconEffect *effect = KIconLoader::global()->iconEffect();
00440 QPixmap result = m_icon.pixmap(iconRect(bounds).toRect().size());
00441
00442 if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
00443 if (qFuzzyCompare(qreal(1.0), m_alpha)) {
00444 result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
00445 } else {
00446 result = Plasma::PaintUtils::transition(
00447 result,
00448 effect->apply(result, KIconLoader::Desktop,
00449 KIconLoader::ActiveState), m_fadeIn?m_alpha:1-m_alpha);
00450 }
00451 }
00452 painter->drawPixmap(iconRect(bounds).topLeft(), result);
00453 }
00454
00455 painter->setPen(QPen(textColor(), 1.0));
00456
00457 QRect rect = textRect(bounds).toRect();
00458 if (rect.height() > 20) {
00459 rect.adjust(2, 2, -2, -2);
00460 }
00461 QTextLayout layout;
00462 layout.setFont(KGlobalSettings::taskbarFont());
00463 layout.setTextOption(textOption());
00464
00465 layoutText(layout, m_text, rect.size());
00466 drawTextLayout(painter, layout, rect);
00467
00468 TaskGroupItem *groupItem = qobject_cast<TaskGroupItem *>(this);
00469 if (groupItem) {
00470 QFont font(KGlobalSettings::smallestReadableFont());
00471 QFontMetrics fm(font);
00472 QRectF rect(expanderRect(bounds));
00473
00474 Plasma::FrameSvg *itemBackground = m_applet->itemBackground();
00475
00476 if (itemBackground && itemBackground->hasElement(expanderElement())) {
00477 QSizeF arrowSize(itemBackground->elementSize(expanderElement()));
00478 QRectF arrowRect(rect.center()-QPointF(arrowSize.width()/2, arrowSize.height()+fm.xHeight()/2), arrowSize);
00479 itemBackground->paint(painter, arrowRect, expanderElement());
00480
00481 painter->setFont(font);
00482 rect.setTop(arrowRect.bottom());
00483 painter->drawText(rect, Qt::AlignHCenter|Qt::AlignTop, QString::number(groupItem->memberList().count()));
00484 } else {
00485 painter->setFont(font);
00486 painter->drawText(rect, Qt::AlignCenter, QString::number(groupItem->memberList().count()));
00487 }
00488 }
00489 }
00490
00491 QTextOption AbstractTaskItem::textOption() const
00492 {
00493 Qt::LayoutDirection direction = QApplication::layoutDirection();
00494 Qt::Alignment alignment = QStyle::visualAlignment(direction, Qt::AlignLeft | Qt::AlignVCenter);
00495
00496 QTextOption option;
00497 option.setTextDirection(direction);
00498 option.setAlignment(alignment);
00499
00500 return option;
00501 }
00502
00503 QSize AbstractTaskItem::layoutText(QTextLayout &layout, const QString &text,
00504 const QSize &constraints) const
00505 {
00506 QFontMetrics metrics(layout.font());
00507 int leading = metrics.leading();
00508 int height = 0;
00509 int maxWidth = constraints.width();
00510 int widthUsed = 0;
00511 int lineSpacing = metrics.lineSpacing();
00512 QTextLine line;
00513
00514 layout.setText(text);
00515
00516 layout.beginLayout();
00517 while ((line = layout.createLine()).isValid()) {
00518 height += leading;
00519
00520
00521
00522
00523 if (height + 2 * lineSpacing > constraints.height()) {
00524 line.setPosition(QPoint(0, height));
00525 break;
00526 }
00527
00528 line.setLineWidth(maxWidth);
00529 line.setPosition(QPoint(0, height));
00530
00531 height += int(line.height());
00532 widthUsed = int(qMax(qreal(widthUsed), line.naturalTextWidth()));
00533 }
00534 layout.endLayout();
00535
00536 return QSize(widthUsed, height);
00537 }
00538
00539 void AbstractTaskItem::drawTextLayout(QPainter *painter, const QTextLayout &layout, const QRect &rect) const
00540 {
00541 if (rect.width() < 1 || rect.height() < 1) {
00542 return;
00543 }
00544
00545 QPixmap pixmap(rect.size());
00546 pixmap.fill(Qt::transparent);
00547
00548 QPainter p(&pixmap);
00549 p.setPen(painter->pen());
00550
00551
00552 QLinearGradient alphaGradient(0, 0, 1, 0);
00553 alphaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
00554 if (layout.textOption().textDirection() == Qt::LeftToRight)
00555 {
00556 alphaGradient.setColorAt(0, QColor(0, 0, 0, 255));
00557 alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
00558 } else
00559 {
00560 alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
00561 alphaGradient.setColorAt(1, QColor(0, 0, 0, 255));
00562 }
00563
00564 QFontMetrics fm(layout.font());
00565 int textHeight = layout.lineCount() * fm.lineSpacing();
00566
00567 QPointF position = textHeight < rect.height() ?
00568 QPointF(0, (rect.height() - textHeight) / 2 + (fm.tightBoundingRect("M").height() - fm.xHeight())) : QPointF(0, 0);
00569 QList<QRect> fadeRects;
00570 int fadeWidth = 30;
00571
00572
00573 for (int i = 0; i < layout.lineCount(); i++)
00574 {
00575 QTextLine line = layout.lineAt(i);
00576 line.draw(&p, position);
00577
00578
00579 if (line.naturalTextWidth() > rect.width())
00580 {
00581 int x = int(qMin(line.naturalTextWidth(), (qreal)pixmap.width())) - fadeWidth;
00582 int y = int(line.position().y() + position.y());
00583 QRect r = QStyle::visualRect(layout.textOption().textDirection(), pixmap.rect(),
00584 QRect(x, y, fadeWidth, int(line.height())));
00585 fadeRects.append(r);
00586 }
00587 }
00588
00589
00590 if (!fadeRects.isEmpty())
00591 {
00592 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00593 foreach (const QRect &rect, fadeRects) {
00594 p.fillRect(rect, alphaGradient);
00595 }
00596 }
00597
00598 p.end();
00599
00600
00601 QColor shadowColor;
00602 if (textColor().value() < 128) {
00603 shadowColor = Qt::white;
00604 } else {
00605 shadowColor = Qt::black;
00606 }
00607
00608 QImage shadow = pixmap.toImage();
00609 Plasma::PaintUtils::shadowBlur(shadow, 2, shadowColor);
00610
00611 painter->drawImage(rect.topLeft() + QPoint(1,2), shadow);
00612 painter->drawPixmap(rect.topLeft(), pixmap);
00613 }
00614
00615
00616
00617 void AbstractTaskItem::animationUpdate(qreal progress)
00618 {
00619 if (qFuzzyCompare(qreal(1.0), progress)) {
00620 m_animId = 0;
00621 m_fadeIn = true;
00622 }
00623
00624 m_alpha = progress;
00625
00626
00627 update();
00628 }
00629
00630 void AbstractTaskItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
00631 {
00632 if (event->mimeData()->hasFormat(TaskManager::Task::mimetype()) ||
00633 event->mimeData()->hasFormat(TaskManager::Task::groupMimetype())) {
00634 event->ignore();
00635 return;
00636 }
00637
00638 event->accept();
00639
00640 if (!m_activateTimer) {
00641 m_activateTimer = new QTimer(this);
00642 m_activateTimer->setSingleShot(true);
00643 m_activateTimer->setInterval(300);
00644 connect(m_activateTimer, SIGNAL(timeout()), this, SLOT(activate()));
00645 }
00646 m_activateTimer->start();
00647 }
00648
00649 void AbstractTaskItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
00650 {
00651 Q_UNUSED(event);
00652
00653
00654
00655 if (m_activateTimer) {
00656 m_activateTimer->start();
00657 }
00658 }
00659
00660 void AbstractTaskItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
00661 {
00662 Q_UNUSED(event);
00663
00664 if (m_activateTimer) {
00665 delete m_activateTimer;
00666 m_activateTimer = 0;
00667 }
00668 }
00669
00670 QRect AbstractTaskItem::iconGeometry() const
00671 {
00672 if (!scene() || !boundingRect().isValid()) {
00673 return QRect();
00674 }
00675
00676 QGraphicsView *parentView = 0;
00677 QGraphicsView *possibleParentView = 0;
00678
00679 foreach (QGraphicsView *view, scene()->views()) {
00680 if (view->sceneRect().intersects(sceneBoundingRect()) ||
00681 view->sceneRect().contains(scenePos())) {
00682 if (view->isActiveWindow()) {
00683 parentView = view;
00684 break;
00685 } else {
00686 possibleParentView = view;
00687 }
00688 }
00689 }
00690
00691 if (!parentView) {
00692 parentView = possibleParentView;
00693
00694 if (!parentView) {
00695 return QRect();
00696 }
00697 }
00698
00699 QRect rect = parentView->mapFromScene(mapToScene(boundingRect())).boundingRect().adjusted(0, 0, 1, 1);
00700 rect.moveTopLeft(parentView->mapToGlobal(rect.topLeft()));
00701 return rect;
00702 }
00703
00704 void AbstractTaskItem::publishIconGeometry() const
00705 {
00706 }
00707
00708 void AbstractTaskItem::publishIconGeometry(const QRect &rect) const
00709 {
00710 }
00711
00712 void AbstractTaskItem::setGeometry(const QRectF& geometry)
00713 {
00714 QGraphicsWidget::setGeometry(geometry);
00715 publishIconGeometry();
00716 }
00717
00718 QRectF AbstractTaskItem::iconRect(const QRectF &b) const
00719 {
00720 QRectF bounds(b);
00721 const int right = bounds.right();
00722
00723 bounds.setWidth(qMax(bounds.width() / 3, qMin(minimumSize().height(), bounds.width())));
00724
00725
00726 if (QApplication::layoutDirection() == Qt::RightToLeft) {
00727 bounds.moveRight(right);
00728 }
00729
00730 QSize iconSize = m_icon.actualSize(bounds.size().toSize());
00731
00732 return QStyle::alignedRect(QApplication::layoutDirection(), Qt::AlignLeft | Qt::AlignVCenter,
00733 iconSize, bounds.toRect());
00734 }
00735
00736 QRectF AbstractTaskItem::expanderRect(const QRectF &bounds) const
00737 {
00738 const TaskGroupItem *groupItem = qobject_cast<const TaskGroupItem *>(this);
00739 if (!groupItem) {
00740 return QRectF();
00741 }
00742
00743 QFontMetrics fm(KGlobalSettings::smallestReadableFont());
00744 Plasma::FrameSvg *itemBackground = m_applet->itemBackground();
00745
00746 QSize expanderSize(qMax(fm.width(QString::number(groupItem->memberList().count())),
00747 itemBackground ? itemBackground->elementSize(expanderElement()).width() : 0),
00748 size().height());
00749
00750 return QStyle::alignedRect(QApplication::layoutDirection(), Qt::AlignRight | Qt::AlignVCenter,
00751 expanderSize, bounds.toRect());
00752 }
00753
00754 QRectF AbstractTaskItem::textRect(const QRectF &bounds) const
00755 {
00756 QSize size(bounds.size().toSize());
00757 QRectF effectiveBounds(bounds);
00758
00759 size.rwidth() -= int(iconRect(bounds).width()) + qMax(0, IconTextSpacing - 2);
00760 if (!isWindowItem()) {
00761 size.rwidth() -= int(expanderRect(bounds).width()) + qMax(0, IconTextSpacing - 2);
00762
00763 if (QApplication::layoutDirection() == Qt::RightToLeft) {
00764 effectiveBounds.setLeft(expanderRect(bounds).right());
00765 } else {
00766 effectiveBounds.setRight(expanderRect(bounds).left());
00767 }
00768 }
00769
00770 return QStyle::alignedRect(QApplication::layoutDirection(), Qt::AlignRight | Qt::AlignVCenter,
00771 size, effectiveBounds.toRect());
00772 }
00773
00774 QColor AbstractTaskItem::textColor() const
00775 {
00776 QColor color;
00777 qreal bias;
00778 Plasma::Theme *theme = Plasma::Theme::defaultTheme();
00779
00780 if ((m_oldBackgroundPrefix == "attention" || m_backgroundPrefix == "attention") &&
00781 m_applet->itemBackground() && m_applet->itemBackground()->hasElement("hint-attention-button-color")) {
00782 if (!m_animId && m_backgroundPrefix != "attention") {
00783 color = theme->color(Plasma::Theme::TextColor);
00784 } else if (!m_animId) {
00785 color = theme->color(Plasma::Theme::ButtonTextColor);
00786 } else {
00787 if (m_oldBackgroundPrefix == "attention") {
00788 bias = 1 - m_alpha;
00789 } else {
00790 bias = m_alpha;
00791 }
00792
00793 color = KColorUtils::mix(theme->color(Plasma::Theme::TextColor),
00794 theme->color(Plasma::Theme::ButtonTextColor), bias);
00795 }
00796 } else {
00797 color = theme->color(Plasma::Theme::TextColor);
00798 }
00799
00800 if (m_flags & TaskIsMinimized) {
00801 color.setAlphaF(0.85);
00802 }
00803
00804 return color;
00805 }
00806
00807 QString AbstractTaskItem::expanderElement() const
00808 {
00809 switch (m_applet->location()) {
00810 case Plasma::TopEdge:
00811 return "group-expander-top";
00812 case Plasma::RightEdge:
00813 return "group-expander-right";
00814 case Plasma::LeftEdge:
00815 return "group-expander-left";
00816 case Plasma::BottomEdge:
00817 default:
00818 return "group-expander-bottom";
00819 }
00820 }
00821
00822
00823 bool AbstractTaskItem::isGroupMember(const TaskGroupItem *group) const
00824 {
00825 if (!m_abstractItem || !group) {
00826 kDebug() <<"no task";
00827 return false;
00828 }
00829
00830 return m_abstractItem->isGroupMember(group->group());
00831
00832 }
00833
00834 bool AbstractTaskItem::isGrouped() const
00835 {
00836 if (!m_abstractItem) {
00837 kDebug() <<"no item";
00838 return false;
00839 }
00840 return m_abstractItem->isGrouped();
00841 }
00842
00843 TaskGroupItem * AbstractTaskItem::parentGroup() const
00844 {
00845 return qobject_cast<TaskGroupItem*>(parentWidget());
00846 }
00847
00848 TaskManager::AbstractItemPtr AbstractTaskItem::abstractItem()
00849 {
00850 return m_abstractItem;
00851 }
00852
00853 #include "abstracttaskitem.moc"