Dear all,

   Thanks for your reviews and Seigo's encouragements!

   According to your discussion, I make another two patches based on Seigo's 
patch.  

1 kdelibs-palsma-tooltip-previewclick-aseigo-modified.patch 
  It should apply to the directory  kdelibs/plasma/

2 kdebase-workspace-plasma-tasks-previewclick-aseigo-modified.patch
  It should apply to the directory  kdebase/workspace/plasma/applets/tasks/


Best regards
pwp



Index: taskgroupitem.cpp
===================================================================
--- taskgroupitem.cpp	(版本 979277)
+++ taskgroupitem.cpp	(工作副本)
@@ -45,7 +45,6 @@
 
 #include <Plasma/Theme>
 #include <Plasma/FrameSvg>
-#include <Plasma/ToolTipManager>
 #include <Plasma/Corona>
 #include <Plasma/Containment>
 #include <Plasma/Dialog>
@@ -251,7 +250,7 @@
         return;
     }
 
-    Plasma::ToolTipContent data(m_group->name(),
+    ToolTipContent data(m_group->name(),
                                 i18nc("Which virtual desktop a window is currently on", "On %1",
                                        KWindowSystem::desktopName(m_group->desktop())));
 //    data.image = m_group->icon().pixmap(QSize::small);
@@ -273,9 +272,11 @@
     }
 
     data.setWindowsToPreview(windows);
+	data.setClickable(true);
 
+    connect(ToolTipManager::self(), SIGNAL(clicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)), this, SLOT(toolTipClicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)));
 
-    Plasma::ToolTipManager::self()->setContent(this, data);
+    ToolTipManager::self()->setContent(this, data);
 }
 
 
@@ -1236,5 +1237,34 @@
     return m_popupDialog;
 }
 
+void TaskGroupItem::toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data)
+{
+	if (clickTarget != ToolTipManager::WindowPreviewClicked)
+		return;
+	
+	if (event->button() != Qt::LeftButton)
+		return;
+	
+	bool ok = false;
+	WId wid = data.toInt(&ok);
+	
+	if (ok == false)
+		return;
+
+	if (wid <= 0)
+		return;
+
+	foreach (AbstractGroupableItem *item, m_group->members())
+	{
+		TaskManager::TaskItem *taskItem = qobject_cast<TaskManager::TaskItem *>(item);
+
+		if ((taskItem != NULL) && (taskItem->task()->window() == wid))
+		{
+			taskItem->task()->activateRaiseOrIconify();
+			break;
+		}
+	}
+}
+
 #include "taskgroupitem.moc"
 
Index: taskgroupitem.h
===================================================================
--- taskgroupitem.h	(版本 979277)
+++ taskgroupitem.h	(工作副本)
@@ -130,6 +130,7 @@
 
 public slots:
     void updateActive(AbstractTaskItem *);
+    void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data);
 
 protected:
     AbstractTaskItem *taskItemForWId(WId id);
Index: windowtaskitem.cpp
===================================================================
--- windowtaskitem.cpp	(版本 979277)
+++ windowtaskitem.cpp	(工作副本)
@@ -45,7 +45,6 @@
 
 #include <Plasma/Theme>
 #include <Plasma/FrameSvg>
-#include <Plasma/ToolTipManager>
 #include <Plasma/Corona>
 #include <Plasma/Containment>
 
@@ -193,12 +192,15 @@
                      Qt::KeepAspectRatio, Qt::SmoothTransformation);
     }
 
-    Plasma::ToolTipContent data(m_task->name(),
+    ToolTipContent data(m_task->name(),
                                 i18nc("Which virtual desktop a window is currently on", "On %1",
                                       KWindowSystem::desktopName(m_task->desktop())), p);
     data.setWindowToPreview(m_task->task()->window());
+	data.setClickable(true);
 
-    Plasma::ToolTipManager::self()->setContent(this, data);
+    connect(ToolTipManager::self(), SIGNAL(clicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)), this, SLOT(toolTipClicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)));
+
+    ToolTipManager::self()->setContent(this, data);
 }
 
 void WindowTaskItem::setStartupTask(TaskItem *task)
@@ -317,5 +319,25 @@
     }
 }
 
