Merge branch 'bufferviewoverlay'
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 24 Mar 2009 16:36:06 +0000 (17:36 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 24 Mar 2009 16:36:06 +0000 (17:36 +0100)
Conflicts:

src/client/client.cpp
src/client/client.h

1  2 
src/client/CMakeLists.txt
src/client/client.cpp
src/client/client.h
src/client/messagemodel.cpp
src/qtui/mainwin.cpp

@@@ -12,8 -12,8 +12,9 @@@ set(SOURCE
      backlogrequester.cpp
      buffermodel.cpp
      buffersettings.cpp
+     bufferviewoverlay.cpp
      client.cpp
 +    clientaliasmanager.cpp
      clientbacklogmanager.cpp
      clientbufferviewconfig.cpp
      clientbufferviewmanager.cpp
@@@ -22,7 -22,6 +23,7 @@@
      clientsettings.cpp
      clientsyncer.cpp
      clientuserinputhandler.cpp
 +    execwrapper.cpp
      irclistmodel.cpp
      messagefilter.cpp
      messagemodel.cpp
@@@ -34,8 -33,8 +35,9 @@@ set(MOC_HDR
      abstractmessageprocessor.h
      abstractui.h
      buffermodel.h
+     bufferviewoverlay.h
      client.h
 +    clientaliasmanager.h
      clientbacklogmanager.h
      clientbufferviewconfig.h
      clientbufferviewmanager.h
@@@ -44,7 -43,6 +46,7 @@@
      clientirclisthelper.h
      clientuserinputhandler.h
      clientsyncer.h
 +    execwrapper.h
      irclistmodel.h
      messagefilter.h
      messagemodel.h
diff --combined src/client/client.cpp
@@@ -27,7 -27,7 +27,8 @@@
  #include "buffersettings.h"
  #include "buffersyncer.h"
  #include "bufferviewconfig.h"
+ #include "bufferviewoverlay.h"
 +#include "clientaliasmanager.h"
  #include "clientbacklogmanager.h"
  #include "clientbufferviewmanager.h"
  #include "clientirclisthelper.h"
@@@ -51,11 -51,6 +52,11 @@@ AccountId Client::_currentCoreAccount 
  
  /*** Initialization/destruction ***/
  
 +bool Client::instanceExists()
 +{
 +  return instanceptr;
 +}
 +
  Client *Client::instance() {
    if(!instanceptr)
      instanceptr = new Client();
@@@ -82,11 -77,11 +83,12 @@@ Client::Client(QObject *parent
      _networkModel(0),
      _bufferModel(0),
      _bufferSyncer(0),
 +    _aliasManager(0),
      _backlogManager(new ClientBacklogManager(this)),
      _bufferViewManager(0),
+     _bufferViewOverlay(new BufferViewOverlay(this)),
      _ircListHelper(new ClientIrcListHelper(this)),
 -    _inputHandler(new ClientUserInputHandler(this)),
 +    _inputHandler(0),
      _messageModel(0),
      _messageProcessor(0),
      _connectedToCore(false),
@@@ -95,6 -90,7 +97,7 @@@
      _debugLog(&_debugLogBuffer)
  {
    _signalProxy->synchronize(_ircListHelper);
+   connect(this, SIGNAL(requestInitialBacklog()), _backlogManager, SLOT(requestInitialBacklog()), Qt::QueuedConnection);
  }
  
  Client::~Client() {
@@@ -111,7 -107,6 +114,7 @@@ void Client::init() 
    _bufferModel = new BufferModel(_networkModel);
    _messageModel = mainUi()->createMessageModel(this);
    _messageProcessor = mainUi()->createMessageProcessor(this);
 +  _inputHandler = new ClientUserInputHandler(this);
  
    SignalProxy *p = signalProxy();
  
@@@ -273,21 -268,9 +276,21 @@@ void Client::coreIdentityRemoved(Identi
    }
  }
  
 -/***  ***/
 +/*** User input handling ***/
 +
  void Client::userInput(const BufferInfo &bufferInfo, const QString &message) {
 -  inputHandler()->handleUserInput(bufferInfo, message);
 +  // we need to make sure that AliasManager is ready before processing input
 +  if(aliasManager() && aliasManager()->isInitialized())
 +    inputHandler()->handleUserInput(bufferInfo, message);
 +  else
 +   instance()-> _userInputBuffer.append(qMakePair(bufferInfo, message));
 +}
 +
 +void Client::sendBufferedUserInput() {
 +  for(int i = 0; i < _userInputBuffer.count(); i++)
 +    userInput(_userInputBuffer.at(i).first, _userInputBuffer.at(i).second);
 +
 +  _userInputBuffer.clear();
  }
  
  /*** core connection stuff ***/
@@@ -313,30 -296,30 +316,36 @@@ void Client::setSyncedToCore() 
    connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString)));
    connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), this, SLOT(buffersPermanentlyMerged(BufferId, BufferId)));
    connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), _messageModel, SLOT(buffersPermanentlyMerged(BufferId, BufferId)));
