/* * Copyright 2011 by Aaron Seigo * * 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 "graphicsviewappletprivate_p.h" #include #include #include "kwindowsystem.h" #include "corona.h" #include "dialog.h" #include "paintutils.h" #include "popupapplet.h" #include "theme.h" #include "tooltipmanager.h" #include "widgets/busywidget.h" #include "widgets/iconwidget.h" #include "widgets/label.h" #include "widgets/pushbutton.h" namespace Plasma { GraphicsViewAppletPrivate::GraphicsViewAppletPrivate(KService::Ptr service, const KPluginInfo *info, int uniqueID, Applet *applet) : AppletPrivate(service, info, uniqueID, applet), messageOverlay(0), messageOverlayProxy(0), busyWidget(0) { q->setCacheMode(QGraphicsItem::DeviceCoordinateCache); q->setAcceptsHoverEvents(true); q->setFlag(QGraphicsItem::ItemIsFocusable, true); q->setFocusPolicy(Qt::ClickFocus); // FIXME: adding here because nothing seems to be doing it in QGraphicsView, // but it doesn't actually work anyways =/ q->setLayoutDirection(qApp->layoutDirection()); } void GraphicsViewAppletPrivate::showMessage(const QIcon &icon, const QString &message, const MessageButtons buttons) { if (message.isEmpty()) { destroyMessageOverlay(); return; } Corona *corona = qobject_cast(q->scene()); QGraphicsWidget *mainWidget = new QGraphicsWidget; QGraphicsLinearLayout *mainLayout = new QGraphicsLinearLayout(mainWidget); mainLayout->setOrientation(Qt::Vertical); mainLayout->addStretch(); QGraphicsLinearLayout *messageLayout = new QGraphicsLinearLayout(); messageLayout->setOrientation(Qt::Horizontal); QGraphicsLinearLayout *buttonLayout = new QGraphicsLinearLayout(); buttonLayout->setOrientation(Qt::Horizontal); mainLayout->addItem(messageLayout); mainLayout->addItem(buttonLayout); mainLayout->addStretch(); IconWidget *messageIcon = new IconWidget(mainWidget); Label *messageText = new Label(mainWidget); messageText->nativeWidget()->setWordWrap(true); messageLayout->addStretch(); messageLayout->addItem(messageIcon); messageLayout->addItem(messageText); messageLayout->addStretch(); messageIcon->setIcon(icon); messageText->setText(message); buttonLayout->addStretch(); if (buttons & ButtonOk) { messageOkButton = new PushButton(mainWidget); messageOkButton.data()->setText(i18n("&OK")); messageOkButton.data()->setIcon(KDE::icon("dialog-ok")); buttonLayout->addItem(messageOkButton.data()); QObject::connect(messageOkButton.data(), SIGNAL(clicked()), q, SLOT(destroyMessageOverlay())); } if (buttons & ButtonYes) { messageYesButton = new PushButton(mainWidget); messageYesButton.data()->setText(i18n("&Yes")); buttonLayout->addItem(messageYesButton.data()); QObject::connect(messageYesButton.data(), SIGNAL(clicked()), q, SLOT(destroyMessageOverlay())); } if (buttons & ButtonNo) { messageNoButton = new PushButton(mainWidget); messageNoButton.data()->setText(i18n("&No")); buttonLayout->addItem(messageNoButton.data()); QObject::connect(messageNoButton.data(), SIGNAL(clicked()), q, SLOT(destroyMessageOverlay())); } if (buttons & ButtonCancel) { messageCancelButton = new PushButton(mainWidget); messageCancelButton.data()->setText(i18n("&Cancel")); messageCancelButton.data()->setIcon(KDE::icon("dialog-cancel")); buttonLayout->addItem(messageCancelButton.data()); QObject::connect(messageCancelButton.data(), SIGNAL(clicked()), q, SLOT(destroyMessageOverlay())); } messageCloseAction = new QAction(messageOverlay); messageCloseAction.data()->setShortcut(Qt::Key_Escape); mainWidget->addAction(messageCloseAction.data()); QObject::connect(messageCloseAction.data(), SIGNAL(triggered()), q, SLOT(destroyMessageOverlay())); buttonLayout->addStretch(); mainWidget->adjustSize(); QSizeF hint = mainWidget->preferredSize(); if (hint.height() > q->size().height() || hint.width() > q->size().width()) { // either a collapsed popup in h/v form factor or just too small, // so show it in a dialog associated with ourselves if (corona) { corona->addOffscreenWidget(mainWidget); } if (messageDialog) { delete messageDialog.data()->graphicsWidget(); } else { messageDialog = new Plasma::Dialog; } ToolTipManager::self()->hide(q); KWindowSystem::setOnAllDesktops(messageDialog.data()->winId(), true); KWindowSystem::setState(messageDialog.data()->winId(), NET::SkipTaskbar | NET::SkipPager); messageDialog.data()->setGraphicsWidget(mainWidget); QObject::connect(messageDialog.data(), SIGNAL(destroyed(QObject*)), mainWidget, SLOT(deleteLater())); // if we are going to show it in a popup, then at least make sure it can be dismissed if (buttonLayout->count() < 1) { PushButton *ok = new PushButton(mainWidget); ok->setText(i18n("OK")); ok->setIcon(KDE::icon("dialog-ok")); buttonLayout->addItem(ok); QObject::connect(ok, SIGNAL(clicked()), q, SLOT(destroyMessageOverlay())); } } else { delete messageDialog.data(); createMessageOverlay(); messageOverlay->opacity = 0.8; mainWidget->setParentItem(messageOverlay); QGraphicsLinearLayout *l = new QGraphicsLinearLayout(messageOverlay); l->addItem(mainWidget); } if (messageDialog) { QPoint pos = q->geometry().topLeft().toPoint(); if (corona) { pos = corona->popupPosition(q, messageDialog.data()->size()); } messageDialog.data()->move(pos); messageDialog.data()->animatedShow(locationToDirection(q->location())); } else { messageOverlay->show(); } } void GraphicsViewAppletPrivate::updateFailedToLaunch(const QString &reason) { if (failed == failed) { if (failed && !reason.isEmpty()) { foreach (QGraphicsItem *item, q->QGraphicsItem::children()) { Label *l = dynamic_cast