From 13ddc52057c69c0b828ecd7733fd6e229a4527ff Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 19 Mar 2009 22:15:29 +0000 Subject: [PATCH] support for multiple windows thumbnails in a tooltip svn path=/trunk/KDE/kdelibs/; revision=941541 --- private/tooltip.cpp | 11 +++- private/windowpreview.cpp | 106 +++++++++++++++++++++++++++++--------- private/windowpreview_p.h | 15 ++++-- tooltipcontent.cpp | 28 +++++++--- tooltipcontent.h | 9 ++++ 5 files changed, 131 insertions(+), 38 deletions(-) diff --git a/private/tooltip.cpp b/private/tooltip.cpp index 57ca609f3..1e8792220 100644 --- a/private/tooltip.cpp +++ b/private/tooltip.cpp @@ -226,7 +226,14 @@ void ToolTip::setContent(QObject *tipper, const ToolTipContent &data) //reset our size d->text->setContent(data); d->imageLabel->setPixmap(data.image()); - d->preview->setWindowId(data.windowToPreview()); + if (data.windowsToPreview().size() > 1) { + d->preview->setWindowIds(data.windowsToPreview()); + } else { + QListids; + ids.append(data.windowToPreview()); + d->preview->setWindowIds(ids); + } + d->autohide = data.autohide(); d->source = tipper; @@ -239,7 +246,7 @@ void ToolTip::setContent(QObject *tipper, const ToolTipContent &data) void ToolTip::prepareShowing() { - if (d->preview->windowId() != 0) { + if (!d->preview->isEmpty()) { // show/hide the preview area d->preview->show(); } else { diff --git a/private/windowpreview.cpp b/private/windowpreview.cpp index a34fb2800..044ccad30 100644 --- a/private/windowpreview.cpp +++ b/private/windowpreview.cpp @@ -65,53 +65,86 @@ WindowPreview::WindowPreview(QWidget *parent) m_background->setElementPrefix("raised"); } -void WindowPreview::setWindowId(WId w) +void WindowPreview::setWindowIds(const QList wids) { if (!previewsAvailable()) { setMinimumSize(0,0); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - id = 0; + ids.clear(); return; } - id = w; - readWindowSize(); + ids = wids; + readWindowSizes(); QSize s(sizeHint()); if (s.isValid()) { setFixedSize(sizeHint()); } } -WId WindowPreview::windowId() const +QList WindowPreview::windowIds() const { - return id; + return ids; } QSize WindowPreview::sizeHint() const { - if (id == 0) { + if (ids.size() == 0) { return QSize(); } - if (!windowSize.isValid()) { - readWindowSize(); + if (!windowSizes.size() == 0) { + readWindowSizes(); } - QSize s = windowSize; - s.scale(200, 150, Qt::KeepAspectRatio); + + int maxHeight = 0; + int totalWidth = 0; + foreach (QSize s, windowSizes) { + if (s.height() > maxHeight) { + maxHeight = s.height(); + } + + totalWidth += s.width(); + } + + QSize s(totalWidth, maxHeight); + + qreal left, top, right, bottom; + m_background->getMargins(left, top, right, bottom); + + s.scale(windowWidth*windowSizes.size(), windowHeight, Qt::KeepAspectRatio); + + s = s + QSize(left+right+windowMargin*(windowSizes.size()-1), top+bottom); return s; } -void WindowPreview::readWindowSize() const +void WindowPreview::readWindowSizes() const { + windowSizes.clear(); + foreach (WId id, ids) { #ifdef Q_WS_X11 - if (id > 0) { - KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry|NET::WMFrameExtents); - windowSize = info.frameGeometry().size(); - } else { - windowSize = QSize(); - } + if (id > 0) { + KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry|NET::WMFrameExtents); + windowSizes.append(info.frameGeometry().size()); + } else { + windowSizes.append(QSize()); + } #else - windowSize = QSize(); + windowSizes.append(QSize()); #endif + } +} + +bool WindowPreview::isEmpty() const +{ + if (ids.size() == 0) { + return true; + } + foreach (WId id, ids) { + if (id != 0) { + return false; + } + } + return true; } void WindowPreview::setInfo() @@ -119,14 +152,14 @@ void WindowPreview::setInfo() #ifdef Q_WS_X11 Display *dpy = QX11Info::display(); Atom atom = XInternAtom(dpy, "_KDE_WINDOW_PREVIEW", False); - if (id == 0) { + if (isEmpty()) { XDeleteProperty(dpy, parentWidget()->winId(), atom); return; } - if (!windowSize.isValid()) { - readWindowSize(); + if (windowSizes.size() == 0) { + readWindowSizes(); } - if (!windowSize.isValid()) { + if (windowSizes.size() == 0) { XDeleteProperty(dpy, parentWidget()->winId(), atom); return; } @@ -140,8 +173,33 @@ void WindowPreview::setInfo() m_background->getMargins(left, top, right, bottom); QRect thumbnailRect = geometry().adjusted(left, top, -right, -bottom); + const int numWindows = ids.size(); + + QList thumbnailRects; + int x = thumbnailRect.x(); + + foreach (QSize s, windowSizes) { + s.scale((qreal)(thumbnailRect.width()-5*(numWindows-1))/numWindows, thumbnailRect.height(), Qt::KeepAspectRatio); + int y = thumbnailRect.y() + (thumbnailRect.height() - s.height())/2; + thumbnailRects.append(QRect(QPoint(x,y), s)); + x += s.width() + 5; + } + + long data[(1 + 6*numWindows)]; + data[0] = numWindows; + + for (int i = 0; iwinId(), atom, atom, 32, PropModeReplace, reinterpret_cast(data), sizeof(data) / sizeof(data[ 0 ])); #endif diff --git a/private/windowpreview_p.h b/private/windowpreview_p.h index 462838b6f..2b76a7220 100644 --- a/private/windowpreview_p.h +++ b/private/windowpreview_p.h @@ -44,20 +44,25 @@ public: WindowPreview(QWidget *parent = 0); - void setWindowId(WId w); - WId windowId() const; + void setWindowIds(const QList w); + QList windowIds() const; void setInfo(); + bool isEmpty() const; virtual QSize sizeHint() const; protected: void paintEvent(QPaintEvent *e); private: - void readWindowSize() const; + void readWindowSizes() const; - WId id; - mutable QSize windowSize; + QList ids; + mutable QList windowSizes; FrameSvg *m_background; + + static const int windowMargin = 5; + static const int windowWidth = 200; + static const int windowHeight = 150; }; } // namespace Plasma diff --git a/tooltipcontent.cpp b/tooltipcontent.cpp index 88d3a6c85..c9a5d691b 100644 --- a/tooltipcontent.cpp +++ b/tooltipcontent.cpp @@ -46,15 +46,14 @@ class ToolTipContentPrivate { public: ToolTipContentPrivate() - : windowToPreview(0), - autohide(true) + : autohide(true) { } QString mainText; QString subText; QPixmap image; - WId windowToPreview; + QList windowsToPreview; QHash resources; bool autohide; }; @@ -105,7 +104,7 @@ bool ToolTipContent::isEmpty() const return d->mainText.isEmpty() && d->subText.isEmpty() && d->image.isNull() && - d->windowToPreview == 0; + (d->windowsToPreview.size() == 0); } void ToolTipContent::setMainText(const QString &text) @@ -143,14 +142,29 @@ QPixmap ToolTipContent::image() const return d->image; } -void ToolTipContent::setWindowToPreview(WId id) +void ToolTipContent::setWindowToPreview(const WId id) { - d->windowToPreview = id; + d->windowsToPreview.clear(); + d->windowsToPreview.append(id); } WId ToolTipContent::windowToPreview() const { - return d->windowToPreview; + if (d->windowsToPreview.size() == 1) { + return d->windowsToPreview.first(); + } else { + return 0; + } +} + +void ToolTipContent::setWindowsToPreview(QList ids) +{ + d->windowsToPreview = ids; +} + +QList ToolTipContent::windowsToPreview() const +{ + return d->windowsToPreview; } void ToolTipContent::setAutohide(bool autohide) diff --git a/tooltipcontent.h b/tooltipcontent.h index e54df9812..e3aa0f2ab 100644 --- a/tooltipcontent.h +++ b/tooltipcontent.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -91,12 +92,20 @@ public: /** An icon to display */ QPixmap image() const; + //BIC FIXME: remove when we can break BC /** Sets the ID of the window to show a preview for */ void setWindowToPreview(WId id); + //BIC FIXME: remove when we can break BC /** Id of a window if you want to show a preview */ WId windowToPreview() const; + /** Sets the IDS of the windows to show a preview for */ + void setWindowsToPreview(const QList ids); + + /** Ids of a windows if you want to show a preview */ + QList windowsToPreview() const; + /** Sets whether or not to autohide the tooltip, defaults to true */ void setAutohide(bool autohide);