Fixing Topic Widget (vertical centering, scrolling and doubleclickination)
authorMarcus Eggenberger <egs@quassel-irc.org>
Wed, 2 Jul 2008 14:14:26 +0000 (16:14 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Wed, 2 Jul 2008 14:14:26 +0000 (16:14 +0200)
src/qtui/CMakeLists.txt
src/qtui/topicbutton.cpp [deleted file]
src/qtui/topiclabel.cpp [new file with mode: 0644]
src/qtui/topiclabel.h [moved from src/qtui/topicbutton.h with 77% similarity]
src/qtui/topicwidget.cpp
src/qtui/topicwidget.h
src/qtui/ui/topicwidget.ui
src/uisupport/CMakeLists.txt
src/uisupport/clickablelabel.cpp [new file with mode: 0644]
src/uisupport/clickablelabel.h [new file with mode: 0644]

index 561b46e..1bb30fe 100644 (file)
@@ -21,7 +21,7 @@ set(SOURCES
     settingsdlg.cpp
     settingspagedlg.cpp
     titlesetter.cpp
-    topicbutton.cpp
+    topiclabel.cpp
     topicwidget.cpp
     verticaldock.cpp)
 
@@ -40,7 +40,7 @@ set(MOC_HDRS
     settingsdlg.h
     settingspagedlg.h
     titlesetter.h
-    topicbutton.h
+    topiclabel.h
     topicwidget.h
     verticaldock.h)
 
diff --git a/src/qtui/topicbutton.cpp b/src/qtui/topicbutton.cpp
deleted file mode 100644 (file)
index f2f60af..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005/06 by the Quassel Project                          *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program 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 General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#include "topicbutton.h"
-
-
-#include <QDebug>
-
-#include <QApplication>
-#include <QPainter>
-#include <QHBoxLayout>
-#include <QFont>
-#include <QFontMetrics>
-
-#include "qtui.h"
-#include "message.h"
-
-TopicButton::TopicButton(QWidget *parent)
-  : QAbstractButton(parent)
-{
-  setFixedHeight(QFontMetrics(qApp->font()).height());
-  setToolTip(tr("Click to edit!"));
-}
-
-void TopicButton::paintEvent(QPaintEvent *event) {
-  Q_UNUSED(event);
-
-  QPainter painter(this);
-  painter.setBackgroundMode(Qt::OpaqueMode);
-
-  // FIXME re-enable topic painting
-#ifndef SPUTDEV
-  QRect drawRect = rect();
-  QRect brect;
-  QString textPart;
-  foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
-    textPart = styledContents.plainText.mid(fr.start, fr.length);
-    painter.setFont(fr.format.font());
-    painter.setPen(QPen(fr.format.foreground(), 0));
-    painter.setBackground(fr.format.background());
-    painter.drawText(drawRect, Qt::AlignLeft|Qt::TextSingleLine, textPart, &brect);
-    drawRect.setLeft(brect.right());
-  }
-#endif
-}
-
-void TopicButton::setAndStyleText(const QString &text) {
-  if(QAbstractButton::text() == text)
-    return;
-
-  setText(text); // this triggers a repaint event
-
-#ifndef SPUTDEV
-  styledContents = QtUi::style()->styleString(Message::mircToInternal(text));
-  int height = 1;
-  foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
-    height = qMax(height, QFontMetrics(fr.format.font()).height());
-  }
-
-  // ensure the button is editable (height != 1) if there is no text to show
-  if(text.isEmpty())
-    height = QFontMetrics(qApp->font()).height();
-  
-  setFixedHeight(height);
-#endif  
-  // show topic in tooltip
-  setToolTip(tr("%1\n\nClick to edit!").arg(QAbstractButton::text()));
-}
-
diff --git a/src/qtui/topiclabel.cpp b/src/qtui/topiclabel.cpp
new file mode 100644 (file)
index 0000000..33a752c
--- /dev/null
@@ -0,0 +1,168 @@
+/***************************************************************************
+ *   Copyright (C) 2005/06 by the Quassel Project                          *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "topiclabel.h"
+
+
+#include <QDebug>
+
+#include <QApplication>
+#include <QDesktopServices>
+#include <QPainter>
+// #include <QHBoxLayout>
+#include <QFont>
+#include <QFontMetrics>
+
+#include "qtui.h"
+#include "message.h"
+
+TopicLabel::TopicLabel(QWidget *parent)
+  : QFrame(parent),
+    offset(0),
+    dragStartX(0),
+    dragMode(false)
+{
+}
+
+void TopicLabel::paintEvent(QPaintEvent *event) {
+  Q_UNUSED(event);
+
+  textPartOffset.clear();
+  
+  QPainter painter(this);
+  painter.setBackgroundMode(Qt::OpaqueMode);
+
+  // FIXME re-enable topic painting
+#ifndef SPUTDEV
+  QRect drawRect = rect().adjusted(offset, 0, 0, 0);
+  QRect brect;
+  QString textPart;
+  foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
+    textPart = styledContents.plainText.mid(fr.start, fr.length);
+    textPartOffset << drawRect.left();
+    painter.setFont(fr.format.font());
+    painter.setPen(QPen(fr.format.foreground(), 0));
+    painter.setBackground(fr.format.background());
+    painter.drawText(drawRect, Qt::AlignLeft|Qt::AlignVCenter, textPart, &brect);
+    drawRect.setLeft(brect.right());
+  }
+#endif
+}
+
+void TopicLabel::setText(const QString &text) {
+  if(_text == text)
+    return;
+
+  _text = text;
+  update();
+
+#ifndef SPUTDEV
+  styledContents = QtUi::style()->styleString(Message::mircToInternal(text));
+  int height = 1;
+  foreach(QTextLayout::FormatRange fr, styledContents.formatList) {
+    height = qMax(height, QFontMetrics(fr.format.font()).height());
+  }
+
+  // ensure the label is editable (height != 1) if there is no text to show
+  if(text.isEmpty())
+    height = QFontMetrics(qApp->font()).height();
+  
+  // setFixedHeight(height);
+#endif  
+  // show topic in tooltip
+  setToolTip(_text);
+}
+
+
+void TopicLabel::mouseMoveEvent(QMouseEvent *event) {
+  if(!dragMode)
+    return;
+
+  event->accept();
+  offset = event->pos().x() - dragStartX;
+  update();
+}
+
+void TopicLabel::mousePressEvent(QMouseEvent *event) {
+  event->accept();
+  dragMode = true;
+  dragStartX = event->pos().x() - offset;
+}
+
+void TopicLabel::mouseReleaseEvent(QMouseEvent *event) {
+  event->accept();
+  dragMode = false;
+  if(qAbs(offset) < 10) {
+    offset = 0;
+    update();
+  }
+}
+
+void TopicLabel::mouseDoubleClickEvent(QMouseEvent *event) {
+#ifndef SPUTDEV
+  event->accept();
+  int textPart = 0;
+  int textOffset = 0;
+
+  if(textPartOffset.isEmpty())
+    return;
+
+  // find the text part that contains the url. We don't expect color codes in urls so we expect only full parts (yet?)
+  int x = event->pos().x();
+  while(textPart + 1 < textPartOffset.count()) {
+    if(textPartOffset[textPart + 1] < x) {
+      textPart++;
+      textOffset = textPartOffset[textPart];
+    } else {
+      break;
+    }
+  }
+
+  // we've Identified the needed text part \o/
+  QString text = styledContents.plainText.mid(styledContents.formatList[textPart].start, styledContents.formatList[textPart].length);
+
+  // now we have to find the the left and right word delimiters of the clicked word
+  QFontMetrics fontMetric(styledContents.formatList[textPart].format.font());
+  
+  int start = 0;
+  int spacePos = text.indexOf(" ");
+  while(spacePos != -1) {
+    if(fontMetric.width(text.left(spacePos + 1)) + textOffset < x) {
+      start = spacePos + 1;
+      spacePos = text.indexOf(" ", start + 1);
+    } else {
+      break;
+    }
+  }
+
+  int end = text.indexOf(" ", start);
+  int len = -1;
+  if(end != -1) {
+    len = end - start;
+  }
+  QString word = text.mid(start, len);
+  qDebug() << word;
+  QRegExp regex("^(h|f)t{1,2}ps?:\\/\\/");
+  if(regex.indexIn(word) != -1) {
+    QDesktopServices::openUrl(QUrl(word));
+  }
+#endif
+  
+}
similarity index 77%
rename from src/qtui/topicbutton.h
rename to src/qtui/topiclabel.h
index 71e9cd8..756c35a 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#ifndef TOPICBUTTON_H
-#define TOPICBUTTON_H
+#ifndef TOPICLABEL_H
+#define TOPICLABEL_H
 
 #include <QSize>
-#include <QAbstractButton>
+#include <QFrame>
 
 #include "uistyle.h"
 
-class TopicButton : public QAbstractButton {
+class TopicLabel : public QFrame {
   Q_OBJECT
 
 public:
-  TopicButton(QWidget *parent = 0);
+  TopicLabel(QWidget *parent = 0);
 
-  void setAndStyleText(const QString &text);
+  void setText(const QString &text);
 
 protected:
   virtual void paintEvent(QPaintEvent *event);
 
+  void mouseMoveEvent(QMouseEvent *event);
+  void mousePressEvent(QMouseEvent *event);
+  void mouseReleaseEvent(QMouseEvent *event);
+  void mouseDoubleClickEvent(QMouseEvent *event);
+  
 private:
 #ifndef SPUTDEV
   UiStyle::StyledText styledContents;
 #endif
+  QString _text;
   QSize _sizeHint;
+
+  int offset;
+  int dragStartX;
+  bool dragMode;
+
+  QList<int> textPartOffset; // needed for location url positions
 };
 
 #endif
index cb646ed..bb55280 100644 (file)
@@ -28,7 +28,7 @@ TopicWidget::TopicWidget(QWidget *parent)
   ui.setupUi(this);
   ui.topicLineEdit->hide();
   ui.topicLineEdit->installEventFilter(this);
-  ui.topicButton->show();
+  ui.topicLabel->show();
 }
 
 void TopicWidget::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
@@ -48,7 +48,7 @@ void TopicWidget::setTopic(const QString &newtopic) {
     return;
   
   _topic = newtopic;
-  ui.topicButton->setAndStyleText(newtopic);
+  ui.topicLabel->setText(newtopic);
   ui.topicLineEdit->setText(newtopic);
   switchPlain();
 }
@@ -58,19 +58,21 @@ void TopicWidget::on_topicLineEdit_returnPressed() {
   switchPlain();
 }
 
-void TopicWidget::on_topicButton_clicked() {
+void TopicWidget::on_topicEditButton_clicked() {
   switchEditable();
 }
 
 void TopicWidget::switchEditable() {
-  ui.topicButton->hide();
+  ui.topicLabel->hide();
+  ui.topicEditButton->hide();
   ui.topicLineEdit->show();
   ui.topicLineEdit->setFocus();
 }
 
 void TopicWidget::switchPlain() {
   ui.topicLineEdit->hide();
-  ui.topicButton->show();
+  ui.topicLabel->show();
+  ui.topicEditButton->show();
   ui.topicLineEdit->setText(_topic);
 }
 
@@ -93,3 +95,4 @@ bool TopicWidget::eventFilter(QObject *obj, QEvent *event) {
   
   return false;
 }
+
index 37d2321..5933d5e 100644 (file)
@@ -44,7 +44,7 @@ protected slots:
 
 private slots:
   void on_topicLineEdit_returnPressed();
-  void on_topicButton_clicked();
+  void on_topicEditButton_clicked();
   void switchEditable();
   void switchPlain();
   
index 8452e8d..cb00366 100644 (file)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>515</width>
-    <height>44</height>
+    <width>634</width>
+    <height>36</height>
    </rect>
   </property>
   <property name="sizePolicy" >
    <string>Form</string>
   </property>
   <layout class="QHBoxLayout" >
-   <property name="leftMargin" >
-    <number>2</number>
-   </property>
-   <property name="topMargin" >
-    <number>2</number>
-   </property>
-   <property name="rightMargin" >
+   <property name="margin" >
     <number>4</number>
    </property>
-   <property name="bottomMargin" >
-    <number>10</number>
-   </property>
-   <item>
-    <widget class="ClearableLineEdit" name="topicLineEdit" />
-   </item>
    <item>
-    <widget class="TopicButton" native="1" name="topicButton" >
+    <widget class="ClickableLabel" name="topicEditButton" >
      <property name="sizePolicy" >
-      <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+      <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
+     <property name="text" >
+      <string/>
+     </property>
+     <property name="pixmap" >
+      <pixmap resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/edit-clear.png</pixmap>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="TopicLabel" name="topicLabel" >
+     <property name="frameShape" >
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow" >
+      <enum>QFrame::Raised</enum>
+     </property>
     </widget>
    </item>
+   <item>
+    <widget class="ClearableLineEdit" name="topicLineEdit" />
+   </item>
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>TopicButton</class>
-   <extends>QWidget</extends>
-   <header location="global" >topicbutton.h</header>
-   <container>1</container>
-  </customwidget>
   <customwidget>
    <class>ClearableLineEdit</class>
    <extends>QLineEdit</extends>
    <header location="global" >clearablelineedit.h</header>
   </customwidget>
+  <customwidget>
+   <class>ClickableLabel</class>
+   <extends>QLabel</extends>
+   <header location="global" >clickablelabel.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TopicLabel</class>
+   <extends>QFrame</extends>
+   <header location="global" >topiclabel.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="../../icons/icons.qrc" />
index ad63477..a070ab2 100644 (file)
@@ -10,6 +10,7 @@ set(SOURCES
     bufferview.cpp
     bufferviewfilter.cpp
     clearablelineedit.cpp
+    clickablelabel.cpp
     colorbutton.cpp
     nickviewfilter.cpp
     inputline.cpp
@@ -25,6 +26,7 @@ set(MOC_HDRS
     bufferview.h
     bufferviewfilter.h
     clearablelineedit.h
+    clickablelabel.h
     colorbutton.h
     nickviewfilter.h
     inputline.h
diff --git a/src/uisupport/clickablelabel.cpp b/src/uisupport/clickablelabel.cpp
new file mode 100644 (file)
index 0000000..debad83
--- /dev/null
@@ -0,0 +1,38 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "clickablelabel.h"
+
+#include <QDebug>
+#include <QMouseEvent>
+
+ClickableLabel::ClickableLabel(QWidget *parent)
+  : QLabel(parent)
+{
+}
+
+
+void ClickableLabel::mouseReleaseEvent(QMouseEvent *event) {
+  if(event->pos().x() > size().width() || event->pos().y() > size().height())
+    return;
+
+  event->accept();
+  emit clicked();
+}
diff --git a/src/uisupport/clickablelabel.h b/src/uisupport/clickablelabel.h
new file mode 100644 (file)
index 0000000..11ebeb5
--- /dev/null
@@ -0,0 +1,39 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef CLICKABLELABEL_H
+#define CLICKABLELABEL_H
+
+#include <QLabel>
+
+class ClickableLabel : public QLabel {
+  Q_OBJECT
+
+public:
+  ClickableLabel(QWidget *parent = 0);
+
+signals:
+  void clicked();
+
+protected:
+  void mouseReleaseEvent(QMouseEvent *event);
+};
+
+#endif //CLICKABLELABEL_H