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

Applets

abstracttaskitem.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  *   Copyright (C) 2008 by Marco Martin <notmart@gmail.com>                *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  *   This program is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU General Public License for more details.                          *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU General Public License     *
00017  *   along with this program; if not, write to the                         *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
00020  ***************************************************************************/
00021 
00022 // Own
00023 #include "abstracttaskitem.h"
00024 
00025 // Qt
00026 #include <QGraphicsSceneContextMenuEvent>
00027 #include <QStyleOptionGraphicsItem>
00028 #include <QGraphicsView>
00029 #include <QTimer>
00030 #include <QApplication>
00031 #include <QTextLayout>
00032 #include <QGraphicsLinearLayout>
00033 
00034 // KDE
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     //the 4 should be the default spacing between layout items, is there a way to fetch it without hardcoding?
00091     // in small panels, we'll reduce the spacing a bit so it's easier to cramp the text in and still get two rows
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; //icon.pixmap(MinTaskIconSize);
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         //kDebug() << "task attention state changed" << m_attentionTimerId;
00154         if (flags & TaskWantsAttention) {
00155             // start attention getting
00156             if (!m_attentionTimerId) {
00157                 m_attentionTimerId = startTimer(500);
00158             }
00159         } else if (m_attentionTimerId) {
00160             killTimer(m_attentionTimerId);
00161             m_attentionTimerId = 0;
00162             // stop attention getting
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/* || event->button() == Qt::MidButton*/) {
00261         activate();
00262     }
00263 }
00264 
00265 void AbstractTaskItem::mousePressEvent(QGraphicsSceneMouseEvent *)
00266 {
00267     update();
00268 }
00269 
00270 void AbstractTaskItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00271 {
00272     //kDebug();
00273     if (QPoint(event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance()) {
00274         return;
00275     } //Wait a bit before starting drag
00276 
00277   /*  if((m_applet->taskSortOrder() != Tasks::NoSorting) && (m_applet->taskSortOrder() != Tasks::GroupSorting)){ //FIXME check somhow if drag is allowed
00278         return;
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    // drag->setDragCursor( set the correct cursor //TODO
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     // draw background
00327     drawBackground(painter, option, widget);
00328 
00329     // draw icon and text
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     // Do not paint with invalid sizes, the happens when the layout is being initialized
00360     if (!option->rect.isValid()) {
00361         return;
00362     }
00363 
00364     /*FIXME -could be done more elegant with caching in tasks in a qhash <size,svg>.
00365     -do not use size() directly because this introduces the blackline syndrome.
00366     -This line is only needed when we have different items in the taskbar because of an expanded group for example. otherwise the resizing in the resizeEvent is sufficient
00367     */
00368     Plasma::FrameSvg *itemBackground = m_applet->itemBackground();
00369 
00370     if (!itemBackground) {
00371         return;
00372     }
00373 
00374     //if the size is changed have to resize all the elements
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         //restore the prefix
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         //itemBackground->paintFrame(painter, backgroundPosition);
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); // Create a text margin
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         // Make the last line that will fit infinitely long.
00521         // drawTextLayout() will handle this by fading the line out
00522         // if it won't fit in the contraints.
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     // Create the alpha gradient for the fade out effect
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     // Draw each line in the layout
00573     for (int i = 0; i < layout.lineCount(); i++)
00574     {
00575         QTextLine line = layout.lineAt(i);
00576         line.draw(&p, position);
00577 
00578         // Add a fade out rect to the list if the line is too long
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     // Reduce the alpha in each fade out rect using the alpha gradient
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     // explicit update
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(); //ignore it so the taskbar gets the event
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     // restart the timer so that activate() is only called after the mouse
00654     // stops moving
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     // The following was taken from Plasma::Applet, it doesn't make sense to make the item an applet, and this was the easiest way around it.
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     //leave enough space for the text. useful in vertical panel
00723     bounds.setWidth(qMax(bounds.width() / 3, qMin(minimumSize().height(), bounds.width())));
00724 
00725     //restore right position if the layout is RTL
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"

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