Introducing search in the chatview. See views -> show search bar
authorMarcus Eggenberger <egs@quassel-irc.org>
Sat, 16 Aug 2008 18:23:56 +0000 (20:23 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Sat, 16 Aug 2008 18:26:51 +0000 (20:26 +0200)
Known issues:
 - fixed color
 - cannot make the view scroll to a result (buttons are disabled)
 - no shortcuts
 - doesn't react on newly inserted messages

14 files changed:
src/qtui/CMakeLists.txt
src/qtui/bufferwidget.cpp
src/qtui/bufferwidget.h
src/qtui/chatitem.cpp
src/qtui/chatitem.h
src/qtui/chatlinemodelitem.h
src/qtui/chatscene.h
src/qtui/chatviewsearchbar.cpp [new file with mode: 0644]
src/qtui/chatviewsearchbar.h [new file with mode: 0644]
src/qtui/chatviewsearchcontroller.cpp [new file with mode: 0644]
src/qtui/chatviewsearchcontroller.h [new file with mode: 0644]
src/qtui/mainwin.cpp
src/qtui/ui/bufferwidget.ui
src/qtui/ui/chatviewsearchbar.ui [new file with mode: 0644]

index 74db1aa..1fca894 100644 (file)
@@ -17,6 +17,8 @@ set(SOURCES
     chatmonitorview.cpp
     chatscene.cpp
     chatview.cpp
+    chatviewsearchbar.cpp
+    chatviewsearchcontroller.cpp
     columnhandleitem.cpp
     coreconfigwizard.cpp
     coreconnectdlg.cpp
@@ -49,6 +51,8 @@ set(MOC_HDRS
     chatmonitorview.h
     chatscene.h
     chatview.h
+    chatviewsearchbar.h
+    chatviewsearchcontroller.h
     columnhandleitem.h
     coreconfigwizard.h
     coreconnectdlg.h
@@ -81,6 +85,7 @@ set(FORMS
     bufferviewwidget.ui
     bufferwidget.ui
     channellistdlg.ui
+    chatviewsearchbar.ui
     coreaccounteditdlg.ui
     coreconfigwizardintropage.ui
     coreconfigwizardadminuserpage.ui
index fc06346..a0f71c6 100644 (file)
 
 #include "bufferwidget.h"
 #include "chatview.h"
+#include "chatviewsearchbar.h"
+#include "chatviewsearchcontroller.h"
 #include "settings.h"
 #include "client.h"
 
 #include "global.h"
 
-BufferWidget::BufferWidget(QWidget *parent) : AbstractBufferContainer(parent) {
+#include <QLayout>
+
+BufferWidget::BufferWidget(QWidget *parent)
+  : AbstractBufferContainer(parent),
+    _chatViewSearchController(new ChatViewSearchController(this))
+{
   ui.setupUi(this);
+  layout()->setContentsMargins(0, 0, 0, 0);
+  layout()->setSpacing(0);
+  // ui.searchBar->hide();
+
+  _chatViewSearchController->setCaseSensitive(ui.searchBar->caseSensitiveBox()->isChecked());
+  _chatViewSearchController->setSearchSenders(ui.searchBar->searchSendersBox()->isChecked());
+  _chatViewSearchController->setSearchMsgs(ui.searchBar->searchMsgsBox()->isChecked());
+  _chatViewSearchController->setSearchOnlyRegularMsgs(ui.searchBar->searchOnlyRegularMsgsBox()->isChecked());
+  
+  connect(ui.searchBar->searchEditLine(), SIGNAL(textChanged(const QString &)),
+         _chatViewSearchController, SLOT(setSearchString(const QString &)));
+  connect(ui.searchBar->caseSensitiveBox(), SIGNAL(toggled(bool)),
+         _chatViewSearchController, SLOT(setCaseSensitive(bool)));
+  connect(ui.searchBar->searchSendersBox(), SIGNAL(toggled(bool)),
+         _chatViewSearchController, SLOT(setSearchSenders(bool)));
+  connect(ui.searchBar->searchMsgsBox(), SIGNAL(toggled(bool)),
+         _chatViewSearchController, SLOT(setSearchMsgs(bool)));
+  connect(ui.searchBar->searchOnlyRegularMsgsBox(), SIGNAL(toggled(bool)),
+         _chatViewSearchController, SLOT(setSearchOnlyRegularMsgs(bool)));
+}
+
+BufferWidget::~BufferWidget() {
+  delete _chatViewSearchController;
+  _chatViewSearchController = 0;
 }
 
 AbstractChatView *BufferWidget::createChatView(BufferId id) {
@@ -48,7 +79,13 @@ void BufferWidget::removeChatView(BufferId id) {
 }
 
 void BufferWidget::showChatView(BufferId id) {
-  if(!id.isValid()) ui.stackedWidget->setCurrentWidget(ui.page);
-  else ui.stackedWidget->setCurrentWidget(_chatViews.value(id));
+  if(!id.isValid()) {
+    ui.stackedWidget->setCurrentWidget(ui.page);
+  } else {
+    ChatView *view = qobject_cast<ChatView *>(_chatViews.value(id));
+    Q_ASSERT(view);
+    ui.stackedWidget->setCurrentWidget(view);
+    _chatViewSearchController->setScene(view->scene());
+  }
 }
 
index e2876ad..6f48f09 100644 (file)
 
 #include "abstractbuffercontainer.h"
 
+class ChatViewSearchBar;
+class ChatViewSearchController;
+
 class BufferWidget : public AbstractBufferContainer {
   Q_OBJECT
 
   public:
     BufferWidget(QWidget *parent);
+    ~BufferWidget();
+
+  inline ChatViewSearchBar *searchBar() const { return ui.searchBar; }
 
   protected:
     virtual AbstractChatView *createChatView(BufferId);
@@ -41,6 +47,8 @@ class BufferWidget : public AbstractBufferContainer {
   private:
     Ui::BufferWidget ui;
     QHash<BufferId, QWidget *> _chatViews;
+
+  ChatViewSearchController *_chatViewSearchController;
 };
 
 #endif
index da9bbf5..d7a14ff 100644 (file)
@@ -209,6 +209,36 @@ void ChatItem::continueSelecting(const QPointF &pos) {
   update();
 }
 
+QList<QRectF> ChatItem::findWords(const QString &searchWord, Qt::CaseSensitivity caseSensitive) {
+  QList<QRectF> resultList;
+  const QAbstractItemModel *model_ = model();
+  if(!model_)
+    return resultList;
+
+  QString plainText = model_->data(model_->index(row(), column()), MessageModel::DisplayRole).toString();
+  QList<int> indexList;
+  int searchIdx = plainText.indexOf(searchWord, 0, caseSensitive);
+  while(searchIdx != -1) {
+    indexList << searchIdx;
+    searchIdx = plainText.indexOf(searchWord, searchIdx + 1, caseSensitive);
+  }
+
+  if(!haveLayout())
+    updateLayout();
+
+  Q_ASSERT(_layout);
+  foreach(int idx, indexList) {
+    QTextLine line = _layout->lineForTextPosition(idx);
+    qreal x = line.cursorToX(idx);
+    qreal width = line.cursorToX(idx + searchWord.count()) - x;
+    qreal height = fontMetrics()->lineSpacing();
+    qreal y = height * line.lineNumber();
+    resultList << QRectF(x, y, width, height);
+  }
+  return resultList;
+}
+
+
 void ChatItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
   if(event->buttons() == Qt::LeftButton) {
     if(_selectionMode == NoSelection) {
index 678c3c6..72d1fb6 100644 (file)
@@ -62,6 +62,8 @@ class ChatItem : public QGraphicsItem {
     void setFullSelection();
     void continueSelecting(const QPointF &pos);
 
+  QList<QRectF> findWords(const QString &searchWord, Qt::CaseSensitivity caseSensitive);
+
   protected:
     virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
     virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
@@ -90,7 +92,7 @@ class ChatItem : public QGraphicsItem {
     int _col;
     quint8 _lines;
 
-    QList<quint16> _wrapPositions;
+    QTextLayout * _layout;
 
     enum SelectionMode { NoSelection, PartialSelection, FullSelection };
     SelectionMode _selectionMode;
index a2ef9b9..1e9a8cc 100644 (file)
@@ -31,7 +31,7 @@ public:
   ChatLineModelItem(const Message &);
 
   virtual QVariant data(int column, int role) const;
-  virtual inline bool setData(int column, const QVariant &value, int role) { return false; }
+  virtual inline bool setData(int column, const QVariant &value, int role) { Q_UNUSED(column); Q_UNUSED(value); Q_UNUSED(role); return false; }
 
 private:
   void computeWrapList();
index c0231f7..1b31d1f 100644 (file)
@@ -50,6 +50,7 @@ class ChatScene : public QGraphicsScene {
     int sectionByScenePos(int x);
     inline int sectionByScenePos(const QPoint &pos) { return sectionByScenePos(pos.x()); }
     inline bool isSingleBufferScene() const { return _singleBufferScene; }
+    inline ChatLine *chatLine(int row) { return (row < _lines.count()) ? _lines[row] : 0; }
 
   public slots:
     void setWidth(qreal);
diff --git a/src/qtui/chatviewsearchbar.cpp b/src/qtui/chatviewsearchbar.cpp
new file mode 100644 (file)
index 0000000..121070d
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   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 "chatviewsearchbar.h"
+
+#include <QAction>
+
+ChatViewSearchBar::ChatViewSearchBar(QWidget *parent)
+  : QWidget(parent)
+{
+  ui.setupUi(this);
+  layout()->setContentsMargins(0, 0, 0, 0);
+
+  ui.searchUpButton->setEnabled(false);
+  ui.searchDownButton->setEnabled(false);
+
+  _toggleViewAction = new QAction(tr("Show search bar"), this);
+  _toggleViewAction->setCheckable(true);
+  _toggleViewAction->setChecked(false);
+  connect(_toggleViewAction, SIGNAL(toggled(bool)),
+         this, SLOT(setVisible(bool)));
+  setVisible(false);
+
+  connect(ui.hideButton, SIGNAL(clicked()),
+         _toggleViewAction, SLOT(toggle()));
+}
+
+void ChatViewSearchBar::setVisible(bool visible) {
+  QWidget::setVisible(visible);
+  ui.searchEditLine->clear();
+}
diff --git a/src/qtui/chatviewsearchbar.h b/src/qtui/chatviewsearchbar.h
new file mode 100644 (file)
index 0000000..043e4ba
--- /dev/null
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *   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 CHATVIEWSEARCHBAR_H
+#define CHATVIEWSEARCHBAR_H
+
+#include "ui_chatviewsearchbar.h"
+
+#include <QWidget>
+
+class QAction;
+
+class ChatViewSearchBar : public QWidget {
+  Q_OBJECT
+
+public:
+  ChatViewSearchBar(QWidget *parent = 0);
+
+  inline QLineEdit *searchEditLine() const { return ui.searchEditLine; }
+  inline QCheckBox *caseSensitiveBox() const { return ui.caseSensitiveBox; }
+  inline QCheckBox *searchSendersBox() const { return ui.searchSendersBox; }
+  inline QCheckBox *searchMsgsBox() const { return ui.searchMsgsBox; }
+  inline QCheckBox *searchOnlyRegularMsgsBox() const { return ui.searchOnlyRegularMsgsBox; }
+
+  inline QAction *toggleViewAction() const { return _toggleViewAction; }
+
+public slots:
+  void setVisible(bool visible);
+
+private:
+  Ui::ChatViewSearchBar ui;
+  QAction *_toggleViewAction;
+};
+
+#endif //CHATVIEWSEARCHBAR_H
diff --git a/src/qtui/chatviewsearchcontroller.cpp b/src/qtui/chatviewsearchcontroller.cpp
new file mode 100644 (file)
index 0000000..44ddc69
--- /dev/null
@@ -0,0 +1,213 @@
+/***************************************************************************
+ *   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 "chatviewsearchcontroller.h"
+
+#include <QAbstractItemModel>
+#include <QPainter>
+
+#include "chatitem.h"
+#include "chatlinemodel.h"
+#include "chatscene.h"
+#include "messagemodel.h"
+
+ChatViewSearchController::ChatViewSearchController(QObject *parent)
+  : QObject(parent),
+    _scene(0),
+    _caseSensitive(false),
+    _searchSenders(false),
+    _searchMsgs(true),
+    _searchOnlyRegularMsgs(true)
+{
+}
+
+void ChatViewSearchController::setSearchString(const QString &searchString) {
+  QString oldSearchString = _searchString;
+  _searchString = searchString;
+  if(_scene) {
+    if(!searchString.startsWith(oldSearchString) || oldSearchString.isEmpty()) {
+      // we can't reuse our all findings... cler the scene and do it all over
+      updateHighlights();
+    } else {
+      // reuse all findings
+      updateHighlights(true);
+    }
+  }
+}
+
+ void ChatViewSearchController::setScene(ChatScene *scene) {
+  Q_ASSERT(scene);
+  if(scene == _scene)
+    return;
+
+  if(_scene) {
+    disconnect(_scene, 0, this, 0);
+    qDeleteAll(_highlightItems);
+    _highlightItems.clear();
+  }
+
+  _scene = scene;
+  if(!scene)
+    return;
+
+  connect(_scene, SIGNAL(destroyed()), this, SLOT(sceneDestroyed()));
+  updateHighlights();
+ }
+
+
+
+void ChatViewSearchController::updateHighlights(bool reuse) {
+  if(!_scene)
+    return;
+  
+  QAbstractItemModel *model = _scene->model();
+  Q_ASSERT(model);
+
+
+  QList<ChatLine *> chatLines;
+  if(reuse) {
+    foreach(SearchHighlightItem *highlightItem, _highlightItems) {
+      ChatLine *line = dynamic_cast<ChatLine *>(highlightItem->parentItem());
+      if(!line || chatLines.contains(line))
+       continue;
+      chatLines << line;
+    }
+  }
+
+  qDeleteAll(_highlightItems);
+  _highlightItems.clear();
+  Q_ASSERT(_highlightItems.isEmpty());
+
+  if(searchString().isEmpty() || !(_searchSenders || _searchMsgs))
+    return;
+
+  if(reuse) {
+    QModelIndex index;
+    foreach(ChatLine *line, chatLines) {
+      if(_searchOnlyRegularMsgs) {
+       index = model->index(line->row(), 0);
+       if(!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
+         continue;
+      }
+      highlightLine(line);
+    }
+  } else {
+    // we have to crawl through the data
+    QModelIndex index;
+    QString plainText;
+    int rowCount = model->rowCount();
+    for(int row = 0; row < rowCount; row++) {
+      ChatLine *line = _scene->chatLine(row);
+
+      if(_searchOnlyRegularMsgs) {
+       index = model->index(row, 0);
+       if(!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
+         continue;
+      }
+      highlightLine(line);
+    }
+  }
+}
+
+void ChatViewSearchController::highlightLine(ChatLine *line) {
+  QList<ChatItem *> checkItems;
+  if(_searchSenders)
+    checkItems << &(line->item(MessageModel::SenderColumn));
+  
+  if(_searchMsgs)
+    checkItems << &(line->item(MessageModel::ContentsColumn));
+  
+  foreach(ChatItem *item, checkItems) {
+    foreach(QRectF wordRect, item->findWords(searchString(), caseSensitive())) {
+      _highlightItems << new SearchHighlightItem(wordRect.adjusted(item->x(), 0, item->x(), 0), line);
+    }
+  }
+}
+
+void ChatViewSearchController::sceneDestroyed() {
+  // WARNING: don't call any methods on scene!
+  _scene = 0;
+  // the items will be automatically deleted when the scene is destroyed
+  // so we just have to clear the list;
+  _highlightItems.clear();
+}
+
+void ChatViewSearchController::setCaseSensitive(bool caseSensitive) {
+  if(_caseSensitive == caseSensitive)
+    return;
+
+  _caseSensitive = caseSensitive;
+
+  // we can reuse the original search results if the new search
+  // parameters are a restriction of the original one
+  updateHighlights(caseSensitive);
+}
+
+void ChatViewSearchController::setSearchSenders(bool searchSenders) {
+  if(_searchSenders == searchSenders)
+    return;
+
+  _searchSenders = searchSenders;
+  // we can reuse the original search results if the new search
+  // parameters are a restriction of the original one
+  updateHighlights(!searchSenders);
+}
+
+void ChatViewSearchController::setSearchMsgs(bool searchMsgs) {
+  if(_searchMsgs == searchMsgs)
+    return;
+
+  _searchMsgs = searchMsgs;
+
+  // we can reuse the original search results if the new search
+  // parameters are a restriction of the original one
+  updateHighlights(!searchMsgs);
+}
+
+void ChatViewSearchController::setSearchOnlyRegularMsgs(bool searchOnlyRegularMsgs) {
+  if(_searchOnlyRegularMsgs == searchOnlyRegularMsgs)
+    return;
+
+  _searchOnlyRegularMsgs = searchOnlyRegularMsgs;
+
+  // we can reuse the original search results if the new search
+  // parameters are a restriction of the original one
+  updateHighlights(searchOnlyRegularMsgs);
+}
+
+
+
+SearchHighlightItem::SearchHighlightItem(QRectF wordRect, QGraphicsItem *parent)
+  : QGraphicsItem(parent),
+    _boundingRect(QRectF(-wordRect.width() / 2, -wordRect.height() / 2, wordRect.width(), wordRect.height()))
+{
+  setPos(wordRect.x() + wordRect.width() / 2 , wordRect.y() + wordRect.height() / 2);
+  scale(1.2, 1.2);
+}
+
+void SearchHighlightItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+  Q_UNUSED(widget);
+  
+  painter->setPen(QPen(Qt::black, 1.5));
+  //painter->setBrush(QColor(127, 133, 250));
+  painter->setBrush(QColor(254, 237, 45));
+  painter->setRenderHints(QPainter::Antialiasing);
+  painter->drawRoundedRect(boundingRect(), 30, 30, Qt::RelativeSize);
+}
diff --git a/src/qtui/chatviewsearchcontroller.h b/src/qtui/chatviewsearchcontroller.h
new file mode 100644 (file)
index 0000000..6d8dc2d
--- /dev/null
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *   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 CHATVIEWSEARCHCONTROLLER_H
+#define CHATVIEWSEARCHCONTROLLER_H
+
+#include <QObject>
+#include <QHash>
+#include <QPointer>
+#include <QString>
+
+#include "message.h"
+
+class ChatLine;
+class ChatScene;
+class SearchHighlightItem;
+
+class ChatViewSearchController : public QObject {
+  Q_OBJECT
+
+public:
+  ChatViewSearchController(QObject *parent = 0);
+
+  inline const QString &searchString() const { return _searchString; }
+
+  void setScene(ChatScene *scene);
+
+public slots:
+  void setSearchString(const QString &searchString);
+  void setCaseSensitive(bool caseSensitive);
+  void setSearchSenders(bool searchSenders);
+  void setSearchMsgs(bool searchMsgs);
+  void setSearchOnlyRegularMsgs(bool searchOnlyRegularMsgs);
+
+private slots:
+  void sceneDestroyed();
+  void updateHighlights(bool reuse = false);
+
+private:
+  QString _searchString;
+  ChatScene *_scene;
+  QList<SearchHighlightItem *> _highlightItems;
+
+  bool _caseSensitive;
+  bool _searchSenders;
+  bool _searchMsgs;
+  bool _searchOnlyRegularMsgs;
+
+  inline Qt::CaseSensitivity caseSensitive() const { return _caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; }
+
+  inline bool checkType(Message::Type type) const { return type & (Message::Plain | Message::Notice | Message::Action); }
+  void highlightLine(ChatLine *line);
+};
+
+
+// Highlight Items
+#include <QGraphicsItem>
+
+class SearchHighlightItem : public QGraphicsItem {
+public:
+  SearchHighlightItem(QRectF wordRect, QGraphicsItem *parent = 0);
+  inline virtual QRectF boundingRect() const { return _boundingRect; }
+  virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+private:
+  QRectF _boundingRect;
+};
+
+#endif //CHATVIEWSEARCHCONTROLLER_H
index beba80f..a7c99ff 100644 (file)
@@ -29,6 +29,7 @@
 #include "chatmonitorfilter.h"
 #include "chatmonitorview.h"
 #include "chatview.h"
+#include "chatviewsearchbar.h"
 #include "client.h"
 #include "clientbacklogmanager.h"
 #include "coreinfodlg.h"
@@ -163,6 +164,7 @@ void MainWin::init() {
   // attach the BufferWidget to the BufferModel and the default selection
   ui.bufferWidget->setModel(Client::bufferModel());
   ui.bufferWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
+  ui.menuViews->addAction(ui.bufferWidget->searchBar()->toggleViewAction());
 
   _titleSetter.setModel(Client::bufferModel());
   _titleSetter.setSelectionModel(Client::bufferModel()->standardSelectionModel());
index b404314..5593be9 100644 (file)
   <property name="windowTitle" >
    <string/>
   </property>
-  <layout class="QVBoxLayout" >
-   <property name="margin" >
-    <number>0</number>
-   </property>
+  <layout class="QVBoxLayout" name="verticalLayout" >
    <item>
     <widget class="QStackedWidget" name="stackedWidget" >
      <property name="sizePolicy" >
@@ -47,8 +44,8 @@
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>782</width>
-        <height>542</height>
+        <width>758</width>
+        <height>498</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" >
@@ -94,8 +91,19 @@ p, li { white-space: pre-wrap; }
      </widget>
     </widget>
    </item>
+   <item>
+    <widget class="ChatViewSearchBar" native="1" name="searchBar" />
+   </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ChatViewSearchBar</class>
+   <extends>QWidget</extends>
+   <header location="global" >chatviewsearchbar.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources>
   <include location="../../icons/quassel-icons.qrc" />
  </resources>
diff --git a/src/qtui/ui/chatviewsearchbar.ui b/src/qtui/ui/chatviewsearchbar.ui
new file mode 100644 (file)
index 0000000..d24b470
--- /dev/null
@@ -0,0 +1,115 @@
+<ui version="4.0" >
+ <class>ChatViewSearchBar</class>
+ <widget class="QWidget" name="ChatViewSearchBar" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>727</width>
+    <height>51</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout" >
+   <item>
+    <widget class="QToolButton" name="hideButton" >
+     <property name="text" >
+      <string>...</string>
+     </property>
+     <property name="icon" >
+      <iconset resource="../../icons/icons.qrc" >
+       <normaloff>:/16x16/actions/oxygen/16x16/actions/application-exit.png</normaloff>:/16x16/actions/oxygen/16x16/actions/application-exit.png</iconset>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="ClearableLineEdit" name="searchEditLine" />
+   </item>
+   <item>
+    <widget class="QToolButton" name="searchDownButton" >
+     <property name="text" >
+      <string>...</string>
+     </property>
+     <property name="icon" >
+      <iconset resource="../../icons/icons.qrc" >
+       <normaloff>:/16x16/actions/oxygen/16x16/actions/go-down.png</normaloff>:/16x16/actions/oxygen/16x16/actions/go-down.png</iconset>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QToolButton" name="searchUpButton" >
+     <property name="text" >
+      <string>...</string>
+     </property>
+     <property name="icon" >
+      <iconset resource="../../icons/icons.qrc" >
+       <normaloff>:/16x16/actions/oxygen/16x16/actions/go-up.png</normaloff>:/16x16/actions/oxygen/16x16/actions/go-up.png</iconset>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="caseSensitiveBox" >
+     <property name="text" >
+      <string>case sensitive</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="searchSendersBox" >
+     <property name="text" >
+      <string>search nick</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="searchMsgsBox" >
+     <property name="text" >
+      <string>search message</string>
+     </property>
+     <property name="checkable" >
+      <bool>true</bool>
+     </property>
+     <property name="checked" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="searchOnlyRegularMsgsBox" >
+     <property name="text" >
+      <string>ignore joins, parts, etc.</string>
+     </property>
+     <property name="checked" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="horizontalSpacer" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0" >
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ClearableLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header location="global" >clearablelineedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../../icons/icons.qrc" />
+ </resources>
+ <connections/>
+</ui>