-   connect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog()));
    connect(networkModel(), SIGNAL(setLastSeenMsg(BufferId, MsgId)), bufferSyncer(), SLOT(requestSetLastSeenMsg(BufferId, const MsgId &)));
    signalProxy()->synchronize(bufferSyncer());
  
    // create a new BufferViewManager
    Q_ASSERT(!_bufferViewManager);
    _bufferViewManager = new ClientBufferViewManager(signalProxy(), this);
-   connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog()));
    connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(createDefaultBufferView()));
+   connect(bufferViewManager(), SIGNAL(viewsInitialized()), this, SLOT(requestInitialBacklogBarrier()));
  
 +  // create AliasManager
 +  Q_ASSERT(!_aliasManager);
 +  _aliasManager = new ClientAliasManager(this);
 +  connect(aliasManager(), SIGNAL(initDone()), SLOT(sendBufferedUserInput()));
 +  signalProxy()->synchronize(aliasManager());
 +
    _syncedToCore = true;
    emit connected();
    emit coreConnectionStateChanged(true);
  }
  
- void Client::requestInitialBacklog() {
-   if(bufferViewManager()->isInitialized() && bufferSyncer()->isInitialized())
-     Client::backlogManager()->requestInitialBacklog();
+ void Client::requestInitialBacklogBarrier() {
+   // usually it _should_ take longer until the bufferViews are initialized, so that's what
+   // triggers this slot. But we have to make sure that we know all buffers yet.
+   // so we check the BufferSyncer and in case it wasn't initialized we wait for that instead
+   if(!bufferSyncer()->isInitialized()) {
+     disconnect(bufferViewManager(), SIGNAL(viewsInitialized()), this, SLOT(requestInitialBacklogBarrier()));
+     connect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(requestInitialBacklogBarrier()));
+     return;
+   }
+   emit requestInitialBacklog();
  }
  
  void Client::createDefaultBufferView() {
@@@ -377,14 -360,6 +386,14 @@@ void Client::disconnectedFromCore() 
      _bufferViewManager = 0;
    }
  
 +  if(_aliasManager) {
 +    _aliasManager->deleteLater();
 +    _aliasManager = 0;
 +  }
 +
 +  // we probably don't want to save pending input for reconnect
 +  _userInputBuffer.clear();
 +
    _messageModel->clear();
    _networkModel->clear();
  
@@@ -501,12 -476,6 +510,12 @@@ void Client::logMessage(QtMsgType type
      Quassel::logFatalMessage(msg);
    } else {
      QString msgString = QString("%1\n").arg(msg);
 +
 +    //Check to see if there is an instance around, else we risk recursions
 +    //when calling instance() and creating new ones.
 +    if (!instanceExists())
 +      return;
 +
      instance()->_debugLog << msgString;
      emit instance()->logUpdated(msgString);
    }
diff --combined src/client/client.h
@@@ -42,7 -42,7 +42,8 @@@ class AbstractUiMsg
  class NetworkModel;
  class BufferModel;
  class BufferSyncer;
+ class BufferViewOverlay;
 +class ClientAliasManager;
  class ClientBacklogManager;
  class ClientBufferViewManager;
  class ClientIrcListHelper;
@@@ -62,7 -62,6 +63,7 @@@ public
      RemoteCore
    };
  
 +  static bool instanceExists();
    static Client *instance();
    static void destroy();
    static void init(AbstractUi *);
    static inline AbstractMessageProcessor *messageProcessor() { return instance()->_messageProcessor; }
    static inline SignalProxy *signalProxy() { return instance()->_signalProxy; }
  
 +  static inline ClientAliasManager *aliasManager() { return instance()->_aliasManager; }
    static inline ClientBacklogManager *backlogManager() { return instance()->_backlogManager; }
    static inline ClientIrcListHelper *ircListHelper() { return instance()->_ircListHelper; }
    static inline ClientBufferViewManager *bufferViewManager() { return instance()->_bufferViewManager; }
