remove classes that weren't built anymore

PopupApplet
Dialog
ToolTip
ToolTipManager
ToolTipContent
This commit is contained in:
Marco Martin 2012-11-09 14:00:01 +01:00
parent 4e08835046
commit 81d2a33a0f
15 changed files with 0 additions and 4043 deletions

View File

@ -133,7 +133,6 @@ set(plasma_LIB_SRCS
private/serviceprovider.cpp
private/storage.cpp
private/storagethread.cpp
private/tooltip.cpp
private/wallpaperrenderthread.cpp
private/windowpreview.cpp
private/windowshadows.cpp
@ -166,9 +165,6 @@ set(plasma_LIB_SRCS
servicejob.cpp
svg.cpp
theme.cpp
tooltipcontent.cpp
#FIXME: re-enable
#tooltipmanager.cpp
version.cpp
wallpaper.cpp
@ -186,34 +182,11 @@ set(plasma_LIB_SRCS
private/qtjolie-branch/qtjolie/pendingreply.cpp
private/qtjolie-branch/qtjolie/server.cpp
private/qtjolie-branch/qtjolie/serverthread.cpp
#FIXME: all these must move into the qgv library
#view.cpp
applet.cpp
containment.cpp
corona.cpp
#dialog.cpp
#should popupapplet still exist?
#popupapplet.cpp
)
#TODO: all those files will have to be deleted
# set (plasmaqgv_LIB_SRCS
# dialog.cpp
# view.cpp
# private/themedwidgetinterface.cpp
# widgets/iconwidget.cpp
# #FIXME: this is duplicated with libplasma because iconwidget requires it!
# private/themedwidgetinterface.cpp
#
# graphicsview/private/graphicsviewappletprivate.cpp
#
# private/declarative/declarativenetworkaccessmanagerfactory.cpp
# private/declarative/dataenginebindings.cpp
#
# widgets/declarativewidget.cpp
# )
kconfig_add_kcfg_files(plasma_LIB_SRCS data/kconfigxt/libplasma-theme-global.kcfgc)
kde4_add_ui_files(plasma_LIB_SRCS
@ -272,7 +245,6 @@ set(plasma_LIB_INCLUDES
corona.h
datacontainer.h
dataengine.h
dialog.h
pluginloader.h
paintutils.h
framesvg.h
@ -280,7 +252,6 @@ set(plasma_LIB_INCLUDES
packagestructure.h
plasma.h
${CMAKE_CURRENT_BINARY_DIR}/plasma_export.h
popupapplet.h
querymatch.h
remote/accessappletjob.h
remote/accessmanager.h
@ -297,8 +268,6 @@ set(plasma_LIB_INCLUDES
servicejob.h
svg.h
theme.h
tooltipcontent.h
tooltipmanager.h
version.h
view.h
wallpaper.h)
@ -319,7 +288,6 @@ install(FILES
install(FILES
data/servicetypes/plasma-applet.desktop
data/servicetypes/plasma-applet-popupapplet.desktop
data/servicetypes/plasma-containment.desktop
data/servicetypes/plasma-containmentactions.desktop
data/servicetypes/plasma-dataengine.desktop

View File

@ -84,7 +84,6 @@
#include "remote/authorizationmanager.h"
#include "remote/authorizationmanager_p.h"
#include "theme.h"
#include "tooltipmanager.h"
#include "wallpaper.h"
#include "paintutils.h"
#include "abstractdialogmanager.h"

View File

@ -45,7 +45,6 @@
#include "pluginloader.h"
#include "private/applet_p.h"
#include "private/containment_p.h"
#include "tooltipmanager.h"
#include "view.h"
using namespace Plasma;

View File

@ -1,73 +0,0 @@
[Desktop Entry]
Type=ServiceType
X-KDE-ServiceType=Plasma/PopupApplet
Comment=Plasma scripting popup applet
Comment[ar]=بريمج منبثق بواسطة سكربت بلازما
Comment[ast]=Miniaplicación emerxente de script pa Plasma
Comment[be@latin]=Skryptavy vypłyŭny aplet Plasma
Comment[bg]=Аплет за Plasma за скриптове за изскачащи прозорци
Comment[bs]=Plazma skriptovani iskačući aplet
Comment[ca]=Miniaplicació emergent d'scripting del Plasma
Comment[ca@valencia]=Miniaplicació emergent d'scripting del Plasma
Comment[cs]=Skriptovací vyskakující Plasma applet
Comment[da]=Popop-applet til Plasma-scripting
Comment[de]=Plasma-Skript-Miniprogramm
Comment[el]=Αναδυόμενη μικροεφαρμογή σεναρίου plasma
Comment[en_GB]=Plasma scripting popup applet
Comment[es]=Miniaplicación emergente de script para Plasma
Comment[et]=Plasma skriptimise hüpikaplett
Comment[eu]=Plasma scripting popup appleta
Comment[fi]=Skriptikielellä tehty Plasma-ponnahdussovelma
Comment[fr]=Applet de script Plasma
Comment[fy]=Plasma scripting popup applet
Comment[ga]=Feidhmchláirín aníos scriptithe Plasma
Comment[gl]=Applet contextual de scripts de Plasma
Comment[gu]= િ
Comment[he]=תפריט מוקפץ עבור יישומון תסריט של Plasma
Comment[hr]=Plasmin skriptni skočni applet
Comment[hu]=Szkriptkezelő kisalkalmazás a Plasmához
Comment[ia]=Applet popup de scripting de Plasma
Comment[id]=Applet popup skrip Plasma
Comment[is]=Plasma smáforrit fyrir skriftun
Comment[it]=Applet Plasma scripting a comparsa
Comment[ja]=Plasma
Comment[kk]=Қалқымалы Plasma скрипт апплеті
Comment[km]=
Comment[kn]= ಿಿ (ಿ) ಿ ಿ () ()
Comment[ko]=Plasma 릿
Comment[ku]=Sepanoka skrîptkirina agahiyan ya Plasma
Comment[lv]=Plasma skriptu uznirstošais logs
Comment[ml]= ിിി ി
Comment[nb]=Oppsprett-miniprogram for Plasma-skripting
Comment[nds]=Skript-Opduklüttprogramm vun Plasma
Comment[nl]=Plasma-applet voor scripting-popup
Comment[nn]=Sprettoppelement for Plasma-skript
Comment[pa]= ਿਿ ਿ
Comment[pl]=Aplet Plazmy do skryptów
Comment[pt]='Applet' de programação do Plasma
Comment[pt_BR]=Miniaplicativo de script do Plasma
Comment[ro]=Miniaplicație Plasma de indicii ale scripturilor
Comment[ru]=Аплет программируемого контекстного окна Plasma
Comment[se]=Plasma-skripten báhccanprográmmaš
Comment[si]= -
Comment[sk]=Skriptovací vyskakujúci Plasma aplet
Comment[sl]=Plasma skriptni pojavni programček
Comment[sr]=Плазма скриптовани искачући аплет
Comment[sr@ijekavian]=Плазма скриптовани искачући аплет
Comment[sr@ijekavianlatin]=Plasma skriptovani iskačući aplet
Comment[sr@latin]=Plasma skriptovani iskačući aplet
Comment[sv]=Plasmaskript-miniprogram
Comment[ta]=ி scripting popup applet
Comment[tg]=Барномаи скрипти пайдошавандаи Plasma
Comment[th]=
Comment[tr]=Plasma betik kullanan açılabilir gereci
Comment[tt]=Plasma контекст тәрәзә өчен программалау кушымтасы
Comment[ug]=Plasma قوليازماسىمان قاڭقىشچان قوللانچاق
Comment[uk]=Аплет програмованого контекстного вікна Плазми
Comment[wa]=Aplikete di scriptaedje d' aspitant purnea di Plasma
Comment[x-test]=xxPlasma scripting popup appletxx
Comment[zh_CN]=Plasma
Comment[zh_TW]=Plasma 稿

View File

@ -1,864 +0,0 @@
/*
* Copyright 2008 by Alessandro Diaferia <alediaferia@gmail.com>
* Copyright 2007 by Alexis ©nard <darktears31@gmail.com>
* Copyright 2007 Sebastian Kuegler <sebas@kde.org>
* Copyright 2006 Aaron Seigo <aseigo@kde.org>
*
* 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 "dialog.h"
#include "private/dialog_p.h"
#include <QPainter>
#include <QSvgRenderer>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QBitmap>
#include <QTimer>
#include <QVBoxLayout>
#include <QGraphicsSceneEvent>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include <QApplication>
#include <QDesktopWidget>
#include <QVarLengthArray>
#include <QGraphicsLayout>
#include <kdebug.h>
#include <kwindoweffects.h>
#include <kwindowsystem.h>
#include <netwm.h>
#include "plasma/applet.h"
#include "plasma/animator.h"
#include "plasma/containment.h"
#include "plasma/corona.h"
#include "plasma/framesvg.h"
#include "plasma/theme.h"
#include "plasma/widgets/scrollwidget.h"
#include "plasma/private/windowshadows_p.h"
namespace Plasma
{
void DialogPrivate::scheduleBorderCheck(bool triggeredByResize)
{
//kDebug();
if (triggeredByResize) {
resizeChecksWithBorderCheck = true;
// to keep the UI as fluid as possible, we call checkBorders
// immediately when there is a resize, and therefore stop any
// move-triggered scheduled calls to it. this keeps things
// looking reasonable during resize while avoiding as many
// calls to checkBorders as possible
if (moveTimer) {
moveTimer->stop();
}
checkBorders();
return;
}
if (!moveTimer) {
moveTimer = new QTimer(q);
moveTimer->setSingleShot(true);
QObject::connect(moveTimer, SIGNAL(timeout()), q, SLOT(checkBorders()));
}
moveTimer->start(0);
}
void DialogPrivate::themeChanged()
{
checkBorders(false);
if (background->hasElement("shadow-top")) {
WindowShadows::self()->addWindow(q);
} else {
WindowShadows::self()->removeWindow(q);
}
const bool translucency = Plasma::Theme::defaultTheme()->windowTranslucencyEnabled();
// WA_NoSystemBackground is going to fail combined with sliding popups, but is needed
// when we aren't compositing
q->setAttribute(Qt::WA_NoSystemBackground, !translucency);
updateMask();
q->update();
}
void DialogPrivate::updateMask()
{
const bool translucency = Plasma::Theme::defaultTheme()->windowTranslucencyEnabled();
KWindowEffects::enableBlurBehind(q->winId(), translucency,
translucency ? background->mask() : QRegion());
if (translucency) {
q->clearMask();
} else {
q->setMask(background->mask());
}
}
void DialogPrivate::checkBorders()
{
checkBorders(true);
}
void DialogPrivate::delayedAdjustSize()
{
q->syncToGraphicsWidget();
}
void DialogPrivate::checkBorders(bool updateMaskIfNeeded)
{
if (resizeChecksWithBorderCheck) {
background->resizeFrame(q->size());
}
QGraphicsWidget *graphicsWidget = graphicsWidgetPtr.data();
const FrameSvg::EnabledBorders currentBorders = background->enabledBorders();
FrameSvg::EnabledBorders borders = FrameSvg::AllBorders;
Plasma::Applet *applet = appletPtr.data();
//used to remove borders at the edge of the desktop
QRect avail;
QRect screenGeom;
QDesktopWidget *desktop = QApplication::desktop();
Plasma::Corona *c = 0;
if (applet) {
c = qobject_cast<Plasma::Corona *>(applet->scene());
} else if (graphicsWidget) {
c = qobject_cast<Plasma::Corona *>(graphicsWidget->scene());
}
if (c) {
QRegion r = c->availableScreenRegion(desktop->screenNumber(q));
QRect maxRect;
foreach (QRect rect, r.rects()) {
if (rect.width() > maxRect.width() && rect.height() > maxRect.height()) {
maxRect = rect;
}
}
avail = maxRect;
screenGeom = c->screenGeometry(desktop->screenNumber(q));
} else {
avail = desktop->availableGeometry(desktop->screenNumber(q));
screenGeom = desktop->screenGeometry(desktop->screenNumber(q));
}
QRect dialogGeom = q->geometry();
qreal topHeight(0);
qreal leftWidth(0);
qreal rightWidth(0);
qreal bottomHeight(0);
//decide about disabling the border attached to the panel
//don't cut borders on tooltips
if (applet && !q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) {
background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
switch (applet->location()) {
case BottomEdge:
if (applet->containment() &&
dialogGeom.bottom() + 2 >= screenGeom.bottom() - applet->containment()->size().height() &&
dialogGeom.width() <= applet->containment()->size().width()) {
borders &= ~FrameSvg::BottomBorder;
leftWidth = 0;
rightWidth = 0;
bottomHeight = 0;
}
break;
case TopEdge:
if (applet->containment() &&
dialogGeom.top() <= screenGeom.top() + applet->containment()->size().height() &&
dialogGeom.width() <= applet->containment()->size().width()) {
borders &= ~FrameSvg::TopBorder;
topHeight = 0;
leftWidth = 0;
rightWidth = 0;
}
break;
case LeftEdge:
if (applet->containment() &&
dialogGeom.left() <= screenGeom.left() + applet->containment()->size().width() &&
dialogGeom.height() <= applet->containment()->size().height()) {
borders &= ~FrameSvg::LeftBorder;
leftWidth = 0;
rightWidth = 0;
}
break;
case RightEdge:
if (applet->containment() &&
dialogGeom.right() + 2 >= screenGeom.right() - applet->containment()->size().width() &&
dialogGeom.height() <= applet->containment()->size().height()) {
borders &= ~FrameSvg::RightBorder;
leftWidth = 0;
rightWidth = 0;
}
break;
default:
break;
}
}
//decide if to disable the other borders
if (q->isVisible() && !q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) {
if (dialogGeom.left() <= avail.left()) {
borders &= ~FrameSvg::LeftBorder;
}
if (dialogGeom.top() <= avail.top()) {
borders &= ~FrameSvg::TopBorder;
}
//FIXME: that 2 pixels offset has probably something to do with kwin
if (dialogGeom.right() + 2 > avail.right()) {
borders &= ~FrameSvg::RightBorder;
}
if (dialogGeom.bottom() + 2 > avail.bottom()) {
borders &= ~FrameSvg::BottomBorder;
}
}
background->setEnabledBorders(borders);
background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
//kDebug() << leftWidth << topHeight << rightWidth << bottomHeight;
q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
if (resizeChecksWithBorderCheck) {
updateResizeCorners();
updateMask();
q->update();
} else if (currentBorders != borders) {
if (updateMaskIfNeeded) {
updateMask();
}
q->update();
}
resizeChecksWithBorderCheck = false;
}
void Dialog::syncToGraphicsWidget()
{
d->adjustViewTimer->stop();
QGraphicsWidget *graphicsWidget = d->graphicsWidgetPtr.data();
if (d->view && graphicsWidget && d->resizeStartCorner != -1) {
const int prevStartCorner = d->resizeStartCorner;
d->resizeStartCorner = -1;
QSize prevSize = size();
/*
#ifndef NDEBUG
kDebug() << "Widget size:" << graphicsWidget->size()
#endif
<< "| Widget size hint:" << graphicsWidget->effectiveSizeHint(Qt::PreferredSize)
<< "| Widget minsize hint:" << graphicsWidget->minimumSize()
<< "| Widget maxsize hint:" << graphicsWidget->maximumSize()
<< "| Widget bounding rect:" << graphicsWidget->sceneBoundingRect();
*/
//set the sizehints correctly:
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QDesktopWidget *desktop = QApplication::desktop();
QSize maxSize = desktop->availableGeometry(desktop->screenNumber(this)).size();
setMinimumSize(0, 0);
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
QSize newSize(qMin(int(graphicsWidget->size().width()) + left + right, maxSize.width()),
qMin(int(graphicsWidget->size().height()) + top + bottom, maxSize.height()));
const QSizeF minimum = graphicsWidget->effectiveSizeHint(Qt::MinimumSize);
QSize newMinimumSize(qMin(int(minimum.width()) + left + right, maxSize.width()),
qMin(int(minimum.height()) + top + bottom, maxSize.height()));
QSize newMaximumSize(qMin(int(graphicsWidget->maximumSize().width()) + left + right, maxSize.width()),
qMin(int(graphicsWidget->maximumSize().height()) + top + bottom, maxSize.height()));
Plasma::Applet *applet = d->appletPtr.data();
if (applet) {
QRect currentGeometry(geometry());
currentGeometry.setSize(newSize);
if (applet->location() == Plasma::TopEdge ||
applet->location() == Plasma::LeftEdge) {
currentGeometry.setSize(newSize);
} else if (applet->location() == Plasma::RightEdge) {
currentGeometry.moveTopRight(geometry().topRight());
//BottomEdge and floating
} else {
currentGeometry.moveBottomLeft(geometry().bottomLeft());
}
setGeometry(currentGeometry);
} else {
resize(newSize);
}
setMinimumSize(newMinimumSize);
setMaximumSize(newMaximumSize);
updateGeometry();
//reposition and resize the view.
//force a valid rect, otherwise it will take up the whole scene
QRectF sceneRect(graphicsWidget->sceneBoundingRect());
sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
d->view->setSceneRect(sceneRect);
//d->view->resize(graphicsWidget->size().toSize());
d->view->centerOn(graphicsWidget);
if (size() != prevSize) {
//the size of the dialog has changed, emit the signal:
emit dialogResized();
}
d->resizeStartCorner = prevStartCorner;
}
}
int DialogPrivate::calculateWidthForHeightAndRatio(int height, qreal ratio)
{
switch (aspectRatioMode) {
case KeepAspectRatio:
return qRound(height * ratio);
break;
case Square:
return height;
break;
case ConstrainedSquare:
return height;
break;
default:
return -1;
}
}
Dialog::Dialog(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f | Qt::FramelessWindowHint),
d(new DialogPrivate(this))
{
setMouseTracking(true);
setAttribute(Qt::WA_TranslucentBackground);
d->background = new FrameSvg(this);
d->background->setImagePath("dialogs/background");
d->background->setEnabledBorders(FrameSvg::AllBorders);
d->background->resizeFrame(size());
connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(themeChanged()));
QPalette pal = palette();
pal.setColor(backgroundRole(), Qt::transparent);
setPalette(pal);
KWindowEffects::overrideShadow(winId(), true);
d->adjustViewTimer = new QTimer(this);
d->adjustViewTimer->setSingleShot(true);
connect(d->adjustViewTimer, SIGNAL(timeout()), this, SLOT(syncToGraphicsWidget()));
d->adjustSizeTimer = new QTimer(this);
d->adjustSizeTimer->setSingleShot(true);
connect(d->adjustSizeTimer, SIGNAL(timeout()), this, SLOT(delayedAdjustSize()));
d->themeChanged();
}
Dialog::~Dialog()
{
delete d;
}
void Dialog::paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.setCompositionMode(QPainter::CompositionMode_Source);
d->background->paintFrame(&p, e->rect(), e->rect());
}
void Dialog::mouseMoveEvent(QMouseEvent *event)
{
if (event->modifiers() == Qt::AltModifier) {
unsetCursor();
} else if (d->resizeAreas[Dialog::NorthEast].contains(event->pos())) {
setCursor(Qt::SizeBDiagCursor);
} else if (d->resizeAreas[Dialog::NorthWest].contains(event->pos())) {
setCursor(Qt::SizeFDiagCursor);
} else if (d->resizeAreas[Dialog::SouthEast].contains(event->pos())) {
setCursor(Qt::SizeFDiagCursor);
} else if (d->resizeAreas[Dialog::SouthWest].contains(event->pos())) {
setCursor(Qt::SizeBDiagCursor);
} else if (!(event->buttons() & Qt::LeftButton)) {
unsetCursor();
}
// here we take care of resize..
if (d->resizeStartCorner != Dialog::NoCorner) {
int newWidth;
int newHeight;
QPoint position;
qreal aspectRatio = (qreal)width() / (qreal)height();
switch(d->resizeStartCorner) {
case Dialog::NorthEast:
newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() - event->y()));
newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
if (newWidth == -1) {
newWidth = qMin(maximumWidth(), qMax(minimumWidth(), event->x()));
}
position = QPoint(x(), y() + height() - newHeight);
break;
case Dialog::NorthWest:
newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() - event->y()));
newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
if (newWidth == -1) {
newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() - event->x()));
}
position = QPoint(x() + width() - newWidth, y() + height() - newHeight);
break;
case Dialog::SouthWest:
newHeight = qMin(maximumHeight(), qMax(minimumHeight(), event->y()));
newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
if (newWidth == -1) {
newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() - event->x()));
}
position = QPoint(x() + width() - newWidth, y());
break;
case Dialog::SouthEast:
newHeight = qMin(maximumHeight(), qMax(minimumHeight(), event->y()));
newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
if (newWidth == -1) {
newWidth = qMin(maximumWidth(), qMax(minimumWidth(), event->x()));
}
position = QPoint(x(), y());
break;
default:
newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height()));
newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
if (newWidth == -1) {
newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width()));
}
position = QPoint(x(), y());
break;
}
QRect newGeom(position, QSize(newWidth, newHeight));
// now sanity check the resize results again min constraints, if any
if (d->leftResizeMin > -1 && newGeom.left() > d->leftResizeMin) {
newGeom.setLeft(d->leftResizeMin);
}
if (d->topResizeMin > -1 && newGeom.top() > d->topResizeMin) {
newGeom.setTop(d->topResizeMin);
}
if (d->rightResizeMin > -1 && newGeom.right() < d->rightResizeMin) {
newGeom.setRight(d->rightResizeMin);
}
if (d->bottomResizeMin > -1 && newGeom.bottom() < d->bottomResizeMin) {
newGeom.setBottom(d->bottomResizeMin);
}
if ((newGeom.width() >= minimumSize().width()) && (newGeom.height() >= minimumSize().height())) {
setGeometry(newGeom);
}
}
QWidget::mouseMoveEvent(event);
}
void Dialog::mousePressEvent(QMouseEvent *event)
{
if (d->resizeAreas[Dialog::NorthEast].contains(event->pos())) {
d->resizeStartCorner = Dialog::NorthEast;
} else if (d->resizeAreas[Dialog::NorthWest].contains(event->pos())) {
d->resizeStartCorner = Dialog::NorthWest;
} else if (d->resizeAreas[Dialog::SouthEast].contains(event->pos())) {
d->resizeStartCorner = Dialog::SouthEast;
} else if (d->resizeAreas[Dialog::SouthWest].contains(event->pos())) {
d->resizeStartCorner = Dialog::SouthWest;
} else {
d->resizeStartCorner = Dialog::NoCorner;
}
QWidget::mousePressEvent(event);
}
void Dialog::mouseReleaseEvent(QMouseEvent *event)
{
if (d->resizeStartCorner != Dialog::NoCorner) {
emit dialogResized();
d->resizeStartCorner = Dialog::NoCorner;
unsetCursor();
}
QWidget::mouseReleaseEvent(event);
}
void Dialog::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape) {
hide();
}
}
bool Dialog::event(QEvent *event)
{
return QWidget::event(event);
}
void Dialog::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
//kDebug();
d->scheduleBorderCheck(true);
if (d->resizeStartCorner != -1 && d->view && d->graphicsWidgetPtr) {
QGraphicsWidget *graphicsWidget = d->graphicsWidgetPtr.data();
graphicsWidget->resize(d->view->size());
QRectF sceneRect(graphicsWidget->sceneBoundingRect());
sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
d->view->setSceneRect(sceneRect);
d->view->centerOn(graphicsWidget);
}
}
void DialogPrivate::updateResizeCorners()
{
const int resizeAreaMargin = 20;
const QRect r = q->rect();
const FrameSvg::EnabledBorders borders = background->enabledBorders();
// IMPLEMENTATION NOTE: we set resize corners for the corners set, but also
// for the complimentary corners if we've cut out an edge of our SVG background
// which implies we are up against an immovable edge (e.g. a screen edge)
resizeAreas.clear();
if (resizeCorners & Dialog::NorthEast ||
(resizeCorners & Dialog::NorthWest && !(borders & FrameSvg::LeftBorder)) ||
(resizeCorners & Dialog::SouthEast && !(borders & FrameSvg::BottomBorder))) {
resizeAreas[Dialog::NorthEast] = QRect(r.right() - resizeAreaMargin, 0,
resizeAreaMargin, resizeAreaMargin);
}
if (resizeCorners & Dialog::NorthWest ||
(resizeCorners & Dialog::NorthEast && !(borders & FrameSvg::RightBorder)) ||
(resizeCorners & Dialog::SouthWest && !(borders & FrameSvg::BottomBorder))) {
resizeAreas[Dialog::NorthWest] = QRect(0, 0, resizeAreaMargin, resizeAreaMargin);
}
if (resizeCorners & Dialog::SouthEast ||
(resizeCorners & Dialog::SouthWest && !(borders & FrameSvg::LeftBorder)) ||
(resizeCorners & Dialog::NorthEast && !(borders & FrameSvg::TopBorder))) {
resizeAreas[Dialog::SouthEast] = QRect(r.right() - resizeAreaMargin,
r.bottom() - resizeAreaMargin,
resizeAreaMargin, resizeAreaMargin);
}
if (resizeCorners & Dialog::SouthWest ||
(resizeCorners & Dialog::SouthEast && !(borders & FrameSvg::RightBorder)) ||
(resizeCorners & Dialog::NorthWest && !(borders & FrameSvg::TopBorder))) {
resizeAreas[Dialog::SouthWest] = QRect(0, r.bottom() - resizeAreaMargin,
resizeAreaMargin, resizeAreaMargin);
}
}
void Dialog::setGraphicsWidget(QGraphicsWidget *widget)
{
if (d->graphicsWidgetPtr) {
d->graphicsWidgetPtr.data()->removeEventFilter(this);
}
d->graphicsWidgetPtr = widget;
if (widget) {
Plasma::Corona *c = qobject_cast<Plasma::Corona *>(widget->scene());
if (c) {
c->addOffscreenWidget(widget);
}
if (!layout()) {
QVBoxLayout *lay = new QVBoxLayout(this);
lay->setMargin(0);
lay->setSpacing(0);
}
d->checkBorders();
if (!d->view) {
d->view = new QGraphicsView(this);
d->view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->view->setFrameShape(QFrame::NoFrame);
d->view->viewport()->setAutoFillBackground(false);
layout()->addWidget(d->view);
}
d->view->setScene(widget->scene());
//try to have the proper size -before- showing the dialog
d->view->centerOn(widget);
if (widget->layout()) {
widget->layout()->activate();
}
static_cast<QGraphicsLayoutItem *>(widget)->updateGeometry();
widget->resize(widget->size().expandedTo(widget->effectiveSizeHint(Qt::MinimumSize)));
syncToGraphicsWidget();
//d->adjustSizeTimer->start(150);
widget->installEventFilter(this);
d->view->installEventFilter(this);
} else {
delete d->view;
d->view = 0;
}
}
QGraphicsWidget *Dialog::graphicsWidget() const
{
return d->graphicsWidgetPtr.data();
}
bool Dialog::eventFilter(QObject *watched, QEvent *event)
{
if (d->resizeStartCorner == Dialog::NoCorner && watched == d->graphicsWidgetPtr.data() &&
(event->type() == QEvent::GraphicsSceneResize || event->type() == QEvent::GraphicsSceneMove)) {
d->adjustViewTimer->start(150);
}
// when moving the cursor with a 45° angle from the outside
// to the inside passing over a resize angle the cursor changes its
// shape to a resize cursor. As a side effect this is the only case
// when the cursor immediately enters the view without giving
// the dialog the chance to restore the original cursor shape.
if (event->type() == QEvent::Enter && watched == d->view) {
unsetCursor();
}
return QWidget::eventFilter(watched, event);
}
void Dialog::hideEvent(QHideEvent * event)
{
Q_UNUSED(event);
emit dialogVisible(false);
}
void Dialog::showEvent(QShowEvent * event)
{
Q_UNUSED(event);
//check if the widget size is still synced with the view
d->checkBorders();
d->updateResizeCorners();
QGraphicsWidget *graphicsWidget = d->graphicsWidgetPtr.data();
if (graphicsWidget &&
((d->view && graphicsWidget->size().toSize() != d->view->size()) ||
d->oldGraphicsWidgetMinimumSize != graphicsWidget->minimumSize() ||
d->oldGraphicsWidgetMaximumSize != graphicsWidget->maximumSize())) {
//here have to be done immediately, ideally should have to be done -before- shwing, but is not possible to catch show() so early
syncToGraphicsWidget();
d->oldGraphicsWidgetMinimumSize = graphicsWidget->minimumSize().toSize();
d->oldGraphicsWidgetMaximumSize = graphicsWidget->maximumSize().toSize();
}
if (d->view) {
d->view->setFocus();
}
if (graphicsWidget) {
graphicsWidget->setFocus();
}
emit dialogVisible(true);
KWindowEffects::overrideShadow(winId(), true);
}
void Dialog::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event)
if (d->view) {
d->view->setFocus();
}
QGraphicsWidget *graphicsWidget = d->graphicsWidgetPtr.data();
if (graphicsWidget) {
graphicsWidget->setFocus();
}
}
void Dialog::moveEvent(QMoveEvent *event)
{
Q_UNUSED(event)
//kDebug();
d->scheduleBorderCheck();
}
void Dialog::setResizeHandleCorners(ResizeCorners corners)
{
if ((d->resizeCorners != corners) && (aspectRatioMode() != FixedSize)) {
d->resizeCorners = corners;
d->updateResizeCorners();
}
}
Dialog::ResizeCorners Dialog::resizeCorners() const
{
return d->resizeCorners;
}
bool Dialog::isUserResizing() const
{
return d->resizeStartCorner > NoCorner;
}
void Dialog::setMinimumResizeLimits(int left, int top, int right, int bottom)
{
d->leftResizeMin = left;
d->topResizeMin = top;
d->rightResizeMin = right;
d->bottomResizeMin = bottom;
}
void Dialog::getMinimumResizeLimits(int *left, int *top, int *right, int *bottom)
{
if (left) {
*left = d->leftResizeMin;
}
if (top) {
*top = d->topResizeMin;
}
if (right) {
*right = d->rightResizeMin;
}
if (bottom) {
*bottom = d->bottomResizeMin;
}
}
void Dialog::animatedHide(Plasma::Direction direction)
{
if (!isVisible()) {
return;
}
if (!Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
hide();
return;
}
KWindowEffects::SlideFromLocation location = KWindowEffects::NoEdge;
switch (direction) {
case Down:
location = KWindowEffects::BottomEdge;
break;
case Right:
location = KWindowEffects::RightEdge;
break;
case Left:
location = KWindowEffects::LeftEdge;
break;
case Up:
location = KWindowEffects::TopEdge;
break;
default:
break;
}
KWindowEffects::slideWindow(this, location);
hide();
}
void Dialog::animatedShow(Plasma::Direction direction)
{
if (!Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
show();
return;
}
//copied to not add new api
KWindowEffects::SlideFromLocation location = KWindowEffects::NoEdge;
switch (direction) {
case Up:
location = KWindowEffects::BottomEdge;
break;
case Left:
location = KWindowEffects::RightEdge;
break;
case Right:
location = KWindowEffects::LeftEdge;
break;
case Down:
location = KWindowEffects::TopEdge;
break;
default:
break;
}
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
KWindowEffects::slideWindow(this, location);
}
show();
}
bool Dialog::inControlArea(const QPoint &point)
{
foreach (const QRect &r, d->resizeAreas) {
if (r.contains(point)) {
return true;
}
}
return false;
}
Plasma::AspectRatioMode Dialog::aspectRatioMode() const
{
return d->aspectRatioMode;
}
void Dialog::setAspectRatioMode(Plasma::AspectRatioMode mode)
{
if (mode == FixedSize) {
setResizeHandleCorners(NoCorner);
}
d->aspectRatioMode = mode;
}
}
#include "moc_dialog.cpp"

