- BufferWidget behaves now like a view
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 22 Jan 2008 22:58:45 +0000 (22:58 +0000)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 22 Jan 2008 22:58:45 +0000 (22:58 +0000)
- Fixed ab Bug with the TabCompleter
- Nick selector works now
... and btw: am I the only one who tries to keep version.inc up to date? ;)

src/client/buffermodel.cpp
src/client/buffermodel.h
src/client/modelpropertymapper.cpp
src/client/treemodel.cpp
src/qtui/bufferwidget.cpp
src/qtui/bufferwidget.h
src/qtui/mainwin.cpp
src/uisupport/tabcompleter.cpp
version.inc

index 80b16a3..c9537f3 100644 (file)
 
 BufferModel::BufferModel(NetworkModel *parent)
   : QSortFilterProxyModel(parent),
-    _selectionModelSynchronizer(new SelectionModelSynchronizer(this)),
-    _propertyMapper(new ModelPropertyMapper(this))
+    _selectionModelSynchronizer(this),
+    _propertyMapper(this)
 {
   setSourceModel(parent);
 
   // initialize the Property Mapper
-  _propertyMapper->setModel(this);
-  delete _propertyMapper->selectionModel();
-  MappedSelectionModel *mappedSelectionModel = new MappedSelectionModel(this);
-  _propertyMapper->setSelectionModel(mappedSelectionModel);
-  synchronizeSelectionModel(mappedSelectionModel);
-  
-  connect(_selectionModelSynchronizer, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
+  _propertyMapper.setModel(this);
+  _selectionModelSynchronizer.addRegularSelectionModel(_propertyMapper.selectionModel());
+  connect(&_selectionModelSynchronizer, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
          this, SLOT(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
 }
 
@@ -47,8 +43,8 @@ BufferModel::~BufferModel() {
 }
 
 bool BufferModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const {
-  Q_UNUSED(sourceRow)
-    
+  Q_UNUSED(sourceRow);
+  // hide childs of buffers and everything below
   if(parent.data(NetworkModel::ItemTypeRole) == NetworkModel::BufferItemType)
     return false;
   else
@@ -56,19 +52,19 @@ bool BufferModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) con
 }
 
 void BufferModel::synchronizeSelectionModel(MappedSelectionModel *selectionModel) {
-  selectionModelSynchronizer()->addSelectionModel(selectionModel);
+  _selectionModelSynchronizer.addSelectionModel(selectionModel);
 }
 
 void BufferModel::synchronizeView(QAbstractItemView *view) {
   MappedSelectionModel *mappedSelectionModel = new MappedSelectionModel(view->model());
-  selectionModelSynchronizer()->addSelectionModel(mappedSelectionModel);
+  _selectionModelSynchronizer.addSelectionModel(mappedSelectionModel);
   Q_ASSERT(mappedSelectionModel);
   delete view->selectionModel();
   view->setSelectionModel(mappedSelectionModel);
 }
 
 void BufferModel::mapProperty(int column, int role, QObject *target, const QByteArray &property) {
-  propertyMapper()->addMapping(column, role, target, property);
+  _propertyMapper.addMapping(column, role, target, property);
 }
 
 // This Slot indicates that the user has selected a different buffer in the gui
index e45c60e..4eb2230 100644 (file)
@@ -43,8 +43,9 @@ public:
 
   bool filterAcceptsRow(int sourceRow, const QModelIndex &parent) const;
   
-  inline SelectionModelSynchronizer *selectionModelSynchronizer() { return _selectionModelSynchronizer; }
-  inline ModelPropertyMapper *propertyMapper() { return _propertyMapper; }
+  inline const SelectionModelSynchronizer *selectionModelSynchronizer() const { return &_selectionModelSynchronizer; }
+  inline const ModelPropertyMapper *propertyMapper() const { return &_propertyMapper; }
+  inline QItemSelectionModel *standardSelectionModel() const { return _propertyMapper.selectionModel(); }
 
   void synchronizeSelectionModel(MappedSelectionModel *selectionModel);
   void synchronizeView(QAbstractItemView *view);
@@ -58,8 +59,8 @@ signals:
   void selectionChanged(const QModelIndex &);
 
 private:
-  QPointer<SelectionModelSynchronizer> _selectionModelSynchronizer;
-  QPointer<ModelPropertyMapper> _propertyMapper;
+  SelectionModelSynchronizer _selectionModelSynchronizer;
+  ModelPropertyMapper _propertyMapper;
   BufferId currentBuffer;
 };
 
index 32dfe7f..a10a73d 100644 (file)
@@ -35,13 +35,13 @@ ModelPropertyMapper::~ModelPropertyMapper() {
 
 void ModelPropertyMapper::setModel(QAbstractItemModel *model) {
   if(_model) {
-    setSelectionModel(new QItemSelectionModel(model));
     disconnect(_model, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
               this, SLOT(dataChanged(QModelIndex, QModelIndex)));
   }
   _model = model;
   connect(_model, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
          this, SLOT(dataChanged(QModelIndex, QModelIndex)));
+  setSelectionModel(new QItemSelectionModel(model));
 }
 
 QAbstractItemModel *ModelPropertyMapper::model() const {
index ffcec13..0dc19b7 100644 (file)
@@ -105,7 +105,6 @@ void AbstractTreeItem::removeAllChilds() {
     return;
 
   emit beginRemoveChilds(0, childCount() - 1);
-
   AbstractTreeItem *child;
   foreach(int column, _childItems.keys()) {
     QList<AbstractTreeItem *>::iterator iter = _childItems[column].begin();
@@ -289,6 +288,19 @@ TreeModel::TreeModel(const QList<QVariant> &data, QObject *parent)
   : QAbstractItemModel(parent)
 {
   rootItem = new SimpleTreeItem(data, 0);
+
+  connect(rootItem, SIGNAL(dataChanged(int)),
+         this, SLOT(itemDataChanged(int)));
+  
+  connect(rootItem, SIGNAL(newChild(AbstractTreeItem *)),
+         this, SLOT(newChild(AbstractTreeItem *)));
+
+  connect(rootItem, SIGNAL(beginRemoveChilds(int, int)),
+         this, SLOT(beginRemoveChilds(int, int)));
+  
+  connect(rootItem, SIGNAL(endRemoveChilds()),
+         this, SLOT(endRemoveChilds()));
+
 }
 
 TreeModel::~TreeModel() {
@@ -507,6 +519,5 @@ bool TreeModel::removeRows(int row, int count, const QModelIndex &parent) {
 }
 
 void TreeModel::clear() {
-  removeRows(0, rowCount());
-  reset();
+  rootItem->removeAllChilds();
 }
index 541ddb5..14a846f 100644 (file)
 #include "chatwidget.h"
 #include "settings.h"
 #include "client.h"
+#include "identity.h"
 #include "network.h"
+#include "networkmodel.h"
 
 BufferWidget::BufferWidget(QWidget *parent)
   : QWidget(parent),
-    _currentBuffer(0),
-    _currentNetwork(0)
+    _bufferModel(0),
+    _selectionModel(0)
 {
   ui.setupUi(this);
   ui.ownNick->clear();  // TODO add nick history
   connect(ui.inputEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed()));
+  connect(ui.ownNick, SIGNAL(activated(QString)), this, SLOT(changeNick(QString)));
+}
+
+BufferWidget::~BufferWidget() {
 }
 
 void BufferWidget::init() {
+}
 
+void BufferWidget::setModel(BufferModel *bufferModel) {
+  if(_bufferModel) {
+    disconnect(_bufferModel, 0, this, 0);
+  }
+  _bufferModel = bufferModel;
+  connect(bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
+         this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int)));
 }
 
-BufferWidget::~BufferWidget() {
+void BufferWidget::setSelectionModel(QItemSelectionModel *selectionModel) {
+  if(_selectionModel) {
+    disconnect(_selectionModel, 0, this, 0);
+  }
+  _selectionModel = selectionModel;
+  connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
+         this, SLOT(currentChanged(QModelIndex, QModelIndex)));
+}
+
+void BufferWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
+  Q_ASSERT(model());
+  if(!parent.isValid()) {
+    // ok this means that whole networks are about to be removed
+    // we can't determine which buffers are affect, so we hope that all nets are removed
+    // this is the most common case (for example disconnecting from the core or terminating the clint)
+    if(model()->rowCount(parent) != end - start + 1)
+      return;
+
+    ChatWidget *chatWidget;
+    QHash<BufferId, ChatWidget *>::iterator iter = _chatWidgets.begin();
+    while(iter != _chatWidgets.end()) {
+      chatWidget = *iter;
+      iter = _chatWidgets.erase(iter);
+      ui.stackedWidget->removeWidget(chatWidget);
+      chatWidget->deleteLater();
+    }
+    
+  } else {
+    // check if there are explicitly buffers removed
+    for(int i = start; i <= end; i++) {
+      QVariant variant = parent.child(i,0).data(NetworkModel::BufferIdRole);
+      if(!variant.isValid())
+       continue;
+      
+      BufferId bufferId = qVariantValue<BufferId>(variant);
+      removeBuffer(bufferId);
+    }
+  }
+}
+
+void BufferWidget::removeBuffer(BufferId bufferId) {
+  if(!_chatWidgets.contains(bufferId))
+    return;
+
+  ChatWidget *chatWidget = _chatWidgets.take(bufferId);
+  ui.stackedWidget->removeWidget(chatWidget);
+  chatWidget->deleteLater();
 }
 
-BufferId BufferWidget::currentBuffer() const {
-  return _currentBuffer;
+void BufferWidget::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
+  Q_UNUSED(previous);
+  QVariant variant;
+
+  variant = current.data(NetworkModel::BufferIdRole);
+  if(!variant.isValid())
+    return;
+  
+  setCurrentBuffer(qVariantValue<BufferId>(variant));
+  updateNickSelector();
 }
 
 void BufferWidget::setCurrentBuffer(BufferId bufferId) {
@@ -78,34 +146,45 @@ void BufferWidget::setCurrentBuffer(BufferId bufferId) {
 
 }
 
-NetworkId BufferWidget::currentNetwork() const {
-  return _currentNetwork;
+Network *BufferWidget::currentNetwork() const {
+  if(!selectionModel())
+    return 0;
+
+  QVariant variant = selectionModel()->currentIndex().data(NetworkModel::NetworkIdRole);
+  if(!variant.isValid())
+    return 0;
+
+  return Client::network(qVariantValue<NetworkId>(variant));
 }
 
-void BufferWidget::setCurrentNetwork(NetworkId networkId) {
-  Network *net = Client::network(networkId);
+void BufferWidget::updateNickSelector() const {
+  Network *net = currentNetwork();
   if(!net)
     return;
-  _currentNetwork = networkId;
-  
-  ui.ownNick->clear();
-  ui.ownNick->addItem(net->myNick());
-}
 
-void BufferWidget::removeBuffer(BufferId bufferId) {
-  if(!_chatWidgets.contains(bufferId))
+  const Identity *identity = Client::identity(net->identity());
+  if(!identity) {
+    qWarning() << "BufferWidget::setCurrentNetwork(): can't find Identity for Network" << net->networkId();
     return;
+  }
 
-  ChatWidget *chatWidget = _chatWidgets.take(bufferId);
-  ui.stackedWidget->removeWidget(chatWidget);
-  chatWidget->deleteLater();
-}
-
-void BufferWidget::saveState() {
+  int nickIdx;
+  QStringList nicks = identity->nicks();
+  if((nickIdx = nicks.indexOf(net->myNick())) == -1) {
+    nicks.prepend(net->myNick());
+    nickIdx = 0;
+  }
+  
+  ui.ownNick->clear();
+  ui.ownNick->addItems(nicks);
+  ui.ownNick->setCurrentIndex(nickIdx);
 }
 
-QSize BufferWidget::sizeHint() const {
-  return QSize(800,400);
+void BufferWidget::changeNick(const QString &newNick) const {
+  Network *net = currentNetwork();
+  if(!net || net->isMyNick(newNick))
+    return;
+  emit userInput(QString("/nick %1").arg(newNick));
 }
 
 void BufferWidget::enterPressed() {
@@ -117,11 +196,3 @@ void BufferWidget::enterPressed() {
   ui.inputEdit->clear();
 }
 
-
-
-/*
-void BufferWidget::displayMsg(Message msg) {
-  chatWidget->appendMsg(msg);
-}
-*/
-
index b805c66..317d3ee 100644 (file)
 #include "chatview.h"
 #include "types.h"
 
+class Network;
 class ChatView;
 class ChatWidget;
 class LayoutThread;
 
+#include "buffermodel.h"
+#include <QItemSelectionModel>
+
 //! Displays the contents of a Buffer.
 /**
 */
 class BufferWidget : public QWidget {
   Q_OBJECT
 
-  Q_PROPERTY(BufferId currentBuffer READ currentBuffer WRITE setCurrentBuffer);
-  Q_PROPERTY(NetworkId currentNetwork READ currentNetwork WRITE setCurrentNetwork);
-
 public:
   BufferWidget(QWidget *parent = 0);
   virtual ~BufferWidget();
   void init();
 
-  QSize sizeHint() const;
+  inline BufferModel *model() { return _bufferModel; }
+  void setModel(BufferModel *bufferModel);
+
+  inline QItemSelectionModel *selectionModel() const { return _selectionModel; }
+  void setSelectionModel(QItemSelectionModel *selectionModel);
 
+  Network *currentNetwork() const;
+  
 signals:
-  void userInput(QString msg);
+  void userInput(QString msg) const;
   void aboutToClose();
 
-public slots:
-  BufferId currentBuffer() const;
-  void setCurrentBuffer(BufferId bufferId);
-
-  NetworkId currentNetwork() const;
-  void setCurrentNetwork(NetworkId networkId);
-
-  void saveState();
+protected slots:
+//   virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
+//   virtual void commitData(QWidget *editor);
+  virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+//   virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+//   virtual void editorDestroyed(QObject *editor);
+  virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+//   virtual void rowsInserted(const QModelIndex &parent, int start, int end);
+//   virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
 
 private slots:
   void enterPressed();
+  void changeNick(const QString &newNick) const;
   void removeBuffer(BufferId bufferId);
 
+  void setCurrentBuffer(BufferId bufferId);
+  void updateNickSelector() const;
+
 private:
   Ui::BufferWidget ui;
   QHash<BufferId, ChatWidget *> _chatWidgets;
-  BufferId _currentBuffer;
-  NetworkId _currentNetwork;
-};
 
+  QPointer<BufferModel> _bufferModel;
+  QPointer<QItemSelectionModel> _selectionModel;
+};
 
 #endif
index 7e7d61a..56f7d7e 100644 (file)
@@ -128,10 +128,8 @@ void MainWin::init() {
 
 
   // attach the BufferWidget to the PropertyMapper
-  Client::bufferModel()->mapProperty(0, NetworkModel::BufferIdRole, ui.bufferWidget, "currentBuffer");
-  Client::bufferModel()->mapProperty(0, NetworkModel::NetworkIdRole, ui.bufferWidget, "currentNetwork");
-  connect(Client::networkModel(), SIGNAL(bufferAboutToBeRemoved(BufferId)),
-          ui.bufferWidget, SLOT(removeBuffer(BufferId)));
+  ui.bufferWidget->setModel(Client::bufferModel());
+  ui.bufferWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
 
   // attach the NickList to the PropertyMapper
   Client::bufferModel()->mapProperty(0, NetworkModel::BufferIdRole, nickListWidget, "currentBuffer");
@@ -275,7 +273,6 @@ void MainWin::showDebugConsole() {
 void MainWin::closeEvent(QCloseEvent *event)
 {
   //if (userReallyWantsToQuit()) {
-    ui.bufferWidget->saveState();
     UiSettings s;
     s.setValue("MainWinSize", size());
     s.setValue("MainWinPos", pos());
index 41ea4ff..fdd2c68 100644 (file)
@@ -37,6 +37,8 @@ TabCompleter::TabCompleter(InputLine *inputLine_)
 }
 
 void TabCompleter::buildCompletionList() {
+  completionList.clear();
+  nextCompletion = completionList.begin();
   // this is the first time tab is pressed -> build up the completion list and it's iterator
   QModelIndex currentIndex = Client::bufferModel()->currentIndex();
   if(!currentIndex.data(NetworkModel::BufferIdRole).isValid())
@@ -70,7 +72,6 @@ void TabCompleter::buildCompletionList() {
   completionList.sort();
   nextCompletion = completionList.begin();
   lastCompletionLength = tabAbbrev.length();
-  
 }
 
 void TabCompleter::ircUserJoinedOrParted(IrcUser *ircUser) {
index 7f38308..a243e6a 100644 (file)
@@ -4,8 +4,8 @@
 { using namespace Global;
 
   quasselVersion = "0.2.0-pre";
-  quasselDate = "2008-01-21";
-  quasselBuild = 372;
+  quasselDate = "2008-01-22";
+  quasselBuild = 375;
 
   //! Minimum client build number the core needs
   clientBuildNeeded = 358;