[SCM] ktp-contact-list packaging branch, master, updated. debian/15.12.1-2-1070-g6c56f91

Maximiliano Curia maxy at moszumanska.debian.org
Sat May 28 00:08:10 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-contact-list.git;a=commitdiff;h=3bf6a53

The following commit has been merged in the master branch:
commit 3bf6a533141f6f4a0f68540798f61ad4c9d84258
Author: Martin Klapetek <martin.klapetek at gmail.com>
Date:   Wed Dec 7 12:00:02 2011 +0100

    QWidget based tooltips
    
    This work is based on system settings tooltips and replaces the standard rich-text-qt-tooltips, which gives us better flexibility and control over what's in the tooltip as well as how is it displayed.
    
    The code was adapted by David Edmundson and finished later by Google Code-In student Geoffry Song.
    
    REVIEW: 103297
    BUG: 282207
---
 CMakeLists.txt                                     |   5 +
 abstract-contact-delegate.cpp                      |  87 +--------
 main-widget.cpp                                    |   4 +
 tooltips/contacttooltip.cpp                        | 118 ++++++++++++
 .../contact-info.h => tooltips/contacttooltip.h    |  30 ++--
 tooltips/contacttooltip.ui                         | 143 +++++++++++++++
 tooltips/ktooltip.cpp                              | 116 ++++++++++++
 tooltips/ktooltip.h                                |  48 +++++
 tooltips/ktooltipwindow.cpp                        |  94 ++++++++++
 .../contact-info.h => tooltips/ktooltipwindow_p.h  |  36 ++--
 tooltips/tooltipmanager.cpp                        | 197 +++++++++++++++++++++
 tooltips/tooltipmanager.h                          |  83 +++++++++
 12 files changed, 843 insertions(+), 118 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68dc90c..a1cddd7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,10 @@ set (contactlist_SRCS
      dialogs/contact-info.cpp
      dialogs/custom-presence-dialog.cpp
      presence-model.cpp
+     tooltips/ktooltip.cpp
+     tooltips/tooltipmanager.cpp
+     tooltips/ktooltipwindow.cpp
+     tooltips/contacttooltip.cpp
 )
 
 
@@ -54,6 +58,7 @@ kde4_add_ui_files (contactlist_SRCS
                    dialogs/join-chat-room-dialog.ui
                    dialogs/remove-contact-dialog.ui
                    dialogs/contact-info.ui
+                   tooltips/contacttooltip.ui
 )
 
 add_subdirectory (icons)
diff --git a/abstract-contact-delegate.cpp b/abstract-contact-delegate.cpp
index 2bd0f55..a9eaee6 100644
--- a/abstract-contact-delegate.cpp
+++ b/abstract-contact-delegate.cpp
@@ -165,90 +165,5 @@ QSize AbstractContactDelegate::sizeHintHeader(const QStyleOptionViewItem &option
 
 bool AbstractContactDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
 {
-    Q_UNUSED(option);
-
-    // Check and make sure that we only want it to work on contacts and nothing else.
-    if (index.data(AccountsModel::ItemRole).userType() != qMetaTypeId<ContactModelItem*>()) {
-        return false;
-    }
-
-    if (event->type() != QEvent::ToolTip) {
-        return false;
-    }
-
-    const QString contactAvatar = index.data(AccountsModel::AvatarRole).toString();
-    const QString displayName = index.parent().data(AccountsModel::DisplayNameRole).toString();
-    const QString cmIconPath = KIconLoader::global()->iconPath(index.parent().data(AccountsModel::IconRole).toString(), 1);
-    const QString alias = index.data(AccountsModel::AliasRole).toString();
-    const QString id = index.data(AccountsModel::IdRole).toString();
-    const QString presenceStatus = index.data(AccountsModel::PresenceMessageRole).toString();
-    QString presenceIconPath;
-    QString presenceText;
-
-    switch (index.data(AccountsModel::PresenceTypeRole).toUInt()) {
-    case Tp::ConnectionPresenceTypeAvailable:
-        presenceIconPath = KIconLoader::global()->iconPath("user-online", 1);
-        presenceText = i18nc("This is an IM user status", "Online");
-        break;
-    case Tp::ConnectionPresenceTypeAway:
-        presenceIconPath = KIconLoader::global()->iconPath("user-away", 1);
-        presenceText = i18nc("This is an IM user status", "Away");
-        break;
-    case Tp::ConnectionPresenceTypeExtendedAway:
-        presenceIconPath = KIconLoader::global()->iconPath("user-away-extended", 1);
-        presenceText = i18nc("This is an IM user status", "Away");
-        break;
-    case Tp::ConnectionPresenceTypeBusy:
-        presenceIconPath = KIconLoader::global()->iconPath("user-busy", 1);
-        presenceText = i18nc("This is an IM user status", "Busy");
-        break;
-    case Tp::ConnectionPresenceTypeHidden:
-        presenceIconPath = KIconLoader::global()->iconPath("user-invisible", 1);
-        presenceText = i18nc("This is an IM user status", "Invisible");
-        break;
-    case Tp::ConnectionPresenceTypeOffline:
-        presenceIconPath = KIconLoader::global()->iconPath("user-offline", 1);
-        presenceText = i18nc("This is an IM user status", "Offline");
-        break;
-    default:
-        presenceIconPath = KIconLoader::global()->iconPath("task-attention", 1);
-        // What presence Text should be here??
-        break;
-    }
-
-    /* The tooltip is composed of a HTML table to display the items in it of the contact.
-     * ---------------------------
-     * |          | Con's Alias  |
-     * |  Avatar  | (Con's Id)   |
-     * |          ----------------
-     * |          | Con's Status*|
-     * ---------------------------
-     * |  Contact is blocked*    |
-     * ---------------------------
-     * * Display actual status name if contact has no custom status message.
-     * * Contact is blocked will only show if the contact is blocked, else no display.
-     */
-
-    QString table;
-    table += QString("<table><tr><td rowspan='2' width='96'>");
-    if (contactAvatar.isEmpty() || QPixmap(contactAvatar).isNull()) {
-        table += QString("<img src='%1' width='96' />").arg(KIconLoader::global()->iconPath("im-user", -1));
-    } else {
-        table += QString("<img src='%1' width='96' />").arg(contactAvatar);
-    }
-
-    table += QString("</td>");
-    table += QString("<td rowspan='2'><img src='%1' height='16' width='16' /> </td>").arg(presenceIconPath);
-    table += QString("<td><b>%1</b><br>(%2)</td></tr>").arg(alias).arg(id);
-    table += QString("<tr><td>");
-    table += QString("%2").arg(presenceStatus.isEmpty() ? presenceText : presenceStatus);
-    table += QString("</td></tr>");
-    if (index.data(AccountsModel::BlockedRole).toBool()) {
-        table += QString("<tr><td colspan='2'>%1</td></tr>").arg(i18n("User is blocked"));
-    }
-    table += QString("</table>");
-
-    QToolTip::showText(QCursor::pos(), table, view);
-
-    return true;
+    return false;
 }
diff --git a/main-widget.cpp b/main-widget.cpp
index 12dc598..646dae4 100644
--- a/main-widget.cpp
+++ b/main-widget.cpp
@@ -79,6 +79,8 @@
 #include <KTelepathy/Models/proxy-tree-node.h>
 #include <KTelepathy/text-parser.h>
 
+#include "tooltips/tooltipmanager.h"
+
 #define PREFERRED_TEXTCHAT_HANDLER "org.freedesktop.Telepathy.Client.KDE.TextUi"
 #define PREFERRED_FILETRANSFER_HANDLER "org.freedesktop.Telepathy.Client.KDE.FileTransfer"
 #define PREFERRED_AUDIO_VIDEO_HANDLER "org.freedesktop.Telepathy.Client.KDE.CallUi"
@@ -272,6 +274,8 @@ MainWidget::MainWidget(QWidget *parent)
 
     emit enableOverlays(guiConfigGroup.readEntry("selected_delegate", "full") == QLatin1String("full"));
 
+    new ToolTipManager(m_contactsListView);
+
     connect(m_contactsListView, SIGNAL(customContextMenuRequested(QPoint)),
             this, SLOT(onCustomContextMenuRequested(QPoint)));
 
diff --git a/tooltips/contacttooltip.cpp b/tooltips/contacttooltip.cpp
new file mode 100644
index 0000000..f851688
--- /dev/null
+++ b/tooltips/contacttooltip.cpp
@@ -0,0 +1,118 @@
+/*
+ * Contact Tooltip
+ *
+ * Copyright (C) 2011 David Edmundson <kde at davidedmundson.co.uk>
+ * Copyright (C) 2011 Geoffry Song <goffrie at 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 "contacttooltip.h"
+
+#include "ui_contacttooltip.h"
+#include "ktooltip.h"
+
+#include <KTelepathy/Models/accounts-model.h>
+#include <KTelepathy/text-parser.h>
+#include <KTelepathy/presence.h>
+
+#include <QDesktopServices>
+#include <QTextDocument>
+
+#include <KToolInvocation>
+#include <KDebug>
+
+ContactToolTip::ContactToolTip(const QModelIndex &index) :
+    QWidget(0),
+    ui(new Ui::ContactToolTip)
+{
+    ui->setupUi(this);
+    ui->nameLabel->setText(index.data(Qt::DisplayRole).toString());
+    ui->idLabel->setText(index.data(AccountsModel::IdRole).toString());
+
+    QString avatar = index.data(AccountsModel::AvatarRole).toString();
+    if (avatar.isEmpty()) {
+        ui->avatarLabel->setPixmap(KIconLoader::global()->loadIcon("im-user", KIconLoader::NoGroup, 96));
+    } else {
+        ui->avatarLabel->setPixmap(QPixmap(avatar));
+    }
+
+    KTp::Presence presence = index.data(AccountsModel::PresenceRole).value<KTp::Presence>();
+
+    QString presenceMessage;
+    QString presenceIconPath = KIconLoader::global()->iconPath("task-attention", 1);
+    QString presenceText = i18nc("This is an IM user status", "Unknown");
+
+    if (presence.isValid()) {
+        presenceMessage = getTextWithHyperlinks(presence.statusMessage());
+        presenceIconPath = KIconLoader::global()->iconPath(presence.icon().name(), 1);
+        presenceText = presence.displayString();
+    }
+
+    if (presence.type() == Tp::ConnectionPresenceTypeError) {
+        presenceIconPath = KIconLoader::global()->iconPath("task-attention", 1);
+        presenceText = i18nc("This is an IM user status", "Error Getting Presence");
+
+        /** if the presence is error, the message might containt server's error,
+        *   so let's print it out and unset it so it won't be displayed to user
+        */
+        kDebug() << presenceMessage;
+        presenceMessage = QString();
+    }
+
+    ui->presenceIcon->setPixmap(QPixmap(presenceIconPath));
+    ui->presenceLabel->setText(presenceText);
+    ui->presenceMessageLabel->setText(presenceMessage);
+    ui->blockedLabel->setShown(index.data(AccountsModel::BlockedRole).toBool());
+
+    connect(ui->presenceMessageLabel, SIGNAL(linkActivated(QString)), this, SLOT(openLink(QString)));
+}
+
+ContactToolTip::~ContactToolTip()
+{
+    delete ui;
+}
+
+void ContactToolTip::openLink(QString url)
+{
+    KToolInvocation::invokeBrowser(url);
+    KToolTip::hideTip();
+}
+
+QString ContactToolTip::getTextWithHyperlinks(QString text)
+{
+    KTp::TextUrlData urls = KTp::TextParser::instance()->extractUrlData(text);
+    QString result;
+    int position = 0;
+
+    for (int i = 0; i < urls.fixedUrls.size(); ++i) {
+        QPair<int, int> pair = urls.urlRanges[i];
+        QString displayLink = text.mid(pair.first, pair.second);
+        QString fixedLink = urls.fixedUrls[i];
+
+        if (pair.first > position) {
+            result += Qt::escape(text.mid(position, pair.first - position));
+        }
+
+        result += QString("<a href=\"%1\">%2</a>").arg(Qt::escape(fixedLink)).arg(Qt::escape(displayLink));
+        position = pair.first + pair.second;
+    }
+
+    if (position < text.length()) {
+        result += Qt::escape(text.mid(position));
+    }
+
+    return result;
+}
diff --git a/dialogs/contact-info.h b/tooltips/contacttooltip.h
similarity index 65%
copy from dialogs/contact-info.h
copy to tooltips/contacttooltip.h
index 95add7d..60e8428 100644
--- a/dialogs/contact-info.h
+++ b/tooltips/contacttooltip.h
@@ -1,7 +1,8 @@
 /*
- * Dialog for showing contact info
+ * Contact Tooltip
  *
  * Copyright (C) 2011 David Edmundson <kde at davidedmundson.co.uk>
+ * Copyright (C) 2011 Geoffry Song <goffrie at gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,29 +19,32 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#ifndef CONTACTTOOLTIP_H
+#define CONTACTTOOLTIP_H
 
-#ifndef CONTACTINFO_H
-#define CONTACTINFO_H
-
-#include <KDialog>
-#include <TelepathyQt4/Contact>
+#include <QWidget>
+#include <QModelIndex>
 
 
 namespace Ui {
-    class ContactInfo;
+    class ContactToolTip;
 }
 
-class ContactInfo : public KDialog
+class ContactToolTip : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit ContactInfo(const Tp::ContactPtr &contact, QWidget *parent = 0);
-    ~ContactInfo();
+    explicit ContactToolTip(const QModelIndex &index);
+    ~ContactToolTip();
+
+    static QString getTextWithHyperlinks(QString text);
+
+public slots:
+    void openLink(QString);
 
 private:
-    Ui::ContactInfo *ui;
-    KIcon iconForPresenceState(Tp::Contact::PresenceState state) const;
+    Ui::ContactToolTip *ui;
 };
 
-#endif // CONTACTINFO_H
+#endif // CONTACTTOOLTIP_H
diff --git a/tooltips/contacttooltip.ui b/tooltips/contacttooltip.ui
new file mode 100644
index 0000000..2f28ef3
--- /dev/null
+++ b/tooltips/contacttooltip.ui
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ContactToolTip</class>
+ <widget class="QWidget" name="ContactToolTip">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>378</width>
+    <height>114</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,1,0" columnstretch="0,0,1">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item row="0" column="0" rowspan="5">
+    <widget class="QLabel" name="avatarLabel">
+     <property name="minimumSize">
+      <size>
+       <width>96</width>
+       <height>96</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>96</width>
+       <height>96</height>
+      </size>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="scaledContents">
+      <bool>true</bool>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignHCenter|Qt::AlignTop</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" rowspan="5">
+    <widget class="QLabel" name="presenceIcon">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignHCenter|Qt::AlignTop</set>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="2">
+    <widget class="QLabel" name="nameLabel">
+     <property name="font">
+      <font>
+       <weight>75</weight>
+       <bold>true</bold>
+      </font>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+     <property name="textFormat">
+      <enum>Qt::PlainText</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QLabel" name="idLabel">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="textFormat">
+      <enum>Qt::PlainText</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="2">
+    <widget class="QLabel" name="presenceLabel">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="textFormat">
+      <enum>Qt::PlainText</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <widget class="QLabel" name="presenceMessageLabel">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="textFormat">
+      <enum>Qt::RichText</enum>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="2">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>268</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="5" column="0" colspan="3">
+    <widget class="QLabel" name="blockedLabel">
+     <property name="text">
+      <string>User is blocked</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+  <slot>openLink(QString)</slot>
+ </slots>
+</ui>
diff --git a/tooltips/ktooltip.cpp b/tooltips/ktooltip.cpp
new file mode 100644
index 0000000..2d2215b
--- /dev/null
+++ b/tooltips/ktooltip.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 by Fredrik Höglund <fredrik at kde.org>
+ * Copyright (C) 2011 by Geoffry Song <goffrie at 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 "ktooltip.h"
+#include "ktooltipwindow_p.h"
+
+#include <QLabel>
+#include <QPoint>
+#include <QWidget>
+
+#include <kglobal.h>
+
+class KToolTipManager
+{
+public:
+    KToolTipManager();
+    ~KToolTipManager();
+
+    void showTip(const QPoint &pos, QWidget *content);
+    KToolTipWindow *createTipWindow(QWidget *content);
+    KToolTipWindow *currentTip();
+    void hideTip();
+
+private:
+    QWeakPointer<KToolTipWindow> m_window;
+};
+
+K_GLOBAL_STATIC(KToolTipManager, s_instance)
+
+KToolTipManager::KToolTipManager()
+{
+}
+
+KToolTipManager::~KToolTipManager()
+{
+    if (!m_window.isNull()) {
+        delete m_window.data();
+    }
+}
+
+void KToolTipManager::showTip(const QPoint &pos, QWidget *content)
+{
+    hideTip();
+    if (!m_window.isNull()) {
+        delete m_window.data();
+    }
+    KToolTipWindow *tooltip = qobject_cast<KToolTipWindow*>(content);
+    m_window = (tooltip ? tooltip : createTipWindow(content));
+    m_window.data()->move(pos);
+    m_window.data()->show();
+}
+
+KToolTipWindow *KToolTipManager::createTipWindow(QWidget* content)
+{
+    return new KToolTipWindow(content);
+}
+
+KToolTipWindow *KToolTipManager::currentTip()
+{
+    return m_window.data();
+}
+
+void KToolTipManager::hideTip()
+{
+    if (!m_window.isNull()) {
+        m_window.data()->hide();
+        m_window.data()->deleteLater();
+    }
+}
+
+namespace KToolTip
+{
+    void showText(const QPoint &pos, const QString &text)
+    {
+        QLabel *label = new QLabel(text);
+        label->setForegroundRole(QPalette::ToolTipText);
+        showTip(pos, createTipWindow(label));
+    }
+
+    void showTip(const QPoint &pos, QWidget *content)
+    {
+        s_instance->showTip(pos, content);
+    }
+
+    QWidget *createTipWindow(QWidget *content)
+    {
+        return s_instance->createTipWindow(content);
+    }
+
+    QWidget *currentTip()
+    {
+        return s_instance->currentTip();
+    }
+
+    void hideTip()
+    {
+        s_instance->hideTip();
+    }
+}
+
diff --git a/tooltips/ktooltip.h b/tooltips/ktooltip.h
new file mode 100644
index 0000000..a1e8289
--- /dev/null
+++ b/tooltips/ktooltip.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 by Fredrik Höglund <fredrik at kde.org>
+ * Copyright (C) 2011 by Geoffry Song <goffrie at 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 KTOOLTIP_H
+#define KTOOLTIP_H
+
+class QPoint;
+class QString;
+class QWidget;
+
+/**
+ * Allows to show tooltips having a widget as content.
+ */
+namespace KToolTip
+{
+    void showText(const QPoint &pos, const QString &text);
+
+    /**
+     * Shows the tip @p content at the global position indicated by @p pos.
+     *
+     * Ownership of the content widget is transferred to KToolTip. The widget will be deleted
+     * automatically when it is hidden.
+     *
+     * The tip is shown immediately when this function is called.
+     */
+    void showTip(const QPoint &pos, QWidget *window);
+    QWidget *createTipWindow(QWidget *content);
+    QWidget *currentTip();
+    void hideTip();
+}
+
+#endif
diff --git a/tooltips/ktooltipwindow.cpp b/tooltips/ktooltipwindow.cpp
new file mode 100644
index 0000000..749b010
--- /dev/null
+++ b/tooltips/ktooltipwindow.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 by Fredrik Höglund <fredrik at kde.org>
+ * Copyright (C) 2008 by Konstantin Heil <konst.heil at stud.uni-heidelberg.de>
+ * Copyright (C) 2009 by Peter Penz <peter.penz at gmx.at>
+ *
+ * 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 "ktooltipwindow_p.h"
+
+#include <kcolorscheme.h>
+#include <kwindowsystem.h>
+
+#include <QPainter>
+#include <QVBoxLayout>
+
+KToolTipWindow::KToolTipWindow(QWidget *content) :
+    QWidget(0)
+{
+    setAttribute(Qt::WA_TranslucentBackground);
+    setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
+
+    QVBoxLayout* layout = new QVBoxLayout(this);
+    layout->addWidget(content);
+    adjustSize();
+
+    QPalette p = palette();
+    p.setColor(QPalette::WindowText, p.color(QPalette::ToolTipText));
+    setPalette(p);
+}
+
+KToolTipWindow::~KToolTipWindow()
+{
+}
+
+void KToolTipWindow::paintEvent(QPaintEvent *event)
+{
+    Q_UNUSED(event);
+
+    QPainter painter(this);
+
+    QColor toColor = palette().brush(QPalette::ToolTipBase).color();
+    QColor fromColor = KColorScheme::shade(toColor, KColorScheme::LightShade, 0.2);
+
+    const bool haveAlphaChannel = KWindowSystem::compositingActive();
+    if (haveAlphaChannel) {
+        painter.setRenderHint(QPainter::Antialiasing);
+        painter.translate(0.5, 0.5);
+        toColor.setAlpha(220);
+        fromColor.setAlpha(220);
+    }
+
+    QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(0.0, height()));
+    gradient.setColorAt(0.0, fromColor);
+    gradient.setColorAt(1.0, toColor);
+    painter.setPen(Qt::NoPen);
+    painter.setBrush(gradient);
+
+    const QRect rect(0, 0, width(), height());
+    if (haveAlphaChannel) {
+        const qreal radius = 5.0;
+
+        QPainterPath path;
+        path.moveTo(rect.left(), rect.top() + radius);
+        arc(path, rect.left()  + radius, rect.top()    + radius, radius, 180, -90);
+        arc(path, rect.right() - radius, rect.top()    + radius, radius,  90, -90);
+        arc(path, rect.right() - radius, rect.bottom() - radius, radius,   0, -90);
+        arc(path, rect.left()  + radius, rect.bottom() - radius, radius, 270, -90);
+        path.closeSubpath();
+
+        painter.drawPath(path);
+    } else {
+        painter.drawRect(rect);
+    }
+}
+
+void KToolTipWindow::arc(QPainterPath &path, qreal cx, qreal cy, qreal radius, qreal angle, qreal sweeplength)
+{
+    path.arcTo(cx-radius, cy-radius, radius * 2, radius * 2, angle, sweeplength);
+}
+
+#include "ktooltipwindow_p.moc"
diff --git a/dialogs/contact-info.h b/tooltips/ktooltipwindow_p.h
similarity index 58%
copy from dialogs/contact-info.h
copy to tooltips/ktooltipwindow_p.h
index 95add7d..6939eee 100644
--- a/dialogs/contact-info.h
+++ b/tooltips/ktooltipwindow_p.h
@@ -1,7 +1,5 @@
 /*
- * Dialog for showing contact info
- *
- * Copyright (C) 2011 David Edmundson <kde at davidedmundson.co.uk>
+ * Copyright (C) 2009 by Peter Penz <peter.penz at gmx.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,29 +16,29 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#ifndef KTOOLTIPWINDOW_H
+#define KTOOLTIPWINDOW_H
 
-#ifndef CONTACTINFO_H
-#define CONTACTINFO_H
-
-#include <KDialog>
-#include <TelepathyQt4/Contact>
-
+#include <QWidget>
+class QPaintEvent;
 
-namespace Ui {
-    class ContactInfo;
-}
-
-class ContactInfo : public KDialog
+class KToolTipWindow : public QWidget
 {
     Q_OBJECT
 
 public:
-    explicit ContactInfo(const Tp::ContactPtr &contact, QWidget *parent = 0);
-    ~ContactInfo();
+    explicit KToolTipWindow(QWidget *content);
+    virtual ~KToolTipWindow();
+
+protected:
+    virtual void paintEvent(QPaintEvent *event);
 
 private:
-    Ui::ContactInfo *ui;
-    KIcon iconForPresenceState(Tp::Contact::PresenceState state) const;
+    /**
+     * Helper method for KToolTipWindow::paintEvent() to adjust the painter path \p path
+     * by rounded corners.
+     */
+    static void arc(QPainterPath &path, qreal cx, qreal cy, qreal radius, qreal angle, qreal sweeplength);
 };
 
-#endif // CONTACTINFO_H
+#endif
diff --git a/tooltips/tooltipmanager.cpp b/tooltips/tooltipmanager.cpp
new file mode 100644
index 0000000..6e7fcb1
--- /dev/null
+++ b/tooltips/tooltipmanager.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2008 by Konstantin Heil <konst.heil at stud.uni-heidelberg.de>
+ * Copyright (C) 2011 Geoffry Song <goffrie at 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"
+
+#include "ktooltip.h"
+#include "contacttooltip.h"
+
+#include <QRect>
+#include <QLabel>
+#include <QTimer>
+#include <QPainter>
+#include <QHelpEvent>
+#include <QScrollBar>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QAbstractItemView>
+
+#ifdef Q_WS_X11
+#include <QX11Info>
+#endif
+
+#include <KIcon>
+#include <KColorScheme>
+
+class ToolTipManager::Private
+{
+public:
+    Private() :
+        view(0),
+        timer(0)
+        { }
+
+    QAbstractItemView *view;
+    QTimer            *timer;
+    QTimer            *hideTimer;
+    QModelIndex        item;
+    QRect              itemRect;
+};
+
+ToolTipManager::ToolTipManager(QAbstractItemView *parent)
+    : QObject(parent)
+    , d(new ToolTipManager::Private)
+{
+    d->view = parent;
+
+    connect(parent, SIGNAL(viewportEntered()), this, SLOT(hideToolTip()));
+    connect(parent, SIGNAL(entered(QModelIndex)), this, SLOT(requestToolTip(QModelIndex)));
+
+    d->timer = new QTimer(this);
+    d->timer->setSingleShot(true);
+    connect(d->timer, SIGNAL(timeout()), this, SLOT(prepareToolTip()));
+    d->hideTimer = new QTimer(this);
+    d->hideTimer->setSingleShot(true);
+    connect(d->hideTimer, SIGNAL(timeout()), this, SLOT(hideToolTip()));
+
+    // When the mousewheel is used, the items don't get a hovered indication
+    // (Qt-issue #200665). To assure that the tooltip still gets hidden,
+    // the scrollbars are observed.
+    connect(parent->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
+    connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
+
+    d->view->viewport()->installEventFilter(this);
+}
+
+ToolTipManager::~ToolTipManager()
+{
+    delete d;
+}
+
+bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
+{
+    if (watched == d->view->viewport()) {
+        switch (event->type()) {
+            case QEvent::Leave:
+                d->hideTimer->start(80);
+                break;
+            case QEvent::MouseButtonPress:
+                hideToolTip();
+                break;
+            case QEvent::ToolTip:
+                return true;
+            default:
+                break;
+        }
+    } else if (watched == KToolTip::currentTip()) {
+        if (event->type() == QEvent::Leave) {
+            d->hideTimer->start(80);
+        }
+        return false;
+    }
+
+    return QObject::eventFilter(watched, event);
+}
+
+void ToolTipManager::requestToolTip(const QModelIndex &index)
+{
+    // only request a tooltip for the name column and when no selection or
+    // drag & drop operation is done (indicated by the left mouse button)
+    if (!(QApplication::mouseButtons() & Qt::LeftButton) && index.isValid()) {
+        KToolTip::hideTip();
+
+        QRect rect = d->view->visualRect(index);
+        d->itemRect = QRect(d->view->viewport()->mapToGlobal(rect.topLeft()),
+                            d->view->viewport()->mapToGlobal(rect.bottomRight()));
+        d->item = index;
+        d->timer->start(300);
+        d->hideTimer->stop();
+    } else {
+        hideToolTip();
+    }
+}
+
+void ToolTipManager::hideToolTip()
+{
+    if ( KToolTip::currentTip() && KToolTip::currentTip()->geometry().contains(QCursor::pos()) ) return;
+    d->timer->stop();
+    d->hideTimer->stop();
+    KToolTip::hideTip();
+}
+
+void ToolTipManager::prepareToolTip()
+{
+    if (d->item.isValid()) {
+        showToolTip(d->item);
+    }
+}
+
+void ToolTipManager::showToolTip(const  QModelIndex &menuItem)
+{
+    if (QApplication::mouseButtons() & Qt::LeftButton || !menuItem.isValid()) {
+        return;
+    }
+
+    QWidget *tip = KToolTip::createTipWindow(createTipContent(menuItem));
+
+    // calculate the x- and y-position of the tooltip
+    const QSize size = tip->size();
+    const QRect desktop = QApplication::desktop()->screenGeometry( QCursor::pos() );
+
+    // d->itemRect defines the area of the item, where the tooltip should be
+    // shown. Per default the tooltip is shown to the right
+    // If the tooltip content exceeds the desktop borders, it must be assured that:
+    // - the content is fully visible, if possible
+    // - the content is not drawn inside d->itemRect
+    const int margin = 3;
+    const bool hasRoomToLeft  = (d->itemRect.left()   - size.width()  - margin >= desktop.left());
+    const bool hasRoomToRight = (d->itemRect.right()  + size.width()  + margin <= desktop.right());
+    const bool hasRoomAbove   = (d->itemRect.top()    - size.height() - margin >= desktop.top());
+    const bool hasRoomBelow   = (d->itemRect.bottom() + size.height() + margin <= desktop.bottom());
+    if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) {
+        delete tip;
+        tip = 0;
+        return;
+    }
+
+    int x = 0;
+    int y = 0;
+
+    if (hasRoomToLeft || hasRoomToRight) {
+        x = hasRoomToRight ? d->itemRect.right() + margin : d->itemRect.left() - size.width() - margin;
+        y = qMin(qMax(desktop.top() + margin, d->itemRect.center().y() - size.height() / 2), desktop.bottom() - size.height() - margin);
+    } else {
+        Q_ASSERT(hasRoomBelow || hasRoomAbove);
+        y = hasRoomBelow ? d->itemRect.bottom() + margin : d->itemRect.top() - size.height() - margin;
+        x = qMin(qMax(desktop.left() + margin, d->itemRect.center().x() - size.width() / 2), desktop.right() - size.width() - margin);
+    }
+
+    tip->installEventFilter(this);
+    // the ownership of tip is transferred to KToolTip
+    KToolTip::showTip(QPoint(x, y), tip);
+}
+
+QWidget * ToolTipManager::createTipContent(const QModelIndex &index)
+{
+     return new ContactToolTip(index);
+}
+
+#include "tooltipmanager.moc"
diff --git a/tooltips/tooltipmanager.h b/tooltips/tooltipmanager.h
new file mode 100644
index 0000000..34c151f
--- /dev/null
+++ b/tooltips/tooltipmanager.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 by Konstantin Heil <konst.heil at stud.uni-heidelberg.de>
+ * Copyright (C) 2011 Geoffry Song <goffrie at 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 TOOLTIPMANAGER_H
+#define TOOLTIPMANAGER_H
+
+#include <QtCore/QObject>
+
+#include <QtCore/QModelIndex>
+
+class QLayout;
+class MenuItem;
+class KToolTipItem;
+class QAbstractItemView;
+
+/**
+ * @brief Manages the tooltips for an item view.
+ *
+ * When hovering an item, a tooltip is shown after
+ * a short timeout. The tooltip is hidden again when the
+ * viewport is hovered or the item view has been left.
+ */
+class ToolTipManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+    * Standard constructor. The ToolTipManager will start handling ToolTip events on the provided
+    * view immediately.
+    *
+    * @param parent The view which will have the tooltips displayed for.
+    */
+    explicit ToolTipManager(QAbstractItemView *parent);
+    virtual ~ToolTipManager();
+
+public Q_SLOTS:
+    /**
+     * Hides the currently shown tooltip. Invoking this method is
+     * only needed when the tooltip should be hidden although
+     * an item is hovered.
+     */
+    void hideToolTip();
+
+protected:
+    /**
+    * Please see the Qt documentation for more details.
+    *
+    * @param watched The object that was being watched.
+    * @param event The event object.
+    * @returns true if the event was handled in this filter, or false if it was not.
+    */
+    virtual bool eventFilter(QObject *watched, QEvent *event);
+
+private Q_SLOTS:
+    void prepareToolTip();
+    void requestToolTip(const QModelIndex &index);
+
+private:
+    void showToolTip(const QModelIndex &index);
+    QWidget * createTipContent(const QModelIndex &index);
+
+    class Private;
+    ToolTipManager::Private *d;
+};
+
+#endif

-- 
ktp-contact-list packaging



More information about the pkg-kde-commits mailing list