215
dialog.h
View File

@ -1,215 +0,0 @@
/*
* Copyright 2008 by Alessandro Diaferia <alediaferia@gmail.com>
* Copyright 2007 by Alexis Ménard <darktears31@gmail.com>
* Copyright 2007 Sebastian Kuegler <sebas@kde.org>
* Copyright 2006 Aaron Seigo <aseigo@kde.org>
*
* 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_DIALOG_H
#define PLASMA_DIALOG_H
#include <QWidget>
#include <QGraphicsSceneEvent>
#include <QGraphicsView>
#include <plasma/plasma_export.h>
#include <plasma/plasma.h>
namespace Plasma
{
class DialogPrivate;
/**
* @class Dialog plasma/dialog.h <Plasma/Dialog>
*
* @short A dialog that uses the Plasma style
*
* Dialog provides a dialog-like widget that can be used to display additional
* information.
*
* Dialog uses the plasma theme, and usually has no window decoration. It's meant
* as an interim solution to display widgets as extension to plasma applets, for
* example when you click on an applet like the devicenotifier or the clock, the
* widget that is then displayed, is a Dialog.
*/
class PLASMA_EXPORT Dialog : public QWidget
{
Q_OBJECT
public:
/**
* Use these flags to choose the active resize corners.
*/
enum ResizeCorner {
NoCorner = 0,
NorthEast = 1,
SouthEast = 2,
NorthWest = 4,
SouthWest = 8,
All = NorthEast | SouthEast | NorthWest | SouthWest
};
Q_DECLARE_FLAGS(ResizeCorners, ResizeCorner)
/**
* @param parent the parent widget, for plasmoids, this is usually 0.
* @param f the Qt::WindowFlags, default is to not show a windowborder.
*/
explicit Dialog(QWidget * parent = 0, Qt::WindowFlags f = Qt::Window);
virtual ~Dialog();
/**
* Sets a QGraphicsWidget to be shown as the content in this dialog.
* The dialog will then set up a QGraphicsView and coordinate geometry with
* the widget automatically.
*
* @param widget the QGraphicsWidget to display in this dialog
*/
void setGraphicsWidget(QGraphicsWidget *widget);
/**
* @return the graphics widget shown in this dialog
*/
QGraphicsWidget *graphicsWidget() const;
/**
* @param corners the corners the resize handlers should be placed in.
*/
void setResizeHandleCorners(ResizeCorners corners);
/**
* Convenience method to get the enabled resize corners.
* @return which resize corners are active.
*/
ResizeCorners resizeCorners() const;
/**
* @return true if currently being resized by the user
*/
bool isUserResizing() const;
/**
* Sets the minimum values that each of four sides of the rect may expand to or from
*
* @param left the screen coordinate that the left may not go beyond; -1 for no limit
* @param top the screen coordinate that the top may not go beyond; -1 for no limit
* @param right the screen coordinate that the right may not go beyond; -1 for no limit
* @param bottom the screen coordinate that the bottom may not go beyond; -1 for no limit
*/
void setMinimumResizeLimits(int left, int top, int right, int bottom);
/**
* Retrives the minimum resize limits for the dialog
*
* @param left the screen coordinate that the left may not go beyond; -1 for no limit
* @param top the screen coordinate that the top may not go beyond; -1 for no limit
* @param right the screen coordinate that the right may not go beyond; -1 for no limit
* @param bottom the screen coordinate that the bottom may not go beyond; -1 for no limit
*/
void getMinimumResizeLimits(int *left, int *top, int *right, int *bottom);
/**
* Causes an animated hide; requires compositing to work, otherwise
* the dialog will simply hide.
* @since 4.3
*/
void animatedHide(Plasma::Direction direction);
/**
* Causes an animated show; requires compositing to work, otherwise
* the dialog will simply show.
* @since 4.3
*/
void animatedShow(Plasma::Direction direction);
/**
* @return the preferred aspect ratio mode for placement and resizing
* @since 4.4
*/
Plasma::AspectRatioMode aspectRatioMode() const;
/**
* Sets the preferred aspect ratio mode for placement and resizing
* @since 4.4
*/
void setAspectRatioMode(Plasma::AspectRatioMode mode);
Q_SIGNALS:
/**
* Fires when the dialog automatically resizes.
*/
void dialogResized();
/**
* Emit a signal when the dialog become visible/invisible
*/
void dialogVisible(bool status);
public Q_SLOTS:
/**
* Adjusts the dialog to the associated QGraphicsWidget's geometry
* Should not normally need to be called by users of Dialog as Dialog
* does it automatically. Event compression may cause unwanted delays,
* however, and so this method may be called to immediately cause a
* synchronization.
* @since 4.5
*/
void syncToGraphicsWidget();
protected:
/**
* Reimplemented from QWidget
*/
void paintEvent(QPaintEvent *e);
bool event(QEvent *event);
void resizeEvent(QResizeEvent *e);
bool eventFilter(QObject *watched, QEvent *event);
void hideEvent(QHideEvent *event);
void showEvent(QShowEvent *event);
void focusInEvent(QFocusEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void moveEvent(QMoveEvent *event);
/**
* Convenience method to know whether the point is in a control area (e.g. resize area)
* or not.
* @return true if the point is in the control area.
*/
bool inControlArea(const QPoint &point);
private:
DialogPrivate *const d;
friend class DialogPrivate;
/**
* React to theme changes
*/
Q_PRIVATE_SLOT(d, void themeChanged())
Q_PRIVATE_SLOT(d, void checkBorders())
Q_PRIVATE_SLOT(d, void delayedAdjustSize())
friend class PopupAppletPrivate;
};
} // Plasma namespace
Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::Dialog::ResizeCorners)
#endif

