• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

Plasma

extendergroup.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor,
00017  * Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include "extendergroup.h"
00021 
00022 #include <QAction>
00023 #include <QApplication>
00024 #include <QString>
00025 #include <QList>
00026 #include <QTimer>
00027 #include <QtGui/QGraphicsWidget>
00028 #include <QtGui/QGraphicsLinearLayout>
00029 #include <QtGui/QGraphicsSceneDragDropEvent>
00030 
00031 #include "applet.h"
00032 #include "extender.h"
00033 #include "extenderitem.h"
00034 #include "theme.h"
00035 #include "widgets/scrollwidget.h"
00036 
00037 #include "private/extender_p.h"
00038 #include "private/extendergroup_p.h"
00039 #include "private/extenderitemmimedata_p.h"
00040 
00041 namespace Plasma
00042 {
00043 
00044 ExtenderGroup::ExtenderGroup(Extender *parent, uint groupId)
00045              : ExtenderItem(parent, groupId),
00046                d(new ExtenderGroupPrivate(this))
00047 {
00048     connect(extender(), SIGNAL(itemAttached(Plasma::ExtenderItem*)),
00049             this, SLOT(addItemToGroup(Plasma::ExtenderItem*)));
00050     connect(extender(), SIGNAL(itemDetached(Plasma::ExtenderItem*)),
00051             this, SLOT(removeItemFromGroup(Plasma::ExtenderItem*)));
00052 
00053     //this isn't actually connected to anything, we will just check if it's running or not
00054     d->resizeTimer = new QTimer(this);
00055     d->resizeTimer->setSingleShot(true);
00056 
00057     config().writeEntry("isGroup", true);
00058 
00059     setAcceptDrops(true);
00060 
00061     QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout *>(layout());
00062     d->childsWidget = new QGraphicsWidget(this);
00063     d->childsWidget->installEventFilter(this);
00064     d->layout = new QGraphicsLinearLayout(Qt::Vertical, d->childsWidget);
00065     d->childsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00066     lay->addItem(d->childsWidget);
00067 
00068     QAction *expand = new QAction(this);
00069     expand->setVisible(false);
00070     expand->setToolTip(i18n("Show this group."));
00071     connect(expand, SIGNAL(triggered()), this, SLOT(expandGroup()));
00072     addAction("expand", expand);
00073 
00074     QAction *collapse = new QAction(this);
00075     collapse->setVisible(true);
00076     collapse->setToolTip(i18n("Hide this group."));
00077     connect(collapse, SIGNAL(triggered()), this, SLOT(collapseGroup()));
00078     addAction("collapse", collapse);
00079 
00080     d->themeChanged();
00081 
00082     QString groupName;
00083     foreach (ExtenderItem *item, extender()->attachedItems()) {
00084         groupName = item->config().readEntry("group", "");
00085         if (!groupName.isEmpty() && groupName == name()) {
00086             item->setGroup(this);
00087         }
00088     }
00089 
00090     if (items().isEmpty() && d->autoHide && !isDetached()) {
00091         extender()->itemRemovedEvent(this);
00092         hide();
00093     }
00094 
00095     if (!config().readEntry("groupCollapsed", true)) {
00096         expandGroup();
00097     }
00098 
00099     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
00100             this, SLOT(themeChanged()));
00101 
00102 }
00103 
00104 ExtenderGroup::~ExtenderGroup()
00105 {
00106     delete d;
00107 }
00108 
00109 QList<ExtenderItem*> ExtenderGroup::items() const
00110 {
00111     QList<ExtenderItem*> result;
00112     foreach (ExtenderItem *item, extender()->attachedItems()) {
00113         if (item->group() == this) {
00114             result.append(item);
00115         }
00116     }
00117 
00118     return result;
00119 }
00120 
00121 bool ExtenderGroup::autoHide() const
00122 {
00123     return d->autoHide;
00124 }
00125 
00126 void ExtenderGroup::setAutoHide(bool autoHide)
00127 {
00128     d->autoHide = autoHide;
00129     if (autoHide && items().isEmpty()) {
00130         extender()->itemRemovedEvent(this);
00131         hide();
00132     } else if (!autoHide && !isVisible()) {
00133         extender()->itemAddedEvent(this);
00134         show();
00135     }
00136 }
00137 
00138 bool ExtenderGroup::isAutoCollapse() const
00139 {
00140     return d->autoCollapse;
00141 }
00142 
00143 void ExtenderGroup::setAutoCollapse(bool collapse)
00144 {
00145     d->autoCollapse = collapse;
00146 }
00147 
00148 bool ExtenderGroup::isGroupCollapsed() const
00149 {
00150     return d->collapsed;
00151 }
00152 
00153 void ExtenderGroup::setGroupCollapsed(bool collapsed)
00154 {
00155     if (collapsed) {
00156         collapseGroup();
00157     } else {
00158         expandGroup();
00159     }
00160 }
00161 
00162 void ExtenderGroup::expandGroup()
00163 {
00164     if (d->autoCollapse) {
00165         setCollapsed(false);
00166     }
00167     if (d->collapsed == false) {
00168         return;
00169     }
00170 
00171     d->collapsed = false;
00172     config().writeEntry("groupCollapsed", d->collapsed);
00173     action("collapse")->setVisible(true);
00174     action("expand")->setVisible(false);
00175 
00176     d->childsWidget->show();
00177     static_cast<QGraphicsLinearLayout *>(layout())->addItem(d->childsWidget);
00178     updateGeometry();
00179 
00180     foreach (ExtenderItem *item, extender()->attachedItems()) {
00181         if (item->group() == this) {
00182             item->show();
00183             extender()->itemAddedEvent(item);
00184         }
00185     }
00186 
00187     //extender()->resize(extender()->effectiveSizeHint(Qt::PreferredSize));
00188 }
00189 
00190 void ExtenderGroup::collapseGroup()
00191 {
00192     if (d->autoCollapse) {
00193         setCollapsed(true);
00194     }
00195     if (d->collapsed == true) {
00196         return;
00197     }
00198 
00199     d->collapsed = true;
00200     config().writeEntry("groupCollapsed", d->collapsed);
00201     action("collapse")->setVisible(false);
00202     action("expand")->setVisible(true);
00203 
00204     d->childsWidget->hide();
00205     static_cast<QGraphicsLinearLayout *>(layout())->removeItem(d->childsWidget);
00206     updateGeometry();
00207 
00208     foreach (ExtenderItem *item, extender()->attachedItems()) {
00209         if (item != this && item->group() == this) {
00210             item->hide();
00211             extender()->itemRemovedEvent(item);
00212         }
00213     }
00214 }
00215 
00216 void ExtenderGroup::resizeEvent(QGraphicsSceneResizeEvent *event)
00217 {
00218     ExtenderItem::resizeEvent(event);
00219 }
00220 
00221 bool ExtenderGroup::eventFilter(QObject *watched, QEvent *event)
00222 {
00223     if (watched == d->childsWidget && event->type() == QEvent::GraphicsSceneResize) {
00224         static_cast<QGraphicsLayoutItem *>(extender()->d->scrollWidget)->updateGeometry();
00225         if (!d->resizeTimer->isActive()) {
00226             static_cast<QGraphicsLayoutItem *>(extender())->updateGeometry();
00227             extender()->d->adjustSize();
00228             d->resizeTimer->start(0);
00229         }
00230     }
00231 
00232     return ExtenderItem::eventFilter(watched, event);
00233 }
00234 
00235 void ExtenderGroup::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
00236 {
00237     if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
00238         event->accept();
00239 
00240         dragMoveEvent(event);
00241     }
00242 }
00243 
00244 void ExtenderGroup::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
00245 {
00246     if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
00247         const ExtenderItemMimeData *mimeData =
00248             qobject_cast<const ExtenderItemMimeData*>(event->mimeData());
00249 
00250         if (mimeData) {
00251             QPointF pos(event->pos());
00252             if (d->spacerWidget && d->spacerWidget->geometry().contains(pos)) {
00253                 return;
00254             }
00255 
00256             //Make sure we remove any spacer that might already be in the layout.
00257             if (d->spacerWidget) {
00258                 d->layout->removeItem(d->spacerWidget);
00259             }
00260 
00261             int insertIndex = d->insertIndexFromPos(pos);
00262 
00263             //Create a widget that functions as spacer, and add that to the layout.
00264             if (!d->spacerWidget) {
00265                 Spacer *widget = new Spacer(this);
00266                 ExtenderItem *item = mimeData->extenderItem();
00267                 qreal left, top, right, bottom;
00268                 extender()->d->background->getMargins(left, top, right, bottom);
00269                 widget->setMargins(left, 4, right, 4);
00270 
00271                 widget->setMinimumSize(item->minimumSize());
00272                 widget->setPreferredSize(item->preferredSize());
00273                 widget->setMaximumSize(item->maximumSize());
00274                 widget->setSizePolicy(item->sizePolicy());
00275                 d->spacerWidget = widget;
00276             }
00277             d->layout->insertItem(insertIndex, d->spacerWidget);
00278 
00279             extender()->d->setPositionFromDragPosition(event->scenePos());
00280         }
00281     }
00282 }
00283 
00284 void ExtenderGroup::dropEvent(QGraphicsSceneDragDropEvent *event)
00285 {
00286     if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
00287         const ExtenderItemMimeData *mimeData =
00288             qobject_cast<const ExtenderItemMimeData*>(event->mimeData());
00289 
00290         if (mimeData) {
00291             mimeData->extenderItem()->setGroup(this, event->pos());
00292             QApplication::restoreOverrideCursor();
00293             d->layout->removeItem(d->spacerWidget);
00294             d->spacerWidget->deleteLater();
00295             d->spacerWidget = 0;
00296         }
00297     }
00298 }
00299 
00300 void ExtenderGroup::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
00301 {
00302     if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
00303         if (d->spacerWidget) {
00304             d->layout->removeItem(d->spacerWidget);
00305             d->spacerWidget->deleteLater();
00306             d->spacerWidget = 0;
00307         }
00308     }
00309 }
00310 
00311 ExtenderGroupPrivate::ExtenderGroupPrivate(ExtenderGroup *group)
00312     : q(group),
00313       spacerWidget(0),
00314       svg(new Svg(group)),
00315       collapsed(false),
00316       autoHide(true),
00317       autoCollapse(false)
00318 {
00319 }
00320 
00321 ExtenderGroupPrivate::~ExtenderGroupPrivate()
00322 {
00323 }
00324 
00325 void ExtenderGroupPrivate::addItemToGroup(Plasma::ExtenderItem *item, const QPointF &pos)
00326 {
00327     if (item->group() == q) {
00328         item->setParentItem(childsWidget);
00329         item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00330         layout->insertItem(insertIndexFromPos(pos), item);
00331         layout->activate();
00332 
00333         if (!q->isVisible() && !q->items().isEmpty()) {
00334             q->extender()->itemAddedEvent(q);
00335             q->show();
00336         }
00337         childsWidget->setVisible(!q->isGroupCollapsed());
00338 
00339         if (!q->isGroupCollapsed()) {
00340             layout->updateGeometry();
00341             static_cast<QGraphicsLayoutItem *>(q)->updateGeometry();
00342             static_cast<QGraphicsLayoutItem *>(childsWidget)->updateGeometry();
00343             static_cast<QGraphicsLayoutItem *>(q->extender()->d->scrollWidget)->updateGeometry();
00344         }
00345 
00346         q->extender()->d->adjustSize();
00347     }
00348 }
00349 
00350 void ExtenderGroupPrivate::removeItemFromGroup(Plasma::ExtenderItem *item)
00351 {
00352     if (item->group() == q) {
00353         if (q->items().isEmpty() && autoHide && !q->isDetached()) {
00354             q->extender()->itemRemovedEvent(q);
00355             q->hide();
00356         }
00357         layout->removeItem(item);
00358         item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00359 
00360         layout->updateGeometry();
00361         static_cast<QGraphicsLayoutItem *>(q)->updateGeometry();
00362         static_cast<QGraphicsLayoutItem *>(childsWidget)->updateGeometry();
00363         static_cast<QGraphicsLayoutItem *>(q->extender()->d->scrollWidget)->updateGeometry();
00364 
00365         q->extender()->d->adjustSize();
00366     }
00367 }
00368 
00369 void ExtenderGroupPrivate::themeChanged()
00370 {
00371     svg->setImagePath("widgets/configuration-icons");
00372     svg->resize();
00373 
00374     q->action("expand")->setIcon(QIcon(svg->pixmap("restore")));
00375     q->action("collapse")->setIcon(QIcon(svg->pixmap("collapse")));
00376 }
00377 
00378 int ExtenderGroupPrivate::insertIndexFromPos(const QPointF &pos) const
00379 {
00380     int insertIndex = -1;
00381 
00382     //XXX: duplicated from panel
00383     if (pos != QPointF(-1, -1)) {
00384         for (int i = 0; i < layout->count(); ++i) {
00385             QRectF siblingGeometry = layout->itemAt(i)->geometry();
00386             qreal middle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0;
00387             if (pos.y() < middle) {
00388                 insertIndex = i;
00389                 break;
00390             } else if (pos.y() <= siblingGeometry.bottom()) {
00391                 insertIndex = i + 1;
00392                 break;
00393             }
00394         }
00395     }
00396 
00397     return insertIndex;
00398 }
00399 
00400 } // Plasma namespace
00401 
00402 #include "extendergroup.moc"

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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