+   static inline BufferViewOverlay *bufferViewOverlay() { return instance()->_bufferViewOverlay; }
    static inline ClientUserInputHandler *inputHandler() { return instance()->_inputHandler; }
  
    static AccountId currentCoreAccount();
    static inline void registerClientSyncer(ClientSyncer *syncer) { emit instance()->newClientSyncer(syncer); }
  
  signals:
+   void requestInitialBacklog();
    void requestNetworkStates();
  
    void showConfigWizard(const QVariantMap &coredata);
@@@ -186,11 -186,9 +189,11 @@@ private slots
  
    void setConnectedToCore(AccountId id, QIODevice *socket = 0);
    void setSyncedToCore();
-   void requestInitialBacklog();
+   void requestInitialBacklogBarrier();
    void createDefaultBufferView();
  
 +  void sendBufferedUserInput();
 +
  private:
    Client(QObject *parent = 0);
    virtual ~Client();
    NetworkModel * _networkModel;
    BufferModel * _bufferModel;
    BufferSyncer * _bufferSyncer;
 +  ClientAliasManager *_aliasManager;
    ClientBacklogManager *_backlogManager;
    ClientBufferViewManager *_bufferViewManager;
+   BufferViewOverlay *_bufferViewOverlay;
    ClientIrcListHelper *_ircListHelper;
    ClientUserInputHandler *_inputHandler;
  
    QString _debugLogBuffer;
    QTextStream _debugLog;
  
 +  QList<QPair<BufferInfo, QString> > _userInputBuffer;
 +
    friend class ClientSyncer;
  };
  
@@@ -219,7 -219,7 +219,7 @@@ int MessageModel::insertMessagesGracefu
      while(iter != msglist.constBegin()) {
        iter--;
  
-       if(!fastForward && (*iter).msgId() < minId)
+       if(!fastForward && (*iter).msgId() <= minId)
        break;
        processedMsgs++;
  
      }
    } else {
      while(iter != msglist.constEnd()) {
-       if(!fastForward && (*iter).msgId() < minId)
+       if(!fastForward && (*iter).msgId() <= minId)
        break;
        processedMsgs++;
  
@@@ -348,18 -348,6 +348,18 @@@ void MessageModel::changeOfDay() 
    _nextDayChange = _nextDayChange.addSecs(86400);
  }
  
 +void MessageModel::insertErrorMessage(BufferInfo bufferInfo, const QString &errorString) {
 +  int idx = messageCount();
 +  beginInsertRows(QModelIndex(), idx, idx);
 +  Message msg(bufferInfo, Message::Error, errorString);
 +  if(!messagesIsEmpty())
 +    msg.setMsgId(messageItemAt(idx-1)->msgId());
 +  else
 +    msg.setMsgId(0);
 +  insertMessage__(idx, msg);
 +  endInsertRows();
 +}
 +
  void MessageModel::requestBacklog(BufferId bufferId) {
    if(_messagesWaiting.contains(bufferId))
      return;
diff --combined src/qtui/mainwin.cpp
@@@ -35,6 -35,8 +35,8 @@@
  #include "actioncollection.h"
  #include "buffermodel.h"
  #include "bufferview.h"
+ #include "bufferviewoverlay.h"
+ #include "bufferviewoverlayfilter.h"
  #include "bufferwidget.h"
  #include "channellistdlg.h"
  #include "chatlinemodel.h"
@@@ -238,7 -240,7 +240,7 @@@ void MainWin::setupActions() 
    connect(lockAct, SIGNAL(toggled(bool)), SLOT(on_actionLockLayout_toggled(bool)));
  
    coll->addAction("ToggleSearchBar", new Action(SmallIcon("edit-find"), tr("Show &Search Bar"), coll,
 -                                              0, 0, tr("Ctrl+F")))->setCheckable(true);
 +                                              0, 0, QKeySequence::Find))->setCheckable(true);
    coll->addAction("ShowAwayLog", new Action(tr("Show Away Log"), coll,
                                            this, SLOT(showAwayLog())));
    coll->addAction("ToggleStatusBar", new Action(tr("Show Status &Bar"), coll,
                                           qApp, SLOT(aboutQt())));
    coll->addAction("DebugNetworkModel", new Action(SmallIcon("tools-report-bug"), tr("Debug &NetworkModel"), coll,
                                         this, SLOT(on_actionDebugNetworkModel_triggered())));