View File

@ -1,896 +0,0 @@
/*
* Copyright 2008 by Montel Laurent <montel@kde.org>
* Copyright 2008 by Marco Martin <notmart@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 "popupapplet.h"
#include "private/popupapplet_p.h"
#include "private/dialog_p.h"
#include <QApplication>
#include <QGraphicsProxyWidget>
#include <QGraphicsLinearLayout>
#include <QTimer>
#include <QVBoxLayout>
#include <kiconloader.h>
#include <kwindowsystem.h>
#include <kglobalsettings.h>
#include <netwm.h>
#include "plasma/private/applet_p.h"
#include "plasma/corona.h"
#include "plasma/containment.h"
#include "plasma/private/containment_p.h"
#include "plasma/dialog.h"
#include "plasma/package.h"
#include "plasma/theme.h"
#include "plasma/scripting/appletscript.h"
#include "plasma/tooltipmanager.h"
#include "plasma/widgets/iconwidget.h"
namespace Plasma
{
PopupApplet::PopupApplet(QObject *parent, const QVariantList &args)
: Applet(parent, args),
d(new PopupAppletPrivate(this))
{
}
PopupApplet::PopupApplet(const QString &packagePath, uint appletId, const QVariantList &args)
: Applet(packagePath, appletId, args),
d(new PopupAppletPrivate(this))
{
}
PopupApplet::~PopupApplet()
{
delete widget();
delete d;
}
void PopupApplet::setPopupIcon(const QIcon &icon)
{
if (icon.isNull()) {
if (d->icon) {
delete d->icon;
d->icon = 0;
setLayout(0);
setAspectRatioMode(d->savedAspectRatio);
d->popupConstraintsEvent(FormFactorConstraint);
}
return;
}
d->createIconWidget();
d->icon->setIcon(icon);
}
void PopupApplet::setPopupIcon(const QString &iconName)
{
// Attempt 1: is it in the plasmoid package?
if (package().isValid()) {
const QString file = package().filePath("images", iconName);
if (!file.isEmpty()) {
setPopupIcon(KDE::icon(file));
return;
}
}
// Attempt 2: is it a svg in the icons directory?
QString name = QString("icons/") + iconName.split("-").first();
if (!Plasma::Theme::defaultTheme()->imagePath(name).isEmpty()) {
d->createIconWidget();
d->icon->setSvg(name, iconName);
if (d->icon->svg().isEmpty()) {
setPopupIcon(KDE::icon(iconName));
}
return;
}
// Final Attempt: use KDE::icon
setPopupIcon(KDE::icon(iconName));
}
QIcon PopupApplet::popupIcon() const
{
return d->icon ? d->icon->icon() : QIcon();
}
QWidget *PopupApplet::widget()
{
return d->widget;
}
void PopupApplet::setWidget(QWidget *widget)
{
if (d->widget) {
Plasma::Dialog *dialog = d->dialogPtr.data();
if (dialog) {
dialog->setGraphicsWidget(0);
QVBoxLayout *lay = 0;
QLayout *existingLayout = dialog->layout();
if (existingLayout) {
lay = dynamic_cast<QVBoxLayout *>(existingLayout);
if (!lay) {
delete existingLayout;
}
}
if (!lay) {
lay = new QVBoxLayout;
dialog->setLayout(lay);
}
lay->removeWidget(d->widget);
lay->addWidget(widget);
} else if (d->proxy) {
d->proxy.data()->setWidget(widget);
}
}
d->widget = widget;
}
QGraphicsWidget *PopupApplet::graphicsWidget()
{
return d->graphicsWidget.data();
}
void PopupApplet::setGraphicsWidget(QGraphicsWidget *graphicsWidget)
{
if (d->graphicsWidget) {
if (d->dialogPtr) {
d->dialogPtr.data()->setGraphicsWidget(graphicsWidget);
} else if (layout()) {
QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout *>(layout());
lay->removeAt(0);
if (graphicsWidget) {
lay->addItem(graphicsWidget);
}
}
}
d->graphicsWidget = graphicsWidget;
}
void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
{
Plasma::FormFactor f = q->formFactor();
if (constraints & Plasma::FormFactorConstraint ||
constraints & Plasma::StartupCompletedConstraint ||
(constraints & Plasma::SizeConstraint &&
(f == Plasma::Vertical || f == Plasma::Horizontal))) {
QGraphicsLinearLayout *lay = dynamic_cast<QGraphicsLinearLayout *>(q->layout());
if (icon && lay && lay->count() > 0) {
lay->removeAt(0);
}
QSizeF minimum;
QSizeF parentSize;
QGraphicsWidget *gWidget = q->graphicsWidget();
//kDebug() << "graphics widget is" << (QObject*)gWidget;
QWidget *qWidget = q->widget();
if (gWidget) {
minimum = gWidget->minimumSize();
// our layout may have been replaced on us in the call to graphicsWidget!
lay = dynamic_cast<QGraphicsLinearLayout *>(q->layout());
} else if (qWidget) {
minimum = qWidget->minimumSizeHint();
}
//99% of the times q->parentWidget() is the containment, but using it we can also manage the applet-in-applet case (i.e. systray)
//there are also cases where the parentlayoutitem is bigger than the containment (e.g. newspaper)
if (q->parentLayoutItem()) {
parentSize = q->parentLayoutItem()->geometry().size();
} else if (q->parentWidget()) {
parentSize = q->parentWidget()->size();
}
//check if someone did the nasty trick of applets in applets, in this case we always want to be collapsed
QGraphicsWidget *candidateParentApplet = q;
Plasma::Applet *parentApplet = 0;
//this loop should be executed normally a single time, at most 2-3 times for quite complex containments
while (candidateParentApplet) {
candidateParentApplet = candidateParentApplet->parentWidget();
parentApplet = qobject_cast<Plasma::Applet *>(candidateParentApplet);
if (parentApplet) {
break;
}
}
//Applet on desktop
if ((!parentApplet || parentApplet->isContainment() ) && icon && (!icon->svg().isEmpty() || !icon->icon().isNull()) && ((f != Plasma::Vertical && f != Plasma::Horizontal) ||
((f == Plasma::Vertical && parentSize.width() >= minimum.width()) ||
(f == Plasma::Horizontal && parentSize.height() >= minimum.height())))) {
//kDebug() << "we are expanding the popupapplet";
// we only switch to expanded if we aren't horiz/vert constrained and
// this applet has an icon.
// otherwise, we leave it up to the applet itself to figure it out
if (icon) {
icon->hide();
}
if (savedAspectRatio != Plasma::InvalidAspectRatioMode) {
q->setAspectRatioMode(savedAspectRatio);
}
Dialog *dialog = dialogPtr.data();
if (dialog) {
if (dialog->layout() && qWidget) {
//we don't want to delete Widget inside the dialog layout
dialog->layout()->removeWidget(qWidget);
}
if (qWidget) {
qWidget->setParent(0);
}
delete dialog;
}
if (!lay) {
lay = new QGraphicsLinearLayout();
lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0);
lay->setOrientation(Qt::Horizontal);
q->setLayout(lay);
}
QSize prefSize;
if (gWidget) {
if (proxy) {
proxy.data()->setWidget(0);
delete proxy.data();
}
Corona *corona = qobject_cast<Corona *>(gWidget->scene());
if (corona) {
corona->removeOffscreenWidget(gWidget);
}
lay->addItem(gWidget);
prefSize = gWidget->preferredSize().toSize();
} else if (qWidget) {
if (!proxy) {
proxy = new QGraphicsProxyWidget(q);
proxy.data()->setWidget(qWidget);
proxy.data()->show();
}
lay->addItem(proxy.data());
prefSize = qWidget->sizeHint();
}
//we could be on a big panel, but in that case we will be able to resize
//more than the natural minimum size, because we'll transform into an icon
if (f == Plasma::Horizontal) {
minimum.setHeight(0);
} else if (f == Plasma::Vertical) {
minimum.setWidth(0);
}
qreal left, top, right, bottom;
q->getContentsMargins(&left, &top, &right, &bottom);
QSizeF oldSize(q->size());
//size not saved/invalid size saved
if (oldSize.width() < q->minimumSize().width() || oldSize.height() < q->minimumSize().height()) {
q->resize(prefSize);
emit q->appletTransformedItself();
}
} else {
//Applet on popup
if (icon && lay) {
lay->addItem(icon);
}
//kDebug() << "about to switch to a popup";
if (!qWidget && !gWidget) {
delete dialogPtr.data();
return;
}
//there was already a dialog? don't make the switch again
if (dialogPtr) {
return;
}
if (proxy) {
proxy.data()->setWidget(0); // prevent it from deleting our widget!
delete proxy.data();
}
//save the aspect ratio mode in case we drag'n drop in the Desktop later
savedAspectRatio = q->aspectRatioMode();
if (icon) {
icon->show();
q->setAspectRatioMode(Plasma::ConstrainedSquare);
}
Dialog *dialog = new Dialog();
dialog->d->appletPtr = q;
dialogPtr = dialog;
if (icon) {
dialog->setAspectRatioMode(savedAspectRatio);
}
//no longer use Qt::Popup since that seems to cause a lot of problem when you drag
//stuff out of your Dialog (extenders). Monitor WindowDeactivate events so we can
//emulate the same kind of behavior as Qt::Popup (close when you click somewhere
//else.
if (gWidget) {
Corona *corona = qobject_cast<Corona *>(gWidget->scene());
if (!corona) {
corona = qobject_cast<Corona *>(q->scene());
}
if (corona) {
corona->addOffscreenWidget(gWidget);
}
gWidget->show();
dialog->setGraphicsWidget(gWidget);
dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | (gWidget->windowFlags() & Qt::X11BypassWindowManagerHint));
} else if (qWidget) {
QVBoxLayout *l_layout = new QVBoxLayout(dialog);
l_layout->setSpacing(0);
l_layout->setMargin(0);
l_layout->addWidget(qWidget);
dialog->adjustSize();
dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | (qWidget->windowFlags() & Qt::X11BypassWindowManagerHint));
} else {
dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}
restoreDialogSize();
KWindowSystem::setState(dialog->winId(), NET::SkipTaskbar | NET::SkipPager);
dialog->installEventFilter(q);
QObject::connect(dialog, SIGNAL(dialogResized()), q, SLOT(dialogSizeChanged()));
QObject::connect(dialog, SIGNAL(dialogVisible(bool)), q, SLOT(dialogStatusChanged(bool)));
}
}
if (constraints & Plasma::PopupConstraint) {
updateDialogPosition();
}
if (icon) {
// emit the size hint changing stuff for our applet as we are handling
// the size changings
emit q->sizeHintChanged(Qt::PreferredSize);
}
}
void PopupAppletPrivate::appletActivated()
{
internalTogglePopup(true);
}
QSizeF PopupApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
{
if (!d->dialogPtr || which != Qt::PreferredSize) {
return Applet::sizeHint(which, constraint);
}
switch (formFactor()) {
case Vertical:
case Horizontal: {
const int size = IconSize(KIconLoader::Panel);
return QSizeF(size, size);
}
default:
break;
}
const int size = IconSize(KIconLoader::Desktop);
return QSizeF(size, size);
}
void PopupApplet::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (!d->icon && !d->popupLostFocus && event->buttons() == Qt::LeftButton) {
d->clicked = scenePos().toPoint();
event->setAccepted(true);
return;
} else {
d->popupLostFocus = false;
Applet::mousePressEvent(event);
}
}
void PopupApplet::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (!d->icon &&
(d->clicked - scenePos().toPoint()).manhattanLength() < QApplication::startDragDistance()) {
d->internalTogglePopup();
} else {
Applet::mouseReleaseEvent(event);
}
}
bool PopupApplet::eventFilter(QObject *watched, QEvent *event)
{
if (!d->passive && watched == d->dialogPtr.data() && (event->type() == QEvent::WindowDeactivate)) {
d->popupLostFocus = true;
QTimer::singleShot(100, this, SLOT(clearPopupLostFocus()));
}
if (watched == d->dialogPtr.data() && event->type() == QEvent::ContextMenu) {
//pass it up to the applet
//well, actually we have to pass it to the *containment*
//because all the code for showing an applet's contextmenu is actually in Containment.
Containment *c = containment();
if (c) {
Applet *applet = this;
Dialog *dialog = d->dialogPtr.data();
if (dialog && dialog->graphicsWidget()) {
int left, top, right, bottom;
dialog->getContentsMargins(&left, &top, &right, &bottom);
const QPoint eventPos = static_cast<QContextMenuEvent*>(event)->pos() - QPoint(left, top);
QPointF pos = dialog->graphicsWidget()->mapToScene(eventPos);
if (Applet *actual = c->d->appletAt(pos)) {
applet = actual;
}
}
KMenu desktopMenu;
c->d->addAppletActions(desktopMenu, applet, event);
if (!desktopMenu.isEmpty()) {
desktopMenu.exec(static_cast<QContextMenuEvent*>(event)->globalPos());
return true;
}
return false;
}
}
return Applet::eventFilter(watched, event);
}
void PopupApplet::showPopup(uint popupDuration)
{
// use autohideTimer to store when the next show should be
if (popupDuration > 0 || d->autohideTimer) {
if (!d->autohideTimer) {
d->autohideTimer = new QTimer(this);
d->autohideTimer->setSingleShot(true);
connect(d->autohideTimer, SIGNAL(timeout()), this, SLOT(hideTimedPopup()));
}
d->autohideTimer->stop();
d->autohideTimer->setInterval(popupDuration);
}
//kDebug() << "starting delayed show, duration for popup is" << popupDuration;
d->delayedShowTimer.start(0, this);
}
void PopupApplet::timerEvent(QTimerEvent *event)
{
if (event->timerId() == d->delayedShowTimer.timerId()) {
d->delayedShowTimer.stop();
Dialog *dialog = d->dialogPtr.data();
if (dialog) {
// move the popup before its fist show, even if the show isn't triggered by
// a click, this should fix the first random position seen in some widgets
if (!dialog->isVisible()) {
d->internalTogglePopup();
}
const int popupDuration = d->autohideTimer ? d->autohideTimer->interval() : 0;
//kDebug() << "popupDuration is:" << (d->autohideTimer ? d->autohideTimer->interval() : 0);
if (popupDuration > 0) {
d->autohideTimer->start();
} else if (d->autohideTimer) {
d->autohideTimer->stop();
}
}
} else if (event->timerId() == d->showDialogTimer.timerId()) {
d->showDialogTimer.stop();
d->showDialog();
} else {
Applet::timerEvent(event);
}
}
void PopupApplet::hidePopup()
{
d->showDialogTimer.stop();
d->delayedShowTimer.stop();
Dialog *dialog = d->dialogPtr.data();
if (dialog && dialog->isVisible()) {
if (location() != Floating) {
dialog->animatedHide(locationToInverseDirection(location()));
} else {
dialog->hide();
}
}
}
void PopupApplet::togglePopup()
{
d->internalTogglePopup();
}
Plasma::PopupPlacement PopupApplet::popupPlacement() const
{
return d->popupPlacement;
}
void PopupApplet::setPopupAlignment(Qt::AlignmentFlag alignment)
{
d->popupAlignment = alignment;
}
Qt::AlignmentFlag PopupApplet::popupAlignment() const
{
return d->popupAlignment;
}
void PopupApplet::popupEvent(bool popped)
{
if (Applet::d->script) {
emit Applet::d->script->popupEvent(popped);
}
}
void PopupApplet::setPassivePopup(bool passive)
{
d->passive = passive;
}
bool PopupApplet::isPassivePopup() const
{
return d->passive;
}
bool PopupApplet::isPopupShowing() const
{
return d->dialogPtr && d->dialogPtr.data()->isVisible();
}
bool PopupApplet::isIconified() const
{
return d->dialogPtr;
}
PopupAppletPrivate::PopupAppletPrivate(PopupApplet *applet)
: q(applet),
icon(0),
widget(0),
popupPlacement(Plasma::FloatingPopup),
popupAlignment(Qt::AlignLeft),
savedAspectRatio(Plasma::InvalidAspectRatioMode),
autohideTimer(0),
preShowStatus(UnknownStatus),
popupLostFocus(false),
passive(false)
{
int iconSize = IconSize(KIconLoader::Desktop);
q->resize(iconSize, iconSize);
q->setAcceptDrops(true);
QObject::disconnect(q, SIGNAL(activate()), static_cast<Applet*>(q), SLOT(setFocus()));
QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
QObject::connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), q, SLOT(iconSizeChanged(int)));
}
PopupAppletPrivate::~PopupAppletPrivate()
{
if (proxy) {
proxy.data()->setWidget(0);
}
delete dialogPtr.data();
delete icon;
}
void PopupAppletPrivate::iconSizeChanged(int group)
{
if (icon && (group == KIconLoader::Desktop || group == KIconLoader::Panel)) {
q->updateGeometry();
}
}
void PopupAppletPrivate::internalTogglePopup(bool fromActivatedSignal)
{
if (autohideTimer) {
autohideTimer->stop();
}
delayedShowTimer.stop();
Plasma::Dialog *dialog = dialogPtr.data();
if (!dialog) {
q->setFocus(Qt::ShortcutFocusReason);
if (!fromActivatedSignal) {
QObject::disconnect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
emit q->activate();
QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
}
return;
}
if (!q->view()) {
return;
}
if (dialog->isVisible()) {
if (q->location() != Floating) {
dialog->animatedHide(locationToInverseDirection(q->location()));
} else {
dialog->hide();
}
dialog->clearFocus();
} else {
if (!graphicsWidget) {
// we have nothing to show, so let's not.
if (!fromActivatedSignal) {
QObject::disconnect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
emit q->activate();
QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
}
return;
}
ToolTipManager::self()->hide(q);
showDialogTimer.start(0, q);
}
}
void PopupAppletPrivate::showDialog()
{
Plasma::Dialog *dialog = dialogPtr.data();
if (!dialog) {
return;
}
updateDialogPosition();
KWindowSystem::setOnAllDesktops(dialog->winId(), true);
KWindowSystem::setState(dialog->winId(), NET::SkipTaskbar | NET::SkipPager);
if (icon) {
dialog->setAspectRatioMode(savedAspectRatio);
}
if (q->location() != Floating) {
dialog->animatedShow(locationToDirection(q->location()));
} else {
dialog->show();
}
if (!(dialog->windowFlags() & Qt::X11BypassWindowManagerHint)) {
KWindowSystem::activateWindow(dialog->winId());
}
}
void PopupAppletPrivate::hideTimedPopup()
{
autohideTimer->stop();
q->hidePopup();
}
void PopupAppletPrivate::clearPopupLostFocus()
{
if (!icon || !icon->isDown()) {
q->hidePopup();
}
popupLostFocus = false;
}
KConfigGroup PopupAppletPrivate::popupConfigGroup()
{
KConfigGroup *mainGroup = static_cast<Applet*>(q)->d->mainConfigGroup();
return KConfigGroup(mainGroup, "PopupApplet");
}
void PopupAppletPrivate::dialogSizeChanged()
{
//Reposition the dialog
Plasma::Dialog *dialog = dialogPtr.data();
if (dialog) {
KConfigGroup sizeGroup = popupConfigGroup();
sizeGroup.writeEntry("DialogHeight", dialog->height());
sizeGroup.writeEntry("DialogWidth", dialog->width());
updateDialogPosition(!dialog->isUserResizing());
emit q->configNeedsSaving();
emit q->appletTransformedByUser();
}
}
void PopupAppletPrivate::dialogStatusChanged(bool shown)
{
if (shown) {
preShowStatus = q->status();
q->setStatus(NeedsAttentionStatus);
QObject::connect(q, SIGNAL(newStatus(Plasma::ItemStatus)),
q, SLOT(statusChangeWhileShown(Plasma::ItemStatus)),
Qt::UniqueConnection);
} else {
QObject::disconnect(q, SIGNAL(newStatus(Plasma::ItemStatus)),
q, SLOT(statusChangeWhileShown(Plasma::ItemStatus)));
q->setStatus(preShowStatus);
}
q->popupEvent(shown);
}
void PopupAppletPrivate::statusChangeWhileShown(Plasma::ItemStatus status)
{
preShowStatus = status;
}
void PopupAppletPrivate::createIconWidget()
{
if (icon) {
return;
}
icon = new Plasma::IconWidget(q);
QObject::connect(icon, SIGNAL(clicked()), q, SLOT(internalTogglePopup()));
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->setOrientation(Qt::Horizontal);
layout->addItem(icon);
layout->setAlignment(icon, Qt::AlignCenter);
q->setLayout(layout);
}
void PopupAppletPrivate::restoreDialogSize()
{
Plasma::Dialog *dialog = dialogPtr.data();
if (!dialog) {
return;
}
Corona *corona = qobject_cast<Corona *>(q->scene());
if (!corona) {
return;
}
KConfigGroup sizeGroup = popupConfigGroup();
int preferredWidth = 0;
int preferredHeight = 0;
QGraphicsWidget *gWidget = dialog->graphicsWidget();
if (gWidget) {
preferredWidth = gWidget->preferredSize().width();
preferredHeight = gWidget->preferredSize().height();
}
const int width = qMin(sizeGroup.readEntry("DialogWidth", preferredWidth),
corona->screenGeometry(-1).width() - 50);
const int height = qMin(sizeGroup.readEntry("DialogHeight", preferredHeight),
corona->screenGeometry(-1).height() - 50);
QSize saved(width, height);
if (saved.isNull()) {
saved = dialog->sizeHint();
} else {
saved = saved.expandedTo(dialog->minimumSizeHint());
}
if (saved.width() != dialog->width() || saved.height() != dialog->height()) {
dialog->resize(saved);
/*if (gWidget) {
gWidget->resize(saved);
}*/
}
}
void PopupAppletPrivate::updateDialogPosition(bool move)
{
Plasma::Dialog *dialog = dialogPtr.data();
if (!dialog) {
return;
}
Corona *corona = qobject_cast<Corona *>(q->scene());
if (!corona) {
return;
}
QGraphicsView *view = q->view();
if (!view) {
return;
}
const QPoint appletPos = view->mapToGlobal(view->mapFromScene(q->scenePos()));
QPoint dialogPos = dialog->pos();
if (move) {
if (!q->containment() || view == q->containment()->view()) {
dialogPos = corona->popupPosition(q, dialog->size(), popupAlignment);
} else {
dialogPos = corona->popupPosition(q->parentItem(), dialog->size(), popupAlignment);
}
}
bool reverse = false;
if (q->formFactor() == Plasma::Vertical) {
reverse = (appletPos.y() + (q->size().height() / 2)) < (dialogPos.y() + (dialog->size().height() / 2));
dialog->setMinimumResizeLimits(-1, appletPos.y(), -1, appletPos.y() + q->size().height());
} else {
reverse = (appletPos.x() + (q->size().width() / 2)) < (dialogPos.x() + (dialog->size().width() / 2));
dialog->setMinimumResizeLimits(appletPos.x(), -1, appletPos.x() + q->size().width(), -1);
}
Dialog::ResizeCorners resizeCorners = Dialog::NoCorner;
switch (q->location()) {
case BottomEdge:
resizeCorners = Dialog::NorthEast | Dialog::NorthWest;
popupPlacement = reverse ? TopPosedLeftAlignedPopup : TopPosedRightAlignedPopup;
break;
case TopEdge:
resizeCorners = Dialog::SouthEast | Dialog::SouthWest;
popupPlacement = reverse ? Plasma::BottomPosedLeftAlignedPopup : Plasma::BottomPosedRightAlignedPopup;
break;
case LeftEdge:
resizeCorners = Dialog::SouthEast | Dialog::NorthEast;
popupPlacement = reverse ? RightPosedTopAlignedPopup : RightPosedBottomAlignedPopup;
break;
case RightEdge:
resizeCorners = Dialog::SouthWest | Dialog::NorthWest;
popupPlacement = reverse ? LeftPosedTopAlignedPopup : LeftPosedBottomAlignedPopup;
break;
default:
popupPlacement = FloatingPopup;
resizeCorners = Dialog::All;
break;
}
dialog->setResizeHandleCorners(resizeCorners);
if (move) {
dialog->move(dialogPos);
}
}
} // Plasma namespace
#include "moc_popupapplet.cpp"

View File

@ -1,221 +0,0 @@
/*
* Copyright 2008 by Montel Laurent <montel@kde.org>
*
* 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_POPUPAPPLET_H
#define PLASMA_POPUPAPPLET_H
#include <plasma/applet.h>
#include <plasma/plasma_export.h>
#include <plasma/plasma.h>
class QGraphicsProxyWidget;
class QGraphicsLinearLayout;
namespace Plasma
{
class PopupAppletPrivate;
/**
* Allows applets to automatically 'collapse' into an icon when put in an panel.
*
* Applets that subclass this class should implement either widget() or graphicsWidget() to return a
* widget that will be displayed in the applet if the applet is in a Planar or MediaCenter form
* factor. If the applet is put in a panel, an icon will be displayed instead, which shows the
* widget in a popup when clicked.
*/
class PLASMA_EXPORT PopupApplet : public Plasma::Applet
{
Q_OBJECT
Q_PROPERTY(Qt::AlignmentFlag popupAlignment READ popupAlignment WRITE setPopupAlignment)
public:
PopupApplet(QObject *parent, const QVariantList &args);
~PopupApplet();
/**
* @param icon the icon that has to be displayed when the applet is in a panel.
* Passing in a null icon means that the popup applet itself
* will provide an interface for when the PopupApplet is not showing
* the widget() or graphicsWidget() directly.
*/
void setPopupIcon(const QIcon &icon);
/**
* @param icon the icon that has to be displayed when the applet is in a panel.
* Passing in an empty QString() means that the popup applet itself
* will provide an interface for when the PopupApplet is not showing
* the widget() or graphicsWidget() directly.
* If you set a popup icon you must also set a minimum size of the applet. When the applet
* is smaller than this minimum size, it will be displayed as that icon.
*/
void setPopupIcon(const QString &iconName);
/**
* @return the icon that is displayed when the applet is in a panel.
*/
QIcon popupIcon() const;
/**
* Implement either this function or graphicsWidget().
* @return the widget that will get shown in either a layout, in the applet or in a Dialog,
* depending on the form factor of the applet.
*/
virtual QWidget *widget();
void setWidget(QWidget * widget);
/**
* Implement either this function or widget().
* @return the widget that will get shown in either a layout, in the applet or in a Dialog,
* depending on the form factor of the applet.
* If you set a popup icon you must also set a minimum size of the applet. When the applet
* is smaller than this minimum size, it will be displayed as that icon.
*/
virtual QGraphicsWidget *graphicsWidget();
void setGraphicsWidget(QGraphicsWidget * widget);
/**
* @return the placement of the popup relating to the applet
*/
Plasma::PopupPlacement popupPlacement() const;
/**
* Sets the default alignment of the popup relative to the applet
* @param alignment the alignment to use; Qt::AlignLeft or Qt::AlignRight
* @since 4.6
*/
void setPopupAlignment(Qt::AlignmentFlag alignment);
/**
* @return the default alignment of the popup relative to the applet
* @since 4.6
*/
Qt::AlignmentFlag popupAlignment() const;
/**
* Sets whether or not the dialog popup that gets created should be a "passive" popup
* that does not steal focus from other windows or not.
*
* @param passive true if the dialog should be treated as a passive popup
*/
void setPassivePopup(bool passive);
/**
* @return true if the dialog will be treated as a passive poup
*/
bool isPassivePopup() const;
/**
* @return true if the applet is popped up
*/
bool isPopupShowing() const;
/**
* @return true if the applet is collapsed to an icon
* @since 4.6
*/
bool isIconified() const;
public Q_SLOTS:
/**
* Hides the popup.
*/
void hidePopup();
/**
* Shows the dialog showing the widget if the applet is in a panel.
* @param displayTime the time in ms that the popup should be displayed, defaults to 0 which means
* always (until the user closes it again, that is).
*/
void showPopup(uint displayTime = 0);
/**
* Toggles the popup.
*/
void togglePopup();
protected:
/**
* This event handler can be reimplemented in a subclass to receive an
* event before the popup is shown or hidden.
* @param show true if the popup is going to be shown, false if the popup
* is going to be hidden.
* Note that showing and hiding the popup on click is already done in PopupApplet.
*/
virtual void popupEvent(bool show);
/**
* Reimplemented from QGraphicsLayoutItem
*/
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF()) const;
/**
* Reimplemented from QGraphicsLayoutItem
*/
void mousePressEvent(QGraphicsSceneMouseEvent *event);
/**
* Reimplemented from QGraphicsLayoutItem
*/
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
/**
* Reimplemented from QGraphicsLayoutItem
*/
bool eventFilter(QObject *watched, QEvent *event);
/**
* Reimplemented from QGraphicsLayoutItem
*/
void timerEvent(QTimerEvent *event);
private:
/**
* @internal This constructor is to be used with the Package loading system.
*
* @param parent a QObject parent; you probably want to pass in 0
* @param args a list of strings containing two entries: the service id
* and the applet id
* @since 4.3
*/
PopupApplet(const QString &packagePath, uint appletId, const QVariantList &args);
Q_PRIVATE_SLOT(d, void internalTogglePopup())
Q_PRIVATE_SLOT(d, void hideTimedPopup())
Q_PRIVATE_SLOT(d, void clearPopupLostFocus())
Q_PRIVATE_SLOT(d, void dialogSizeChanged())
Q_PRIVATE_SLOT(d, void dialogStatusChanged(bool))
Q_PRIVATE_SLOT(d, void updateDialogPosition())
Q_PRIVATE_SLOT(d, void appletActivated())
Q_PRIVATE_SLOT(d, void iconSizeChanged(int))
Q_PRIVATE_SLOT(d, void statusChangeWhileShown(Plasma::ItemStatus status))
friend class Applet;
friend class AppletPrivate;
friend class PopupAppletPrivate;
PopupAppletPrivate * const d;
};
} // Plasma namespace
#endif /* POPUPAPPLET_H */