+void WindowTaskItem::toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data)
+{
+	if (clickTarget != ToolTipManager::WindowPreviewClicked)
+		return;
+	
+	if (event->button() != Qt::LeftButton)
+		return;
+	
+	bool ok = false;
+	WId wid = data.toInt(&ok);
+	
+	if (ok == false)
+		return;
+
+	if (wid != m_task->task()->window())
+		return;
+
+	activate();
+}
+ 
 #include "windowtaskitem.moc"
 
Index: abstracttaskitem.h
===================================================================
--- abstracttaskitem.h	(版本 979277)
+++ abstracttaskitem.h	(工作副本)
@@ -25,6 +25,7 @@
 
 // KDE
 #include <KColorScheme>
+#include <Plasma/ToolTipManager>
 // Own
 #include <taskmanager/taskgroup.h>
 
@@ -37,13 +38,13 @@
 class QTextLayout;
 class QString;
 
-
 // Plasma
 #include <Plasma/Animator>
 
 class Tasks;
 class TaskGroupItem;
 class LayoutWidget;
+using namespace Plasma;
 
 /**
  * A baseclass for a task
@@ -138,6 +139,7 @@
     virtual void activate() = 0;
     void toolTipAboutToShow();
     void toolTipHidden();
+    virtual void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data) = 0;
 
 protected:
     void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
Index: windowtaskitem.h
===================================================================
--- windowtaskitem.h	(版本 979277)
+++ windowtaskitem.h	(工作副本)
@@ -24,7 +24,6 @@
 
 #include "abstracttaskitem.h"
 // Own
-#include <taskmanager/taskmanager.h>
 #include <taskmanager/taskitem.h>
 
 /**
@@ -62,6 +61,7 @@
 public slots:
     void activate();
     void close();
+    void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data);
 
 protected:
     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
Index: tasks.cpp
===================================================================
--- tasks.cpp	(版本 979277)
+++ tasks.cpp	(工作副本)
@@ -62,7 +62,6 @@
     resize(500, 58);
 
     setAcceptDrops(true);
-
 }
 
 Tasks::~Tasks()
@@ -405,7 +404,6 @@
     return m_rootGroupItem;
 }
 
-
 K_EXPORT_PLASMA_APPLET(tasks, Tasks)
 
 #include "tasks.moc"
Index: tasks.h
===================================================================
--- tasks.h	(版本 979277)
+++ tasks.h	(工作副本)
@@ -108,7 +108,6 @@
 
         void needsVisualFocus();
 
-
 signals:
     /**
     * emitted whenever we receive a constraintsEvent
Index: tooltipmanager.cpp
===================================================================
--- tooltipmanager.cpp	(版本 979276)
+++ tooltipmanager.cpp	(工作副本)
@@ -62,9 +62,10 @@
           tipWidget(new ToolTip(0)),
           state(ToolTipManager::Activated),
           isShown(false),
-          delayedHide(false)
+          delayedHide(false),
+          clickable(false)
     {
-
+        QObject::connect(tipWidget, SIGNAL(windowPreviewClicked(WId, QMouseEvent *)), q, SLOT(windowPreviewClicked(WId, QMouseEvent *)));
     }
 
     ~ToolTipManagerPrivate()
@@ -81,9 +82,10 @@
       * called when a widget inside the tooltip manager is deleted
       */
     void onWidgetDestroyed(QObject * object);
-    void removeWidget(QGraphicsWidget *w);
+    void removeWidget(QGraphicsWidget *w, bool canSafelyAccess = true);
     void clearTips();
     void doDelayedHide();
+    void windowPreviewClicked(WId wid, QMouseEvent *event);
 
     ToolTipManager *q;
     QGraphicsWidget *currentWidget;
@@ -94,6 +96,7 @@
     ToolTipManager::State state;
     bool isShown : 1;
     bool delayedHide : 1;
+    bool clickable : 1;
 };
 
 //TOOLTIP IMPLEMENTATION
@@ -137,6 +140,10 @@
         return;
     }
 
+    if (d->currentWidget) {
+        disconnect(this, 0, d->currentWidget, 0);
+    }
+
     d->hideTimer->stop();
     d->delayedHide = false;
     d->showTimer->stop();
@@ -160,7 +167,13 @@
 {
     showTimer->stop();  // stop the timer to show the tooltip
     delayedHide = true;
-    hideTimer->start(250);
+
+    if (isShown && clickable) {
+        // leave enough time for user to choose
+        hideTimer->start(1000);
+    } else {
+        hideTimer->start(250);
+    }
 }
 
 void ToolTipManager::hide(QGraphicsWidget *widget)
@@ -169,6 +182,10 @@
         return;
     }
 
+    if (d->currentWidget) {
+        disconnect(this, 0, d->currentWidget, 0);
+    }
+
     d->currentWidget = 0;
     d->showTimer->stop();  // stop the timer to show the tooltip
     d->delayedHide = false;
@@ -205,6 +222,7 @@
 
     registerWidget(widget);
     d->tooltips.insert(widget, data);
+    d->clickable = data.isClickable();
 
     if (d->currentWidget == widget) {
         if (data.isEmpty()) {
@@ -267,13 +285,16 @@
     // 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);
+    removeWidget(w, false);
 }
 
-void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w)
+void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w, bool canSafelyAccess)
 {
-    // DO NOT ACCESS w HERE!! IT MAY BE IN THE PROCESS OF DELETION!
-    if (currentWidget == w) {
+    if (currentWidget == w && currentWidget) {
+        if (canSafelyAccess) {
+            QObject::disconnect(q, 0, currentWidget, 0);
+        }
+
         currentWidget = 0;
         showTimer->stop();  // stop the timer to show the tooltip
         tipWidget->setContent(0, ToolTipContent());
@@ -296,6 +317,7 @@
             //One might have moused out and back in again
             delayedHide = false;
             isShown = false;
+            QObject::disconnect(q, 0, currentWidget, 0);
             currentWidget = 0;
             tipWidget->hide();
         }
@@ -353,6 +375,11 @@
     }
 }
 
+void ToolTipManagerPrivate::windowPreviewClicked(WId wid, QMouseEvent *event)
+{
+    emit q->clicked(ToolTipManager::WindowPreviewClicked, event, QVariant::fromValue(wid));
+}
+
 bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
 {
     QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched);
@@ -399,6 +426,7 @@
 
         case QEvent::GraphicsSceneMousePress:
             hide(widget);
+            break;
 
         case QEvent::GraphicsSceneWheel:
         default:
Index: tooltipcontent.h
===================================================================
--- tooltipcontent.h	(版本 979276)
+++ tooltipcontent.h	(工作副本)
@@ -48,79 +48,135 @@
 public:
     enum ResourceType { ImageResource = 0, HtmlResource, CssResource };
 
-    /** Creates an empty Content */
+    /**
+     * Creates an empty Content
+     */
     ToolTipContent();
 
     ~ToolTipContent();
 
-    /** Copy constructor */
+    /**
+     * Copy constructor
+     */
     ToolTipContent(const ToolTipContent &other);
 
-    /** Constructor that sets the common fields */
+    /**
+     * Constructor that sets the common fields
+     */
     ToolTipContent(const QString &mainText,
                    const QString &subText,
                    const QPixmap &image = QPixmap());
 
-    /** Constructor that sets the common fields */
+    /**
+     * 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 */
+    /**
+     * @return true if all the fields are empty
+     */
     bool isEmpty() const;
 
-    /** Sets the main text which containts important information, e.g. the title */
+    /**
+     * Sets the main text which containts important information, e.g. the title
+     */
     void setMainText(const QString &text);
 
-    /** Important information, e.g. the title */
+    /**
+     * Important information, e.g. the title
+     */
     QString mainText() const;
 
-    /** Sets text which elaborates on the @p mainText */
+    /**
+     * Sets text which elaborates on the @p mainText
+     */
     void setSubText(const QString &text) ;
 
-    /** Elaborates on the @p mainText */
+    /**
+     * Elaborates on the @p mainText
+     */
     QString subText() const;
 
-    /** Sets the icon to show **/
+    /**
+     * Sets the icon to show
+     */
     void setImage(const QPixmap &image);
 
-    /** Sets the icon to show **/
+    /**
+     * Sets the icon to show
+     */
     void setImage(const QIcon &icon);
 
-    /** An icon to display */
+    /**
+     * 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 */
+    /**
+     * Sets the ID of the window to show a preview for.
+     * @deprecated
+     * @see setWindowsToPreview
+     */
     void setWindowToPreview(WId id);
 
-    //BIC FIXME: remove when we can break BC
-    /** Id of a window if you want to show a preview */
+    /**
+     * Id of a window if you want to show a preview
+     * @deprecated
+     * @see windowsToPreview
+     */
     WId windowToPreview() const;
 
-    /** Sets the IDS of the windows to show a preview for
-        @since 4.3*/
+    /**
+     * 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*/
+    /**
+     * Ids of a windows if you want to show a preview
+     * @since 4.3
+     */
     QList<WId> windowsToPreview() const;
 
-    /** Sets whether or not to autohide the tooltip, defaults to true */
+    /** 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 */
+    /**
+     * Whether or not to autohide the tooltip, defaults to true
+     */
     bool autohide() const;
 
-    /** Adds a resource that can then be referenced from the text elements
-        using rich text **/
+    /**
+     * 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 */
+    /**
+     * 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;
+
 private:
     ToolTipContentPrivate * const d;
 };
Index: tooltipcontent.cpp
===================================================================
--- tooltipcontent.cpp	(版本 979276)
+++ tooltipcontent.cpp	(工作副本)
@@ -47,7 +47,8 @@
 {
 public:
     ToolTipContentPrivate()
-      : autohide(true)
+      : autohide(true),
+        clickable(false)
     {
     }
 
@@ -56,7 +57,8 @@
     QPixmap image;
     QList<WId> windowsToPreview;
     QHash<QString, ToolTipResource> resources;
-    bool autohide;
+    bool autohide : 1;
+    bool clickable : 1;
 };
 
 ToolTipContent::ToolTipContent()
@@ -211,6 +213,16 @@
     }
 }
 
+void ToolTipContent::setClickable(bool clickable)
+{
+    d->clickable = clickable;
+}
+
+bool ToolTipContent::isClickable() const
+{
+    return d->clickable;
+}
+
 } // namespace Plasma
 
 
Index: private/tooltip_p.h
===================================================================
--- private/tooltip_p.h	(版本 979276)
+++ private/tooltip_p.h	(工作副本)
@@ -43,6 +43,9 @@
     bool autohide() const;
     void setDirection(Plasma::Direction);
 
+signals:
+    void windowPreviewClicked(WId wid, QMouseEvent *event);
+
 protected:
     void checkSize();
     void adjustPosition(const QSize &previous, const QSize &current);
Index: private/windowpreview.cpp
===================================================================
--- private/windowpreview.cpp	(版本 979276)
+++ private/windowpreview.cpp	(工作副本)
@@ -22,6 +22,7 @@
 
 #include <QPainter>
 #include <QVarLengthArray>
+#include <QMouseEvent>
 
 #include <kwindowsystem.h>
 #include <kdebug.h>
@@ -224,6 +225,23 @@
 #endif
 }
 
+void WindowPreview::mousePressEvent(QMouseEvent *event)
+{
+    QPoint p = event->pos();
+    WId wid = 0;
+
+    for (int i = 0; i < m_thumbnailRects.size(); ++i) {
+        if (m_thumbnailRects[i].contains(p)) {
+            wid = ids[i];
+            break;
+        }
+    }
+
+    if (wid) {
+        emit windowPreviewClicked(wid, event);
+    }
+}
+
 } // namespace Plasma
 
 #include "windowpreview_p.moc"
Index: private/tooltip.cpp
===================================================================
--- private/tooltip.cpp	(版本 979276)
+++ private/tooltip.cpp	(工作副本)
@@ -165,6 +165,7 @@
     d->background->setEnabledBorders(FrameSvg::AllBorders);
     updateTheme();
     connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme()));
+    connect(d->preview, SIGNAL(windowPreviewClicked(WId, QMouseEvent *)), this, SIGNAL(windowPreviewClicked(WId, QMouseEvent *)));
 
     l->addWidget(d->preview, 0, 0, 1, 2);
     l->addWidget(d->imageLabel, 1, 0);
Index: private/windowpreview_p.h
===================================================================
--- private/windowpreview_p.h	(版本 979276)
+++ private/windowpreview_p.h	(工作副本)
@@ -50,8 +50,12 @@
     bool isEmpty() const;
     virtual QSize sizeHint() const;
 
+signals:
+    void windowPreviewClicked(WId wid, QMouseEvent *event);
+
 protected:
     void paintEvent(QPaintEvent *e);
+    void mousePressEvent(QMouseEvent *event);
 
 private:
     void readWindowSizes() const;
Index: containment.cpp
===================================================================
--- containment.cpp	(版本 979276)
+++ containment.cpp	(工作副本)
@@ -144,20 +144,32 @@
 
     //fix the text of the actions that need name()
     //btw, do we really want to use name() when it's a desktopcontainment?
-    QAction *closeApplet = d->actions()->action("remove");
-    closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name()));
-    QAction *configAction = d->actions()->action("configure");
-    configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", name()));
+    QAction *closeApplet = action("remove");
+    if (closeApplet) {
+        closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name()));
+    }
 
+    QAction *configAction = action("configure");
+    if (configAction) {
+        configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", name()));
+    }
+
     QAction *appletBrowserAction = action("add widgets");
-    appletBrowserAction->setVisible(unlocked);
-    appletBrowserAction->setEnabled(unlocked);
-    connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets()));
+    if (appletBrowserAction) {
+        appletBrowserAction->setVisible(unlocked);
+        appletBrowserAction->setEnabled(unlocked);
+        connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets()));
+    }
 
     QAction *act = action("next applet");
-    connect(act, SIGNAL(triggered()), this, SLOT(focusNextApplet()));
+    if (act) {
+        connect(act, SIGNAL(triggered()), this, SLOT(focusNextApplet()));
+    }
+
     act = action("previous applet");
-    connect(act, SIGNAL(triggered()), this, SLOT(focusPreviousApplet()));
+    if (act) {
+        connect(act, SIGNAL(triggered()), this, SLOT(focusPreviousApplet()));
+    }
 
     if (immutability() != SystemImmutable && corona()) {
         QAction *lockDesktopAction = corona()->action("lock widgets");
@@ -169,7 +181,7 @@
 
     if (d->type == PanelContainment ||
         d->type == CustomPanelContainment) {
-        d->actions()->removeAction(d->actions()->action("zoom in"));
+        d->actions()->removeAction(action("zoom in"));
     } else {
         QAction *zoomAction = action("zoom in");
         connect(zoomAction, SIGNAL(triggered()), this, SLOT(zoomIn()));
Index: tooltipmanager.h
===================================================================
--- tooltipmanager.h	(版本 979276)
+++ tooltipmanager.h	(工作副本)
@@ -22,6 +22,8 @@
 #ifndef PLASMA_TOOLTIP_MANAGER_H
 #define PLASMA_TOOLTIP_MANAGER_H
 
+#include <QMouseEvent>
+
 //plasma
 #include <plasma/plasma.h>
 #include <plasma/plasma_export.h>
@@ -76,6 +78,13 @@
         Deactivated /**<< Will discard tooltip data, and not attempt to show them */
     };
 
+    enum ClickTarget {
+        NothingClicked = 0,
+        WindowPreviewClicked = 1,
+        LinkClicked = 2,
+        IconClicked = 3
+    };
+
     /**
      * @return The singleton instance of the manager.
      */
@@ -164,6 +173,17 @@
      */
     ToolTipManager::State state() const;
 
+signals:
+    /**
+     * This signal is emitted when something in the tooltip is clicked.
+     * @arg clickTarget what kind of item was clicked @see ClickTarget
+     * @arg event QMouseEvent infomation 
+     * @arg data what was clicked, such as a url in the case of a hyperlink,
+     *           or a window id in the case of a window preview.
+     * @since 4.3
+     */
+    void clicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data);
+
 private:
     /**
      * Default constructor.
@@ -188,6 +208,7 @@
     Q_PRIVATE_SLOT(d, void showToolTip())
     Q_PRIVATE_SLOT(d, void resetShownState())
     Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*))
+    Q_PRIVATE_SLOT(d, void windowPreviewClicked(WId wid, QMouseEvent *event))
 };
 
 } // namespace Plasma
_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to