+   coll->addAction("DebugBufferViewOverlay", new Action(SmallIcon("tools-report-bug"), tr("Debug &BufferViewOverlay"), coll,
+                                        this, SLOT(on_actionDebugBufferViewOverlay_triggered())));
    coll->addAction("DebugMessageModel", new Action(SmallIcon("tools-report-bug"), tr("Debug &MessageModel"), coll,
                                         this, SLOT(on_actionDebugMessageModel_triggered())));
    coll->addAction("DebugLog", new Action(SmallIcon("tools-report-bug"), tr("Debug &Log"), coll,
@@@ -315,6 -319,7 +319,7 @@@ void MainWin::setupMenus() 
    _helpMenu->addSeparator();
    _helpDebugMenu = _helpMenu->addMenu(SmallIcon("tools-report-bug"), tr("Debug"));
    _helpDebugMenu->addAction(coll->action("DebugNetworkModel"));
+   _helpDebugMenu->addAction(coll->action("DebugBufferViewOverlay"));
    _helpDebugMenu->addAction(coll->action("DebugMessageModel"));
    _helpDebugMenu->addAction(coll->action("DebugLog"));
  }
@@@ -351,6 -356,7 +356,7 @@@ void MainWin::addBufferView(ClientBuffe
    addDockWidget(Qt::LeftDockWidgetArea, dock);
    _bufferViewsMenu->addAction(dock->toggleViewAction());
  
+   connect(dock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(bufferViewToggled(bool)));
    _bufferViews.append(dock);
  }
  
@@@ -370,6 -376,35 +376,35 @@@ void MainWin::removeBufferView(int buff
    }
  }
  
+ void MainWin::bufferViewToggled(bool enabled) {
+   QAction *action = qobject_cast<QAction *>(sender());
+   Q_ASSERT(action);
+   BufferViewDock *dock = qobject_cast<BufferViewDock *>(action->parent());
+   Q_ASSERT(dock);
+   if(enabled) {
+     Client::bufferViewOverlay()->addView(dock->bufferViewId());
+     BufferViewConfig *config = dock->config();
+     if(config && config->isInitialized()) {
+       BufferIdList buffers;
+       if(config->networkId().isValid()) {
+         foreach(BufferId bufferId, config->bufferList()) {
+           if(Client::networkModel()->networkId(bufferId) == config->networkId())
+             buffers << bufferId;
+         }
+         foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) {
+           if(Client::networkModel()->networkId(bufferId) == config->networkId())
+             buffers << bufferId;
+         }
+       } else {
+         buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers());
+       }
+       Client::backlogManager()->checkForBacklog(buffers);
+     }
+   } else {
+     Client::bufferViewOverlay()->removeView(dock->bufferViewId());
+   }
+ }
  BufferView *MainWin::allBuffersView() const {
    // "All Buffers" is always the first dock created
    if(_bufferViews.count() > 0)
@@@ -897,6 -932,20 +932,20 @@@ void MainWin::on_actionDebugNetworkMode
    view->show();
  }
  
+ void MainWin::on_actionDebugBufferViewOverlay_triggered() {
+   QTreeView *view = new QTreeView;
+   view->setAttribute(Qt::WA_DeleteOnClose);
+   view->setWindowTitle("Debug BufferViewOverlay View");
+   BufferViewOverlayFilter *filter = new BufferViewOverlayFilter(Client::bufferModel(), Client::bufferViewOverlay());
+   filter->setParent(view);
+   view->setModel(filter);
+   view->setColumnWidth(0, 250);
+   view->setColumnWidth(1, 250);
+   view->setColumnWidth(2, 80);
+   view->resize(610, 300);
+   view->show();
+ }
  void MainWin::on_actionDebugMessageModel_triggered() {
    QTableView *view = new QTableView(0);
    DebugMessageModelFilter *filter = new DebugMessageModelFilter(view);