View File

@ -1,78 +0,0 @@
/*
* Copyright 2008 by Montel Laurent <montel@kde.org>
*
* 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 POPUPAPPLET_P_H
#define POPUPAPPLET_P_H
#include <QBasicTimer>
#include <QWeakPointer>
#include <plasma/plasma.h>
namespace Plasma
{
class IconWidget;
class Dialog;
class PopupAppletPrivate
{
public:
PopupAppletPrivate(PopupApplet *applet);
~PopupAppletPrivate();
void iconSizeChanged(int group);
void internalTogglePopup(bool fromActivatedSignal = false);
void showDialog();
void hideTimedPopup();
void clearPopupLostFocus();
void dialogSizeChanged();
void dialogStatusChanged(bool status);
void restoreDialogSize();
void updateDialogPosition(bool move = true);
void popupConstraintsEvent(Plasma::Constraints constraints);
void checkExtenderAppearance(Plasma::FormFactor f);
KConfigGroup popupConfigGroup();
void appletActivated();
void statusChangeWhileShown(Plasma::ItemStatus status);
void createIconWidget();
PopupApplet *q;
Plasma::IconWidget *icon;
QWeakPointer<Plasma::Dialog> dialogPtr;
QWeakPointer<QGraphicsProxyWidget> proxy;
QWidget *widget;
QWeakPointer<QGraphicsWidget> graphicsWidget;
Plasma::PopupPlacement popupPlacement;
Qt::AlignmentFlag popupAlignment;
Plasma::AspectRatioMode savedAspectRatio;
QTimer *autohideTimer;
QBasicTimer delayedShowTimer;
QBasicTimer showDialogTimer;
QPoint clicked;
ItemStatus preShowStatus;
bool popupLostFocus : 1;
bool passive : 1;
};
} // Plasma namespace
#endif

View File

@ -1,402 +0,0 @@
/*
* 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 <QAbstractTextDocumentLayout>
#include <QBitmap>
#include <QGridLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QPainter>
#include <QPalette>
#include <QTextDocument>
#include <QPropertyAnimation>
#include <QTextBlock>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kwindoweffects.h>
#include <plasma/plasma.h>
#include <plasma/paintutils.h>
#include <plasma/theme.h>
#include <plasma/framesvg.h>
namespace Plasma {
class TipTextWidget : public QWidget
{
public:
TipTextWidget(ToolTip *parent)
: QWidget(parent),
m_toolTip(parent),
m_document(new QTextDocument(this))
{
QTextOption option = m_document->defaultTextOption();
option.setWrapMode(QTextOption::WordWrap);
m_document->setDefaultTextOption(option);
}
void setStyleSheet(const QString &css)
{
m_document->setDefaultStyleSheet(css);
}
void setContent(const ToolTipContent &data)
{
QString html;
QString mainText = data.mainText();
if (!mainText.isEmpty()) {
if (mainText.size() < 50) {
// don't let short texts wrap on us!
mainText = mainText.replace(" ", "&nbsp;");
}
html.append("<div align=\"center\"><b>" + mainText + "</b></div>");
}
html.append(data.subText());
m_anchor.clear();
m_document->clear();
data.registerResources(m_document);
if (!html.isEmpty()) {
m_document->setHtml("<p>" + html + "</p>");
} else {
m_document->clear();
}
m_document->adjustSize();
update();
}
QSize minimumSizeHint() const
{
const int margin = 6;
return m_document->size().toSize() + QSize(margin, margin)*2;
}
QSize maximumSizeHint() const
{
return minimumSizeHint();
}
void paintEvent(QPaintEvent *event)
{
QPainter p(this);
m_document->drawContents(&p, event->rect());
}
void mousePressEvent(QMouseEvent *event)
{
QAbstractTextDocumentLayout *layout = m_document->documentLayout();
if (layout) {
m_anchor = layout->anchorAt(event->pos());
}
}
void mouseReleaseEvent(QMouseEvent *event)
{
QAbstractTextDocumentLayout *layout = m_document->documentLayout();
if (layout) {
QString anchor = layout->anchorAt(event->pos());
if (anchor == m_anchor) {
m_toolTip->linkActivated(m_anchor, event);
}
m_anchor.clear();
}
}
private:
ToolTip *m_toolTip;
QTextDocument *m_document;
QString m_anchor;
};
class ToolTipPrivate
{
public:
ToolTipPrivate()
: text(0),
imageLabel(0),
preview(0),
direction(Plasma::Up),
autohide(true)
{ }
TipTextWidget *text;
QLabel *imageLabel;
WindowPreview *preview;
FrameSvg *background;
QWeakPointer<QObject> source;
QPropertyAnimation *animation;
Plasma::Direction direction;
bool autohide;
};
ToolTip::ToolTip(QWidget *parent)
: QWidget(parent),
d(new ToolTipPrivate())
{
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::ToolTip);
d->preview = new WindowPreview(this);
d->text = new TipTextWidget(this);
d->imageLabel = new QLabel(this);
d->imageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
d->animation = new QPropertyAnimation(this, "pos", this);
d->animation->setEasingCurve(QEasingCurve::InOutQuad);
d->animation->setDuration(250);
d->background = new FrameSvg(this);
d->background->setImagePath("widgets/tooltip");
d->background->setEnabledBorders(FrameSvg::AllBorders);
updateTheme();
connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme()));
connect(d->preview, SIGNAL(windowPreviewClicked(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
this, SIGNAL(activateWindowByWId(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
QHBoxLayout *previewHBoxLayout = new QHBoxLayout;
previewHBoxLayout->addWidget(d->preview);
QHBoxLayout *iconTextHBoxLayout = new QHBoxLayout;
iconTextHBoxLayout->addWidget(d->imageLabel);
iconTextHBoxLayout->setAlignment(d->imageLabel, Qt::AlignTop | Qt::AlignHCenter);
iconTextHBoxLayout->addWidget(d->text);
iconTextHBoxLayout->setAlignment(d->text, Qt::AlignLeft | Qt::AlignVCenter);
iconTextHBoxLayout->setStretchFactor(d->text, 1);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(previewHBoxLayout);
mainLayout->addLayout(iconTextHBoxLayout);
setLayout(mainLayout);
}
ToolTip::~ToolTip()
{
delete d;
}
void ToolTip::showEvent(QShowEvent *e)
{
checkSize();
QWidget::showEvent(e);
d->preview->setInfo();
KWindowEffects::overrideShadow(winId(), true);
}
void ToolTip::hideEvent(QHideEvent *e)
{
QWidget::hideEvent(e);
d->animation->stop();
QObject *source = d->source.data();
if (source && source->metaObject()->indexOfMethod("toolTipHidden()") != -1) {
QMetaObject::invokeMethod(source, "toolTipHidden");
}
KWindowEffects::highlightWindows(winId(), QList<WId>());
}
void ToolTip::mouseReleaseEvent(QMouseEvent *event)
{
if (rect().contains(event->pos()) &&
(!d->preview || !d->preview->geometry().contains(event->pos()))) {
hide();
}
}
void ToolTip::enterEvent(QEvent *)
{
emit hovered(true);
}
void ToolTip::leaveEvent(QEvent *)
{
emit hovered(false);
}
void ToolTip::checkSize()
{
//FIXME: layout bugs even on qlayouts? oh, please, no.
d->text->setMinimumSize(0, 0);
d->text->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
d->text->setMinimumSize(d->text->minimumSizeHint());
d->text->setMaximumSize(d->text->maximumSizeHint());
adjustSize();
}
void ToolTip::adjustPosition(const QSize &previous, const QSize &current)
{
if (previous != current) {
//offsets to stop tooltips from jumping when they resize
int deltaX = 0;
int deltaY = 0;
if (d->direction == Plasma::Up) {
/*
#ifndef NDEBUG
kDebug() << "resizing from" << current << "to" << hint
#endif
<< "and moving from" << pos() << "to"
<< x() << y() + (current.height() - hint.height())
<< current.height() - hint.height();
*/
deltaY = previous.height() - current.height();
} else if (d->direction == Plasma::Left) {
/*
#ifndef NDEBUG
kDebug() << "vertical resizing from" << current << "to" << hint
#endif
<< "and moving from" << pos() << "to"
<< x() + (current.width() - hint.width()) << y()
<< current.width() - hint.width(); */
deltaX = previous.width() - current.width();
}
// resize then move if we're getting smaller, vice versa when getting bigger
// this prevents overlap with the item in the smaller case, and a repaint of
// the tipped item when getting bigger
move(x() + deltaX, y() + deltaY);
}
}
void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
{
//reset our size
d->text->setContent(data);
if (data.image().isNull()) {
d->imageLabel->hide();
} else {
d->imageLabel->show();
d->imageLabel->setPixmap(data.image());
}
if (data.highlightWindows() && !data.windowsToPreview().isEmpty()) {
KWindowEffects::highlightWindows(winId(), QList<WId>() << winId() << data.windowsToPreview());
}
d->preview->setWindowIds(data.windowsToPreview());
d->preview->setHighlightWindows(data.highlightWindows());
d->autohide = data.autohide();
d->source = tipper;
if (isVisible()) {
d->preview->setInfo();
//kDebug() << "about to check size";
checkSize();
}
}
void ToolTip::prepareShowing()
{
// show/hide the preview area
d->preview->setVisible(!d->preview->isEmpty());
layout()->activate();
d->preview->setInfo();
//kDebug() << "about to check size";
checkSize();
}
void ToolTip::moveTo(const QPoint &to)
{
if (!isVisible() ||
!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
move(to);
return;
}
d->animation->stop();
d->animation->setEndValue(to);
d->animation->start();
}
void ToolTip::resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);
d->background->resizeFrame(size());
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
KWindowEffects::enableBlurBehind(winId(), true, d->background->mask());
clearMask();
} else {
setMask(d->background->mask());
}
d->preview->setInfo();
if (isVisible()) {
adjustPosition(e->oldSize(), e->size());
}
}
void ToolTip::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setClipRect(e->rect());
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(e->rect(), Qt::transparent);
d->background->paintFrame(&painter);
}
bool ToolTip::autohide() const
{
return d->autohide;
}
void ToolTip::setDirection(Plasma::Direction direction)
{
d->direction = direction;
}
void ToolTip::linkActivated(const QString &anchor, QMouseEvent *event)
{
emit linkActivated(anchor, event->buttons(), event->modifiers(), event->globalPos());
}
void ToolTip::updateTheme()
{
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
QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
QPalette plasmaPalette = QPalette();
plasmaPalette.setColor(QPalette::Window,
Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
plasmaPalette.setColor(QPalette::WindowText, textColor);
setAutoFillBackground(true);
setPalette(plasmaPalette);
d->text->setStyleSheet(QString("p { color: %1; }").arg(textColor.name()));
update();
}
} // namespace Plasma
#include "moc_tooltip_p.cpp"

