Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
kdebase4-workspace
plasma-libs.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File plasma-libs.diff of Package kdebase4-workspace
Patch-rediff: rediff-plasma.sh --- plasma/servicetypes/plasma-dataengine.desktop +++ plasma/servicetypes/plasma-dataengine.desktop @@ -36,7 +36,7 @@ Comment[ml]=പ്ലാസ്മാ ഡേറ്റാ എഞ്ചിന് Comment[mr]=प्लाज्मा माहिती इंजिन Comment[nb]=Plasma datamotor -Comment[nds]=Plasma-Hanteerkarn +Comment[nds]=Plasma-Datenkarn Comment[ne]=प्लाज्मा डेटा इन्जिन Comment[nl]=Plasma-gegevensengine Comment[nn]=Plasma-datamotor @@ -48,8 +48,8 @@ Comment[ru]=Движок данных Plasma Comment[se]=Plasma-dáhtámohtor Comment[sl]=Podatkovni pogon za Plasmo -Comment[sr]=Плазмин мотор -Comment[sr@latin]=Plasmin motor +Comment[sr]=Плазма датомотор +Comment[sr@latin]=Plasma datomotor Comment[sv]=Plasma datagränssnitt Comment[th]=กลไกข้อมูลของพลาสมา Comment[tr]=Plasma Veri Motoru --- plasma/servicetypes/plasma-wallpaper.desktop +++ plasma/servicetypes/plasma-wallpaper.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=Plasma/Wallpaper + +Comment=Plasma wallpaper + +[PropertyDef::X-Plasma-FormFactors] +Type=QStringList + --- plasma/servicetypes/plasma-runner.desktop +++ plasma/servicetypes/plasma-runner.desktop @@ -45,7 +45,7 @@ Comment[pa]=ਕੇ-ਰਨਰ ਪਲੱਗਇਨ Comment[pl]=Wtyczki KRunnera Comment[pt]='Plugin' do KRunner -Comment[pt_BR]=Plugin do KRunner +Comment[pt_BR]=Plug-in do KRunner Comment[ro]=Modlú KRunner Comment[ru]=Модуль KRunner Comment[se]=KRunner-lassemodula --- plasma/servicetypes/plasma-animator.desktop +++ plasma/servicetypes/plasma-animator.desktop @@ -47,8 +47,8 @@ Comment[ru]=Движок анимации Plasma Comment[se]=Plasma-animerenmohtor Comment[sl]=Animacijski pogon za Plasmo -Comment[sr]=Плазмин мотор за анимације -Comment[sr@latin]=Plasmin motor za animacije +Comment[sr]=Плазма мотор анимација +Comment[sr@latin]=Plasma motor animacija Comment[sv]=Animeringsgränssnitt i Plasma Comment[th]=กลไกการแสดงการเคลื่อนไหลของพลาสมา Comment[tr]=Plasma Canlandırma Motoru --- plasma/applet_p.h +++ plasma/applet_p.h @@ -30,6 +30,7 @@ class PanelSvg; class AppletScript; class ShadowItem; +class Wallpaper; class AppletOverlayWidget : public QGraphicsWidget { @@ -63,6 +64,7 @@ void resetConfigurationObject(); void appletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim); void selectItemToDestroy(); + void updateRect(const QRectF& rect); void setFocus(); void cleanUpAndDelete(); --- plasma/corona.cpp +++ plasma/corona.cpp @@ -119,7 +119,9 @@ if (pluginName.isEmpty()) { // default to the desktop containment - pluginName = "desktop"; + KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc"); + KConfigGroup group = KConfigGroup(defaultconfig, "Defaults"); + pluginName = group.readEntry("containment", "desktop"); } if (pluginName != "null") { @@ -134,6 +136,10 @@ delete applet; containment = new Containment(0, 0, id); + if (pluginName == "null") { + containment->setDrawWallpaper(false); + } + // we want to provide something and don't care about the failure to launch containment->setFailedToLaunch(false); containment->setFormFactor(Plasma::Planar); @@ -314,6 +320,11 @@ return 0; } +bool Corona::loadDefaultApplets(Plasma::Containment*, bool) +{ + return true; +} + QList<Containment*> Corona::containments() const { return d->containments; --- plasma/plasma.h +++ plasma/plasma.h @@ -25,6 +25,8 @@ #include <plasma/plasma_export.h> +class QGraphicsView; + /** * Namespace for everything in libplasma */ @@ -193,6 +195,22 @@ **/ PLASMA_EXPORT Direction locationToDirection(Location location); +/** + * Reccomended position for a popup window like a menu or a tooltip + * given its size + * @param s size of the popup + * @returns reccomended position + */ +PLASMA_EXPORT QPoint popupPosition(const QGraphicsItem *item, const QSize &s); + +/** + * Returns the most appropriate QGraphicsView for the item. + * + * @arg item the QGraphicsItem to locate a view for + * @return pointer to a view, or 0 if none was found + */ +PLASMA_EXPORT QGraphicsView *viewFor(const QGraphicsItem *item); + } // Plasma namespace Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::Constraints) --- plasma/includes/ToolTipManager +++ plasma/includes/ToolTipManager @@ -0,0 +1 @@ +#include "../../plasma/tooltipmanager.h" --- plasma/includes/Wallpaper +++ plasma/includes/Wallpaper @@ -0,0 +1 @@ +#include "../../plasma/wallpaper.h" --- plasma/includes/ScrollBar +++ plasma/includes/ScrollBar @@ -0,0 +1 @@ +#include "../../plasma/widgets/scrollbar.h" --- plasma/tooltipmanager.cpp +++ plasma/tooltipmanager.cpp @@ -0,0 +1,424 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright 2008 by Aaron Seigo <aseigo@kde.org> + * Copyright 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "tooltipmanager.h" + +//Qt +#include <QLabel> +#include <QTimer> +#include <QGridLayout> +#include <QGraphicsView> +#include <QDesktopWidget> + +//KDE +#include <KWindowSystem> + +//X11 +#ifdef Q_WS_X11 +#include <QtGui/QX11Info> +#include <X11/Xlib.h> +#include <fixx11h.h> +#endif + + +//Plasma +#include <applet.h> +#include <containment.h> +#include <panelsvg.h> +#include <theme.h> +#include <view.h> +#include <private/tooltip_p.h> + +namespace Plasma +{ + +class ToolTipManagerPrivate +{ +public : + ToolTipManagerPrivate() + : currentWidget(0), + showTimer(0), + hideTimer(0), + isShown(false), + delayedHide(false) + { + + } + ~ToolTipManagerPrivate() + { + + } + + void showToolTip(); + void resetShownState(); + + /** + * called when the theme of plasma has change + */ + void themeUpdated(); + /** + * called when a widget inside the tooltip manager is deleted + */ + void onWidgetDestroyed(QObject * object); + + + QGraphicsWidget *currentWidget; + QTimer *showTimer; + QTimer *hideTimer; + QHash<QGraphicsWidget *, ToolTip *> tooltips; + bool isShown : 1; + bool delayedHide : 1; +}; + +//TOOLTIP IMPLEMENTATION +class ToolTipManagerSingleton +{ + public: + ToolTipManagerSingleton() + { + } + ToolTipManager self; +}; +K_GLOBAL_STATIC( ToolTipManagerSingleton, privateInstance ) + +ToolTipManager *ToolTipManager::self() +{ + return &privateInstance->self; +} + +ToolTipManager::ToolTipContent::ToolTipContent() + : windowToPreview(0) +{ +} + +bool ToolTipManager::ToolTipContent::isEmpty() const +{ + return mainText.isEmpty() && subText.isEmpty() && image.isNull() && windowToPreview == 0; +} + +ToolTipManager::ToolTipManager(QObject* parent) + : QObject(parent), + d(new ToolTipManagerPrivate) +{ + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeUpdated())); + d->themeUpdated(); + + d->showTimer = new QTimer(this); + d->showTimer->setSingleShot(true); + d->hideTimer = new QTimer(this); + d->hideTimer->setSingleShot(true); + + connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip())); + connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState())); +} + +ToolTipManager::~ToolTipManager() +{ + delete d; +} + +void ToolTipManager::showToolTip(QGraphicsWidget *widget) +{ + if (!d->tooltips.contains(widget)) { + return; + } + + if (d->currentWidget) { + hideToolTip(d->currentWidget); + } + + d->hideTimer->stop(); + d->delayedHide = false; + d->showTimer->stop(); + d->currentWidget = widget; + + if (d->isShown) { + // small delay to prevent unnecessary showing when the mouse is moving quickly across items + // which can be too much for less powerful CPUs to keep up with + d->showTimer->start(200); + } else { + d->showTimer->start(500); + } +} + +bool ToolTipManager::isWidgetToolTipDisplayed(QGraphicsWidget *widget) +{ + ToolTip *tooltip = d->tooltips.value(widget); + if (tooltip) { + return tooltip->isVisible(); + } else { + return false; + } +} + +void ToolTipManager::delayedHideToolTip() +{ + d->showTimer->stop(); // stop the timer to show the tooltip + d->delayedHide = true; + d->hideTimer->start(250); +} + +void ToolTipManager::hideToolTip(QGraphicsWidget *widget) +{ + ToolTip *tooltip = d->tooltips.value(widget); + if (tooltip) { + d->showTimer->stop(); // stop the timer to show the tooltip + d->delayedHide = false; + d->currentWidget = 0; + tooltip->hide(); + } +} + +void ToolTipManager::registerWidget(QGraphicsWidget *widget) +{ + if (d->tooltips.contains(widget)) { + return; + } + + //the tooltip is not registered we add it in our map of tooltips + d->tooltips.insert(widget, 0); + widget->installEventFilter(this); + //connect to object destruction + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onWidgetDestroyed(QObject*))); +} + +void ToolTipManager::unregisterWidget(QGraphicsWidget *widget) +{ + if (!d->tooltips.contains(widget)) { + return; + } + + widget->removeEventFilter(this); + ToolTip *tooltip = d->tooltips.take(widget); + if (tooltip) { + tooltip->deleteLater(); + } +} + +void ToolTipManager::setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data) +{ + registerWidget(widget); + + ToolTip *tooltip = d->tooltips.value(widget); + + if (data.isEmpty()) { + if (tooltip) { + tooltip->deleteLater(); + } + d->tooltips.insert(widget, 0); + return; + } + + if (!tooltip) { + tooltip = new ToolTip(widget); + d->tooltips.insert(widget, tooltip); + } + + tooltip->setContent(data); + tooltip->updateTheme(); +} + +void ToolTipManager::clearToolTipContent(QGraphicsWidget *widget) +{ + ToolTipContent t; + setToolTipContent(widget, t); +} + +bool ToolTipManager::widgetHasToolTip(QGraphicsWidget *widget) const +{ + return d->tooltips.contains(widget); +} + +void ToolTipManager::setToolTipActivated(QGraphicsWidget *widget, bool enable) +{ + registerWidget(widget); + + ToolTip *tooltip = d->tooltips.value(widget); + tooltip->setActivated(enable); + if (!enable) { + hideToolTip(widget); + } else if (d->currentWidget) { + showToolTip(widget); + } +} + +bool ToolTipManager::isToolTipActivated(QGraphicsWidget *widget) +{ + if (!d->tooltips.contains(widget)) { + return false; + } + + ToolTip *tooltip = d->tooltips.value(widget); + return tooltip->isActivated(); +} + +void ToolTipManagerPrivate::themeUpdated() +{ + QHashIterator<QGraphicsWidget*, ToolTip *> iterator(tooltips); + while (iterator.hasNext()) { + iterator.next(); + if (iterator.value()) { + iterator.value()->updateTheme(); + } + } +} + +void ToolTipManagerPrivate::onWidgetDestroyed(QObject *object) +{ + if (!object) { + return; + } + + // we do a static_cast here since it really isn't a QGraphicsWidget by this + // point anymore since we are in the QObject dtor. we don't actually + // try and do anything with it, we just need the value of the pointer + // so this unsafe looking code is actually just fine. + // + // NOTE: DO NOT USE THE w VARIABLE FOR ANYTHING OTHER THAN COMPARING + // THE ADDRESS! ACTUALLY USING THE OBJECT WILL RESULT IN A CRASH!!! + QGraphicsWidget *w = static_cast<QGraphicsWidget*>(object); + + if (currentWidget == w) { + currentWidget = 0; + showTimer->stop(); // stop the timer to show the tooltip + delayedHide = false; + } + + QMutableHashIterator<QGraphicsWidget*, ToolTip *> iterator(tooltips); + while (iterator.hasNext()) { + iterator.next(); + //kDebug() << (int)iterator.key() << (int)w; + if (iterator.key() == w) { + ToolTip *tooltip = iterator.value(); + iterator.remove(); + if (tooltip) { + //kDebug() << "deleting the tooltip!"; + tooltip->hide(); + tooltip->deleteLater(); + } + return; + } + } +} + +void ToolTipManagerPrivate::resetShownState() +{ + if (currentWidget) { + ToolTip * tooltip = tooltips.value(currentWidget); + if (tooltip && (!tooltip->isVisible() || delayedHide)) { + //One might have moused out and back in again + delayedHide = false; + isShown = false; + tooltip->hide(); + currentWidget = 0; + } + } +} + +void ToolTipManagerPrivate::showToolTip() +{ + if (!currentWidget) { + return; + } + + ToolTip *tooltip = tooltips.value(currentWidget); + bool justCreated = false; + + if (!tooltip) { + // give the object a chance for delayed loading of the tip + QMetaObject::invokeMethod(currentWidget, "toolTipAboutToShow"); + tooltip = tooltips.value(currentWidget); + if (tooltip) { + justCreated = true; + } else { + currentWidget = 0; + return; + } + } + + if (tooltip->isActivated()) { + tooltip->setVisible(false); + //kDebug() << "about to show" << justCreated; + tooltip->prepareShowing(!justCreated); + tooltip->move(popupPosition(currentWidget, tooltip->size())); + isShown = true; //ToolTip is visible + tooltip->setVisible(true); + } +} + +bool ToolTipManager::eventFilter(QObject *watched, QEvent *event) +{ + QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched); + if (!widget) { + return QObject::eventFilter(watched, event); + } + + switch (event->type()) { + case QEvent::GraphicsSceneHoverMove: + // If the tooltip isn't visible, run through showing the tooltip again + // so that it only becomes visible after a stationary hover + if (Plasma::ToolTipManager::self()->isWidgetToolTipDisplayed(widget)) { + break; + } + + // Don't restart the show timer on a mouse move event if there hasn't + // been an enter event or the current widget has been cleared by a click + // or wheel event. + if (!d->currentWidget) { + break; + } + + case QEvent::GraphicsSceneHoverEnter: + { + // Check that there is a tooltip to show + if (!widgetHasToolTip(widget)) { + break; + } + + // If the mouse is in the widget's area at the time that it is being + // created the widget can receive a hover event before it is fully + // initialized, in which case view() will return 0. + QGraphicsView *parentView = viewFor(widget); + if (parentView) { + showToolTip(widget); + } + + break; + } + + case QEvent::GraphicsSceneHoverLeave: + delayedHideToolTip(); + break; + + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneWheel: + hideToolTip(widget); + + default: + break; + } + + return QObject::eventFilter(watched,event); +} + +} // Plasma namespace + +#include "tooltipmanager.moc" --- plasma/wallpaper.cpp +++ plasma/wallpaper.cpp @@ -0,0 +1,227 @@ +/* + * Copyright 2008 by Aaron Seigo <aseigo@kde.org> + * Copyright 2008 by Petri Damsten <damu@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "wallpaper.h" + +#include <KServiceTypeTrader> +#include <KDebug> + +#include <version.h> + +namespace Plasma +{ + +class WallpaperPrivate +{ +public: + WallpaperPrivate(KService::Ptr service, Wallpaper *wallpaper) : + q(wallpaper), + wallpaperDescription(service) + { + }; + + ~WallpaperPrivate() + { + }; + + Wallpaper *q; + KPluginInfo wallpaperDescription; + QRectF boundingRect; + KServiceAction mode; +}; + +Wallpaper::Wallpaper(QObject* parentObject, const QVariantList& args) + : d(new WallpaperPrivate(KService::serviceByStorageId(args.count() > 0 ? + args[0].toString() : QString()), this)) +{ + // now remove first item since those are managed by Wallpaper and subclasses shouldn't + // need to worry about them. yes, it violates the constness of this var, but it lets us add + // or remove items later while applets can just pretend that their args always start at 0 + QVariantList &mutableArgs = const_cast<QVariantList&>(args); + if (!mutableArgs.isEmpty()) { + mutableArgs.removeFirst(); + } + setParent(parentObject); +} + +Wallpaper::~Wallpaper() +{ + delete d; +} + +KPluginInfo::List Wallpaper::listWallpaperInfo(const QString &formFactor) +{ + QString constraint; + + if (!formFactor.isEmpty()) { + constraint.append("[X-Plasma-FormFactors] ~~ '").append(formFactor).append("'"); + } + + KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint); + return KPluginInfo::fromServices(offers); +} + +Wallpaper* Wallpaper::load(const QString& wallpaperName, const QVariantList& args) +{ + if (wallpaperName.isEmpty()) { + return 0; + } + + QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(wallpaperName); + KService::List offers = KServiceTypeTrader::self()->query("Plasma/Wallpaper", constraint); + + if (offers.isEmpty()) { + kDebug() << "offers is empty for " << wallpaperName; + return 0; + } + + KService::Ptr offer = offers.first(); + KPluginLoader plugin(*offer); + + if (!Plasma::isPluginVersionCompatible(plugin.pluginVersion())) { + return 0; + } + + QVariantList allArgs; + allArgs << offer->storageId() << args; + QString error; + Wallpaper* wallpaper = offer->createInstance<Plasma::Wallpaper>(0, allArgs, &error); + + if (!wallpaper) { + kDebug() << "Couldn't load wallpaper \"" << wallpaperName << "\"! reason given: " << error; + } + return wallpaper; +} + +Wallpaper* Wallpaper::load(const KPluginInfo& info, const QVariantList& args) +{ + if (!info.isValid()) { + return 0; + } + return load(info.pluginName(), args); +} + +QString Wallpaper::name() const +{ + if (!d->wallpaperDescription.isValid()) { + return i18n("Unknown Wallpaper"); + } + + return d->wallpaperDescription.name(); +} + +QString Wallpaper::icon() const +{ + if (!d->wallpaperDescription.isValid()) { + return QString(); + } + + return d->wallpaperDescription.icon(); +} + +QString Wallpaper::pluginName() const +{ + if (!d->wallpaperDescription.isValid()) { + return QString(); + } + + return d->wallpaperDescription.pluginName(); +} + +KServiceAction Wallpaper::renderingMode() const +{ + return d->mode; +} + +QList<KServiceAction> Wallpaper::listRenderingModes() const +{ + if (!d->wallpaperDescription.isValid()) { + return QList<KServiceAction>(); + } + + return d->wallpaperDescription.service()->actions(); +} + +QRectF Wallpaper::boundingRect() const +{ + return d->boundingRect; +} + +void Wallpaper::setBoundingRect(const QRectF& boundingRect) +{ + d->boundingRect = boundingRect; +} + +void Wallpaper::restore(const KConfigGroup &config, const QString &mode) +{ + d->mode = KServiceAction(); + if (!mode.isEmpty()) { + QList<KServiceAction> modes = listRenderingModes(); + + foreach (const KServiceAction &action, modes) { + if (action.name() == mode) { + d->mode = action; + break; + } + } + } + + init(config); +} + +void Wallpaper::init(const KConfigGroup &config) +{ + Q_UNUSED(config); +} + +void Wallpaper::save(KConfigGroup &config) +{ + Q_UNUSED(config); +} + +QWidget *Wallpaper::createConfigurationInterface(QWidget *parent) +{ + Q_UNUSED(parent); + return 0; +} + +void Wallpaper::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +void Wallpaper::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +void Wallpaper::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +void Wallpaper::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + Q_UNUSED(event) +} + +} // Plasma namespace + +#include "wallpaper.moc" --- plasma/applet.h +++ plasma/applet.h @@ -513,6 +513,11 @@ void geometryChanged(); /** + * Emitted by Applet subclasses when they change a sizeHint and wants to announce the change + */ + void sizeHintChanged(Qt::SizeHint which); + + /** * Emitted when an applet has changed values in its configuration * and wishes for them to be saved at the next save point. As this implies * disk activity, this signal should be used with care. @@ -750,6 +755,7 @@ Q_PRIVATE_SLOT(d, void themeChanged()) Q_PRIVATE_SLOT(d, void appletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim)) Q_PRIVATE_SLOT(d, void selectItemToDestroy()) + Q_PRIVATE_SLOT(d, void updateRect(const QRectF& rect)) /** * Reimplemented from QGraphicsItem --- plasma/plasma.cpp +++ plasma/plasma.cpp @@ -17,8 +17,15 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include <plasma.h> +#include <plasma/plasma.h> +#include <QDesktopWidget> +#include <QGraphicsScene> +#include <QGraphicsView> + +#include <plasma/containment.h> +#include <plasma/view.h> + namespace Plasma { @@ -62,4 +69,78 @@ return Down; } +QPoint popupPosition(const QGraphicsItem * item, const QSize &s) +{ + QGraphicsView *v = viewFor(item); + + if (!v) { + return QPoint(0,0); + } + + QPoint pos = v->mapFromScene(item->scenePos()); + pos = v->mapToGlobal(pos); + //kDebug() << "==> position is" << item->scenePos() << v->mapFromScene(item->scenePos()) << pos; + Plasma::View *pv = dynamic_cast<Plasma::View *>(v); + + Plasma::Location loc = Floating; + if (pv) { + loc = pv->containment()->location(); + } + + switch (loc) { + case BottomEdge: + pos = QPoint(pos.x(), pos.y() - s.height()); + break; + case TopEdge: + pos = QPoint(pos.x(), pos.y() + (int)item->boundingRect().size().height()); + break; + case LeftEdge: + pos = QPoint(pos.x() + (int)item->boundingRect().size().width(), pos.y()); + break; + case RightEdge: + pos = QPoint(pos.x() - s.width(), pos.y()); + break; + default: + if (pos.y() - s.height() > 0) { + pos = QPoint(pos.x(), pos.y() - s.height()); + } else { + pos = QPoint(pos.x(), pos.y() + (int)item->boundingRect().size().height()); + } + } + + //are we out of screen? + QRect screenRect = QApplication::desktop()->screenGeometry(pv ? pv->containment()->screen() : -1); + //kDebug() << "==> rect for" << (pv ? pv->containment()->screen() : -1) << "is" << screenRect; + + if (pos.rx() + s.width() > screenRect.right()) { + pos.rx() -= ((pos.rx() + s.width()) - screenRect.right()); + } + + if (pos.ry() + s.height() > screenRect.bottom()) { + pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom()); + } + + pos.rx() = qMax(0, pos.rx()); + return pos; +} + +QGraphicsView* viewFor(const QGraphicsItem * item) +{ + if (!item->scene()) { + return 0; + } + + QGraphicsView *found = 0; + foreach (QGraphicsView *view, item->scene()->views()) { + if (view->sceneRect().intersects(item->sceneBoundingRect()) || + view->sceneRect().contains(item->scenePos())) { + if (!found || view->isActiveWindow()) { + found = view; + } + } + } + + return found; +} + } // Plasma namespace --- plasma/panelsvg.h +++ plasma/panelsvg.h @@ -119,6 +119,11 @@ void getMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const; /** + * @return the rectangle of the center element, taking the margins into account. + */ + QRectF contentsRect() const; + + /** * Sets the prefix (@see setElementPrefix) to 'north', 'south', 'west' and 'east' * when the location is TopEdge, BottomEdge, LeftEdge and RightEdge, * respectively. Clears the prefix in other cases. @@ -195,6 +200,11 @@ */ Q_INVOKABLE void paintPanel(QPainter* painter, const QRectF& rect, const QPointF& pos = QPointF(0, 0)); + /** + * a convenience method... + */ + Q_INVOKABLE void paintPanel(QPainter* painter, const QPointF& pos = QPointF(0, 0)); + private: PanelSvgPrivate * const d; --- plasma/widgets/scrollbar.cpp +++ plasma/widgets/scrollbar.cpp @@ -0,0 +1,104 @@ +/* + * Copyright © 2008 Fredrik Höglund <fredrik@kde.org> + * Copyright © 2008 Marco Martin <notmart@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "scrollbar.h" + +// #include <plasma/style.h> + +namespace Plasma +{ + +ScrollBar::ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent) + : QGraphicsProxyWidget(parent) +{ + QScrollBar *scrollbar = new QScrollBar(orientation); + scrollbar->setAttribute(Qt::WA_NoSystemBackground); + setWidget(scrollbar); +/* Plasma::Style *style = new Plasma::Style(); + scrollbar->setStyle(style); */ +} + +ScrollBar::~ScrollBar() +{ +} + +void ScrollBar::setRange(int min, int max) +{ + static_cast<QScrollBar*>(widget())->setRange(min, max); +} + +void ScrollBar::setSingleStep(int val) +{ + static_cast<QScrollBar*>(widget())->setSingleStep(val); +} + +int ScrollBar::singleStep() +{ + return static_cast<QScrollBar*>(widget())->singleStep(); +} + +void ScrollBar::setPageStep(int val) +{ + static_cast<QScrollBar*>(widget())->setPageStep(val); +} + +int ScrollBar::pageStep() +{ + return static_cast<QScrollBar*>(widget())->pageStep(); +} + +void ScrollBar::setValue(int val) +{ + static_cast<QScrollBar*>(widget())->setValue(val); +} + +int ScrollBar::value() const +{ + return static_cast<QScrollBar*>(widget())->value(); +} + +int ScrollBar::minimum() const +{ + return static_cast<QScrollBar*>(widget())->minimum(); +} + +int ScrollBar::maximum() const +{ + return static_cast<QScrollBar*>(widget())->maximum(); +} + +void ScrollBar::setStyleSheet(const QString &stylesheet) +{ + widget()->setStyleSheet(stylesheet); +} + +QString ScrollBar::styleSheet() +{ + return widget()->styleSheet(); +} + +QScrollBar *ScrollBar::nativeWidget() const +{ + return static_cast<QScrollBar*>(widget()); +} + +} + +#include <scrollbar.moc> --- plasma/widgets/scrollbar.h +++ plasma/widgets/scrollbar.h @@ -0,0 +1,124 @@ +/* + * Copyright © 2008 Fredrik Höglund <fredrik@kde.org> + * Copyright © 2008 Marco Martin <notmart@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_SCROLLBAR_H +#define PLASMA_SCROLLBAR_H + +#include <QtGui/QScrollBar> +#include <QtGui/QGraphicsProxyWidget> + +#include <plasma/plasma_export.h> + +namespace Plasma +{ + +/** + * @class ScrollBar plasma/widgets/scrollbar.h <Plasma/Widgets/ScrollBar> + * + * @short Provides a plasma-themed QScrollBar. + */ +class PLASMA_EXPORT ScrollBar : public QGraphicsProxyWidget +{ + Q_OBJECT + + Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep) + Q_PROPERTY(int pageStep READ pageStep WRITE setPageStep) + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(int minimum READ minimum) + Q_PROPERTY(int maximum READ maximum) + Q_PROPERTY(QString stylesheet READ styleSheet WRITE setStyleSheet) + Q_PROPERTY(QScrollBar* nativeWidget READ nativeWidget) + +public: + explicit ScrollBar(Qt::Orientation orientation, QGraphicsWidget *parent); + ~ScrollBar(); + + /** + * Sets the scrollbar minimum and maximum values + * @arg min minimum value + * @arg max maximum value + */ + void setRange(int min, int max); + + /** + * Sets the amount of the single step + * i.e how much the slider will move when the user press an arrow button + * @arg val + */ + void setSingleStep(int val); + + /** + * @return the amount of the single step + */ + int singleStep(); + + /** + * Sets the amount the slider will scroll when the user press page up or page down + * @arg val + */ + void setPageStep(int val); + + /** + * @return the amount of the page step + */ + int pageStep(); + + /** + * Sets the current value for the ScrollBar + * @arg value must be minimum() <= value <= maximum() + */ + void setValue(int val); + + /** + * @return the current scrollbar value + */ + int value() const; + + /** + * @return the minimum value bound of this ScrollBar + */ + int minimum() const; + + /** + * @return the maximum value bound of this ScrollBar + */ + int maximum() const; + + /** + * Sets the stylesheet used to control the visual display of this ScrollBar + * + * @arg stylesheet a CSS string + */ + void setStyleSheet(const QString &stylesheet); + + /** + * @return the stylesheet currently used with this widget + */ + QString styleSheet(); + + /** + * @return the native widget wrapped by this ScrollBar + */ + QScrollBar *nativeWidget() const; +}; + +} + +#endif --- plasma/applet.cpp +++ plasma/applet.cpp @@ -76,6 +76,7 @@ #include "plasma/view.h" #include "plasma/widgets/label.h" #include "plasma/widgets/pushbutton.h" +#include "wallpaper.h" //#define DYNAMIC_SHADOWS namespace Plasma @@ -351,6 +352,11 @@ q->destroy(); } +void AppletPrivate::updateRect(const QRectF& rect) +{ + q->update(rect); +} + void AppletPrivate::cleanUpAndDelete() { //kDebug() << "???????????????? DESTROYING APPLET" << name() << " ???????????????????????????"; @@ -411,13 +417,23 @@ return 0; } + QGraphicsView *found = 0; + QGraphicsView *possibleFind = 0; + //kDebug() << "looking through" << scene()->views().count() << "views"; foreach (QGraphicsView *view, scene()->views()) { + //kDebug() << " checking" << view << view->sceneRect() << "against" << sceneBoundingRect() << scenePos(); if (view->sceneRect().intersects(sceneBoundingRect()) || view->sceneRect().contains(scenePos())) { - return view; + //kDebug() << " found something!" << view->isActiveWindow(); + if (view->isActiveWindow()) { + found = view; + } else { + possibleFind = view; + } } } - return 0; + + return found ? found : possibleFind; } QRectF Applet::mapFromView(const QGraphicsView *view, const QRect &rect) const @@ -434,55 +450,7 @@ QPoint Applet::popupPosition(const QSize &s) const { - QGraphicsView *v = view(); - Q_ASSERT(v); - - QPoint pos = v->mapFromScene(scenePos()); - pos = v->mapToGlobal(pos); - //kDebug() << "==> position is" << scenePos() << v->mapFromScene(scenePos()) << pos; - Plasma::View *pv = dynamic_cast<Plasma::View *>(v); - - Plasma::Location loc = Floating; - if (pv) { - loc = pv->containment()->location(); - } - - switch (loc) { - case BottomEdge: - pos = QPoint(pos.x(), pos.y() - s.height()); - break; - case TopEdge: - pos = QPoint(pos.x(), pos.y() + (int)size().height()); - break; - case LeftEdge: - pos = QPoint(pos.x() + (int)size().width(), pos.y()); - break; - case RightEdge: - pos = QPoint(pos.x() - s.width(), pos.y()); - break; - default: - if (pos.y() - s.height() > 0) { - pos = QPoint(pos.x(), pos.y() - s.height()); - } else { - pos = QPoint(pos.x(), pos.y() + (int)size().height()); - } - } - - //are we out of screen? - - QRect screenRect = QApplication::desktop()->screenGeometry(pv ? pv->containment()->screen() : -1); - //kDebug() << "==> rect for" << (pv ? pv->containment()->screen() : -1) << "is" << screenRect; - - if (pos.rx() + s.width() > screenRect.right()) { - pos.rx() -= ((pos.rx() + s.width()) - screenRect.right()); - } - - if (pos.ry() + s.height() > screenRect.bottom()) { - pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom()); - } - pos.rx() = qMax(0, pos.rx()); - - return pos; + return Plasma::popupPosition(this, s); } void Applet::updateConstraints(Plasma::Constraints constraints) @@ -673,6 +641,9 @@ void Applet::paintWindowFrame(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { + Q_UNUSED( painter ); + Q_UNUSED( option ); + Q_UNUSED( widget ); //Here come the code for the window frame //kDebug() << windowFrameGeometry(); //painter->drawRoundedRect(windowFrameGeometry(), 5, 5); @@ -925,10 +896,15 @@ if (widget && isContainment()) { // note that the widget we get is actually the viewport of the view, not the view itself View* v = qobject_cast<Plasma::View*>(widget->parent()); + if (!v || v->isWallpaperEnabled()) { + Containment* c = qobject_cast<Plasma::Containment*>(this); + if (c && c->drawWallpaper() && c->wallpaper()) { + c->wallpaper()->paint(p, contentsRect); + } + Containment::StyleOption coption(*option); coption.view = v; - paintInterface(p, &coption, contentsRect); } @@ -1094,7 +1070,7 @@ //TODO respect security when it's implemented (4.2) QAction *configAction = d->actions.action("configure"); if (hasInterface) { - if (! configAction) { //should be always true + if (!configAction) { //should be always true configAction = new QAction(i18n("%1 Settings", name()), this); configAction->setIcon(KIcon("configure")); configAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); //don't clash with other views --- plasma/private/tooltip_p.h +++ plasma/private/tooltip_p.h @@ -0,0 +1,64 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_TOOLTIP_P_H +#define PLASMA_TOOLTIP_P_H + +#include <QWidget> // base class + +#include <plasma/tooltipmanager.h> //ToolTipContent struct + +namespace Plasma { + +class ToolTipPrivate; + +class ToolTip : public QWidget +{ + Q_OBJECT + +public: + ToolTip(QObject *source); + ~ToolTip(); + + void updateTheme(); + void setContent(const ToolTipManager::ToolTipContent &data); + void prepareShowing(bool cueUpdate); + void setActivated(bool value); + bool isActivated(); + +protected: + void showEvent(QShowEvent *); + void hideEvent(QHideEvent *); + void mouseReleaseEvent(QMouseEvent *); + + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + +private Q_SLOTS: + void sourceDestroyed(); + +private: + ToolTipPrivate * const d; +}; + +} // namespace Plasma + +#endif // PLASMA_TOOLTIP_P_H + --- plasma/private/windowpreview.cpp +++ plasma/private/windowpreview.cpp @@ -0,0 +1,126 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "windowpreview_p.h" + +#include <KWindowSystem> + +#ifdef Q_WS_X11 +#include <QX11Info> + +#include <X11/Xlib.h> +#include <fixx11h.h> +#endif + + +namespace Plasma { + +bool WindowPreview::previewsAvailable() // static +{ + if (!KWindowSystem::compositingActive()) { + return false; + } +#ifdef Q_WS_X11 + // hackish way to find out if KWin has the effect enabled, + // TODO provide proper support + Display* dpy = QX11Info::display(); + Atom atom = XInternAtom(dpy, "_KDE_WINDOW_PREVIEW", False); + int cnt; + Atom* list = XListProperties(dpy, DefaultRootWindow( dpy ), &cnt); + if (list != NULL) { + bool ret = ( qFind(list, list + cnt, atom) != list + cnt ); + XFree(list); + return ret; + } +#endif + return false; +} + + +WindowPreview::WindowPreview(QWidget *parent) + : QWidget(parent) +{ +} + +void WindowPreview::setWindowId(WId w) +{ + if (!previewsAvailable()) { + id = 0; + return; + } + id = w; + readWindowSize(); +} + +QSize WindowPreview::sizeHint() const +{ + if (id == 0) { + return QSize(); + } + if (!windowSize.isValid()) { + readWindowSize(); + } + QSize s = windowSize; + s.scale(200, 150, Qt::KeepAspectRatio); + return s; +} + +void WindowPreview::readWindowSize() const +{ +#ifdef Q_WS_X11 + Window r; + int x, y; + unsigned int w, h, b, d; + if (XGetGeometry(QX11Info::display(), id, &r, &x, &y, &w, &h, &b, &d)) { + windowSize = QSize( w, h ); + } else { + windowSize = QSize(); + } +#else + windowSize = QSize(); +#endif +} + +void WindowPreview::setInfo() +{ +#ifdef Q_WS_X11 + Display *dpy = QX11Info::display(); + Atom atom = XInternAtom(dpy, "_KDE_WINDOW_PREVIEW", False); + if (id == 0) { + XDeleteProperty(dpy, parentWidget()->winId(), atom); + return; + } + if (!windowSize.isValid()) { + readWindowSize(); + } + if (!windowSize.isValid()) { + XDeleteProperty(dpy, parentWidget()->winId(), atom); + return; + } + Q_ASSERT( parentWidget()->isWindow()); // parent must be toplevel + long data[] = { 1, 5, id, x(), y(), width(), height() }; + XChangeProperty(dpy, parentWidget()->winId(), atom, atom, 32, PropModeReplace, + reinterpret_cast< unsigned char* >( data ), sizeof( data ) / sizeof( data[ 0 ] )); +#endif +} + +} // namespace Plasma + +#include "windowpreview_p.moc" --- plasma/private/tooltip.cpp +++ plasma/private/tooltip.cpp @@ -0,0 +1,199 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tooltip_p.h" +#include "windowpreview_p.h" + +#include <QBitmap> +#include <QGridLayout> +#include <QLabel> +#include <QMouseEvent> +#include <QPainter> +#include <QPalette> + +#include <KDebug> +#include <KGlobal> + +#include <plasma/plasma.h> +#include <plasma/theme.h> +#include <plasma/panelsvg.h> + +namespace Plasma { + +class ToolTipPrivate +{ + public: + ToolTipPrivate(QObject *s) + : label(0) + , imageLabel(0) + , preview(0) + , windowToPreview(0) + , source(s) + , isActivated(true) + { } + + QLabel *label; + QLabel *imageLabel; + WindowPreview *preview; + WId windowToPreview; + PanelSvg *background; + QObject *source; + bool isActivated; +}; + +void ToolTip::showEvent(QShowEvent *e) +{ + QWidget::showEvent(e); + d->preview->setInfo(); +} + +void ToolTip::hideEvent(QHideEvent *e) +{ + QWidget::hideEvent(e); + if (d->source) { + QMetaObject::invokeMethod(d->source, "toolTipHidden"); + } +} + +void ToolTip::mouseReleaseEvent(QMouseEvent* event) +{ + if (rect().contains(event->pos())) { + hide(); + } +} + +ToolTip::ToolTip(QObject *source) + : QWidget(0) + , d(new ToolTipPrivate(source)) +{ + if (source) { + connect(source, SIGNAL(destroyed(QObject*)), this, SLOT(sourceDestroyed())); + } + + setWindowFlags(Qt::ToolTip); + QGridLayout *l = new QGridLayout; + d->preview = new WindowPreview(this); + d->label = new QLabel(this); + d->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + d->label->setWordWrap(true); + d->imageLabel = new QLabel(this); + d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); + + d->background = new PanelSvg(this); + connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(update())); + + l->addWidget(d->preview, 0, 0, 1, 2); + l->addWidget(d->imageLabel, 1, 0); + l->addWidget(d->label, 1, 1); + setLayout(l); +} + +ToolTip::~ToolTip() +{ + delete d; +} + +void ToolTip::setContent(const ToolTipManager::ToolTipContent &data) +{ + //reset our size + d->label->setText("<qt><b>" + data.mainText + "</b><br>" + data.subText + "</qt>"); + d->imageLabel->setPixmap(data.image); + d->windowToPreview = data.windowToPreview; + d->preview->setWindowId( d->windowToPreview ); + + if (isVisible()) { + resize(sizeHint()); + } +} + +void ToolTip::prepareShowing(bool cueUpdate) +{ + if (cueUpdate && d->source) { + QMetaObject::invokeMethod(d->source, "toolTipAboutToShow"); + } + + if (d->windowToPreview != 0) { + // show/hide the preview area + d->preview->show(); + } else { + d->preview->hide(); + } + + layout()->activate(); + resize(sizeHint()); +} + +void ToolTip::setActivated(bool value) +{ + d->isActivated = value; +} + +bool ToolTip::isActivated() +{ + return d->isActivated; +} + +void ToolTip::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + d->background->resizePanel(size()); + + setMask(d->background->mask()); +} + +void ToolTip::paintEvent(QPaintEvent *e) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setClipRect(e->rect()); + painter.setCompositionMode(QPainter::CompositionMode_Source ); + painter.fillRect(rect(), Qt::transparent); + + d->background->paintPanel(&painter); +} + +void ToolTip::sourceDestroyed() +{ + d->source = 0; +} + +void ToolTip::updateTheme() +{ + d->background->setImagePath("widgets/tooltip"); + d->background->setEnabledBorders(PanelSvg::AllBorders); + + const int topHeight = d->background->marginSize(Plasma::TopMargin); + const int leftWidth = d->background->marginSize(Plasma::LeftMargin); + const int rightWidth = d->background->marginSize(Plasma::RightMargin); + const int bottomHeight = d->background->marginSize(Plasma::BottomMargin); + setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight); + + // Make the tooltip use Plasma's colorscheme + QPalette plasmaPalette = QPalette(); + plasmaPalette.setColor(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); + plasmaPalette.setColor(QPalette::WindowText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor)); + setAutoFillBackground(true); + setPalette(plasmaPalette); +} + + +} // namespace Plasma + +#include "tooltip_p.moc" --- plasma/private/windowpreview_p.h +++ plasma/private/windowpreview_p.h @@ -0,0 +1,59 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_WINDOWPREVIEW_P_H +#define PLASMA_WINDOWPREVIEW_P_H + +#include <QWidget> // base class +#include <QSize> // stack allocated + +namespace Plasma { + +/** + * @internal + * + * A widget which reserves area for window preview and sets hints on the toplevel + * tooltip widget that tells KWin to render the preview in this area. This depends + * on KWin's TaskbarThumbnail compositing effect (which is automaticaly detected). + */ +class WindowPreview : public QWidget +{ + Q_OBJECT + +public: + static bool previewsAvailable(); + + WindowPreview(QWidget *parent = 0); + + void setWindowId(WId w); + void setInfo(); + virtual QSize sizeHint() const; + +private: + void readWindowSize() const; + + WId id; + mutable QSize windowSize; +}; + +} // namespace Plasma + +#endif // PLASMA_WINDOWPREVIEW_P_H + --- plasma/containment_p.h +++ plasma/containment_p.h @@ -38,10 +38,13 @@ formFactor(Planar), location(Floating), focusedApplet(0), + wallpaper(0), screen(-1), // no screen toolBox(0), type(Containment::NoContainmentType), - positioning(false) + positioning(false), + drawWallpaper(true), + showToolBox(true) { } @@ -71,6 +74,7 @@ void containmentAppletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim); void zoomIn(); void zoomOut(); + bool showContextMenu(const QPointF &point, const QPoint &screenPos, bool includeApplet); /** * Locks or unlocks plasma's applets. @@ -95,11 +99,14 @@ Location location; Applet::List applets; Applet *focusedApplet; + Plasma::Wallpaper *wallpaper; QMap<Applet*, AppletHandle*> handles; int screen; ToolBox *toolBox; Containment::Type type; bool positioning; + bool drawWallpaper; + bool showToolBox; }; } // Plasma namespace --- plasma/view.cpp +++ plasma/view.cpp @@ -25,6 +25,7 @@ #include "corona.h" #include "containment.h" +#include "wallpaper.h" using namespace Plasma; @@ -107,20 +108,24 @@ : QGraphicsView(parent), d(new ViewPrivate(this, 0)) { - Q_ASSERT(containment); d->initGraphicsView(); - setScene(containment->scene()); - setContainment(containment); + + if (containment) { + setScene(containment->scene()); + setContainment(containment); + } } View::View(Containment *containment, int viewId, QWidget *parent) : QGraphicsView(parent), d(new ViewPrivate(this, viewId)) { - Q_ASSERT(containment); d->initGraphicsView(); - setScene(containment->scene()); - setContainment(containment); + + if (containment) { + setScene(containment->scene()); + setContainment(containment); + } } @@ -198,6 +203,8 @@ int screen = -1; if (oldContainment) { screen = d->containment->screen(); + } else { + setScene(containment->scene()); } d->containment = containment; @@ -237,6 +244,44 @@ return d->containment; } +Containment* View::swapContainment(const QString& name, const QVariantList& args) +{ + Containment *old = d->containment; + Plasma::Corona* corona = old->corona(); + Plasma::Containment *c = corona->addContainment(name, args); + if (c) { + KConfigGroup oldConfig = old->config(); + KConfigGroup newConfig = c->config(); + + // ensure that the old containments configuration is up to date + old->save(oldConfig); + + // set our containment to the new one + setContainment(c); + + // Copy configuration to new containment + oldConfig.copyTo(&newConfig); + + // load the configuration of the old containment into the new one + c->restore(newConfig); + foreach(Applet* applet, c->applets()) { + applet->init(); + // We have to flush the applet constraints manually + applet->flushPendingConstraintsEvents(); + } + + // destroy the old one + old->destroy(false); + + // and now save the config + c->save(newConfig); + corona->requestConfigSync(); + + return c; + } + return old; +} + KConfigGroup View::config() const { KConfigGroup views(KGlobal::config(), "PlasmaViews"); --- plasma/panelsvg.cpp +++ plasma/panelsvg.cpp @@ -37,16 +37,14 @@ PanelData() : enabledBorders(PanelSvg::AllBorders), cachedBackground(0), - panelSize(-1,-1), - contentAtOrigin(false) + panelSize(-1,-1) { } PanelData(const PanelData &other) : enabledBorders(other.enabledBorders), cachedBackground(0), - panelSize(other.panelSize), - contentAtOrigin(other.contentAtOrigin) + panelSize(other.panelSize) { } @@ -64,13 +62,18 @@ int leftWidth; int rightWidth; int bottomHeight; + + //margins, are equal to the measures by default + int topMargin; + int leftMargin; + int rightMargin; + int bottomMargin; //size of the svg where the size of the "center" //element is contentWidth x contentHeight bool noBorderPadding : 1; bool stretchBorders : 1; bool tileCenter : 1; - bool contentAtOrigin : 1; }; class PanelSvgPrivate @@ -277,20 +280,20 @@ switch (edge) { case Plasma::TopMargin: - return d->panels[d->prefix]->topHeight; + return d->panels[d->prefix]->topMargin; break; case Plasma::LeftMargin: - return d->panels[d->prefix]->leftWidth; + return d->panels[d->prefix]->leftMargin; break; case Plasma::RightMargin: - return d->panels[d->prefix]->rightWidth; + return d->panels[d->prefix]->rightMargin; break; //Plasma::BottomMargin default: - return d->panels[d->prefix]->bottomHeight; + return d->panels[d->prefix]->bottomMargin; break; } } @@ -304,12 +307,26 @@ return; } - top = panel->topHeight; - left = panel->leftWidth; - right = panel->rightWidth; - bottom = panel->bottomHeight; + top = panel->topMargin; + left = panel->leftMargin; + right = panel->rightMargin; + bottom = panel->bottomMargin; } +QRectF PanelSvg::contentsRect() const +{ + QSizeF size(panelSize()); + + if (size.isValid()) { + QRectF rect(QPointF(0, 0), size); + PanelData *panel = d->panels[d->prefix]; + + return rect.adjusted(panel->leftMargin, panel->topMargin, -panel->rightMargin, -panel->bottomMargin); + } else { + return QRectF(); + } +} + QBitmap PanelSvg::mask() const { PanelData *panel = d->panels[d->prefix]; @@ -359,22 +376,27 @@ Q_ASSERT(panel->cachedBackground); } - //FIXME: this is redundant with generatebackground for now - bool origined = panel->contentAtOrigin; - const int topOffset = origined ? 0 - panel->topHeight : 0; - const int leftOffset = origined ? 0 - panel->leftWidth : 0; + painter->drawPixmap(rect, *(panel->cachedBackground), rect.translated(-pos.x(),-pos.y())); +} - painter->drawPixmap(rect, *(panel->cachedBackground), rect.translated(-pos.x()-leftOffset,-pos.y()-topOffset)); +void PanelSvg::paintPanel(QPainter* painter, const QPointF& pos) +{ + PanelData *panel = d->panels[d->prefix]; + if (!panel->cachedBackground) { + d->generateBackground(panel); + Q_ASSERT(panel->cachedBackground); + } + + painter->drawPixmap(pos, *(panel->cachedBackground)); } void PanelSvgPrivate::generateBackground(PanelData *panel) { //kDebug() << "generating background"; - bool origined = panel->contentAtOrigin; const int topWidth = q->elementSize(prefix + "top").width(); const int leftHeight = q->elementSize(prefix + "left").height(); - const int topOffset = origined ? 0 - panel->topHeight : 0; - const int leftOffset = origined ? 0 - panel->leftWidth : 0; + const int topOffset = 0; + const int leftOffset = 0; if (panel->cachedBackground) { return; @@ -400,14 +422,7 @@ p.setCompositionMode(QPainter::CompositionMode_Source); p.setRenderHint(QPainter::SmoothPixmapTransform); - if (origined) { - p.translate(panel->leftWidth, panel->topHeight); - } - //FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image. - // the transparent border around the svg seems to vary in size depending on the size of the svg and as a result increasing the - // svg image by 2 all around didn't resolve the issue. For now it resizes based on the border size. - //if we must stretch the center or the borders we compute how much we will have to stretch //the svg to get the desired element sizes QSizeF scaledContentSize(0,0); @@ -449,18 +464,14 @@ // Corners if (q->hasElement(prefix + "top") && panel->enabledBorders & PanelSvg::TopBorder) { - if (!origined) { - contentTop = panel->topHeight; - bottomOffset += panel->topHeight; - } + contentTop = panel->topHeight; + bottomOffset += panel->topHeight; if (q->hasElement(prefix + "topleft") && panel->enabledBorders & PanelSvg::LeftBorder) { q->paint(&p, QRect(leftOffset, topOffset, panel->leftWidth, panel->topHeight), prefix + "topleft"); - if (!origined) { - contentLeft = panel->leftWidth; - rightOffset = contentWidth + panel->leftWidth; - } + contentLeft = panel->leftWidth; + rightOffset = contentWidth + panel->leftWidth; } if (q->hasElement(prefix + "topright") && panel->enabledBorders & PanelSvg::RightBorder) { @@ -472,10 +483,8 @@ if (q->hasElement(prefix + "bottomleft") && panel->enabledBorders & PanelSvg::LeftBorder) { q->paint(&p, QRect(leftOffset, bottomOffset, panel->leftWidth, panel->bottomHeight), prefix + "bottomleft"); - if (!origined) { - contentLeft = panel->leftWidth; - rightOffset = contentWidth + panel->leftWidth; - } + contentLeft = panel->leftWidth; + rightOffset = contentWidth + panel->leftWidth; } if (q->hasElement(prefix + "bottomright") && panel->enabledBorders & PanelSvg::RightBorder) { @@ -575,26 +584,50 @@ q->Svg::resize(); if (panel->enabledBorders & PanelSvg::TopBorder) { panel->topHeight = q->elementSize(prefix + "top").height(); + + if (q->hasElement(prefix + "hint-top-margin")) { + panel->topMargin = q->elementSize(prefix + "hint-top-margin").height(); + } else { + panel->topMargin = panel->topHeight; + } } else { - panel->topHeight = 0; + panel->topMargin = panel->topHeight = 0; } if (panel->enabledBorders & PanelSvg::LeftBorder) { panel->leftWidth = q->elementSize(prefix + "left").width(); + + if (q->hasElement(prefix + "hint-left-margin")) { + panel->leftMargin = q->elementSize(prefix + "hint-left-margin").height(); + } else { + panel->leftMargin = panel->leftWidth; + } } else { - panel->leftWidth = 0; + panel->leftMargin = panel->leftWidth = 0; } if (panel->enabledBorders & PanelSvg::RightBorder) { panel->rightWidth = q->elementSize(prefix + "right").width(); + + if (q->hasElement(prefix + "hint-right-margin")) { + panel->rightMargin = q->elementSize(prefix + "hint-right-margin").height(); + } else { + panel->rightMargin = panel->rightWidth; + } } else { - panel->rightWidth = 0; + panel->rightMargin = panel->rightWidth = 0; } if (panel->enabledBorders & PanelSvg::BottomBorder) { panel->bottomHeight = q->elementSize(prefix + "bottom").height(); + + if (q->hasElement(prefix + "hint-bottom-margin")) { + panel->bottomMargin = q->elementSize(prefix + "hint-bottom-margin").height(); + } else { + panel->bottomMargin = panel->bottomHeight; + } } else { - panel->bottomHeight = 0; + panel->bottomMargin = panel->bottomHeight = 0; } //since it's rectangular, topWidth and bottomWidth must be the same --- plasma/tests/packagemetadatatest.desktop +++ plasma/tests/packagemetadatatest.desktop @@ -81,8 +81,8 @@ Comment[ro]=Un fișier birou de test pentru a verifica clasa PackageMetaData. Comment[se]=.desktop-fiilla mainna geahččala PackageMeta-luohká. Comment[sl]=Namizna datoteka za test razreda PackageMetaData. -Comment[sr]=Пробни фајл површи за класу PackageMetaData. -Comment[sr@latin]=Probni fajl površi za klasu PackageMetaData. +Comment[sr]=Пробни .десктоп фајл за класу PackageMetaData. +Comment[sr@latin]=Probni .desktop fajl za klasu PackageMetaData. Comment[sv]=En skrivbordsfil för att testa klassen PackageMetaData. Comment[th]=แฟ้มทดสอบพื้นที่ทำงาน สำหรับทดสอบคลาสข้อมูลกำกับแพ็กเกจ Comment[tr]=PackageMetaData sınıfını test etmek için bir desktop dosyası --- plasma/tests/testengine/plasma-dataengine-testengine.desktop +++ plasma/tests/testengine/plasma-dataengine-testengine.desktop @@ -26,7 +26,7 @@ Name[ml]=ടെസ്റ്റ് ഡേറ്റാ എഞ്ചിന് Name[mr]=चाचणी माहिती इंजिन Name[nb]=Testdata-motor -Name[nds]=Test-Hanteerkarn +Name[nds]=Test-Datenkarn Name[nl]=Test (gegevensengine) Name[nn]=Testdatamotor Name[pa]=ਟੈਸਟ ਡਾਟਾ ਇੰਜਣ @@ -35,8 +35,8 @@ Name[pt_BR]=Mecanismo de dados de teste Name[ro]=Test motor de date Name[sl]=Preizkusni pogon s podatki -Name[sr]=пробни мотор података -Name[sr@latin]=probni motor podataka +Name[sr]=пробни датомотор података +Name[sr@latin]=probni datomotor podataka Name[sv]=Testdatagränssnitt Name[th]=โปรแกรมข้อมูลสำหรับทดสอบ Name[tr]=Test Veri Motoru --- plasma/containment.h +++ plasma/containment.h @@ -42,6 +42,7 @@ class Package; class Corona; class View; +class Wallpaper; class ContainmentPrivate; /** @@ -117,6 +118,8 @@ */ Containment(QObject *parent, const QVariantList &args); + Containment(QObject *parent, const QVariantList &args, bool showToolBox); + ~Containment(); /** @@ -276,6 +279,27 @@ */ void removeAssociatedWidget(QWidget *widget); + /** + * Return whether wallpaper is painted or not. + */ + bool drawWallpaper(); + + /** + * Sets wallpaper plugin. + */ + void setWallpaper(const QString &pluginName, const QString &action = QString()); + + /** + * Return wallpaper plugin. + */ + Plasma::Wallpaper* wallpaper(); + + /** + * Shows the context menu for the containment directly, bypassing Applets + * altogether. + */ + void showContextMenu(const QPointF &containmentPos, const QPoint &screenPos); + Q_SIGNALS: /** * This signal is emitted when a new applet is created by the containment @@ -328,6 +352,11 @@ */ void focusRequested(Plasma::Containment *containment); + /** + * Emitted when the user wants to configure/change containment. + */ + void configureRequested(); + public Q_SLOTS: /** * Informs the Corona as to what position it is in. This is informational @@ -367,6 +396,19 @@ */ void destroy(); + /** + * Destroys this containment and all its applets (after a confirmation dialog); + * it will be removed nicely and deleted. + * Its configuration will also be deleted. + * + * @arg confirm whether or not confirmation from the user should be requested + */ + void destroy(bool confirm); + + /** + * @reimplemented from Plasma::Applet + */ + void showConfigurationInterface(); protected: /** * Sets the type of this containment. @@ -374,6 +416,11 @@ void setContainmentType(Containment::Type type); /** + * Sets whether wallpaper is painted or not. + */ + void setDrawWallpaper(bool drawWallpaper); + + /** * Called when the contents of the containment should be saved. By default this saves * all loaded Applets * @@ -389,11 +436,14 @@ */ virtual void restoreContents(KConfigGroup &group); - + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void keyPressEvent(QKeyEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent *event); bool sceneEventFilter(QGraphicsItem *watched, QEvent *event); QVariant itemChange(GraphicsItemChange change, const QVariant &value); @@ -412,6 +462,11 @@ */ void dropEvent(QGraphicsSceneDragDropEvent *event); + /** + * @reimplemented from QGraphicsItem + */ + void resizeEvent(QGraphicsSceneResizeEvent *event); + private: Q_PRIVATE_SLOT(d, void appletDestroyed(QObject*)) Q_PRIVATE_SLOT(d, void containmentAppletAnimationComplete(QGraphicsItem *item, Plasma::Animator::Animation anim)) @@ -423,6 +478,7 @@ Q_PRIVATE_SLOT(d, void toggleDesktopImmutability()) friend class Applet; + friend class CoronaPrivate; friend class ContainmentPrivate; ContainmentPrivate* const d; }; --- plasma/CMakeLists.txt +++ plasma/CMakeLists.txt @@ -58,9 +58,16 @@ svg.cpp theme.cpp toolbox.cpp + tooltipmanager.cpp + tooltipmanager.h + private/tooltip.cpp + private/tooltip_p.h + private/windowpreview.cpp + private/windowpreview_p.h uiloader.cpp version.cpp view.cpp + wallpaper.cpp widgets/checkbox.cpp widgets/combobox.cpp widgets/flash.cpp @@ -71,6 +78,7 @@ widgets/meter.cpp widgets/pushbutton.cpp widgets/radiobutton.cpp + widgets/scrollbar.cpp widgets/signalplotter.cpp widgets/textedit.cpp widgets/webcontent.cpp @@ -144,8 +152,10 @@ svg.h theme.h uiloader.h + tooltipmanager.h version.h - view.h) + view.h + wallpaper.h) if(QT_QTOPENGL_FOUND AND OPENGL_FOUND) set(plasma_LIB_INCLUDES @@ -168,6 +178,7 @@ widgets/meter.h widgets/pushbutton.h widgets/radiobutton.h + widgets/scrollbar.h widgets/signalplotter.h widgets/textedit.h widgets/webcontent.h @@ -223,15 +234,18 @@ includes/RunnerManager includes/RunnerScript includes/ScriptEngine +includes/ScrollBar includes/Service includes/ServiceJob includes/SignalPlotter includes/Svg includes/TextEdit +includes/ToolTipManager includes/Theme includes/UiLoader includes/View includes/Version +includes/Wallpaper includes/WebContent DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/Plasma COMPONENT Devel) @@ -249,6 +263,7 @@ servicetypes/plasma-packagestructure.desktop servicetypes/plasma-runner.desktop servicetypes/plasma-scriptengine.desktop + servicetypes/plasma-wallpaper.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) install(FILES scripting/plasmoids.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) --- plasma/theme.cpp +++ plasma/theme.cpp @@ -50,7 +50,6 @@ public: ThemePrivate(Theme *theme) : q(theme), - defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME), defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX), defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH), defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT), @@ -61,6 +60,10 @@ hasWallpapers(false) { generalFont = QApplication::font(); + + KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc"); + KConfigGroup group = KConfigGroup(defaultconfig, "Defaults"); + defaultWallpaperTheme = group.readEntry("wallpaper", DEFAULT_WALLPAPER_THEME); } KConfigGroup& config() @@ -247,7 +250,10 @@ cg = d->config(); } - d->defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME); + KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc"); + KConfigGroup group = KConfigGroup(defaultconfig, "Defaults"); + d->defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", group.readEntry("wallpaper", DEFAULT_WALLPAPER_THEME)); + d->defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX); d->defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH); d->defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT); @@ -342,6 +348,10 @@ } } + if (!QFile::exists(fullPath)) { + fullPath = KStandardDirs::locate("wallpaper", d->defaultWallpaperTheme); + } + return fullPath; } --- plasma/containment.cpp +++ plasma/containment.cpp @@ -51,10 +51,14 @@ #include "desktoptoolbox_p.h" #include "paneltoolbox_p.h" #include "svg.h" +#include "wallpaper.h" namespace Plasma { +static const char defaultWallpaper[] = "image"; +static const char defaultWallpaperMode[] = "SingleImage"; + Containment::StyleOption::StyleOption() : QStyleOptionGraphicsItem(), view(0) @@ -102,6 +106,17 @@ setBackgroundHints(NoBackground); } +Containment::Containment(QObject* parent, const QVariantList& args, bool showToolBox) + : Applet(parent, args), + d(new ContainmentPrivate(this)) +{ + // WARNING: do not access config() OR globalConfig() in this method! + // that requires a scene, which is not available at this point + setPos(0, 0); + setBackgroundHints(NoBackground); + d->showToolBox=showToolBox; +} + Containment::~Containment() { delete d; @@ -199,7 +214,21 @@ d->toolBox->addTool(this->action("lock widgets")); } d->toolBox->addTool(this->action("add sibling containment")); + if (hasConfigurationInterface()) { + // re-use the contianment's action. + QAction* configureContainment = this->action("configure"); + if (configureContainment) { + d->toolBox->addTool(this->action("configure")); + } + } + } + + //Set a default wallpaper the first time the containment is created, + //for instance from the toolbox by the user + if (d->drawWallpaper) { + setDrawWallpaper(true); + } } Applet::init(); @@ -245,9 +274,19 @@ setScreen(group.readEntry("screen", d->screen)); flushPendingConstraintsEvents(); - //kDebug() << "Containment" << id() << "geometry is" << geometry() << "config'd with" << appletConfig.name(); restoreContents(group); setImmutability((ImmutabilityType)group.readEntry("immutability", (int)Mutable)); + + setWallpaper(group.readEntry("wallpaperplugin", defaultWallpaper), + group.readEntry("wallpaperpluginmode", defaultWallpaperMode)); + /* + kDebug() << "Containment" << id() << + "screen" << screen() << + "geometry is" << geometry() << + "wallpaper" << ((d->wallpaper) ? d->wallpaper->pluginName() : QString()) << + "wallpaper mode" << wallpaperMode() << + "config entries" << group.entryMap(); + */ } void Containment::save(KConfigGroup &g) const @@ -262,6 +301,15 @@ group.writeEntry("screen", d->screen); group.writeEntry("formfactor", (int)d->formFactor); group.writeEntry("location", (int)d->location); + + if (d->wallpaper) { + group.writeEntry("wallpaperplugin", d->wallpaper->pluginName()); + group.writeEntry("wallpaperpluginmode", d->wallpaper->renderingMode().name()); + KConfigGroup wallpaperConfig(&group, "Wallpaper"); + wallpaperConfig = KConfigGroup(&wallpaperConfig, d->wallpaper->pluginName()); + d->wallpaper->save(wallpaperConfig); + } + saveContents(group); } @@ -321,7 +369,7 @@ return; } - if ((type == DesktopContainment || type == PanelContainment)) { + if ((type == DesktopContainment || type == PanelContainment) && d->showToolBox) { d->createToolBox(); } } @@ -331,6 +379,61 @@ return dynamic_cast<Corona*>(scene()); } +void Containment::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); + if (d->wallpaper) { + QGraphicsItem* item = scene()->itemAt(event->scenePos()); + if (item == this) { + d->wallpaper->mouseMoveEvent(event); + } + } + + if (!event->isAccepted()) { + event->accept(); + Applet::mouseMoveEvent(event); + } +} + +void Containment::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); + if (d->wallpaper) { + QGraphicsItem* item = scene()->itemAt(event->scenePos()); + if (item == this) { + d->wallpaper->mousePressEvent(event); + } + } + + if (event->isAccepted()) { + setFocus(Qt::MouseFocusReason); + } else { + event->accept(); + Applet::mousePressEvent(event); + } +} + +void Containment::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); + if (d->wallpaper) { + QGraphicsItem* item = scene()->itemAt(event->scenePos()); + if (item == this) { + d->wallpaper->mouseReleaseEvent(event); + } + } + + if (!event->isAccepted()) { + event->accept(); + Applet::mouseReleaseEvent(event); + } +} + +void Containment::showContextMenu(const QPointF &containmentPos, const QPoint &screenPos) +{ + d->showContextMenu(mapToScene(containmentPos), screenPos, false); +} + void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { //kDebug() << "let's see if we manage to get a context menu here, huh"; @@ -339,14 +442,22 @@ return; } - QPointF point = event->scenePos(); - QGraphicsItem* item = scene()->itemAt(point); - if (item == this) { - item = 0; + if (!d->showContextMenu(event->scenePos(), event->screenPos(), true)) { + Applet::contextMenuEvent(event); + } else { + event->accept(); } +} +bool ContainmentPrivate::showContextMenu(const QPointF &point, const QPoint &screenPos, bool includeApplet) +{ Applet* applet = 0; + QGraphicsItem* item = q->scene()->itemAt(point); + if (item == q) { + item = 0; + } + while (item) { applet = qgraphicsitem_cast<Applet*>(item); if (applet && !applet->isContainment()) { @@ -362,15 +473,18 @@ //kDebug() << "context menu event " << (QObject*)applet; if (applet) { bool hasEntries = false; + QList<QAction*> actions; - QList<QAction*> actions = applet->contextualActions(); - if (!actions.isEmpty()) { - foreach(QAction* action, actions) { - if (action) { - desktopMenu.addAction(action); + if (includeApplet) { + actions = applet->contextualActions(); + if (!actions.isEmpty()) { + foreach(QAction* action, actions) { + if (action) { + desktopMenu.addAction(action); + } } + hasEntries = true; } - hasEntries = true; } if (applet->hasConfigurationInterface()) { @@ -381,7 +495,7 @@ } } - QList<QAction*> containmentActions = contextualActions(); + QList<QAction*> containmentActions = q->contextualActions(); if (!containmentActions.isEmpty()) { if (hasEntries) { desktopMenu.addSeparator(); @@ -391,7 +505,7 @@ QMenu *containmentActionMenu = &desktopMenu; if (!actions.isEmpty() && containmentActions.count() > 2) { - containmentActionMenu = new KMenu(i18n("%1 Options", name()), &desktopMenu); + containmentActionMenu = new KMenu(i18n("%1 Options", q->name()), &desktopMenu); desktopMenu.addMenu(containmentActionMenu); } @@ -402,7 +516,7 @@ } } - if (scene() && static_cast<Corona*>(scene())->immutability() == Mutable) { + if (static_cast<Corona*>(q->scene())->immutability() == Mutable) { if (hasEntries) { desktopMenu.addSeparator(); } @@ -412,30 +526,28 @@ kDebug() << "no remove action!!!!!!!!"; closeApplet = new QAction(i18n("Remove this %1", applet->name()), &desktopMenu); closeApplet->setIcon(KIcon("edit-delete")); - connect(closeApplet, SIGNAL(triggered(bool)), applet, SLOT(destroy())); + QObject::connect(closeApplet, SIGNAL(triggered(bool)), applet, SLOT(destroy())); } desktopMenu.addAction(closeApplet); hasEntries = true; } if (!hasEntries) { - Applet::contextMenuEvent(event); kDebug() << "no entries"; - return; + return false; } } else { - if (!scene() || (static_cast<Corona*>(scene())->immutability() != Mutable && !KAuthorized::authorizeKAction("unlock_desktop"))) { + if (static_cast<Corona*>(q->scene())->immutability() != Mutable && + !KAuthorized::authorizeKAction("unlock_desktop")) { //kDebug() << "immutability"; - Applet::contextMenuEvent(event); - return; + return false; } - QList<QAction*> actions = contextualActions(); + QList<QAction*> actions = q->contextualActions(); if (actions.count() < 1) { //kDebug() << "no applet, but no actions"; - Applet::contextMenuEvent(event); - return; + return false; } foreach (QAction* action, actions) { @@ -445,9 +557,9 @@ } } - event->accept(); - //kDebug() << "executing at" << event->screenPos(); - desktopMenu.exec(event->screenPos()); + //kDebug() << "executing at" << screenPos; + desktopMenu.exec(screenPos); + return true; } void Containment::setFormFactor(FormFactor formFactor) @@ -795,6 +907,14 @@ } } +void Containment::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Applet::resizeEvent(event); + if (d->wallpaper) { + d->wallpaper->setBoundingRect(boundingRect()); + } +} + void Containment::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { //FIXME Qt4.4 check to see if this is still necessary to avoid unnecessary repaints @@ -826,6 +946,42 @@ } } +void Containment::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + if (d->wallpaper) { + QGraphicsItem* item = scene()->itemAt(event->scenePos()); + if (item == this) { + event->ignore(); + d->wallpaper->wheelEvent(event); + + if (event->isAccepted()) { + return; + } + + event->accept(); + } + } + + if (containmentType() == DesktopContainment) { + QGraphicsItem* item = scene()->itemAt(event->scenePos()); + if (item == this) { + int numDesktops = KWindowSystem::numberOfDesktops(); + int currentDesktop = KWindowSystem::currentDesktop(); + + if (event->delta() > 0) { + KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1); + } else { + KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1); + } + + event->accept(); + return; + } + } + + Applet::wheelEvent(event); +} + bool Containment::sceneEventFilter(QGraphicsItem *watched, QEvent *event) { Applet *applet = qgraphicsitem_cast<Applet*>(watched); @@ -955,6 +1111,85 @@ } } +void Containment::setDrawWallpaper(bool drawWallpaper) +{ + d->drawWallpaper = drawWallpaper; + if (d->drawWallpaper) { + KConfigGroup cfg = config(); + QString wallpaper = cfg.readEntry("wallpaperplugin", defaultWallpaper); + QString mode = cfg.readEntry("wallpaperpluginmode", defaultWallpaperMode); + setWallpaper(wallpaper, mode); + } else if (!d->drawWallpaper && d->wallpaper) { + delete d->wallpaper; + d->wallpaper = 0; + } +} + +bool Containment::drawWallpaper() +{ + return d->drawWallpaper; +} + +void Containment::setWallpaper(const QString &pluginName, const QString &mode) +{ + KConfigGroup cfg = config(); + bool newPlugin = true; + bool newMode = true; + + if (d->drawWallpaper) { + if (d->wallpaper) { + // we have a wallpaper, so let's decide whether we need to swap it out + if (d->wallpaper->pluginName() != pluginName) { + delete d->wallpaper; + d->wallpaper = 0; + } else { + // it's the same plugin, so let's save its state now so when + // we call restore later on we're safe + newMode = d->wallpaper->renderingMode().name() != mode; + newPlugin = false; + } + } + + if (!pluginName.isEmpty() && !d->wallpaper) { + d->wallpaper = Plasma::Wallpaper::load(pluginName); + } + + if (d->wallpaper) { + d->wallpaper->setBoundingRect(boundingRect()); + + KConfigGroup wallpaperConfig = KConfigGroup(&cfg, "Wallpaper"); + wallpaperConfig = KConfigGroup(&wallpaperConfig, pluginName); + d->wallpaper->restore(wallpaperConfig, mode); + + if (newPlugin) { + connect(d->wallpaper, SIGNAL(update(const QRectF&)), + this, SLOT(updateRect(const QRectF&))); + cfg.writeEntry("wallpaperplugin", pluginName); + } + + if (newMode) { + cfg.writeEntry("wallpaperpluginmode", mode); + } + } + + update(); + } + + if (!d->wallpaper) { + cfg.deleteEntry("wallpaperplugin"); + cfg.deleteEntry("wallpaperpluginmode"); + } + + if (newPlugin || newMode) { + emit configNeedsSaving(); + } +} + +Plasma::Wallpaper* Containment::wallpaper() +{ + return d->wallpaper; +} + KActionCollection& ContainmentPrivate::actions() { return static_cast<Applet*>(q)->d->actions; @@ -1022,6 +1257,11 @@ void Containment::destroy() { + destroy(true); +} + +void Containment::destroy(bool confirm) +{ if (immutability() != Mutable) { return; } @@ -1036,7 +1276,7 @@ } //FIXME maybe that %1 should be the containment type not the name - if (KMessageBox::warningContinueCancel(view(), i18n("Do you really want to remove this %1?", name()), + if (!confirm || KMessageBox::warningContinueCancel(view(), i18n("Do you really want to remove this %1?", name()), i18n("Remove %1", name()), KStandardGuiItem::remove()) == KMessageBox::Continue ) { //clearApplets(); Applet::destroy(); @@ -1046,6 +1286,15 @@ } } +void Containment::showConfigurationInterface() +{ + if (isContainment()) { + emit configureRequested(); + } + else { + Applet::showConfigurationInterface(); + } +} // Private class implementation --- plasma/view.h +++ plasma/view.h @@ -119,6 +119,16 @@ Containment* containment() const; /** + * Swap the containment for this view, which will also cause the view + * to track the geometry of the containment. + * + * @param name the plugin name for the new containment. + * @param args argument list to pass to the containment + */ + Containment* swapContainment(const QString& name, + const QVariantList& args = QVariantList()); + + /** * Set whether or not the view should adjust its size when the associated * containment does. * @arg trackChanges true to syncronize the view's size with the containment's --- plasma/corona.h +++ plasma/corona.h @@ -93,6 +93,11 @@ */ Containment* containmentForScreen(int screen) const; + /** + * SUSE-specific extension + **/ + virtual bool loadDefaultApplets(Plasma::Containment* panel, bool askType=false); + public Q_SLOTS: /** * Initializes the layout from a config file. This will first clear any existing --- plasma/tooltipmanager.h +++ plasma/tooltipmanager.h @@ -0,0 +1,223 @@ +/* + * Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com> + * Copyright 2008 by Aaron Seigo <aseigo@kde.org> + * Copyright 2008 by Alexis Ménard <darktears31@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLASMA_TOOL_TIP_MANAGER_H +#define PLASMA_TOOL_TIP_MANAGER_H + +//plasma +#include <plasma/plasma.h> +#include <plasma/plasma_export.h> + +namespace Plasma +{ + +class ToolTipManagerPrivate; +class Applet; + +/** + * @class ToolTipManager plasma/tooltipmanager.h <Plasma/ToolTipManager> + * + * @short Manages tooltips for QGraphicsWidgets in Plasma + * + * If you want a widget to have a tooltip displayed when the mouse is hovered over + * it, you should do something like: + * + * @code + * // widget is a QGraphicsWidget* + * Plasma::ToolTipManager::ToolTipContent data; + * data.mainText = i18n("My Title"); + * data.subText = i18n("This is a little tooltip"); + * data.image = KIcon("some-icon").pixmap(IconSize(KIconLoader::Desktop)); + * Plasma::ToolTipManager::self()->setToolTipContent(widget, data); + * @endcode + * + * Note that, since a Plasma::Applet is a QGraphicsWidget, you can use + * Plasma::ToolTipManager::self()->setToolTipContent(this, data); in the + * applet's init() method to set a tooltip for the whole applet. + * + * The tooltip will be registered automatically by setToolTipContent(). It will be + * automatically unregistered when the associated widget is deleted, freeing the + * memory used by the tooltip, but you can manually unregister it at any time by + * calling unregisterWidget(). + * + * When a tooltip for a widget is about to be shown, the widget's toolTipAboutToShow slot will be + * invoked if it exists. Similarly, when a tooltip is hidden, the widget's toolTipHidden() slot + * will be invoked if it exists. This allows widgets to provide on-demand tooltip data. + */ +class PLASMA_EXPORT ToolTipManager : public QObject +{ + Q_OBJECT +public: + + /** + * @struct ToolTipContent plasma/tooltipmanager.h <Plasma/ToolTipManager> + * + * This provides the content for a tooltip. + * + * Normally you will want to set at least the @p mainText and + * @p subText. + */ + struct PLASMA_EXPORT ToolTipContent + { + /** Creates an empty ToolTipContent */ + ToolTipContent(); + + /** @return true if all the fields are empty */ + bool isEmpty() const; + + /** Important information, e.g. the title */ + QString mainText; + /** Elaborates on the @p mainText */ + QString subText; + /** An icon to display */ + QPixmap image; + /** Id of a window if you want to show a preview */ + WId windowToPreview; + }; + + /** + * @return The singleton instance of the manager. + */ + static ToolTipManager *self(); + + /** + * Default constructor. + * + * You should normall use self() instead. + */ + explicit ToolTipManager(QObject* parent = 0); + + /** + * Default destructor. + */ + ~ToolTipManager(); + + /** + * Show the tooltip for a widget registered in the tooltip manager + * + * @param widget the widget for which the tooltip will be displayed + */ + void showToolTip(QGraphicsWidget *widget); + + /** + * Find out whether the tooltip for a given widget is currently being displayed. + * + * @param widget the widget to check the tooltip for + * @return true if the tooltip of the widget is currently displayed, + * false if not + */ + bool isWidgetToolTipDisplayed(QGraphicsWidget *widget); + + /** + * Hides the currently showing tooltip after a short amount of time. + */ + void delayedHideToolTip(); + + /** + * Hides the tooltip for a widget immediately. + * + * @param widget the widget to hide the tooltip for + */ + void hideToolTip(QGraphicsWidget *widget); + + /** + * Registers a widget with the tooltip manager. + * + * Note that setToolTipContent() will register the widget if it + * has not already been registered, and so you do not normally + * need to use the method. + * + * This is useful for creating tooltip content on demand. You can + * register your widget with registerWidget(), then implement + * a slot named toolTipAboutToShow for the widget. This will be + * called before the tooltip is shown, allowing you to set the + * data with setToolTipContent(). + * + * If the widget also has a toolTipHidden slot, this will be called + * after the tooltip is hidden. + * + * @param widget the desired widget + */ + void registerWidget(QGraphicsWidget *widget); + + /** + * Unregisters a widget from the tooltip manager. + * + * This will free the memory used by the tooltip associated with the widget. + * + * @param widget the desired widget to delete + */ + void unregisterWidget(QGraphicsWidget *widget); + + /** + * Sets the content for the tooltip associated with a widget. + * + * Note that this will register the widget with the ToolTipManager if + * necessary, so there is usually no need to call registerWidget(). + * + * @param widget the widget the tooltip should be associated with + * @param data the content of the tooltip. If an empty ToolTipContent + * is passed in, the tooltip content will be reset. + */ + void setToolTipContent(QGraphicsWidget *widget, const ToolTipContent &data); + + /** + * Clears the tooltip data associated with this widget, but keeps + * the widget registered. + */ + void clearToolTipContent(QGraphicsWidget *widget); + + /** + * Checks whether a widget has a tooltip associated with it. + * + * @param widget the widget to check for an associated tooltip + * @return true if the widget has a tooltip associated, + * false if it does not + */ + bool widgetHasToolTip(QGraphicsWidget *widget) const; + + /** + * Enable/or disable a Tooltip, this method is usefull is we want + * to have a tooltip activated on demand. + * @param widget the widget to change tooltip behaviour + * @param enable if we need the tooltip or not + */ + void setToolTipActivated(QGraphicsWidget *widget, bool enable); + + /** + * Return true is the tooltip will be displayed, false otherwise + */ + bool isToolTipActivated(QGraphicsWidget *widget); + +private: + friend class ToolTipManagerSingleton; + bool eventFilter(QObject *watched, QEvent *event); + + ToolTipManagerPrivate* const d; + Q_PRIVATE_SLOT(d, void showToolTip()) + Q_PRIVATE_SLOT(d, void resetShownState()) + Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*)) + Q_PRIVATE_SLOT(d, void themeUpdated()) +}; + +} // namespace Plasma + +#endif // PLASMA_TOOL_TIP_MANAGER_H --- plasma/wallpaper.h +++ plasma/wallpaper.h @@ -0,0 +1,234 @@ +/* + * Copyright 2008 by Aaron Seigo <aseigo@kde.org> + * Copyright 2008 by Petri Damsten <damu@iki.fi> + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_WALLPAPER_H +#define PLASMA_WALLPAPER_H + +#include <KDE/KPluginInfo> + +#include <plasma/plasma.h> +#include <plasma/version.h> + +namespace Plasma +{ +class WallpaperPrivate; + +/** + * @short The base Wallpaper class + * + * "Wallpapers" are components that paint the background for Containments that + * do not provide their own background rendering. + * + * Wallpaper plugins are registered using .desktop files. These files should be + * named using the following naming scheme: + * + * plasma-wallpaper-<pluginname>.desktop + * + * If a wallpaper plugin provides more than on mode (e.g. Single Image, Wallpaper) + * it should include a Actions= entry in the .desktop file, listing the possible + * actions. An actions group should be included to provide for translatable names. + */ + +class PLASMA_EXPORT Wallpaper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QRectF boundingRect READ boundingRect WRITE setBoundingRect) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QString pluginName READ pluginName) + Q_PROPERTY(QString icon READ icon) + Q_PROPERTY(KServiceAction renderingMode READ renderingMode) + Q_PROPERTY(QList<KServiceAction> listRenderingModes READ listRenderingModes) + + public: + ~Wallpaper(); + + /** + * Returns a list of all known wallpapers. + * + * @return list of wallpapers + **/ + static KPluginInfo::List listWallpaperInfo(const QString &formFactor = QString()); + + /** + * Attempts to load an wallpaper + * + * Returns a pointer to the wallpaper if successful. + * The caller takes responsibility for the wallpaper, including + * deleting it when no longer needed. + * + * @param name the plugin name, as returned by KPluginInfo::pluginName() + * @param args to send the wallpaper extra arguments + * @return a pointer to the loaded wallpaper, or 0 on load failure + **/ + static Wallpaper* load(const QString &name, const QVariantList& args = QVariantList()); + + /** + * Attempts to load an wallpaper + * + * Returns a pointer to the wallpaper if successful. + * The caller takes responsibility for the wallpaper, including + * deleting it when no longer needed. + * + * @param info KPluginInfo object for the desired wallpaper + * @param args to send the wallpaper extra arguments + * @return a pointer to the loaded wallpaper, or 0 on load failure + **/ + static Wallpaper* load(const KPluginInfo& info, const QVariantList& args = QVariantList()); + + /** + * Returns the user-visible name for the wallpaper, as specified in the + * .desktop file. + * + * @return the user-visible name for the wallpaper. + **/ + QString name() const; + + /** + * Returns the plugin name for the wallpaper + */ + QString pluginName() const; + + /** + * Returns the icon related to this wallpaper + **/ + QString icon() const; + + /** + * @return the currently active rendering mode + */ + KServiceAction renderingMode() const; + + /** + * Returns modes the wallpaper has, as specified in the + * .desktop file. + */ + QList<KServiceAction> listRenderingModes() const; + + /** + * Returns bounding rectangle + */ + QRectF boundingRect() const; + + /** + * Sets bounding rectangle + */ + void setBoundingRect(const QRectF& boundingRect); + + /** + * This method is called when the wallpaper should be painted. + * + * @param painter the QPainter to use to do the painting + * @param exposedRect the rect to paint within + **/ + virtual void paint(QPainter *painter, const QRectF& exposedRect) = 0; + + /** + * This method should be called once the wallpaper is loaded or mode is changed. + * @param config Config group to load settings + * @param mode One of the modes supported by the plugin, + * or an empty string for the default mode. + * @see init + **/ + void restore(const KConfigGroup &config, const QString &mode = QString()); + + /** + * This method is called when settings need to be saved. + * @param config Config group to save settings + **/ + virtual void save(KConfigGroup &config); + + /** + * Returns widget for configuration dialog. + */ + virtual QWidget *createConfigurationInterface(QWidget *parent); + + /** + * Mouse move event. To prevent further propagation of the event, + * the event must be accepted. + * + * @param event the mouse event object + */ + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + + /** + * Mouse press event. To prevent further propagation of the even, + * and to receive mouseMoveEvents, the event must be accepted. + * + * @param event the mouse event object + */ + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + + /** + * Mouse release event. To prevent further propagation of the event, + * the event must be accepted. + * + * @param event the mouse event object + */ + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + /** + * Mouse wheel event. To prevent further propagation of the event, + * the event must be accepted. + * + * @param event the wheel event object + */ + virtual void wheelEvent(QGraphicsSceneWheelEvent *event); + + Q_SIGNALS: + /** + * This signal indicates that wallpaper needs to be repainted. + */ + void update(const QRectF &exposedArea); + + protected: + /** + * This constructor is to be used with the plugin loading systems + * found in KPluginInfo and KService. The argument list is expected + * to have one element: the KService service ID for the desktop entry. + * + * @param parent a QObject parent; you probably want to pass in 0 + * @param args a list of strings containing one entry: the service id + */ + Wallpaper(QObject* parent, const QVariantList& args); + + /** + * This method is called once the wallpaper is loaded or mode is changed. + * The mode can be retrieved using the @see renderMode() method. + * @param config Config group to load settings + * @param mode One of the modes supported by the plugin, + * or an empty string for the default mode. + **/ + virtual void init(const KConfigGroup &config); + + private: + WallpaperPrivate* const d; +}; + +} // Plasma namespace + +/** + * Register an wallpaper when it is contained in a loadable module + */ +#define K_EXPORT_PLASMA_WALLPAPER(libname, classname) \ +K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \ +K_EXPORT_PLUGIN(factory("plasma_wallpaper_" #libname)) \ +K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION) + +#endif // multiple inclusion guard --- taskmanager/task.cpp +++ taskmanager/task.cpp @@ -28,7 +28,13 @@ // Qt #include <QMimeData> #include <QTimer> +#include <QApplication> +#include <QDesktopWidget> +#ifdef Q_WS_X11 +#include <QX11Info> +#endif + // KDE #include <KDebug> #include <KIconLoader> @@ -73,6 +79,7 @@ int lastHeight; bool lastResize; QPixmap lastIcon; + QIcon icon; double thumbSize; QPixmap thumb; @@ -191,7 +198,8 @@ } d->lastIcon = QPixmap(); - emit iconChanged(); + d->icon = QIcon(); + emit changed(IconChanged); } void Task::refresh(unsigned int dirty) @@ -201,20 +209,46 @@ NET::WMState | NET::XAWMState | NET::WMDesktop | NET::WMVisibleName | NET::WMGeometry | NET::WMWindowType, NET::WM2AllowedActions); - if (dirty != NET::WMName || name != visibleName()) - { - emit changed(); + TaskChanges changes = TaskUnchanged; + + if (name != visibleName()) { + changes |= NameChanged; } + + if (dirty & NET::WMState || dirty & NET::XAWMState) { + changes |= StateChanged; + } + + if (dirty & NET::WMDesktop) { + changes |= DesktopChanged; + } + + if (dirty & NET::WMGeometry) { + changes |= GeometryChanged; + } + + if (dirty & NET::WMWindowType) { + changes |= WindowTypeChanged; + } + + if (dirty & NET::WM2AllowedActions) { + changes |= ActionsChanged; + } + + if (changes != TaskUnchanged) { + emit changed(changes); + } } void Task::setActive(bool a) { d->active = a; - emit changed(); - if ( a ) + emit changed(StateChanged); + if (a) { emit activated(); - else + } else { emit deactivated(); + } } double Task::thumbnailSize() const { return d->thumbSize; } @@ -357,7 +391,7 @@ if (info.state() & NET::DemandsAttention) { d->transientsDemandingAttention.append(w); - emit changed(); + emit changed(TransientsChanged); } } @@ -397,7 +431,7 @@ return d->info.name(); } -QString Task::className() +QString Task::className() const { XClassHint hint; if(XGetClassHint(QX11Info::display(), d->win, &hint)) { @@ -409,7 +443,7 @@ return QString(); } -QString Task::classClass() +QString Task::classClass() const { XClassHint hint; if(XGetClassHint(QX11Info::display(), d->win, &hint)) { @@ -440,6 +474,22 @@ return newIcon; } +QIcon Task::icon() +{ + if ( !d->icon.isNull() ) + return d->icon; + + d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmall, KIconLoader::SizeSmall, false)); + d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium, false)); + d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeMedium, KIconLoader::SizeMedium, false)); + d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeLarge, KIconLoader::SizeLarge, false)); + + return d->icon; +} + + + + WindowList Task::transients() const { return d->transients; --- taskmanager/taskmanager.h +++ taskmanager/taskmanager.h @@ -28,6 +28,7 @@ // Own #include "startup.h" #include "task.h" +#include <taskmanager/taskmanager_export.h> namespace TaskManager { --- taskmanager/taskmanager_export.h +++ taskmanager/taskmanager_export.h @@ -0,0 +1,45 @@ +/***************************************************************** + +Copyright 2008 Aaron Seigo <aseigo@kde.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + + +#ifndef TASKMANAGER_EXPORT_H +#define TASKMANAGER_EXPORT_H + +/* needed for TASKMANAGER_EXPORT and KDE_IMPORT macros */ +#include <kdemacros.h> + +#ifndef TASKMANAGER_EXPORT +# if defined(MAKE_TASKMANAGER_LIB) + /* We are building this library */ +# define TASKMANAGER_EXPORT KDE_EXPORT +# else + /* We are using this library */ +# define TASKMANAGER_EXPORT KDE_IMPORT +# endif +#endif + +# ifndef TASKMANAGER_EXPORT_DEPRECATED +# define TASKMANAGER_EXPORT_DEPRECATED KDE_DEPRECATED TASKMANAGER_EXPORT +# endif + +#endif --- taskmanager/task.h +++ taskmanager/task.h @@ -29,12 +29,16 @@ #include <QtGui/QDrag> #include <QtGui/QPixmap> #include <QtGui/QWidget> +#include <QtCore/QHash> +#include <QtGui/QIcon> // KDE -#include <ksharedptr.h> -#include <kwindowsystem.h> -#include <netwm.h> +#include <KDE/KSharedPtr> +#include <KDE/KWindowSystem> +#include <KDE/NETWinInfo> +#include <taskmanager/taskmanager_export.h> + namespace TaskManager { @@ -43,8 +47,21 @@ class Task; typedef KSharedPtr<Task> TaskPtr; typedef QVector<TaskPtr> TaskList; -typedef QMap<WId, TaskPtr> TaskDict; +typedef QHash<WId, TaskPtr> TaskDict; +enum TaskChange { TaskUnchanged = 0, + NameChanged = 1, + StateChanged = 2, + DesktopChanged = 32, + GeometryChanged = 64, + WindowTypeChanged = 128, + ActionsChanged = 256, + TransientsChanged = 512, + IconChanged = 1024, + EverythingChanged = 0xffff + }; +Q_DECLARE_FLAGS(TaskChanges, TaskChange) + /** * A dynamic interface to a task (main window). * @@ -84,8 +101,8 @@ QString visibleName() const; QString visibleNameWithState() const; QString name() const; - QString className(); - QString classClass(); + QString className() const; + QString classClass() const; /** * A list of the window ids of all transient windows (dialogs) associated @@ -127,6 +144,11 @@ QPixmap icon( int width, int height, bool allowResize = false ); /** + * \return a QIcon for the task + */ + QIcon icon(); + + /** * Returns true iff the windows with the specified ids should be grouped * together in the task list. */ @@ -388,14 +410,9 @@ /** * Indicates that this task has changed in some way. */ - void changed(); + void changed(::TaskManager::TaskChanges change); /** - * Indicates that the icon for this task has changed. - */ - void iconChanged(); - - /** * Indicates that this task is now the active task. */ void activated(); --- taskmanager/CMakeLists.txt +++ taskmanager/CMakeLists.txt @@ -21,6 +21,6 @@ set_target_properties(taskmanager PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) install(TARGETS taskmanager ${INSTALL_TARGETS_DEFAULT_ARGS} ) -install( FILES task.h startup.h taskmanager.h DESTINATION ${INCLUDE_INSTALL_DIR}/taskmanager COMPONENT Devel ) +install( FILES task.h startup.h taskmanager.h taskmanager_export.h DESTINATION ${INCLUDE_INSTALL_DIR}/taskmanager COMPONENT Devel )
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor