aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Haumann <dhaumann@kde.org>2014-01-25 01:29:53 (GMT)
committerDominik Haumann <dhaumann@kde.org>2014-01-25 01:30:06 (GMT)
commitaff96872b052deea12beada0816db1e246751035 (patch)
tree0df7c972dc18f1373dcc81b1fba33f7694222d28
parent675a750b1322c1cdae96fd94b713e508165c8e2e (diff)
fix KTextEditor::TextHintInterface
This incompatible change is required to allow multiple text hint (tool tip) providers at the same time. How to adapt to the new interface is described in detail in texthintinterface.h. Afaik, the only user of this interface is Sven in KDevelop. CCMAIL: svenbrauch@googlemail.com CCMAIL: aleixpol@kde.org
-rw-r--r--docs/porting.dox10
-rw-r--r--src/include/ktexteditor/texthintinterface.h140
-rw-r--r--src/utils/ktexteditor.cpp7
-rw-r--r--src/view/kateview.cpp18
-rw-r--r--src/view/kateview.h9
-rw-r--r--src/view/kateviewinternal.cpp69
-rw-r--r--src/view/kateviewinternal.h22
7 files changed, 190 insertions, 85 deletions
diff --git a/docs/porting.dox b/docs/porting.dox
index 22367bf..434c38c 100644
--- a/docs/porting.dox
+++ b/docs/porting.dox
@@ -60,8 +60,6 @@ The following interfaces were changed:
\p KTextEditor::Document::characterAt()
- \p KTextEditor::Document::readWriteChanged() \n
This signal is emitted whenever the read-only state of the document changes.
- - \p KTextEditor::TextHintInterfacePrivate::needTextHint() now takes a View
- as first parameter
- \p KTextEditor::View now has a status bar by default. It can be controlled
by \p View::setStatusBarEnabled() and \p View::isStatusBarEnabled()
@@ -83,18 +81,22 @@ The following interfaces are new:
\section kte_port_enhanced_classes Significantly Enhanced Classes
The following classes have been significantly enhanced:
- - KTextEditor::Cursor \n
+ - \p KTextEditor::Cursor \n
The Cursor now is a tuple of two ints, namely the line and column. It has no
virtual destructor so that you cannot derive from Cursor. Since a Cursor
uses 8 Bytes, it is even ok to pass a Cursor as copy in parameters instead
of a reference.
Further, the Cursor has been marked as Q_MOVABLE, making it behave like a
Plain Old Data (POD) type.
- - KTextEditor::Range \n
+ - \p KTextEditor::Range \n
The Range now is a tuple of two Cursors, namely the Range::startCursor() and the
Range::endCursor(). It has no virtual destructor so that you cannot derive from Range.
Further, the Range has been marked as Q_MOVABLE, making it behave like a
Plain Old Data (POD) type.
+ - \p KTextEditor::TextHintInterface \n
+ This interface now requires you to call registerTextHintProvider() and
+ unregisterTextHintProvider() with a cooresponding object that implements
+ \p KTextEditor::TextHintProvider.
\section kte_port_new_classes New Classes
The following classes are either new, or were added late in the KDE 4 release cycle:
diff --git a/src/include/ktexteditor/texthintinterface.h b/src/include/ktexteditor/texthintinterface.h
index 39aa971..a4c4610 100644
--- a/src/include/ktexteditor/texthintinterface.h
+++ b/src/include/ktexteditor/texthintinterface.h
@@ -1,6 +1,6 @@
/* This file is part of the KDE libraries
Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
- Copyright (C) 2013 Dominik Haumann <dhaumann@kde.org>
+ Copyright (C) 2013-2014 Dominik Haumann <dhaumann@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -29,6 +29,8 @@
namespace KTextEditor
{
+class TextHintProvider;
+
/**
* \brief Text hint interface showing tool tips under the mouse for the View.
*
@@ -41,38 +43,32 @@ namespace KTextEditor
* when debugging an application, or showing a complete path of an include
* directive.
*
- * By default, the text hint interface is disable for the View. To enable it,
- * call enableTextHints() with the desired timeout. The timeout specifies the
- * delay the user needs to hover over the text before the tool tip is shown.
- * Therefore, the timeout should not be too large, a value of 200 milliseconds
- * is recommended.
- *
- * Once text hints are enabled, the signal needTextHint() is emitted after the
- * timeout whenever the mouse moved to a new text position in the View.
- * Therefore, in order to show a tool tip, you need to connect to this signal
- * and then fill the parameter \p text with the text to display.
+ * To register as text hint provider, call registerTextHintProvider() with an
+ * instance that inherits TextHintProvider. Finally, make sure you remove your
+ * text hint provider by calling unregisterTextHintProvider().
*
- * To disable all text hints, call disableTextHints(). This, however will disable
- * the text hints entirely for the View. If there are multiple users of the
- * TextHintInterface, this might lead to a conflict.
+ * Text hints are shown after the user hovers with the mouse for a delay of
+ * textHintDelay() milliseconds over the same word. To change the delay, call
+ * setTextHintDelay().
*
* \section texthint_access Accessing the TextHintInterface
*
* The TextHintInterface is an extension interface for a
- * View, i.e. the View inherits the interface \e provided that the
- * used KTextEditor library implements the interface. Use qobject_cast to
- * access the interface:
+ * View, i.e. the View inherits the interface. Use qobject_cast to access the
+ * interface:
* \code
* // view is of type KTextEditor::View*
* KTextEditor::TextHintInterface *iface =
- * qobject_cast<KTextEditor::TextHintInterface*>( view );
+ * qobject_cast<KTextEditor::TextHintInterface*>(view);
*
- * if( iface ) {
+ * if (iface) {
* // the implementation supports the interface
- * // do stuff
+ * // myProvider inherits KTextEditor::TextHintProvider
+ * iface->registerTextHintProvider(myProvider);
* }
* \endcode
*
+ * \see TextHintProvider
* \since KDE 4.11
*/
class KTEXTEDITOR_EXPORT TextHintInterface
@@ -82,45 +78,100 @@ public:
virtual ~TextHintInterface();
/**
- * Enable text hints with the specified \p timeout in milliseconds.
- * The timeout specifies the delay the user needs to hover over the text
- * befure the tool tip is shown. Therefore, \p timeout should not be
- * too large, a value of 200 milliseconds is recommended.
+ * Register the text hint provider \p provider.
+ *
+ * Whenever the user hovers over text, \p provider will be asked for
+ * a text hint. When the provider is about to be destroyed, make
+ * sure to call unregisterTextHintProvider() to avoid a dangling pointer.
+ *
+ * @param provider text hint provider
+ * @see unregisterTextHintProvider(), TextHintProvider
+ */
+ virtual void registerTextHintProvider(KTextEditor::TextHintProvider *provider) = 0;
+
+ /**
+ * Unregister the text hint provider \p provider.
+ *
+ * @param provider text hint provider to unregister
+ * @see registerTextHintProvider(), TextHintProvider
+ */
+ virtual void unregisterTextHintProvider(KTextEditor::TextHintProvider * provider) = 0;
+
+ /**
+ * Set the text hint delay to \p delay milliseconds.
+ *
+ * The delay specifies the time the user needs to hover over the text
+ * befure the tool tip is shown. Therefore, \p delay should not be
+ * too large, a value of 200 milliseconds is recommended and set by
+ * default.
*
- * After enabling the text hints, the signal needTextHint() is emitted
- * whenever the mouse position changed and a new character is underneath
- * the mouse cursor. Calling the signal is delayed for the time specified
- * by \p timeout.
+ * If \p delay is <= 0, the default delay will be set.
*
- * \param timeout tool tip delay in milliseconds
+ * \param delay tool tip delay in milliseconds
*/
- virtual void enableTextHints(int timeout = 200) = 0;
+ virtual void setTextHintDelay(int delay) = 0;
/**
- * Disable all text hints for the view.
- * By default, text hints are disabled.
+ * Get the text hint delay in milliseconds.
+ * By default, the text hint delay is set to 200 milliseconds.
+ * It can be changed by calling \p setTextHintDelay().
*/
- virtual void disableTextHints() = 0;
+ virtual int textHintDelay() const = 0;
- //
- // signals
- //
+private:
+ class TextHintInterfacePrivate * const d;
+};
+
+/**
+ * \brief Class to provide text hints for a View.
+ *
+ * The class TextHintProvider is used in combination with TextHintInterface.
+ * TextHintProvider allows to provide text hint information for text under
+ * the mouse cursor.
+ *
+ * To use this class, derive your provider from TextHintProvider and register
+ * it with TextHintInterface::registerTextHintProvider(). When not needed
+ * anymore, make sure to remove your provider by calling
+ * TextHintInterface::unregisterTextHintProvider(), otherwise the View will
+ * contain a dangling pointer to your potentially deleted provider.
+ *
+ * Detailed information about how to use the TextHintInterface can be found
+ * in the documentation about the TextHintInterface.
+ *
+ * \see TextHintInterface
+ * \p since 5.0
+ */
+class TextHintProvider
+{
public:
/**
- * This signal is emitted whenever the timeout for displaying a text hint
- * is triggered. The text cursor \p position specifies the mouse position
- * in the text. To show a text hint, fill \p text with the text to be
- * displayed. If you do not want a tool tip to be displayed, set \p text to
- * an empty QString() in the connected slot.
+ * Default constructor.
+ */
+ TextHintProvider();
+
+ /**
+ * Virtual destructor to allow inheritance.
+ */
+ virtual ~TextHintProvider();
+
+ /**
+ * This function is called whenever the users hovers over text such
+ * that the text hint delay passes. Then, needTextHint() is called
+ * for each registered TextHintProvider.
+ *
+ * Return the text hint (possibly Qt richtext) for @p view at @p position.
+ *
+ * If you do not have any contents to show, just return an empty QString().
*
* \param view the view that requests the text hint
* \param position text cursor under the mouse position
- * \param text tool tip to be displayed, or empty string to hide
+ * \return text tool tip to be displayed, may be Qt richtext
*/
- virtual void needTextHint(KTextEditor::View *view, const KTextEditor::Cursor &position, QString &text) = 0;
+ virtual QString needTextHint(KTextEditor::View *view,
+ const KTextEditor::Cursor &position) = 0;
private:
- class TextHintInterfacePrivate *const d;
+ class TextHintProviderPrivate * const d;
};
}
@@ -128,4 +179,3 @@ private:
Q_DECLARE_INTERFACE(KTextEditor::TextHintInterface, "org.kde.KTextEditor.TextHintInterface")
#endif
-
diff --git a/src/utils/ktexteditor.cpp b/src/utils/ktexteditor.cpp
index a9c87f0..0f18236 100644
--- a/src/utils/ktexteditor.cpp
+++ b/src/utils/ktexteditor.cpp
@@ -177,6 +177,13 @@ TextHintInterface::TextHintInterface()
TextHintInterface::~TextHintInterface()
{}
+TextHintProvider::TextHintProvider()
+ : d(0)
+{}
+
+TextHintProvider::~TextHintProvider()
+{}
+
VariableInterface::VariableInterface()
: d(0)
{}
diff --git a/src/view/kateview.cpp b/src/view/kateview.cpp
index bc3d74c..d130363 100644
--- a/src/view/kateview.cpp
+++ b/src/view/kateview.cpp
@@ -1501,14 +1501,24 @@ void KTextEditor::ViewPrivate::toggleWriteLock()
m_doc->setReadWrite(! m_doc->isReadWrite());
}
-void KTextEditor::ViewPrivate::enableTextHints(int timeout)
+void KTextEditor::ViewPrivate::registerTextHintProvider(KTextEditor::TextHintProvider *provider)
{
- m_viewInternal->enableTextHints(timeout);
+ m_viewInternal->registerTextHintProvider(provider);
}
-void KTextEditor::ViewPrivate::disableTextHints()
+void KTextEditor::ViewPrivate::unregisterTextHintProvider(KTextEditor::TextHintProvider *provider)
{
- m_viewInternal->disableTextHints();
+ m_viewInternal->unregisterTextHintProvider(provider);
+}
+
+void KTextEditor::ViewPrivate::setTextHintDelay(int delay)
+{
+ m_viewInternal->setTextHintDelay(delay);
+}
+
+int KTextEditor::ViewPrivate::textHintDelay() const
+{
+ return m_viewInternal->textHintDelay();
}
bool KTextEditor::ViewPrivate::viInputMode() const
diff --git a/src/view/kateview.h b/src/view/kateview.h
index 7dc8521..dc888c1 100644
--- a/src/view/kateview.h
+++ b/src/view/kateview.h
@@ -248,11 +248,10 @@ public:
// KTextEditor::TextHintInterface
//
public:
- void enableTextHints(int timeout = 200);
- void disableTextHints();
-
-Q_SIGNALS:
- void needTextHint(KTextEditor::View *view, const KTextEditor::Cursor &position, QString &text);
+ void registerTextHintProvider(KTextEditor::TextHintProvider *provider) Q_DECL_OVERRIDE;
+ void unregisterTextHintProvider(KTextEditor::TextHintProvider *provider) Q_DECL_OVERRIDE;
+ void setTextHintDelay(int delay) Q_DECL_OVERRIDE;
+ int textHintDelay() const Q_DECL_OVERRIDE;
public:
bool dynWordWrap() const
diff --git a/src/view/kateviewinternal.cpp b/src/view/kateviewinternal.cpp
index 75139ff..a2c89d5 100644
--- a/src/view/kateviewinternal.cpp
+++ b/src/view/kateviewinternal.cpp
@@ -43,6 +43,7 @@
#include "katetextanimation.h"
#include <ktexteditor/movingrange.h>
+#include <ktexteditor/texthintinterface.h>
#include <KCursor>
#include "katepartdebug.h"
@@ -93,7 +94,7 @@ KateViewInternal::KateViewInternal(KTextEditor::ViewPrivate *view)
, m_scrollTimer(this)
, m_cursorTimer(this)
, m_textHintTimer(this)
- , m_textHintEnabled(false)
+ , m_textHintDelay(200)
, m_textHintPos(-1, -1)
, m_imPreeditRange(0)
, m_viInputMode(false)
@@ -2873,11 +2874,11 @@ void KateViewInternal::mouseMoveEvent(QMouseEvent *e)
//We need to check whether the mouse position is actually within the widget,
//because other widgets like the icon border forward their events to this,
//and we will create invalid text hint requests if we don't check
- if (m_textHintEnabled && geometry().contains(parentWidget()->mapFromGlobal(e->globalPos()))) {
+ if (textHintsEnabled() && geometry().contains(parentWidget()->mapFromGlobal(e->globalPos()))) {
if (QToolTip::isVisible()) {
QToolTip::hideText();
}
- m_textHintTimer.start(m_textHintTimeout);
+ m_textHintTimer.start(m_textHintDelay);
m_textHintPos = e->pos();
}
}
@@ -3106,14 +3107,22 @@ void KateViewInternal::textHintTimeout()
return;
}
- QString tmp;
-
- emit m_view->needTextHint(m_view, c, tmp);
+ QStringList textHints;
+ foreach(KTextEditor::TextHintProvider * const p, m_textHintProviders) {
+ const QString hint = p->needTextHint(m_view, c);
+ if (!hint.isEmpty()) {
+ textHints.append(hint);
+ }
+ }
- if (!tmp.isEmpty()) {
- qCDebug(LOG_PART) << "Hint text: " << tmp;
+ if (!textHints.isEmpty()) {
+ qCDebug(LOG_PART) << "Hint text: " << textHints;
+ QString hint;
+ foreach(const QString & str, textHints) {
+ hint += QStringLiteral("<p>%1</p>").arg(str);
+ }
QPoint pos(startX() + m_textHintPos.x(), m_textHintPos.y());
- QToolTip::showText(mapToGlobal(pos), tmp);
+ QToolTip::showText(mapToGlobal(pos), hint);
}
}
@@ -3367,25 +3376,47 @@ void KateViewInternal::doDragScroll()
}
}
-void KateViewInternal::enableTextHints(int timeout)
+void KateViewInternal::registerTextHintProvider(KTextEditor::TextHintProvider *provider)
{
- if (timeout >= 0) {
- m_textHintTimeout = timeout;
- m_textHintEnabled = true;
- m_textHintTimer.start(timeout);
- } else {
- qCWarning(LOG_PART) << "Attempt to enable text hints with negative timeout:" << timeout;
+ if (! m_textHintProviders.contains(provider)) {
+ m_textHintProviders.append(provider);
}
+
+ // we have a client, so start timeout
+ m_textHintTimer.start(m_textHintDelay);
}
-void KateViewInternal::disableTextHints()
+void KateViewInternal::unregisterTextHintProvider(KTextEditor::TextHintProvider *provider)
{
- if (m_textHintEnabled) {
- m_textHintEnabled = false;
+ const int index = m_textHintProviders.indexOf(provider);
+ if (index >= 0) {
+ m_textHintProviders.removeAt(index);
+ }
+
+ if (m_textHintProviders.isEmpty()) {
m_textHintTimer.stop();
}
}
+void KateViewInternal::setTextHintDelay(int delay)
+{
+ if (delay <= 0) {
+ m_textHintDelay = 200; // ms
+ } else {
+ m_textHintDelay = delay; // ms
+ }
+}
+
+int KateViewInternal::textHintDelay() const
+{
+ return m_textHintDelay;
+}
+
+bool KateViewInternal::textHintsEnabled()
+{
+ return ! m_textHintProviders.isEmpty();
+}
+
//BEGIN EDIT STUFF
void KateViewInternal::editStart()
{
diff --git a/src/view/kateviewinternal.h b/src/view/kateviewinternal.h
index 6c5ffdb..c0ae259 100644
--- a/src/view/kateviewinternal.h
+++ b/src/view/kateviewinternal.h
@@ -46,6 +46,7 @@
namespace KTextEditor
{
class MovingRange;
+class TextHintProvider;
}
class KateIconBorder;
@@ -418,19 +419,24 @@ private Q_SLOTS:
void documentTextInserted(KTextEditor::Document *document, const KTextEditor::Range &range);
void documentTextRemoved(KTextEditor::Document *document, const KTextEditor::Range &range, const QString &oldText);
- //TextHint
+ //
+ // KTE::TextHintInterface
+ //
public:
- void enableTextHints(int timeout);
- void disableTextHints();
+ void registerTextHintProvider(KTextEditor::TextHintProvider *provider);
+ void unregisterTextHintProvider(KTextEditor::TextHintProvider *provider);
+ void setTextHintDelay(int delay);
+ int textHintDelay() const;
+ bool textHintsEnabled(); // not part of the interface
private:
- bool m_textHintEnabled;
- int m_textHintTimeout;
+ QVector<KTextEditor::TextHintProvider*> m_textHintProviders;
+ int m_textHintDelay;
QPoint m_textHintPos;
- /**
- * IM input stuff
- */
+ //
+ // IM input stuff
+ //
public:
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;