View File

@ -1,78 +0,0 @@
/*
* 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> //Content struct
namespace Plasma {
class ToolTipPrivate;
class ToolTip : public QWidget
{
Q_OBJECT
public:
ToolTip(QWidget *parent);
~ToolTip();
void setContent(QObject *tipper, const ToolTipContent &data);
void prepareShowing();
void moveTo(const QPoint &to);
bool autohide() const;
void setDirection(Plasma::Direction);
void linkActivated(const QString &anchor, QMouseEvent *event);
Q_SIGNALS:
void activateWindowByWId(WId wid,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint& screenPos);
void linkActivated(const QString &anchor,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint& screenPos);
void hovered(bool hovered);
protected:
void checkSize();
void adjustPosition(const QSize &previous, const QSize &current);
void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void mouseReleaseEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *);
private Q_SLOTS:
void updateTheme();
private:
ToolTipPrivate * const d;
};
} // namespace Plasma
#endif // PLASMA_TOOLTIP_P_H

View File

@ -1,256 +0,0 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
*
* 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 "tooltipcontent.h"
#include <QGraphicsWidget>
#include <QHash>
#include <QTextDocument>
#include <kiconloader.h>
namespace Plasma
{
struct ToolTipResource
{
ToolTipResource()
{
}
ToolTipResource(ToolTipContent::ResourceType t, const QVariant &v)
: type(t),
data(v)
{
}
ToolTipContent::ResourceType type;
QVariant data;
};
const int MAXIMUM_TEXT_LENGTH = 5000;
class ToolTipContentPrivate
{
public:
ToolTipContentPrivate()
: autohide(true),
instantPopup(false),
clickable(false),
highlightWindows(false)
{
}
QString mainText;
QString subText;
QPixmap image;
QList<WId> windowsToPreview;
QHash<QUrl, ToolTipResource> resources;
QWeakPointer<QGraphicsWidget> graphicsWidget;
bool autohide : 1;
bool instantPopup : 1;
bool clickable : 1;
bool highlightWindows : 1;
};
ToolTipContent::ToolTipContent()
: d(new ToolTipContentPrivate)
{
}
ToolTipContent::ToolTipContent(const ToolTipContent &other)
: d(new ToolTipContentPrivate(*other.d))
{
}
ToolTipContent::~ToolTipContent()
{
delete d;
}
ToolTipContent &ToolTipContent::operator=(const ToolTipContent &other)
{
*d = *other.d;
return *this;
}
ToolTipContent::ToolTipContent(const QString &mainText,
const QString &subText,
const QPixmap &image)
: d(new ToolTipContentPrivate)
{
setMainText(mainText);
setSubText(subText);
setImage(image);
}
ToolTipContent::ToolTipContent(const QString &mainText,
const QString &subText,
const QIcon &icon)
: d(new ToolTipContentPrivate)
{
setMainText(mainText);
setSubText(subText);
setImage(icon);
}
bool ToolTipContent::isEmpty() const
{
return d->mainText.isEmpty() &&
d->subText.isEmpty() &&
d->image.isNull() &&
(d->windowsToPreview.size() == 0);
}
void ToolTipContent::setMainText(const QString &text)
{
d->mainText = text.trimmed();
}
QString ToolTipContent::mainText() const
{
QString text = d->mainText;
text.truncate(MAXIMUM_TEXT_LENGTH);
return text;
}
void ToolTipContent::setSubText(const QString &text)
{
d->subText = text.trimmed();
}
QString ToolTipContent::subText() const
{
QString text = d->subText;
text.truncate(MAXIMUM_TEXT_LENGTH);
return text;
}
void ToolTipContent::setImage(const QPixmap &image)
{
d->image = image;
}
void ToolTipContent::setImage(const QIcon &icon)
{
d->image = icon.pixmap(IconSize(KIconLoader::Desktop));
}
QPixmap ToolTipContent::image() const
{
return d->image;
}
void ToolTipContent::setWindowsToPreview(const QList<WId> & ids)
{
d->windowsToPreview = ids;
}
QList<WId> ToolTipContent::windowsToPreview() const
{
return d->windowsToPreview;
}
void ToolTipContent::setHighlightWindows(bool highlight)
{
d->highlightWindows = highlight;
}
bool ToolTipContent::highlightWindows() const
{
return d->highlightWindows;
}
void ToolTipContent::setAutohide(bool autohide)
{
d->autohide = autohide;
}
bool ToolTipContent::autohide() const
{
return d->autohide;
}
void ToolTipContent::setInstantPopup(bool enabled)
{
d->instantPopup = enabled;
}
bool ToolTipContent::isInstantPopup() const
{
return d->instantPopup;
}
void ToolTipContent::addResource(ResourceType type, const QUrl &path, const QVariant &resource)
{
d->resources.insert(path, ToolTipResource(type, resource));
}
void ToolTipContent::registerResources(QTextDocument *document) const
{
if (!document) {
return;
}
QHashIterator<QUrl, ToolTipResource> it(d->resources);
while (it.hasNext()) {
it.next();
const ToolTipResource &r = it.value();
QTextDocument::ResourceType t = QTextDocument::ImageResource;
switch (r.type) {
case ImageResource:
break;
case HtmlResource:
t = QTextDocument::HtmlResource;
break;
case CssResource:
t = QTextDocument::StyleSheetResource;
break;
default:
break;
}
document->addResource(t, it.key(), r.data);
}
}
void ToolTipContent::setClickable(bool clickable)
{
d->clickable = clickable;
}
bool ToolTipContent::isClickable() const
{
return d->clickable;
}
void ToolTipContent::setGraphicsWidget(QGraphicsWidget *widget)
{
d->graphicsWidget = widget;
}
QGraphicsWidget *ToolTipContent::graphicsWidget() const
{
return d->graphicsWidget.data();
}
} // namespace Plasma

View File

@ -1,216 +0,0 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
*
* 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_TOOLTIPCONTENT_H
#define PLASMA_TOOLTIPCONTENT_H
#include <QtCore/QString>
#include <QtCore/QUrl>
#include <QtCore/QVariant>
#include <QtCore/QList>
#include <QPixmap>
#include <QIcon>
#include <plasma/plasma_export.h>
class QTextDocument;
class QGraphicsWidget;
/**
* This provides the content for a tooltip.
*
* Normally you will want to set at least the @p mainText and
* @p subText.
*/
namespace Plasma
{
class ToolTipContentPrivate;
class PLASMA_EXPORT ToolTipContent
{
public:
enum ResourceType { ImageResource = 0, HtmlResource, CssResource };
/**
* Creates an empty Content
*/
ToolTipContent();
~ToolTipContent();
/**
* Copy constructor
*/
ToolTipContent(const ToolTipContent &other);
/**
* Constructor that sets the common fields
*/
ToolTipContent(const QString &mainText,
const QString &subText,
const QPixmap &image = QPixmap());
/**
* Constructor that sets the common fields
*/
ToolTipContent(const QString &mainText,
const QString &subText,
const QIcon &icon);
ToolTipContent &operator=(const ToolTipContent &other);
/**
* @return true if all the fields are empty
*/
bool isEmpty() const;
/**
* Sets the main text which containts important information, e.g. the title
*/
void setMainText(const QString &text);
/**
* Important information, e.g. the title
*/
QString mainText() const;
/**
* Sets text which elaborates on the @p mainText
*/
void setSubText(const QString &text) ;
/**
* Elaborates on the @p mainText
*/
QString subText() const;
/**
* Sets the icon to show
*/
void setImage(const QPixmap &image);
/**
* Sets the icon to show
*/
void setImage(const QIcon &icon);
/**
* An icon to display
*/
QPixmap image() const;
/**
* Sets the IDS of the windows to show a preview for
* @since 4.3
*/
void setWindowsToPreview(const QList<WId> &ids);
/**
* Ids of a windows if you want to show a preview
* @since 4.3
*/
QList<WId> windowsToPreview() const;
/**
* sets if when the mouse will be over a thumbnail the corresponding window
* will be highlighted by reducing opacity of all the other windows
* @since 4.4
*/
void setHighlightWindows(bool highlight);
/**
* true if when the mouse will be over a thumbnail the corresponding window
* will be highlighted by reducing opacity of all the other windows
* @since 4.4
*/
bool highlightWindows() const;
/** Sets whether or not to autohide the tooltip, defaults to true
*/
void setAutohide(bool autohide);
/**
* Whether or not to autohide the tooltip, defaults to true
*/
bool autohide() const;
/**
* Sets whether or not the tooltip should popup instantly when
* the widget is hovered, defaults to false.
*
* @since 4.7
*/
void setInstantPopup(bool enabled);
/**
* Whether or not the tooltip should popup instantly when
* the widget is hovered, defaults to false.
*
* @since 4.7
*/
bool isInstantPopup() const;
/**
* Adds a resource that can then be referenced from the text elements
* using rich text
*/
void addResource(ResourceType type, const QUrl &path, const QVariant &resource);
/**
* Registers all resources with a given document
*/
void registerResources(QTextDocument *document) const;
/**
* Sets whether or not the tooltip contains clickable content, such as
* window previews. Defaults to false, or not clickable.
*
* @since 4.3
*/
void setClickable(bool clickable);
/**
* @return true if the tooltip is clickabel
*
* @since 4.3
*/
bool isClickable() const;
/**
* Sets an optional graphicsWidget that will be used for positioning the tooltip
* @since 4.6
*/
void setGraphicsWidget(QGraphicsWidget *widget);
/**
* the graphicsWidget used for positioning the tooltip, if any
* @since 4.6
*/
QGraphicsWidget *graphicsWidget() const;
private:
ToolTipContentPrivate * const d;
};
} // namespace Plasma
#endif

