00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "extenderitem.h"
00021
00022 #include <QAction>
00023 #include <QApplication>
00024 #include <QBitmap>
00025 #include <QDrag>
00026 #include <QGraphicsSceneResizeEvent>
00027 #include <QGraphicsSceneMouseEvent>
00028 #include <QGraphicsLinearLayout>
00029 #include <QLayout>
00030 #include <QMimeData>
00031 #include <QPainter>
00032 #include <QTimer>
00033
00034 #include <kdebug.h>
00035 #include <kicon.h>
00036 #include <kiconloader.h>
00037
00038 #include "applet.h"
00039 #include "containment.h"
00040 #include "corona.h"
00041 #include "dialog.h"
00042 #include "extender.h"
00043 #include "extendergroup.h"
00044 #include "framesvg.h"
00045 #include "popupapplet.h"
00046 #include "theme.h"
00047 #include "view.h"
00048
00049 #include "widgets/iconwidget.h"
00050
00051 #include "private/applethandle_p.h"
00052 #include "private/extender_p.h"
00053 #include "private/extenderapplet_p.h"
00054 #include "private/extendergroup_p.h"
00055 #include "private/extenderitem_p.h"
00056 #include "private/extenderitemmimedata_p.h"
00057
00058 namespace Plasma
00059 {
00060
00061 ExtenderItem::ExtenderItem(Extender *hostExtender, uint extenderItemId)
00062 : QGraphicsWidget(hostExtender),
00063 d(new ExtenderItemPrivate(this, hostExtender))
00064 {
00065 Q_ASSERT(hostExtender);
00066
00067
00068 if (extenderItemId) {
00069 d->extenderItemId = extenderItemId;
00070 ExtenderItemPrivate::s_maxExtenderItemId =
00071 qMax(ExtenderItemPrivate::s_maxExtenderItemId, extenderItemId);
00072 } else {
00073 d->extenderItemId = ++ExtenderItemPrivate::s_maxExtenderItemId;
00074 }
00075
00076
00077 d->toolbox = new QGraphicsWidget(this);
00078 d->toolboxLayout = new QGraphicsLinearLayout(d->toolbox);
00079 d->toolbox->setLayout(d->toolboxLayout);
00080
00081
00082 KConfigGroup cg = hostExtender->d->applet->config("ExtenderItems");
00083 KConfigGroup dg = KConfigGroup(&cg, QString::number(d->extenderItemId));
00084
00085 uint sourceAppletId = dg.readEntry("sourceAppletId", 0);
00086
00087
00088 if (!sourceAppletId) {
00089
00090 dg.writeEntry("sourceAppletPluginName", hostExtender->d->applet->pluginName());
00091 dg.writeEntry("sourceAppletId", hostExtender->d->applet->id());
00092 dg.writeEntry("extenderIconName", hostExtender->d->applet->icon());
00093 d->sourceApplet = hostExtender->d->applet;
00094 d->collapseIcon = new IconWidget(KIcon(hostExtender->d->applet->icon()), "", this);
00095 } else {
00096
00097 d->name = dg.readEntry("extenderItemName", "");
00098 d->title = dg.readEntry("extenderTitle", "");
00099 setCollapsed(dg.readEntry("isCollapsed", false));
00100
00101 QString iconName = dg.readEntry("extenderIconName", "utilities-desktop-extra");
00102 if (iconName.isEmpty()) {
00103 iconName = "utilities-desktop-extra";
00104 }
00105 d->collapseIcon = new IconWidget(KIcon(iconName), "", this);
00106
00107
00108 QString groupName = dg.readEntry("group", "");
00109 d->group = hostExtender->d->findGroup(groupName);
00110
00111
00112 Corona *corona = hostExtender->d->applet->containment()->corona();
00113 foreach (Containment *containment, corona->containments()) {
00114 foreach (Applet *applet, containment->applets()) {
00115 if (applet->id() == sourceAppletId &&
00116 applet->pluginName() == dg.readEntry("sourceAppletPluginName", "")) {
00117 d->sourceApplet = applet;
00118 }
00119 }
00120 }
00121 }
00122
00123
00124
00125 connect(d->sourceApplet, SIGNAL(destroyed()), this, SLOT(sourceAppletRemoved()));
00126 connect(d->collapseIcon, SIGNAL(clicked()), this, SLOT(toggleCollapse()));
00127
00128
00129 setExtender(hostExtender);
00130
00131
00132 d->updateToolBox();
00133
00134
00135 d->themeChanged();
00136
00137 setAcceptsHoverEvents(true);
00138
00139 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeChanged()));
00140 }
00141
00142 ExtenderItem::~ExtenderItem()
00143 {
00144
00145 if (d->mouseOver) {
00146 QApplication::restoreOverrideCursor();
00147 }
00148 delete d;
00149 }
00150
00151 KConfigGroup ExtenderItem::config() const
00152 {
00153 KConfigGroup cg = d->extender->d->applet->config("ExtenderItems");
00154 return KConfigGroup(&cg, QString::number(d->extenderItemId));
00155 }
00156
00157 void ExtenderItem::setTitle(const QString &title)
00158 {
00159 if (d->title != title) {
00160 d->title = title;
00161 config().writeEntry("extenderTitle", title);
00162 update();
00163 }
00164 }
00165
00166 QString ExtenderItem::title() const
00167 {
00168 return d->title;
00169 }
00170
00171 void ExtenderItem::setName(const QString &name)
00172 {
00173 d->name = name;
00174 config().writeEntry("extenderItemName", name);
00175 }
00176
00177 QString ExtenderItem::name() const
00178 {
00179 return d->name;
00180 }
00181
00182 void ExtenderItem::setWidget(QGraphicsItem *widget)
00183 {
00184 if (d->widget) {
00185 d->widget->removeSceneEventFilter(this);
00186 }
00187
00188 if (!widget) {
00189 d->widget = 0;
00190 return;
00191 }
00192
00193 widget->setParentItem(this);
00194 widget->installSceneEventFilter(this);
00195
00196 QSizeF panelSize(QSizeF(size().width() - d->bgLeft - d->bgRight,
00197 d->iconSize + d->dragTop + d->dragBottom));
00198 widget->setPos(QPointF(d->bgLeft + d->dragLeft, panelSize.height() + d->bgTop));
00199 d->widget = widget;
00200 d->updateSizeHints();
00201 }
00202
00203 QGraphicsItem *ExtenderItem::widget() const
00204 {
00205 return d->widget;
00206 }
00207
00208 void ExtenderItem::setIcon(const QIcon &icon)
00209 {
00210 if (d->collapseIcon->icon().isNull() || icon.cacheKey() != d->collapseIcon->icon().cacheKey()) {
00211 d->iconName.clear();
00212 d->collapseIcon->setIcon(icon);
00213 }
00214 }
00215
00216 void ExtenderItem::setIcon(const QString &icon)
00217 {
00218 if (icon != d->iconName) {
00219 d->collapseIcon->setIcon(icon);
00220 d->iconName = icon;
00221 config().writeEntry("extenderIconName", icon);
00222 }
00223 }
00224
00225 QIcon ExtenderItem::icon() const
00226 {
00227 return d->collapseIcon->icon();
00228 }
00229
00230 void ExtenderItem::setExtender(Extender *extender, const QPointF &pos)
00231 {
00232 Q_ASSERT(extender);
00233
00234
00235
00236 d->dragStarted = false;
00237
00238 ExtenderGroup *group = qobject_cast<ExtenderGroup*>(this);
00239 QList<ExtenderItem*> childItems;
00240 if (group) {
00241 childItems = group->items();
00242 }
00243
00244 if (extender == d->extender) {
00245
00246 setParentItem(extender);
00247 extender->d->addExtenderItem(this, pos);
00248 return;
00249 }
00250
00251
00252
00253 d->extender->d->removeExtenderItem(this);
00254
00255
00256 if (d->hostApplet() && (extender != d->extender)) {
00257 KConfigGroup c = extender->d->applet->config("ExtenderItems");
00258 config().reparent(&c);
00259 }
00260
00261
00262 emit d->extender->itemDetached(this);
00263
00264 d->extender = extender;
00265
00266
00267 setParentItem(extender);
00268 extender->d->addExtenderItem(this, pos);
00269
00270
00271 if (d->expirationTimer && isDetached()) {
00272 d->expirationTimer->stop();
00273 delete d->expirationTimer;
00274 d->expirationTimer = 0;
00275 }
00276
00277 Corona *corona = qobject_cast<Corona*>(scene());
00278 KConfigGroup extenderItemGroup(corona->config(), "DetachedExtenderItems");
00279
00280 if (isDetached()) {
00281 kDebug() << "detached, adding entry to the global group";
00282 KConfigGroup itemConfig = extenderItemGroup.group(QString::number(d->extenderItemId));
00283 itemConfig.writeEntry("sourceAppletPluginName",
00284 config().readEntry("sourceAppletPluginName", ""));
00285 itemConfig.writeEntry("sourceAppletId",
00286 config().readEntry("sourceAppletId", 0));
00287 itemConfig.writeEntry("extenderItemName",
00288 config().readEntry("extenderItemName", ""));
00289 } else if (extenderItemGroup.hasGroup(QString::number(d->extenderItemId))) {
00290 kDebug() << "no longer detached, removing entry from the global group";
00291 extenderItemGroup.deleteGroup(QString::number(d->extenderItemId));
00292 }
00293
00294
00295 d->updateToolBox();
00296
00297
00298
00299 if (group) {
00300 foreach (ExtenderItem *item, childItems) {
00301 item->setGroup(group);
00302 }
00303 }
00304 }
00305
00306 Extender *ExtenderItem::extender() const
00307 {
00308 return d->extender;
00309 }
00310
00311 void ExtenderItem::setGroup(ExtenderGroup *group)
00312 {
00313 if (isGroup()) {
00314
00315 kWarning() << "Nesting ExtenderGroups is not supported";
00316 return;
00317 }
00318
00319 d->group = group;
00320
00321 if (group) {
00322 config().writeEntry("group", group->name());
00323
00324 if (group->extender() != extender()) {
00325 kDebug() << "moving to another extender because we're joining a detached group.";
00326 setExtender(group->extender());
00327 }
00328 group->d->addItemToGroup(this);
00329 } else {
00330 config().deleteEntry("group");
00331 }
00332 }
00333
00334 ExtenderGroup *ExtenderItem::group() const
00335 {
00336 return d->group;
00337 }
00338
00339 bool ExtenderItem::isGroup() const
00340 {
00341 return (config().readEntry("isGroup", false));
00342 }
00343
00344 bool ExtenderItem::isCollapsed() const
00345 {
00346 return d->collapsed;
00347 }
00348
00349 void ExtenderItem::setAutoExpireDelay(uint time)
00350 {
00351 if (!time) {
00352 if (d->expirationTimer) {
00353 d->expirationTimer->stop();
00354 delete d->expirationTimer;
00355 d->expirationTimer = 0;
00356 }
00357 return;
00358 }
00359
00360 if (!isDetached()) {
00361 if (!d->expirationTimer) {
00362 d->expirationTimer = new QTimer(this);
00363 connect(d->expirationTimer, SIGNAL(timeout()), this, SLOT(destroy()));
00364 }
00365
00366 d->expirationTimer->stop();
00367 d->expirationTimer->setSingleShot(true);
00368 d->expirationTimer->setInterval(time);
00369 d->expirationTimer->start();
00370 }
00371 }
00372
00373 uint ExtenderItem::autoExpireDelay() const
00374 {
00375 if (d->expirationTimer) {
00376 return d->expirationTimer->interval();
00377 } else {
00378 return 0;
00379 }
00380 }
00381
00382 bool ExtenderItem::isDetached() const
00383 {
00384 if (d->hostApplet()) {
00385 return (d->sourceApplet != d->hostApplet());
00386 } else {
00387 return false;
00388 }
00389 }
00390
00391 void ExtenderItem::addAction(const QString &name, QAction *action)
00392 {
00393 Q_ASSERT(action);
00394 if (d->actionsInOrder.contains(action)) {
00395 return;
00396 }
00397
00398 d->actions.insert(name, action);
00399 d->actionsInOrder.append(action);
00400 connect(action, SIGNAL(changed()), this, SLOT(updateToolBox()));
00401 connect(action, SIGNAL(destroyed(QObject*)), this, SLOT(actionDestroyed(QObject*)));
00402 d->updateToolBox();
00403 }
00404
00405 QAction *ExtenderItem::action(const QString &name) const
00406 {
00407 return d->actions.value(name, 0);
00408 }
00409
00410 void ExtenderItem::showCloseButton()
00411 {
00412 if (d->destroyActionVisibility) {
00413 return;
00414 }
00415
00416 d->destroyActionVisibility = true;
00417 d->updateToolBox();
00418 }
00419
00420 void ExtenderItem::hideCloseButton()
00421 {
00422 if (!d->destroyActionVisibility) {
00423 return;
00424 }
00425
00426 d->destroyActionVisibility = false;
00427 d->updateToolBox();
00428 }
00429
00430 void ExtenderItem::destroy()
00431 {
00432 if (d->dragStarted) {
00433
00434 return;
00435 }
00436
00437
00438 Corona *corona = qobject_cast<Corona*>(scene());
00439 KConfigGroup extenderItemGroup(corona->config(), "DetachedExtenderItems");
00440 if (extenderItemGroup.hasGroup(QString::number(d->extenderItemId))) {
00441 extenderItemGroup.deleteGroup(QString::number(d->extenderItemId));
00442 }
00443
00444 d->hostApplet()->config("ExtenderItems").deleteGroup(QString::number(d->extenderItemId));
00445 d->extender->d->removeExtenderItem(this);
00446 emit d->extender->itemDetached(this);
00447 deleteLater();
00448 }
00449
00450 void ExtenderItem::setCollapsed(bool collapsed)
00451 {
00452 config().writeEntry("isCollapsed", collapsed);
00453 d->collapsed = collapsed;
00454 if (d->widget) {
00455 d->widget->setVisible(!collapsed);
00456 d->updateSizeHints();
00457 }
00458 }
00459
00460 void ExtenderItem::returnToSource()
00461 {
00462 if (!d || !d->sourceApplet) {
00463 return;
00464 }
00465 if (d->sourceApplet->d) {
00466 setExtender(d->sourceApplet->extender());
00467 }
00468 }
00469
00470 void ExtenderItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
00471 QWidget *widget)
00472 {
00473 Q_UNUSED(option);
00474 Q_UNUSED(widget);
00475
00476 painter->setRenderHint(QPainter::TextAntialiasing, true);
00477 painter->setRenderHint(QPainter::Antialiasing, true);
00478
00479 if (d->background->enabledBorders() != (FrameSvg::LeftBorder | FrameSvg::RightBorder) &&
00480 d->background->enabledBorders()) {
00481
00482
00483 d->background->paintFrame(painter, QPointF(0, 0));
00484 }
00485
00486 d->dragger->paintFrame(painter, QPointF(d->bgLeft, d->bgTop));
00487
00488
00489 if (d->title.isEmpty()) {
00490 return;
00491 }
00492
00493
00494 Plasma::Theme *theme = Plasma::Theme::defaultTheme();
00495 QFont font = theme->font(Plasma::Theme::DefaultFont);
00496 font.setWeight(QFont::Bold);
00497
00498
00499 QRectF rect = QRectF(d->titleRect().width() - 30, 0, 30, d->titleRect().height());
00500
00501 QPixmap pixmap(d->titleRect().size().toSize());
00502 pixmap.fill(Qt::transparent);
00503
00504 QPainter p(&pixmap);
00505 p.setPen(theme->color(Plasma::Theme::TextColor));
00506 p.setFont(font);
00507 p.drawText(QRectF(QPointF(0, 0), d->titleRect().size()),
00508 Qt::TextSingleLine | Qt::AlignVCenter | Qt::AlignLeft,
00509 d->title);
00510
00511
00512 QLinearGradient alphaGradient(0, 0, 1, 0);
00513 alphaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
00514
00515 alphaGradient.setColorAt(0, QColor(0, 0, 0, 255));
00516 alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
00517
00518 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00519 p.fillRect(rect, alphaGradient);
00520
00521 p.end();
00522
00523 painter->drawPixmap(d->titleRect().topLeft(), pixmap);
00524 }
00525
00526 void ExtenderItem::moveEvent(QGraphicsSceneMoveEvent *event)
00527 {
00528 Q_UNUSED(event)
00529
00530 }
00531
00532 void ExtenderItem::resizeEvent(QGraphicsSceneResizeEvent *event)
00533 {
00534 Q_UNUSED(event)
00535 d->themeChanged();
00536 }
00537
00538 void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
00539 {
00540 if (!(d->dragHandleRect().contains(event->pos())) ||
00541 d->extender->d->applet->immutability() != Plasma::Mutable) {
00542 event->ignore();
00543 return;
00544 }
00545
00546 d->mousePos = event->pos().toPoint();
00547 }
00548
00549 void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00550 {
00551 if ((event->pos().toPoint() - d->mousePos).manhattanLength()
00552 < QApplication::startDragDistance()) {
00553 return;
00554 }
00555
00556
00557 d->dragStarted = true;
00558 QPointF curPos = pos();
00559
00560
00561
00562 d->extender->itemRemovedEvent(this);
00563 Corona *corona = qobject_cast<Corona*>(scene());
00564 corona->addOffscreenWidget(this);
00565
00566
00567 d->themeChanged();
00568
00569
00570
00571 QGraphicsView view(scene());
00572 QSize screenSize(view.mapFromScene(sceneBoundingRect()).boundingRect().size());
00573 QPixmap pixmap(screenSize);
00574 pixmap.fill(Qt::transparent);
00575 QPainter p(&pixmap);
00576
00577
00578
00579 view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00580 view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00581 view.setFrameShape(QFrame::NoFrame);
00582
00583
00584 view.resize(screenSize);
00585 view.setSceneRect(sceneBoundingRect());
00586 view.render(&p, QRectF(QPointF(0, 0), pixmap.size()), QRect(QPoint(0, 0), screenSize));
00587
00588
00589 ExtenderItemMimeData *mimeData = new ExtenderItemMimeData();
00590 mimeData->setExtenderItem(this);
00591
00592
00593
00594 ExtenderApplet *extenderApplet = qobject_cast<ExtenderApplet*>(d->extender->d->applet);
00595 if (extenderApplet && d->extender->attachedItems().count() < 2 &&
00596 extenderApplet->formFactor() != Plasma::Horizontal &&
00597 extenderApplet->formFactor() != Plasma::Vertical) {
00598 kDebug() << "leaving the internal extender container, so hide the applet and it's handle.";
00599 extenderApplet->hide();
00600 AppletHandle *handle = dynamic_cast<AppletHandle*>(extenderApplet->parentItem());
00601 if (handle) {
00602 handle->hide();
00603 }
00604 }
00605
00606 ExtenderGroup *group = qobject_cast<ExtenderGroup*>(this);
00607 bool collapsedGroup = false;
00608 if (isGroup()) {
00609 collapsedGroup = group->d->collapsed;
00610 group->collapseGroup();
00611 }
00612
00613
00614 QWidget *dragParent = extender()->d->applet->view();
00615 QDrag *drag = new QDrag(dragParent);
00616 drag->setPixmap(pixmap);
00617 drag->setMimeData(mimeData);
00618 drag->setHotSpot(d->mousePos);
00619 Qt::DropAction action = drag->exec();
00620
00621 corona->removeOffscreenWidget(this);
00622
00623 if (!action || !drag->target()) {
00624
00625 d->extender->itemAddedEvent(this, curPos);
00626 }
00627
00628 if (isGroup() && !collapsedGroup) {
00629 group->expandGroup();
00630 }
00631
00632 d->dragStarted = false;
00633 }
00634
00635 void ExtenderItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
00636 {
00637 if (d->titleRect().contains(event->pos())) {
00638 d->toggleCollapse();
00639 }
00640 }
00641
00642 bool ExtenderItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
00643 {
00644 if (watched == d->widget && event->type() == QEvent::GraphicsSceneResize) {
00645 d->updateSizeHints();
00646 }
00647 return false;
00648 }
00649
00650 void ExtenderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00651 {
00652 Q_UNUSED(event)
00653
00654 }
00655
00656 void ExtenderItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
00657 {
00658 if (d->titleRect().contains(event->pos()) &&
00659 d->extender->d->applet->immutability() == Plasma::Mutable) {
00660 if (!d->mouseOver) {
00661 QApplication::setOverrideCursor(Qt::OpenHandCursor);
00662 d->mouseOver = true;
00663 }
00664 } else {
00665 if (d->mouseOver) {
00666 QApplication::restoreOverrideCursor();
00667 d->mouseOver = false;
00668 }
00669 }
00670 }
00671
00672 void ExtenderItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00673 {
00674 Q_UNUSED(event);
00675
00676 if (d->mouseOver) {
00677 QApplication::restoreOverrideCursor();
00678 d->mouseOver = false;
00679 }
00680 }
00681
00682 ExtenderItemPrivate::ExtenderItemPrivate(ExtenderItem *extenderItem, Extender *hostExtender)
00683 : q(extenderItem),
00684 widget(0),
00685 toolbox(0),
00686 extender(hostExtender),
00687 sourceApplet(0),
00688 group(0),
00689 dragger(new FrameSvg(extenderItem)),
00690 background(new FrameSvg(extenderItem)),
00691 collapseIcon(0),
00692 title(QString()),
00693 mouseOver(false),
00694 dragStarted(false),
00695 destroyActionVisibility(false),
00696 collapsed(false),
00697 expirationTimer(0),
00698 iconSize(qreal(0))
00699 {
00700 dragLeft = dragTop = dragRight = dragBottom = 0;
00701 bgLeft = bgTop = bgRight = bgBottom = 0;
00702 }
00703
00704 ExtenderItemPrivate::~ExtenderItemPrivate()
00705 {
00706 delete widget;
00707 widget = 0;
00708 }
00709
00710
00711 QRectF ExtenderItemPrivate::dragHandleRect()
00712 {
00713 QSizeF panelSize(QSizeF(q->size().width() - bgLeft - bgRight,
00714 iconSize + dragTop + dragBottom));
00715 return QRectF(QPointF(bgLeft, bgTop), panelSize);
00716 }
00717
00718 QRectF ExtenderItemPrivate::titleRect()
00719 {
00720 return dragHandleRect().adjusted(dragLeft + collapseIcon->size().width() + 1, dragTop,
00721 -toolbox->size().width() - dragRight, -dragBottom);
00722 }
00723
00724 void ExtenderItemPrivate::toggleCollapse()
00725 {
00726 q->setCollapsed(!q->isCollapsed());
00727 }
00728
00729 void ExtenderItemPrivate::updateToolBox()
00730 {
00731 Q_ASSERT(toolbox);
00732 Q_ASSERT(dragger);
00733 Q_ASSERT(toolboxLayout);
00734
00735
00736 while (toolboxLayout->count()) {
00737 QGraphicsLayoutItem *icon = toolboxLayout->itemAt(0);
00738 QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(icon);
00739 widget->deleteLater();
00740 toolboxLayout->removeAt(0);
00741 }
00742
00743
00744 foreach (QAction *action, actionsInOrder) {
00745 if (action->isVisible()) {
00746 IconWidget *icon = new IconWidget(q);
00747 icon->setAction(action);
00748 QSizeF size = icon->sizeFromIconSize(iconSize);
00749 icon->setMinimumSize(size);
00750 icon->setMaximumSize(size);
00751 toolboxLayout->addItem(icon);
00752 }
00753 }
00754
00755
00756 if (q->isDetached() && sourceApplet) {
00757 IconWidget *returnToSource = new IconWidget(q);
00758 returnToSource->setSvg("widgets/configuration-icons", "return-to-source");
00759 QSizeF size = returnToSource->sizeFromIconSize(iconSize);
00760 returnToSource->setMinimumSize(size);
00761 returnToSource->setMaximumSize(size);
00762
00763 toolboxLayout->addItem(returnToSource);
00764 QObject::connect(returnToSource, SIGNAL(clicked()), q, SLOT(returnToSource()));
00765 }
00766
00767
00768 if (destroyActionVisibility) {
00769 IconWidget *destroyAction = new IconWidget(q);
00770 destroyAction->setSvg("widgets/configuration-icons", "close");
00771 QSizeF size = destroyAction->sizeFromIconSize(iconSize);
00772 destroyAction->setMinimumSize(size);
00773 destroyAction->setMaximumSize(size);
00774
00775 toolboxLayout->addItem(destroyAction);
00776 QObject::connect(destroyAction, SIGNAL(clicked()), q, SLOT(destroy()));
00777 }
00778
00779 toolboxLayout->updateGeometry();
00780
00781
00782 QSizeF minimum = toolboxLayout->minimumSize();
00783 toolbox->resize(minimum);
00784 repositionToolbox();
00785 }
00786
00787 void ExtenderItemPrivate::repositionToolbox()
00788 {
00789 QSizeF minimum = toolboxLayout->minimumSize();
00790 toolbox->setPos(q->size().width() - minimum.width() - bgRight,
00791 (dragHandleRect().height()/2) -
00792 (minimum.height()/2) + bgTop);
00793 }
00794
00795 Applet *ExtenderItemPrivate::hostApplet() const
00796 {
00797 if (extender) {
00798 return extender->d->applet;
00799 } else {
00800 return 0;
00801 }
00802 }
00803
00804 void ExtenderItemPrivate::themeChanged()
00805 {
00806 if (dragStarted) {
00807 background->setImagePath("opaque/widgets/extender-background");
00808 } else {
00809 background->setImagePath("widgets/extender-background");
00810 }
00811 if (dragStarted) {
00812 background->setEnabledBorders(FrameSvg::AllBorders);
00813 } else {
00814 background->setEnabledBorders(extender->enabledBordersForItem(q));
00815 }
00816 background->getMargins(bgLeft, bgTop, bgRight, bgBottom);
00817
00818 dragger->setImagePath("widgets/extender-dragger");
00819
00820
00821
00822 dragger->resize();
00823 QSizeF size = dragger->elementSize("hint-preferred-icon-size");
00824 size = size.expandedTo(QSizeF(KIconLoader::SizeSmall,KIconLoader::SizeSmall));
00825
00826 Plasma::Theme *theme = Plasma::Theme::defaultTheme();
00827 QFont font = theme->font(Plasma::Theme::DefaultFont);
00828 QFontMetrics fm(font);
00829
00830 iconSize = qMax(size.height(), (qreal) fm.height());
00831
00832
00833 dragger->getMargins(dragLeft, dragTop, dragRight, dragBottom);
00834
00835 QSizeF panelSize(QSizeF(q->size().width() - bgLeft - bgRight,
00836 iconSize + dragTop + dragBottom));
00837
00838
00839 collapseIcon->resize(collapseIcon->sizeFromIconSize(iconSize));
00840
00841
00842 collapseIcon->setPos(bgLeft + dragLeft,
00843 panelSize.height()/2 -
00844 collapseIcon->size().height()/2 + bgTop);
00845
00846
00847 if (widget) {
00848 widget->setPos(QPointF(bgLeft + dragLeft, panelSize.height() +
00849 bgTop));
00850 }
00851
00852
00853 repositionToolbox();
00854
00855 updateSizeHints();
00856
00857 if (!q->size().isEmpty())
00858 resizeContent(q->size());
00859 }
00860
00861 void ExtenderItemPrivate::sourceAppletRemoved()
00862 {
00863
00864
00865 sourceApplet = 0;
00866 updateToolBox();
00867 }
00868
00869 void ExtenderItemPrivate::resizeContent(const QSizeF &newSize)
00870 {
00871 qreal width = newSize.width();
00872 qreal height = newSize.height();
00873
00874
00875 dragger->resizeFrame(QSizeF(width - bgLeft - bgRight,
00876 iconSize + dragTop + dragBottom));
00877
00878
00879 background->resizeFrame(newSize);
00880
00881
00882 if (widget && widget->isWidget()) {
00883 QSizeF newWidgetSize(width - bgLeft - bgRight - dragLeft - dragRight,
00884 height - dragHandleRect().height() - bgTop - bgBottom -
00885 dragTop - dragBottom);
00886
00887 QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(widget);
00888 graphicsWidget->resize(newWidgetSize);
00889 }
00890
00891
00892 repositionToolbox();
00893
00894 q->update();
00895 }
00896
00897 void ExtenderItemPrivate::actionDestroyed(QObject *o)
00898 {
00899 QAction *action = static_cast<QAction *>(o);
00900 QMutableHashIterator<QString, QAction *> hit(actions);
00901 while (hit.hasNext()) {
00902 if (hit.next().value() == action) {
00903 hit.remove();
00904 break;
00905 }
00906 }
00907
00908 QMutableListIterator<QAction *> lit(actionsInOrder);
00909 while (lit.hasNext()) {
00910 if (lit.next() == action) {
00911 lit.remove();
00912 break;
00913 }
00914 }
00915 }
00916
00917 void ExtenderItemPrivate::updateSizeHints()
00918 {
00919 if (!widget) {
00920 return;
00921 }
00922
00923 qreal marginWidth = bgLeft + bgRight + dragLeft + dragRight;
00924 qreal marginHeight = bgTop + bgBottom + dragTop + dragBottom;
00925
00926 QSizeF min;
00927 QSizeF pref;
00928 QSizeF max;
00929
00930 if (widget->isWidget()) {
00931 QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(widget);
00932 min = graphicsWidget->minimumSize();
00933 pref = graphicsWidget->preferredSize();
00934 max = graphicsWidget->maximumSize();
00935 } else {
00936 min = widget->boundingRect().size();
00937 pref = widget->boundingRect().size();
00938 max = widget->boundingRect().size();
00939 }
00940
00941 if (collapsed) {
00942 q->setPreferredSize(QSizeF(pref.width() + marginWidth,
00943 dragHandleRect().height() + marginHeight));
00944 q->setMinimumSize(QSizeF(min.width() + marginWidth,
00945 dragHandleRect().height() + marginHeight));
00946 q->setMaximumSize(QSizeF(max.width() + marginWidth,
00947 dragHandleRect().height() + marginHeight));
00948 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
00949
00950 if (collapseIcon) {
00951 collapseIcon->setToolTip(i18n("Expand this widget"));
00952 }
00953 } else {
00954 q->setPreferredSize(QSizeF(pref.width() + marginWidth,
00955 pref.height() + dragHandleRect().height() + marginHeight));
00956 q->setMinimumSize(QSizeF(min.width() + marginWidth,
00957 min.height() + dragHandleRect().height() + marginHeight));
00958 q->setMaximumSize(QSizeF(max.width() + marginWidth,
00959 max.height() + dragHandleRect().height() + marginHeight));
00960
00961
00962 if (extender->d->appearance == Extender::TopDownStacked ||
00963 extender->d->appearance == Extender::BottomUpStacked) {
00964
00965 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
00966 } else if (extender->d->appearance == Extender::NoBorders) {
00967
00968 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
00969 }
00970
00971 if (collapseIcon) {
00972 collapseIcon->setToolTip(i18n("Collapse this widget"));
00973 }
00974 }
00975
00976 q->updateGeometry();
00977 }
00978
00979 uint ExtenderItemPrivate::s_maxExtenderItemId = 0;
00980
00981 }
00982
00983 #include "extenderitem.moc"