Used to be in AliasesModel used by the settingspage, but we also need it for handling
input, so we move it into Client proper. Note that existence of the AliasManager is only
guaranteed as long as Client::isConnected() == true.
#include "buffersettings.h"
#include "buffersyncer.h"
#include "bufferviewconfig.h"
+#include "clientaliasmanager.h"
#include "clientbacklogmanager.h"
#include "clientbufferviewmanager.h"
#include "clientirclisthelper.h"
_networkModel(0),
_bufferModel(0),
_bufferSyncer(0),
+ _aliasManager(0),
_backlogManager(new ClientBacklogManager(this)),
_bufferViewManager(0),
_ircListHelper(new ClientIrcListHelper(this)),
}
}
-/*** ***/
+/*** 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 ***/
connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog()));
connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(createDefaultBufferView()));
+ // 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);
_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();
class NetworkModel;
class BufferModel;
class BufferSyncer;
+class ClientAliasManager;
class ClientBacklogManager;
class ClientBufferViewManager;
class ClientIrcListHelper;
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; }
void requestInitialBacklog();
void createDefaultBufferView();
+ void sendBufferedUserInput();
+
private:
Client(QObject *parent = 0);
virtual ~Client();
NetworkModel * _networkModel;
BufferModel * _bufferModel;
BufferSyncer * _bufferSyncer;
+ ClientAliasManager *_aliasManager;
ClientBacklogManager *_backlogManager;
ClientBufferViewManager *_bufferViewManager;
ClientIrcListHelper *_ircListHelper;
QString _debugLogBuffer;
QTextStream _debugLog;
+ QList<QPair<BufferInfo, QString> > _userInputBuffer;
+
friend class ClientSyncer;
};
#include <QDateTime>
#include "client.h"
+#include "clientaliasmanager.h"
#include "clientuserinputhandler.h"
#include "clientsettings.h"
#include "ircuser.h"
#include "network.h"
ClientUserInputHandler::ClientUserInputHandler(QObject *parent)
-: QObject(parent),
- _initialized(false)
+: QObject(parent)
{
TabCompletionSettings s;
s.notify("CompletionSuffix", this, SLOT(completionSuffixChanged(QVariant)));
completionSuffixChanged(s.completionSuffix());
-
- // we need this signal for future connects to reset the data;
- connect(Client::instance(), SIGNAL(connected()), SLOT(clientConnected()));
- connect(Client::instance(), SIGNAL(disconnected()), SLOT(clientDisconnected()));
- if(Client::isConnected())
- clientConnected();
-}
-
-void ClientUserInputHandler::clientConnected() {
- _aliasManager = ClientAliasManager();
- Client::signalProxy()->synchronize(&_aliasManager);
- connect(&_aliasManager, SIGNAL(initDone()), SLOT(initDone()));
-}
-
-void ClientUserInputHandler::clientDisconnected() {
- // clear alias manager
- _aliasManager = ClientAliasManager();
- _initialized = false;
-}
-
-void ClientUserInputHandler::initDone() {
- _initialized = true;
- for(int i = 0; i < _inputBuffer.count(); i++)
- handleUserInput(_inputBuffer.at(i).first, _inputBuffer.at(i).second);
- _inputBuffer.clear();
}
void ClientUserInputHandler::completionSuffixChanged(const QVariant &v) {
// this would be the place for a client-side hook
void ClientUserInputHandler::handleUserInput(const BufferInfo &bufferInfo, const QString &msg) {
- if(!_initialized) { // aliases not yet synced
- _inputBuffer.append(qMakePair(bufferInfo, msg));
- return;
- }
if(!msg.startsWith('/')) {
if(_nickRx.indexIn(msg) == 0) {
#ifndef CLIENTUSERINPUTHANDLER_H_
#define CLIENTUSERINPUTHANDLER_H_
-#include <QPair>
-
-#include "clientaliasmanager.h"
#include "bufferinfo.h"
class ClientUserInputHandler : public QObject {
void sendInput(const BufferInfo &, const QString &);
private slots:
- void clientConnected();
- void clientDisconnected();
- void initDone();
void completionSuffixChanged(const QVariant &);
+ void handleExec(const BufferInfo &bufferInfo, const QString &execStr);
+
private:
- bool _initialized;
QRegExp _nickRx;
- ClientAliasManager _aliasManager;
- AliasManager::CommandList _inputBuffer;
};
#endif
AliasesModel::AliasesModel(QObject *parent)
: QAbstractItemModel(parent),
- _configChanged(false)
+ _configChanged(false),
+ _modelReady(false)
{
// we need this signal for future connects to reset the data;
connect(Client::instance(), SIGNAL(connected()), this, SLOT(clientConnected()));
connect(Client::instance(), SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
+
if(Client::isConnected())
clientConnected();
else
}
QVariant AliasesModel::data(const QModelIndex &index, int role) const {
+ if(!_modelReady)
+ return QVariant();
+
if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount())
return QVariant();
}
bool AliasesModel::setData(const QModelIndex &index, const QVariant &value, int role) {
+ if(!_modelReady)
+ return false;
+
if(!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() || role != Qt::EditRole)
return false;
}
void AliasesModel::loadDefaults() {
+ if(!_modelReady)
+ return;
+
AliasManager &manager = cloneAliasManager();
if(!manager.isEmpty()) {
QVariant AliasesModel::headerData(int section, Qt::Orientation orientation, int role) const {
QStringList header;
header << tr("Alias")
- << tr("Expansion");
-
+ << tr("Expansion");
+
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
return header[section];
if(_configChanged)
return _clonedAliasManager;
else
- return _aliasManager;
+ return *Client::aliasManager();
}
AliasManager &AliasesModel::aliasManager() {
if(_configChanged)
return _clonedAliasManager;
else
- return _aliasManager;
+ return *Client::aliasManager();
}
AliasManager &AliasesModel::cloneAliasManager() {
if(!_configChanged) {
- _clonedAliasManager = _aliasManager;
+ _clonedAliasManager = *Client::aliasManager();
_configChanged = true;
emit configChanged(true);
}
void AliasesModel::revert() {
if(!_configChanged)
return;
-
+
_configChanged = false;
emit configChanged(false);
reset();
if(!_configChanged)
return;
- _aliasManager.requestUpdate(_clonedAliasManager.toVariantMap());
+ Client::aliasManager()->requestUpdate(_clonedAliasManager.toVariantMap());
revert();
-}
+}
void AliasesModel::initDone() {
reset();
+ _modelReady = true;
emit modelReady(true);
}
void AliasesModel::clientConnected() {
- _aliasManager = ClientAliasManager();
- Client::signalProxy()->synchronize(&_aliasManager);
- connect(&_aliasManager, SIGNAL(initDone()), this, SLOT(initDone()));
- connect(&_aliasManager, SIGNAL(updated(const QVariantMap &)), this, SLOT(revert()));
+ connect(Client::aliasManager(), SIGNAL(updated(QVariantMap)), SLOT(revert()));
+ if(Client::aliasManager()->isInitialized())
+ initDone();
+ else
+ connect(Client::aliasManager(), SIGNAL(initDone()), SLOT(initDone()));
}
void AliasesModel::clientDisconnected() {
- // clear alias managers
- _aliasManager = ClientAliasManager();
+ // clear
_clonedAliasManager = ClientAliasManager();
reset();
+ _modelReady = false;
emit modelReady(false);
}
inline int columnCount(const QModelIndex &parent = QModelIndex()) const { Q_UNUSED(parent) return 2; }
inline bool configChanged() const { return _configChanged; }
+ inline bool isReady() const { return _modelReady; }
public slots:
void newAlias();
void modelReady(bool);
private:
- ClientAliasManager _aliasManager;
ClientAliasManager _clonedAliasManager;
bool _configChanged;
+ bool _modelReady;
const AliasManager &aliasManager() const;
AliasManager &aliasManager();
connect(ui.deleteAliasButton, SIGNAL(clicked()), this, SLOT(deleteSelectedAlias()));
connect(&_aliasesModel, SIGNAL(configChanged(bool)), this, SLOT(setChangedState(bool)));
connect(&_aliasesModel, SIGNAL(modelReady(bool)), this, SLOT(enableDialog(bool)));
+
+ enableDialog(_aliasesModel.isReady());
}
void AliasesSettingsPage::load() {
void AliasesSettingsPage::enableDialog(bool enabled) {
ui.newAliasButton->setEnabled(enabled);
ui.deleteAliasButton->setEnabled(enabled);
+ setEnabled(enabled);
}
void AliasesSettingsPage::deleteSelectedAlias() {