View File

@ -1,493 +0,0 @@
/*
* 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 <QCoreApplication>
#include <QLabel>
#include <QTimer>
#include <QGridLayout>
#include <QGraphicsView>
#include <QGraphicsSceneHoverEvent>
//KDE
#include <kwindowsystem.h>
//Plasma
#include "plasma/applet.h"
#include "plasma/containment.h"
#include "plasma/corona.h"
#include "plasma/framesvg.h"
#include "plasma/popupapplet.h"
#include "plasma/theme.h"
#include "plasma/view.h"
#include "plasma/private/tooltip_p.h"
namespace Plasma
{
class ToolTipManagerPrivate
{
public :
ToolTipManagerPrivate(ToolTipManager *manager)
: q(manager),
currentWidget(0),
showTimer(new QTimer(manager)),
hideTimer(new QTimer(manager)),
tipWidget(0),
state(ToolTipManager::Activated),
isShown(false),
delayedHide(false),
clickable(false)
{
}
~ToolTipManagerPrivate()
{
if (!QCoreApplication::closingDown()) {
delete tipWidget;
}
}
void showToolTip();
void resetShownState();
/**
* called when a widget inside the tooltip manager is deleted
*/
void onWidgetDestroyed(QObject * object);
void removeWidget(QGraphicsWidget *w, bool canSafelyAccess = true);
void clearTips();
void doDelayedHide();
void toolTipHovered(bool);
void createTipWidget();
void hideTipWidget();
ToolTipManager *q;
QGraphicsWidget *currentWidget;
QTimer *showTimer;
QTimer *hideTimer;
QHash<QGraphicsWidget *, ToolTipContent> tooltips;
ToolTip *tipWidget;
ToolTipManager::State state;
bool isShown : 1;
bool delayedHide : 1;
bool clickable : 1;
};
//TOOLTIP IMPLEMENTATION
class ToolTipManagerSingleton
{
public:
ToolTipManagerSingleton()
{
}
ToolTipManager self;
};
Q_GLOBAL_STATIC(ToolTipManagerSingleton, privateInstance)
ToolTipManager *ToolTipManager::self()
{
return &privateInstance()->self;
}
ToolTipManager::ToolTipManager(QObject *parent)
: QObject(parent),
d(new ToolTipManagerPrivate(this))
{
d->showTimer->setSingleShot(true);
connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
d->hideTimer->setSingleShot(true);
connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
}
ToolTipManager::~ToolTipManager()
{
delete d;
}
void ToolTipManager::show(QGraphicsWidget *widget)
{
if (!d->tooltips.contains(widget)) {
return;
}
d->delayedHide = false;
d->hideTimer->stop();
d->showTimer->stop();
const int defaultDelay = Theme::defaultTheme()->toolTipDelay();
if (defaultDelay < 0) {
return;
}
ToolTipContent content = d->tooltips[widget];
qreal delay = content.isInstantPopup() ? 0.0 : defaultDelay;
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(qMax(qreal(200), delay));
}
}
bool ToolTipManager::isVisible(QGraphicsWidget *widget) const
{
return d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible();
}
void ToolTipManagerPrivate::doDelayedHide()
{
showTimer->stop(); // stop the timer to show the tooltip
delayedHide = true;
if (isShown && clickable) {
// leave enough time for user to choose
hideTimer->start(1000);
} else {
hideTimer->start(250);
}
}
void ToolTipManager::hide(QGraphicsWidget *widget)
{
if (d->currentWidget != widget) {
return;
}
d->currentWidget = 0;
d->showTimer->stop(); // stop the timer to show the tooltip
d->delayedHide = false;
d->hideTipWidget();
}
void ToolTipManager::registerWidget(QGraphicsWidget *widget)
{
if (d->state == Deactivated || d->tooltips.contains(widget)) {
return;
}
//the tooltip is not registered we add it in our map of tooltips
d->tooltips.insert(widget, ToolTipContent());
widget->installEventFilter(this);
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onWidgetDestroyed(QObject*)));
}
void ToolTipManager::unregisterWidget(QGraphicsWidget *widget)
{
if (!d->tooltips.contains(widget)) {
return;
}
if (widget == d->currentWidget) {
d->currentWidget = 0;
d->showTimer->stop(); // stop the timer to show the tooltip
d->delayedHide = false;
d->hideTipWidget();
}
widget->removeEventFilter(this);
d->removeWidget(widget);
}
void ToolTipManager::setContent(QGraphicsWidget *widget, const ToolTipContent &data)
{
if (d->state == Deactivated || !widget) {
return;
}
registerWidget(widget);
d->tooltips.insert(widget, data);
if (d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible()) {
if (data.isEmpty()) {
// after this call, d->tipWidget will be null
hide(widget);
} else {
d->delayedHide = data.autohide();
d->clickable = data.isClickable();
if (d->delayedHide) {
//kDebug() << "starting authoide";
d->hideTimer->start(3000);
} else {
d->hideTimer->stop();
}
}
if (d->tipWidget) {
d->tipWidget->setContent(widget, data);
d->tipWidget->prepareShowing();
//look if the data prefers aother graphicswidget, otherwise use the one used as event catcher
QGraphicsWidget *referenceWidget = data.graphicsWidget() ? data.graphicsWidget() : widget;
Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
if (corona) {
d->tipWidget->moveTo(corona->popupPosition(referenceWidget, d->tipWidget->size(), Qt::AlignCenter));
}
}
}
}
void ToolTipManager::clearContent(QGraphicsWidget *widget)
{
setContent(widget, ToolTipContent());
}
void ToolTipManager::setState(ToolTipManager::State state)
{
d->state = state;
switch (state) {
case Activated:
break;
case Deactivated:
d->clearTips();
//fallthrough
case Inhibited:
d->resetShownState();
break;
}
}
ToolTipManager::State ToolTipManager::state() const
{
return d->state;
}
void ToolTipManagerPrivate::createTipWidget()
{
if (tipWidget) {
return;
}
tipWidget = new ToolTip(0);
QObject::connect(tipWidget, SIGNAL(activateWindowByWId(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
q, SIGNAL(windowPreviewActivated(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
QObject::connect(tipWidget, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
q, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
QObject::connect(tipWidget, SIGNAL(hovered(bool)), q, SLOT(toolTipHovered(bool)));
}
void ToolTipManagerPrivate::hideTipWidget()
{
if (tipWidget) {
tipWidget->hide();
tipWidget->deleteLater();
tipWidget = 0;
}
}
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);
removeWidget(w, false);
}
void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w, bool canSafelyAccess)
{
if (currentWidget == w && currentWidget) {
currentWidget = 0;
showTimer->stop(); // stop the timer to show the tooltip
hideTipWidget();
delayedHide = false;
}
if (w && canSafelyAccess) {
QObject::disconnect(q, 0, w, 0);
}
tooltips.remove(w);
}
void ToolTipManagerPrivate::clearTips()
{
tooltips.clear();
}
void ToolTipManagerPrivate::resetShownState()
{
if (!tipWidget || !tipWidget->isVisible() || delayedHide) {
//One might have moused out and back in again
showTimer->stop();
delayedHide = false;
isShown = false;
currentWidget = 0;
hideTipWidget();
}
}
void ToolTipManagerPrivate::showToolTip()
{
if (state != ToolTipManager::Activated ||
!currentWidget ||
QApplication::activePopupWidget() ||
QApplication::activeModalWidget()) {
return;
}
PopupApplet *popup = qobject_cast<PopupApplet*>(currentWidget);
if (popup && popup->isPopupShowing()) {
return;
}
if (currentWidget->metaObject()->indexOfMethod("toolTipAboutToShow()") != -1) {
// toolTipAboutToShow may call into methods such as setContent which play
// with the current widget; so let's just pretend for a moment that we don't have
// a current widget
QGraphicsWidget *temp = currentWidget;
currentWidget = 0;
QMetaObject::invokeMethod(temp, "toolTipAboutToShow");
currentWidget = temp;
}
QHash<QGraphicsWidget *, ToolTipContent>::const_iterator tooltip = tooltips.constFind(currentWidget);
if (tooltip == tooltips.constEnd() || tooltip.value().isEmpty()) {
if (isShown) {
delayedHide = true;
hideTimer->start(250);
}
return;
}
createTipWidget();
Containment *c = dynamic_cast<Containment *>(currentWidget->topLevelItem());
//kDebug() << "about to show" << (QObject*)c;
if (c) {
tipWidget->setDirection(Plasma::locationToDirection(c->location()));
}
clickable = tooltip.value().isClickable();
tipWidget->setContent(currentWidget, tooltip.value());
tipWidget->prepareShowing();
QGraphicsWidget *referenceWidget = tooltip.value().graphicsWidget() ? tooltip.value().graphicsWidget() : currentWidget;
Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
if (corona) {
tipWidget->moveTo(corona->popupPosition(referenceWidget, tipWidget->size(), Qt::AlignCenter));
}
tipWidget->show();
isShown = true; //ToolTip is visible
delayedHide = tooltip.value().autohide();
if (delayedHide) {
//kDebug() << "starting authoide";
hideTimer->start(3000);
} else {
hideTimer->stop();
}
}
void ToolTipManagerPrivate::toolTipHovered(bool hovered)
{
if (!clickable) {
return;
}
if (hovered) {
hideTimer->stop();
} else {
hideTimer->start(500);
}
}
bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
{
QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched);
if (d->state != Activated || !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()->isVisible(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.
{
QGraphicsSceneHoverEvent *me = static_cast<QGraphicsSceneHoverEvent *>(event);
//FIXME: seems that wheel events generate hovermoves as well, with 0 delta
if (!d->currentWidget || (me->pos() == me->lastPos())) {
break;
}
}
case QEvent::GraphicsSceneHoverEnter:
{
// Check that there is a tooltip to show
if (!d->tooltips.contains(widget)) {
break;
}
show(widget);
break;
}
case QEvent::GraphicsSceneHoverLeave:
if (d->currentWidget == widget) {
d->doDelayedHide();
}
break;
case QEvent::GraphicsSceneMousePress:
if (d->currentWidget == widget) {
hide(widget);
}
break;
case QEvent::GraphicsSceneWheel:
default:
break;
}
return QObject::eventFilter(watched, event);
}
} // Plasma namespace
#include "moc_tooltipmanager.cpp"

View File

@ -1,217 +0,0 @@
/*
* 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_TOOLTIP_MANAGER_H
#define PLASMA_TOOLTIP_MANAGER_H
#include <kurl.h>
#include <plasma/plasma.h>
#include <plasma/plasma_export.h>
#include <plasma/tooltipcontent.h>
namespace Plasma
{
class ToolTipManagerPrivate;
class Applet;
class Corona;
/**
* @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::ToolTipContent data;
* data.mainText = i18n("My Title");
* data.subText = i18n("This is a little tooltip");
* data.image = KDE::icon("some-icon").pixmap(IconSize(KIconLoader::Desktop));
* Plasma::ToolTipManager::self()->setContent(widget, data);
* @endcode
*
* Note that, since a Plasma::Applet is a QGraphicsWidget, you can use
* Plasma::ToolTipManager::self()->setContent(this, data); in the
* applet's init() method to set a tooltip for the whole applet.
*
* The tooltip will be registered automatically by setContent(). 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:
enum State {
Activated = 0 /**<< Will accept tooltip data and show tooltips */,
Inhibited /**<< Will accept tooltip data, but not show tooltips */,
Deactivated /**<< Will discard tooltip data, and not attempt to show them */
};
/**
* @return The singleton instance of the manager.
*/
static ToolTipManager *self();
/**
* Show the tooltip for a widget registered in the tooltip manager
*
* @param widget the widget for which the tooltip will be displayed
*/
void show(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 isVisible(QGraphicsWidget *widget) const;
/**
* Hides the tooltip for a widget immediately.
*
* @param widget the widget to hide the tooltip for
*/
void hide(QGraphicsWidget *widget);
/**
* Registers a widget with the tooltip manager.
*
* Note that setContent() 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 setContent().
*
* 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 Content
* is passed in, the tooltip content will be reset.
*/
void setContent(QGraphicsWidget *widget,
const ToolTipContent &data);
/**
* Clears the tooltip data associated with this widget, but keeps
* the widget registered.
*/
void clearContent(QGraphicsWidget *widget);
/**
* Sets the current state of the manager.
* @see State
* @param state the state to put the manager in
*/
void setState(ToolTipManager::State state);
/**
* @return the current state of the manager; @see State
*/
ToolTipManager::State state() const;
Q_SIGNALS:
/**
* This signal is emitted when a window preview in the tooltip is clicked.
* @param window the id of the window that was clicked
* @param buttons the mouse buttons involved in the activation
* @param modifiers the keyboard modifiers involved in the activation, if any
* @since 4.4
*/
void windowPreviewActivated(WId window, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint &screenPos);
/**
* This signal is emitted when a link in the tooltip is clicked.
* @param anchor the achor text (e.g. url) that was clicked on
* @param buttons the mouse buttons involved in the activation
* @param modifiers the keyboard modifiers involved in the activation, if any
* @since 4.4
*/
void linkActivated(const QString &anchor, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint &screenPos);
private:
/**
* Default constructor.
*
* You should normall use self() instead.
*/
explicit ToolTipManager(QObject *parent = 0);
/**
* Default destructor.
*/
~ToolTipManager();
friend class ToolTipManagerSingleton;
friend class Corona; // The corona needs to register itself
friend class ToolTipManagerPrivate;
bool eventFilter(QObject *watched, QEvent *event);
ToolTipManagerPrivate *const d;
Q_PRIVATE_SLOT(d, void showToolTip())
Q_PRIVATE_SLOT(d, void toolTipHovered(bool))
Q_PRIVATE_SLOT(d, void resetShownState())
Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*))
};
} // namespace Plasma
#endif // PLASMA_TOOL_TIP_MANAGER_H