소스 검색

ENH: Do tool tip word wrap

- Event filter installed if tooltips are trapped or word wrapped.
Danielle Pace 13 년 전
부모
커밋
146d65ec76
3개의 변경된 파일142개의 추가작업 그리고 21개의 파일을 삭제
  1. 26 5
      Libs/Widgets/Testing/Cpp/ctkToolTipTrapperTest1.cpp
  2. 97 5
      Libs/Widgets/ctkToolTipTrapper.cpp
  3. 19 11
      Libs/Widgets/ctkToolTipTrapper.h

+ 26 - 5
Libs/Widgets/Testing/Cpp/ctkToolTipTrapperTest1.cpp

@@ -50,13 +50,34 @@ int ctkToolTipTrapperTest1(int argc, char * argv [] )
     std::cerr << "ctkToolTipTrapper::setToolTipsTrapped failed" << std::endl;
     return EXIT_FAILURE;
     }
+
+  if (trapper.toolTipsWordWrapped() != false)
+    {
+    std::cerr << "ctkToolTipTrapper::toolTipsWordWrapped default value" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  trapper.setToolTipsWordWrapped(true);
+
+  if (trapper.toolTipsWordWrapped() != true)
+    {
+    std::cerr << "ctkToolTipTrapper::setToolTipsWordWrapped failed" << std::endl;
+    return EXIT_FAILURE;
+    }
   
-  QPushButton button("button");
-  button.setToolTip("Button tooltip text");
-  button.setCheckable(true);
-  QObject::connect(&button, SIGNAL(toggled(bool)),
+  QPushButton trapButton("button");
+  trapButton.setToolTip("Button tooltip text");
+  trapButton.setCheckable(true);
+  QObject::connect(&trapButton, SIGNAL(toggled(bool)),
                    &trapper, SLOT(setToolTipsTrapped(bool)));
-  button.show();
+  trapButton.show();
+
+  QPushButton wrapButton("button");
+  wrapButton.setToolTip("Button tooltip text");
+  wrapButton.setCheckable(true);
+  QObject::connect(&wrapButton, SIGNAL(toggled(bool)),
+                   &trapper, SLOT(setToolTipsWordWrapped(bool)));
+  wrapButton.show();
 
   if (argc < 2 || QString(argv[1]) != "-I" )
     {

+ 97 - 5
Libs/Widgets/ctkToolTipTrapper.cpp

@@ -51,6 +51,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Qt includes
 #include <QCoreApplication>
+#include <QTextDocument>
+#include <QWidget>
 
 // CTK includes
 #include "ctkToolTipTrapper.h"
@@ -63,7 +65,36 @@ protected:
 public:
   ctkToolTipTrapperPrivate(ctkToolTipTrapper& object);
 
+  enum EventFilterToDo
+    {
+    EVENT_FILTER_DO_NOTHING,
+    EVENT_FILTER_INSTALL,
+    EVENT_FILTER_REMOVE
+    };
+
+  static EventFilterToDo getEventFilterToDo(bool beforeToolTipsTrapped,
+                                            bool beforeToolTipsWordWrapped,
+                                            bool afterToolTipsTrapped,
+                                            bool afterToolTipsWordWrapped)
+    {
+    bool eventFilterWasInstalled = beforeToolTipsTrapped || beforeToolTipsWordWrapped;
+    bool eventFilterShouldBeInstalled = afterToolTipsTrapped || afterToolTipsWordWrapped;
+    if (eventFilterWasInstalled == eventFilterShouldBeInstalled)
+      {
+      return EVENT_FILTER_DO_NOTHING;
+      }
+    else if (eventFilterShouldBeInstalled)
+      {
+      return EVENT_FILTER_INSTALL;
+      }
+    else
+      {
+      return EVENT_FILTER_REMOVE;
+      }
+    };
+
   bool ToolTipsTrapped;
+  bool ToolTipsWordWrapped;
 };
 
 // --------------------------------------------------------------------------
@@ -71,6 +102,7 @@ ctkToolTipTrapperPrivate::ctkToolTipTrapperPrivate(ctkToolTipTrapper& object)
   : q_ptr(&object)
 {
   this->ToolTipsTrapped = false;
+  this->ToolTipsWordWrapped = false;
 }
 
 //------------------------------------------------------------------------------
@@ -79,14 +111,18 @@ ctkToolTipTrapper::ctkToolTipTrapper(QObject * newParent)
   , d_ptr(new ctkToolTipTrapperPrivate(*this))
 {
   this->setToolTipsTrapped(true);
+  this->setToolTipsWordWrapped(false);
 }
 
 //------------------------------------------------------------------------------
-ctkToolTipTrapper::ctkToolTipTrapper(bool toolTipsTrapped, QObject * newParent)
+ctkToolTipTrapper::ctkToolTipTrapper(bool toolTipsTrapped,
+                                     bool toolTipsWordWrapped,
+                                     QObject * newParent)
   : Superclass(newParent)
   , d_ptr(new ctkToolTipTrapperPrivate(*this))
 {
   this->setToolTipsTrapped(toolTipsTrapped);
+  this->setToolTipsWordWrapped(toolTipsWordWrapped);
 }
 
 //------------------------------------------------------------------------------
@@ -102,6 +138,12 @@ bool ctkToolTipTrapper::toolTipsTrapped()const
 }
 
 //------------------------------------------------------------------------------
+bool ctkToolTipTrapper::toolTipsWordWrapped()const
+{
+  Q_D(const ctkToolTipTrapper);
+  return d->ToolTipsWordWrapped;
+}
+//------------------------------------------------------------------------------
 void ctkToolTipTrapper::setToolTipsTrapped(bool toolTipsTrapped)
 {
   Q_D(ctkToolTipTrapper);
@@ -109,12 +151,41 @@ void ctkToolTipTrapper::setToolTipsTrapped(bool toolTipsTrapped)
     {
     return;
     }
+  ctkToolTipTrapperPrivate::EventFilterToDo todo =
+      ctkToolTipTrapperPrivate::getEventFilterToDo(d->ToolTipsTrapped,
+                                                   d->ToolTipsWordWrapped,
+                                                   toolTipsTrapped,
+                                                   d->ToolTipsWordWrapped);
   d->ToolTipsTrapped = toolTipsTrapped;
-  if (toolTipsTrapped)
+  if (todo == ctkToolTipTrapperPrivate::EVENT_FILTER_INSTALL)
+    {
+    QCoreApplication::instance()->installEventFilter(this);
+    }
+  else if (todo == ctkToolTipTrapperPrivate::EVENT_FILTER_REMOVE)
+    {
+    QCoreApplication::instance()->removeEventFilter(this);
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkToolTipTrapper::setToolTipsWordWrapped(bool toolTipsWordWrapped)
+{
+  Q_D(ctkToolTipTrapper);
+  if (toolTipsWordWrapped == d->ToolTipsWordWrapped)
+    {
+    return;
+    }
+  ctkToolTipTrapperPrivate::EventFilterToDo todo =
+      ctkToolTipTrapperPrivate::getEventFilterToDo(d->ToolTipsTrapped,
+                                                   d->ToolTipsWordWrapped,
+                                                   d->ToolTipsTrapped,
+                                                   toolTipsWordWrapped);
+  d->ToolTipsWordWrapped = toolTipsWordWrapped;
+  if (todo == ctkToolTipTrapperPrivate::EVENT_FILTER_INSTALL)
     {
     QCoreApplication::instance()->installEventFilter(this);
     }
-  else
+  else if (todo == ctkToolTipTrapperPrivate::EVENT_FILTER_REMOVE)
     {
     QCoreApplication::instance()->removeEventFilter(this);
     }
@@ -124,9 +195,30 @@ void ctkToolTipTrapper::setToolTipsTrapped(bool toolTipsTrapped)
 bool ctkToolTipTrapper::eventFilter(QObject* watched, QEvent* input_event)
 {
   Q_UNUSED(watched);
-  if(input_event->type() == QEvent::ToolTip)
+  if(input_event->type() == QEvent::ToolTip
+     || input_event->type() == QEvent::ToolTipChange)
     {
-    return true;
+    Q_D(ctkToolTipTrapper);
+    // Trap tooltips so that they are not shown.
+    if (d->ToolTipsTrapped)
+      {
+      return true;
+      }
+    // Convert plain text to rich text to word wrap tooltips, and trigger new
+    // event to show the rich tooltip.
+    // If tooltip is already rich text or empty, let the regular mechanism
+    // handle it.
+    if (d->ToolTipsWordWrapped)
+      {
+      QWidget* widget = qobject_cast<QWidget *>(watched);
+      if (widget && !widget->toolTip().isEmpty()
+          && !Qt::mightBeRichText(widget->toolTip()))
+        {
+        QString richToolTip = Qt::convertFromPlainText(widget->toolTip(), Qt::WhiteSpaceNormal);
+        widget->setToolTip(richToolTip);
+        return true;
+        }
+      }
     }
   return false;
 }

+ 19 - 11
Libs/Widgets/ctkToolTipTrapper.h

@@ -62,33 +62,41 @@ class ctkToolTipTrapperPrivate;
 /// \ingroup Widgets
 /// Filters tooltips, to prevent tooltips from appearing or to word wrap
 /// tooltips.
-/// If toolTipsTrapped is true, installs an event filter to trap tooltips.
-/// If toolTipsTrapped is false, does not install the event filter.
-/// Tooltips are trapped by default.
+/// If toolTipsTrapped or toolTipsWordWrapped is true, installs an event filter to
+/// trap or wrap tooltips.
+/// If toolTipsTrapped and toolTipsWordWrapped are false, does not install the event
+/// filter.
+/// Tooltips are trapped and not word wrapped by default.
 class CTK_WIDGETS_EXPORT ctkToolTipTrapper : public QObject
 {
   Q_OBJECT
   Q_PROPERTY( bool toolTipsTrapped READ toolTipsTrapped WRITE setToolTipsTrapped)
+  Q_PROPERTY( bool toolTipsWordWrapped READ toolTipsWordWrapped WRITE setToolTipsWordWrapped)
 public:
   typedef QObject Superclass;
   /// Constructs a ToolTip trapper which is a child of objectParent
   explicit ctkToolTipTrapper(QObject* objectParent = 0);
-  explicit ctkToolTipTrapper(bool toolTipsTrapped, QObject* objectParent = 0);
+  explicit ctkToolTipTrapper(bool toolTipsTrapped,
+                             bool toolTipsWordWordWrapped,
+                             QObject* objectParent = 0);
   virtual ~ctkToolTipTrapper();
 
-  /// Returns true if the eventFilter is installed and tooltip events are
-  /// filtered
+  /// Returns true if the tooltips are trapped to prevent them from appearing.
   bool toolTipsTrapped()const;
 
-  /// Automatically called when the tooltips are trapped. It prevents the
-  /// tooltips events from being processed. You shouldn't have to call
-  /// it manually.
+  /// Returns true if the tooltips are word wrapped.
+  bool toolTipsWordWrapped()const;
+
+  /// Automatically called when the tooltips are trapped or word wrapped.
+  /// You shouldn't have to call it manually.
   bool eventFilter(QObject* watched, QEvent* event);
 
 public Q_SLOTS:
-  /// If true, it installs the eventFilter on the application. Otherwise
-  /// it removes it.
+  /// If true, installs the eventFilter on the application if it isn't already
+  /// installed.  Otherwise, removes the eventFilter if tooltips are neither
+  /// trapped nor word wrapped.
   void setToolTipsTrapped(bool toolTipsTrapped);
+  void setToolTipsWordWrapped(bool toolTipsWordWrapped);
 
 protected:
   QScopedPointer<ctkToolTipTrapperPrivate> d_ptr;