From: Marcus Eggenberger Date: Sun, 13 Apr 2008 19:59:22 +0000 (+0000) Subject: Introducing the all-new all-fancy bufferviews. X-Git-Tag: 0.2.0-beta1~57 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=f2e4609f070221a010eef8be98524c5ce88d228b Introducing the all-new all-fancy bufferviews. If you notice any strange behaviour, please let me know. Breaking protocol once again --- diff --git a/src/client/client.cpp b/src/client/client.cpp index c2cbb2f1..5e472a10 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -83,6 +83,7 @@ Client::~Client() { void Client::init() { _currentCoreAccount = 0; _networkModel = new NetworkModel(this); + connect(this, SIGNAL(bufferUpdated(BufferInfo)), _networkModel, SLOT(bufferUpdated(BufferInfo))); connect(this, SIGNAL(networkRemoved(NetworkId)), @@ -325,12 +326,12 @@ void Client::setSecuredConnection() { void Client::disconnectFromCore() { if(!isConnected()) return; + _connectedToCore = false; if(socket) { socket->close(); socket->deleteLater(); } - _connectedToCore = false; _syncedToCore = false; setCurrentCoreAccount(0); emit disconnected(); @@ -346,7 +347,7 @@ void Client::disconnectFromCore() { _bufferViewManager->deleteLater(); _bufferViewManager = 0; } - + _networkModel->clear(); QHash::iterator bufferIter = _buffers.begin(); diff --git a/src/client/networkmodel.cpp b/src/client/networkmodel.cpp index 713198aa..9a16ac17 100644 --- a/src/client/networkmodel.cpp +++ b/src/client/networkmodel.cpp @@ -414,7 +414,9 @@ void NetworkItem::attachNetwork(Network *network) { this, SLOT(attachIrcChannel(QString))); connect(network, SIGNAL(connectedSet(bool)), this, SIGNAL(dataChanged())); - + connect(network, SIGNAL(destroyed()), + this, SIGNAL(dataChanged())); + emit dataChanged(); } diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp index 65310a62..9a919803 100644 --- a/src/client/treemodel.cpp +++ b/src/client/treemodel.cpp @@ -147,8 +147,11 @@ AbstractTreeItem *AbstractTreeItem::childById(const quint64 &id) const { return 0; } -int AbstractTreeItem::childCount() const { - return _childItems.count(); +int AbstractTreeItem::childCount(int column) const { + if(column > 0) + return 0; + else + return _childItems.count(); } int AbstractTreeItem::row() const { @@ -293,6 +296,8 @@ TreeModel::TreeModel(const QList &data, QObject *parent) this, SLOT(debug_rowsInserted(const QModelIndex &, int, int))); connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(debug_rowsRemoved(const QModelIndex &, int, int))); + connect(this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(debug_dataChanged(const QModelIndex &, const QModelIndex &))); } } @@ -370,27 +375,23 @@ int TreeModel::rowCount(const QModelIndex &parent) const { else parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); + return parentItem->childCount(parent.column()); } int TreeModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) + return rootItem->columnCount(); // since there the Qt Views don't draw more columns than the header has columns // we can be lazy and simply return the count of header columns // actually this gives us more freedom cause we don't have to ensure that a rows parent // has equal or more columns than that row - -// if(parent.isValid()) { -// AbstractTreeItem *child; -// if(child = static_cast(parent.internalPointer())->child(parent.column(), parent.row())) -// return child->columnCount(); -// else -// return static_cast(parent.internalPointer())->columnCount(); -// } else { -// return rootItem->columnCount(); -// } - return rootItem->columnCount(); +// AbstractTreeItem *parentItem; +// if(!parent.isValid()) +// parentItem = rootItem; +// else +// parentItem = static_cast(parent.internalPointer()); +// return parentItem->columnCount(); } QVariant TreeModel::data(const QModelIndex &index, int role) const { @@ -398,6 +399,9 @@ QVariant TreeModel::data(const QModelIndex &index, int role) const { return QVariant(); AbstractTreeItem *item = static_cast(index.internalPointer()); + if(role == Qt::DisplayRole && !item->data(index.column(), role).isValid()) { + qDebug() << item->data(0, role) << item->columnCount(); + } return item->data(index.column(), role); } @@ -410,12 +414,12 @@ bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int rol } Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const { - AbstractTreeItem *item; - if(!index.isValid()) - item = rootItem; - else - item = static_cast(index.internalPointer()); - return item->flags(); + if(!index.isValid()) { + return rootItem->flags() & Qt::ItemIsDropEnabled; + } else { + AbstractTreeItem *item = static_cast(index.internalPointer()); + return item->flags(); + } } QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -498,29 +502,37 @@ void TreeModel::beginRemoveChilds(int firstRow, int lastRow) { qWarning() << "TreeModel::beginRemoveChilds(): cannot append Childs to unknown parent"; return; } + + for(int i = firstRow; i <= lastRow; i++) { + disconnect(parentItem->child(i), 0, this, 0); + } + + // consitency checks QModelIndex parent = indexByItem(parentItem); Q_ASSERT(firstRow <= lastRow); Q_ASSERT(parentItem->childCount() > lastRow); Q_ASSERT(!_aboutToRemoveOrInsert); - _aboutToRemoveOrInsert = true; _childStatus = ChildStatus(parent, rowCount(parent), firstRow, lastRow); + beginRemoveRows(parent, firstRow, lastRow); } void TreeModel::endRemoveChilds() { AbstractTreeItem *parentItem = qobject_cast(sender()); if(!parentItem) { - qWarning() << "TreeModel::endRemoveChilds(): cannot append Childs to unknown parent"; + qWarning() << "TreeModel::endRemoveChilds(): cannot remove Childs from unknown parent"; return; } + + // concistency checks Q_ASSERT(_aboutToRemoveOrInsert); ChildStatus cs = _childStatus; QModelIndex parent = indexByItem(parentItem); Q_ASSERT(cs.parent == parent); Q_ASSERT(rowCount(parent) == cs.childCount - cs.end + cs.start - 1); - _aboutToRemoveOrInsert = false; + endRemoveRows(); } @@ -537,7 +549,7 @@ void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, parentItem = static_cast(parent.internalPointer()); if(!parentItem) parentItem = rootItem; - qDebug() << "#" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsAboutToBeRemoved" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; QModelIndex child; AbstractTreeItem *childItem; @@ -554,7 +566,7 @@ void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end parentItem = static_cast(parent.internalPointer()); if(!parentItem) parentItem = rootItem; - qDebug() << "#" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsInserted:" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; QModelIndex child; AbstractTreeItem *childItem; @@ -569,3 +581,15 @@ void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end void TreeModel::debug_rowsRemoved(const QModelIndex &parent, int start, int end) { qDebug() << "debug_rowsRemoved" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; } + +void TreeModel::debug_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { + qDebug() << "debug_dataChanged" << topLeft << bottomRight; + QStringList displayData; + for(int row = topLeft.row(); row <= bottomRight.row(); row++) { + displayData = QStringList(); + for(int column = topLeft.column(); column <= bottomRight.column(); column++) { + displayData << data(topLeft.sibling(row, column), Qt::DisplayRole).toString(); + } + qDebug() << " row:" << row << displayData; + } +} diff --git a/src/client/treemodel.h b/src/client/treemodel.h index 599956e2..8caffdd5 100644 --- a/src/client/treemodel.h +++ b/src/client/treemodel.h @@ -52,7 +52,7 @@ public: AbstractTreeItem *child(int row) const; AbstractTreeItem *childById(const quint64 &id) const; - int childCount() const; + int childCount(int column = 0) const; virtual int columnCount() const = 0; @@ -188,6 +188,7 @@ private slots: void debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); void debug_rowsInserted(const QModelIndex &parent, int start, int end); void debug_rowsRemoved(const QModelIndex &parent, int start, int end); + void debug_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); }; #endif diff --git a/src/common/bufferviewconfig.cpp b/src/common/bufferviewconfig.cpp index 7a893b3e..2ffb3a7a 100644 --- a/src/common/bufferviewconfig.cpp +++ b/src/common/bufferviewconfig.cpp @@ -20,10 +20,25 @@ #include "bufferviewconfig.h" +#include "bufferinfo.h" + BufferViewConfig::BufferViewConfig(int bufferViewId, QObject *parent) + : SyncableObject(parent), + _bufferViewId(bufferViewId), + _addNewBuffersAutomatically(true), + _sortAlphabetically(true), + _hideInactiveBuffers(false), + _allowedBufferTypes(BufferInfo::StatusBuffer | BufferInfo::ChannelBuffer | BufferInfo::QueryBuffer | BufferInfo::GroupBuffer), + _minimumActivity(0) +{ + setObjectName(QString::number(bufferViewId)); +} + +BufferViewConfig::BufferViewConfig(int bufferViewId, const QVariantMap &properties, QObject *parent) : SyncableObject(parent), _bufferViewId(bufferViewId) { + fromVariantMap(properties); setObjectName(QString::number(bufferViewId)); } @@ -58,3 +73,85 @@ void BufferViewConfig::setSortAlphabetically(bool sortAlphabetically) { _sortAlphabetically = sortAlphabetically; emit sortAlphabeticallySet(sortAlphabetically); } + +void BufferViewConfig::setAllowedBufferTypes(int bufferTypes) { + if(_allowedBufferTypes == bufferTypes) + return; + + _allowedBufferTypes = bufferTypes; + emit allowedBufferTypesSet(bufferTypes); +} + +void BufferViewConfig::setMinimumActivity(int activity) { + if(_minimumActivity == activity) + return; + + _minimumActivity = activity; + emit minimumActivitySet(activity); +} + +void BufferViewConfig::setHideInactiveBuffers(bool hideInactiveBuffers) { + if(_hideInactiveBuffers == hideInactiveBuffers) + return; + + _hideInactiveBuffers = hideInactiveBuffers; + emit hideInactiveBuffersSet(hideInactiveBuffers); +} + +QVariantList BufferViewConfig::initBufferList() const { + QVariantList buffers; + + foreach(BufferId bufferId, _buffers) { + buffers << qVariantFromValue(bufferId); + } + + return buffers; +} + +void BufferViewConfig::initSetBufferList(const QVariantList &buffers) { + _buffers.clear(); + + foreach(QVariant buffer, buffers) { + _buffers << buffer.value(); + } + + emit bufferListSet(); +} + +void BufferViewConfig::initSetBufferList(const QList &buffers) { + _buffers.clear(); + + foreach(BufferId bufferId, buffers) { + _buffers << bufferId; + } + + emit bufferListSet(); +} + +void BufferViewConfig::addBuffer(const BufferId &bufferId, int pos) { + qDebug() << "addBuffer" << bufferId; + if(_buffers.contains(bufferId)) + return; + + _buffers.insert(pos, bufferId); + emit bufferAdded(bufferId, pos); +} + +void BufferViewConfig::moveBuffer(const BufferId &bufferId, int pos) { + qDebug() << "moveeBuffer" << bufferId; + if(!_buffers.contains(bufferId)) + return; + + qDebug() << "lala" << bufferId << pos; + _buffers.move(_buffers.indexOf(bufferId), pos); + emit bufferMoved(bufferId, pos); +} + +void BufferViewConfig::removeBuffer(const BufferId &bufferId) { + qDebug() << "removeBuffer" << bufferId; + if(!_buffers.contains(bufferId)) + return; + + _buffers.removeAt(_buffers.indexOf(bufferId)); + emit bufferRemoved(bufferId); +} diff --git a/src/common/bufferviewconfig.h b/src/common/bufferviewconfig.h index d728df56..2e2a9aa6 100644 --- a/src/common/bufferviewconfig.h +++ b/src/common/bufferviewconfig.h @@ -31,9 +31,14 @@ class BufferViewConfig : public SyncableObject { Q_PROPERTY(NetworkId networkId READ networkId WRITE setNetworkId) Q_PROPERTY(bool addNewBuffersAutomatically READ addNewBuffersAutomatically WRITE setAddNewBuffersAutomatically) Q_PROPERTY(bool sortAlphabetically READ sortAlphabetically WRITE setSortAlphabetically) + Q_PROPERTY(bool hideInactiveBuffers READ hideInactiveBuffers WRITE setHideInactiveBuffers) + Q_PROPERTY(int allowedBufferTypes READ allowedBufferTypes WRITE setAllowedBufferTypes) + Q_PROPERTY(int minimumActivity READ minimumActivity WRITE setMinimumActivity) public: BufferViewConfig(int bufferViewId, QObject *parent = 0); + BufferViewConfig(int bufferViewId, const QVariantMap &properties, QObject *parent = 0); + public slots: inline int bufferViewId() const { return _bufferViewId; } @@ -50,14 +55,46 @@ public slots: inline bool sortAlphabetically() const { return _sortAlphabetically; } void setSortAlphabetically(bool sortAlphabetically); + inline int allowedBufferTypes() const { return _allowedBufferTypes; } + void setAllowedBufferTypes(int bufferTypes); + + inline int minimumActivity() const { return _minimumActivity; } + void setMinimumActivity(int activity); + + inline bool hideInactiveBuffers() const { return _hideInactiveBuffers; } + void setHideInactiveBuffers(bool hideInactiveBuffers); + virtual inline void requestSetBufferViewName(const QString &bufferViewName) { emit setBufferViewNameRequested(bufferViewName); } + const QList &bufferList() const { return _buffers; } + QVariantList initBufferList() const; + void initSetBufferList(const QVariantList &buffers); + void initSetBufferList(const QList &buffers); + + void addBuffer(const BufferId &bufferId, int pos); + virtual inline void requestAddBuffer(const BufferId &bufferId, int pos) { emit addBufferRequested(bufferId, pos); } + void moveBuffer(const BufferId &bufferId, int pos); + virtual inline void requestMoveBuffer(const BufferId &bufferId, int pos) { emit moveBufferRequested(bufferId, pos); } + void removeBuffer(const BufferId &bufferId); + virtual inline void requestRemoveBuffer(const BufferId &bufferId) { emit removeBufferRequested(bufferId); } + signals: void bufferViewNameSet(const QString &bufferViewName); void networkIdSet(const NetworkId &networkId); void addNewBuffersAutomaticallySet(bool addNewBuffersAutomatically); void sortAlphabeticallySet(bool sortAlphabetically); + void allowedBufferTypesSet(int allowedBufferTypes); + void minimumActivitySet(int activity); + void hideInactiveBuffersSet(bool hideInactiveBuffers); + void bufferListSet(); + void bufferAdded(const BufferId &bufferId, int pos); + void addBufferRequested(const BufferId &bufferId, int pos); + void bufferMoved(const BufferId &bufferId, int pos); + void moveBufferRequested(const BufferId &bufferId, int pos); + void bufferRemoved(const BufferId &bufferId); + void removeBufferRequested(const BufferId &bufferId); + void setBufferViewNameRequested(const QString &bufferViewName); private: @@ -66,6 +103,10 @@ private: NetworkId _networkId; bool _addNewBuffersAutomatically; bool _sortAlphabetically; + bool _hideInactiveBuffers; + int _allowedBufferTypes; + int _minimumActivity; + QList _buffers; }; #endif // BUFFERVIEWCONFIG_H diff --git a/src/common/bufferviewmanager.cpp b/src/common/bufferviewmanager.cpp index 7ab9831f..10469293 100644 --- a/src/common/bufferviewmanager.cpp +++ b/src/common/bufferviewmanager.cpp @@ -53,6 +53,15 @@ void BufferViewManager::addBufferViewConfig(int bufferViewConfigId) { addBufferViewConfig(new BufferViewConfig(bufferViewConfigId, this)); } +void BufferViewManager::deleteBufferViewConfig(int bufferViewConfigId) { + if(!_bufferViewConfigs.contains(bufferViewConfigId)) + return; + + _bufferViewConfigs[bufferViewConfigId]->deleteLater(); + _bufferViewConfigs.remove(bufferViewConfigId); + emit bufferViewConfigDeleted(bufferViewConfigId); +} + QVariantList BufferViewManager::initBufferViewIds() const { QVariantList bufferViewIds; BufferViewConfigHash::const_iterator iter = _bufferViewConfigs.constBegin(); diff --git a/src/common/bufferviewmanager.h b/src/common/bufferviewmanager.h index 143b4000..8aef3da5 100644 --- a/src/common/bufferviewmanager.h +++ b/src/common/bufferviewmanager.h @@ -43,14 +43,23 @@ public slots: void addBufferViewConfig(int bufferViewConfigId); inline void newBufferViewConfig(int bufferViewConfigId) { addBufferViewConfig(bufferViewConfigId); } + void deleteBufferViewConfig(int bufferViewConfigId); + QVariantList initBufferViewIds() const; void initSetBufferViewIds(const QVariantList bufferViewIds); - virtual inline void requestCreateBufferView(const QString &bufferViewName) { emit createBufferViewRequested(bufferViewName); } + virtual inline void requestCreateBufferView(const QVariantMap &properties) { emit createBufferViewRequested(properties); } + virtual inline void requestCreateBufferViews(const QVariantList &properties) { emit createBufferViewsRequested(properties); } + virtual inline void requestDeleteBufferView(int bufferViewId) { emit deleteBufferViewRequested(bufferViewId); } + virtual inline void requestDeleteBufferViews(const QVariantList &bufferViews) { emit deleteBufferViewsRequested(bufferViews); } signals: void bufferViewConfigAdded(int bufferViewConfigId); - void createBufferViewRequested(const QString &bufferViewName); + void bufferViewConfigDeleted(int bufferViewConfigId); + void createBufferViewRequested(const QVariantMap &properties); + void createBufferViewsRequested(const QVariantList &properties); + void deleteBufferViewRequested(int bufferViewId); + void deleteBufferViewsRequested(const QVariantList &bufferViews); protected: typedef QHash BufferViewConfigHash; diff --git a/src/common/syncableobject.cpp b/src/common/syncableobject.cpp index 781dd151..426bc86c 100644 --- a/src/common/syncableobject.cpp +++ b/src/common/syncableobject.cpp @@ -27,13 +27,18 @@ #include "signalproxy.h" #include "util.h" -SyncableObject::SyncableObject(QObject *parent) : QObject(parent) { - _initialized = false; +SyncableObject::SyncableObject(QObject *parent) + : QObject(parent), + _initialized(false), + _allowClientUpdates(false) +{ } -SyncableObject::SyncableObject(const SyncableObject &other, QObject *parent) : QObject(parent) { - _initialized = other._initialized; - +SyncableObject::SyncableObject(const SyncableObject &other, QObject *parent) + : QObject(parent), + _initialized(other._initialized), + _allowClientUpdates(false) +{ } bool SyncableObject::isInitialized() const { @@ -51,9 +56,14 @@ QVariantMap SyncableObject::toVariantMap() { const QMetaObject* meta = metaObject(); // we collect data from properties + QMetaProperty prop; + QString propName; for(int i = 0; i < meta->propertyCount(); i++) { - QMetaProperty prop = meta->property(i); - properties[QString(prop.name())] = prop.read(this); + prop = meta->property(i); + propName = QString(prop.name()); + if(propName == "objectName") + continue; + properties[propName] = prop.read(this); } // ...as well as methods, which have names starting with "init" @@ -84,14 +94,20 @@ void SyncableObject::fromVariantMap(const QVariantMap &properties) { const QMetaObject *meta = metaObject(); QVariantMap::const_iterator iterator = properties.constBegin(); + QString propName; while(iterator != properties.constEnd()) { - QString name = iterator.key(); - int propertyIndex = meta->indexOfProperty(name.toAscii()); + propName = iterator.key(); + if(propName == "objectName") { + iterator++; + continue; + } + + int propertyIndex = meta->indexOfProperty(propName.toAscii()); if(propertyIndex == -1 || !meta->property(propertyIndex).isWritable()) - setInitValue(name, iterator.value()); + setInitValue(propName, iterator.value()); else - setProperty(name.toAscii(), iterator.value()); + setProperty(propName.toAscii(), iterator.value()); // qDebug() << "<<< SYNC:" << name << iterator.value(); iterator++; } @@ -111,3 +127,15 @@ void SyncableObject::renameObject(const QString &newName) { emit objectRenamed(newName, oldName); } } + +void SyncableObject::update(const QVariantMap &properties) { + fromVariantMap(properties); + emit updated(properties); +} + +void SyncableObject::requestUpdate(const QVariantMap &properties) { + if(allowClientUpdates()) { + update(properties); + } + emit updateRequested(properties); +} diff --git a/src/common/syncableobject.h b/src/common/syncableobject.h index 388ed90a..61915cbb 100644 --- a/src/common/syncableobject.h +++ b/src/common/syncableobject.h @@ -49,27 +49,35 @@ public: //! Initialize the object's state from a given QVariantMap. /** \see toVariantMap() for important information concerning this method. */ - virtual void fromVariantMap(const QVariantMap &map); + virtual void fromVariantMap(const QVariantMap &properties); virtual bool isInitialized() const; virtual const QMetaObject *syncMetaObject() const { return metaObject(); }; + inline void setAllowClientUpdates(bool allow) { _allowClientUpdates = allow; } + inline bool allowClientUpdates() const { return _allowClientUpdates; } + public slots: virtual void setInitialized(); + void requestUpdate(const QVariantMap &properties); + void update(const QVariantMap &properties); protected: void renameObject(const QString &newName); - + signals: void initDone(); void updatedRemotely(); + void updated(const QVariantMap &properties); + void updateRequested(const QVariantMap &properties); void objectRenamed(QString newName, QString oldName); private: bool setInitValue(const QString &property, const QVariant &value); bool _initialized; + bool _allowClientUpdates; }; diff --git a/src/core/SQL/SQLite/10/setup_999_version.sql b/src/core/SQL/SQLite/10/setup_999_version.sql deleted file mode 100644 index 205c878c..00000000 --- a/src/core/SQL/SQLite/10/setup_999_version.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO coreinfo (key, value) VALUES ('schemaversion', 10) diff --git a/src/core/SQL/SQLite/10/delete_backlog_by_uid.sql b/src/core/SQL/SQLite/11/delete_backlog_by_uid.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_backlog_by_uid.sql rename to src/core/SQL/SQLite/11/delete_backlog_by_uid.sql diff --git a/src/core/SQL/SQLite/10/delete_backlog_for_buffer.sql b/src/core/SQL/SQLite/11/delete_backlog_for_buffer.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_backlog_for_buffer.sql rename to src/core/SQL/SQLite/11/delete_backlog_for_buffer.sql diff --git a/src/core/SQL/SQLite/10/delete_backlog_for_network.sql b/src/core/SQL/SQLite/11/delete_backlog_for_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_backlog_for_network.sql rename to src/core/SQL/SQLite/11/delete_backlog_for_network.sql diff --git a/src/core/SQL/SQLite/10/delete_buffer_for_bufferid.sql b/src/core/SQL/SQLite/11/delete_buffer_for_bufferid.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_buffer_for_bufferid.sql rename to src/core/SQL/SQLite/11/delete_buffer_for_bufferid.sql diff --git a/src/core/SQL/SQLite/10/delete_buffers_by_uid.sql b/src/core/SQL/SQLite/11/delete_buffers_by_uid.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_buffers_by_uid.sql rename to src/core/SQL/SQLite/11/delete_buffers_by_uid.sql diff --git a/src/core/SQL/SQLite/10/delete_buffers_for_network.sql b/src/core/SQL/SQLite/11/delete_buffers_for_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_buffers_for_network.sql rename to src/core/SQL/SQLite/11/delete_buffers_for_network.sql diff --git a/src/core/SQL/SQLite/10/delete_ircservers_for_network.sql b/src/core/SQL/SQLite/11/delete_ircservers_for_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_ircservers_for_network.sql rename to src/core/SQL/SQLite/11/delete_ircservers_for_network.sql diff --git a/src/core/SQL/SQLite/10/delete_network.sql b/src/core/SQL/SQLite/11/delete_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_network.sql rename to src/core/SQL/SQLite/11/delete_network.sql diff --git a/src/core/SQL/SQLite/10/delete_networks_by_uid.sql b/src/core/SQL/SQLite/11/delete_networks_by_uid.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_networks_by_uid.sql rename to src/core/SQL/SQLite/11/delete_networks_by_uid.sql diff --git a/src/core/SQL/SQLite/10/delete_quasseluser.sql b/src/core/SQL/SQLite/11/delete_quasseluser.sql similarity index 100% rename from src/core/SQL/SQLite/10/delete_quasseluser.sql rename to src/core/SQL/SQLite/11/delete_quasseluser.sql diff --git a/src/core/SQL/SQLite/10/insert_buffer.sql b/src/core/SQL/SQLite/11/insert_buffer.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_buffer.sql rename to src/core/SQL/SQLite/11/insert_buffer.sql diff --git a/src/core/SQL/SQLite/10/insert_message.sql b/src/core/SQL/SQLite/11/insert_message.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_message.sql rename to src/core/SQL/SQLite/11/insert_message.sql diff --git a/src/core/SQL/SQLite/10/insert_network.sql b/src/core/SQL/SQLite/11/insert_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_network.sql rename to src/core/SQL/SQLite/11/insert_network.sql diff --git a/src/core/SQL/SQLite/10/insert_quasseluser.sql b/src/core/SQL/SQLite/11/insert_quasseluser.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_quasseluser.sql rename to src/core/SQL/SQLite/11/insert_quasseluser.sql diff --git a/src/core/SQL/SQLite/10/insert_sender.sql b/src/core/SQL/SQLite/11/insert_sender.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_sender.sql rename to src/core/SQL/SQLite/11/insert_sender.sql diff --git a/src/core/SQL/SQLite/10/insert_server.sql b/src/core/SQL/SQLite/11/insert_server.sql similarity index 100% rename from src/core/SQL/SQLite/10/insert_server.sql rename to src/core/SQL/SQLite/11/insert_server.sql diff --git a/src/core/SQL/SQLite/11/insert_user_setting.sql b/src/core/SQL/SQLite/11/insert_user_setting.sql new file mode 100644 index 00000000..f85d340b --- /dev/null +++ b/src/core/SQL/SQLite/11/insert_user_setting.sql @@ -0,0 +1,2 @@ +INSERT INTO user_setting (userid, settingname, settingvalue) +VALUES (:userid, :settingname, :settingvalue) diff --git a/src/core/SQL/SQLite/10/select_authuser.sql b/src/core/SQL/SQLite/11/select_authuser.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_authuser.sql rename to src/core/SQL/SQLite/11/select_authuser.sql diff --git a/src/core/SQL/SQLite/10/select_bufferByName.sql b/src/core/SQL/SQLite/11/select_bufferByName.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_bufferByName.sql rename to src/core/SQL/SQLite/11/select_bufferByName.sql diff --git a/src/core/SQL/SQLite/10/select_bufferExists.sql b/src/core/SQL/SQLite/11/select_bufferExists.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_bufferExists.sql rename to src/core/SQL/SQLite/11/select_bufferExists.sql diff --git a/src/core/SQL/SQLite/10/select_buffer_by_id.sql b/src/core/SQL/SQLite/11/select_buffer_by_id.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_buffer_by_id.sql rename to src/core/SQL/SQLite/11/select_buffer_by_id.sql diff --git a/src/core/SQL/SQLite/10/select_buffer_lastseen_messages.sql b/src/core/SQL/SQLite/11/select_buffer_lastseen_messages.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_buffer_lastseen_messages.sql rename to src/core/SQL/SQLite/11/select_buffer_lastseen_messages.sql diff --git a/src/core/SQL/SQLite/10/select_buffers.sql b/src/core/SQL/SQLite/11/select_buffers.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_buffers.sql rename to src/core/SQL/SQLite/11/select_buffers.sql diff --git a/src/core/SQL/SQLite/10/select_connected_networks.sql b/src/core/SQL/SQLite/11/select_connected_networks.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_connected_networks.sql rename to src/core/SQL/SQLite/11/select_connected_networks.sql diff --git a/src/core/SQL/SQLite/10/select_messageRange.sql b/src/core/SQL/SQLite/11/select_messageRange.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_messageRange.sql rename to src/core/SQL/SQLite/11/select_messageRange.sql diff --git a/src/core/SQL/SQLite/10/select_messages.sql b/src/core/SQL/SQLite/11/select_messages.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_messages.sql rename to src/core/SQL/SQLite/11/select_messages.sql diff --git a/src/core/SQL/SQLite/10/select_messagesOffset.sql b/src/core/SQL/SQLite/11/select_messagesOffset.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_messagesOffset.sql rename to src/core/SQL/SQLite/11/select_messagesOffset.sql diff --git a/src/core/SQL/SQLite/10/select_messagesSince.sql b/src/core/SQL/SQLite/11/select_messagesSince.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_messagesSince.sql rename to src/core/SQL/SQLite/11/select_messagesSince.sql diff --git a/src/core/SQL/SQLite/10/select_messagesSinceOffset.sql b/src/core/SQL/SQLite/11/select_messagesSinceOffset.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_messagesSinceOffset.sql rename to src/core/SQL/SQLite/11/select_messagesSinceOffset.sql diff --git a/src/core/SQL/SQLite/10/select_networkExists.sql b/src/core/SQL/SQLite/11/select_networkExists.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_networkExists.sql rename to src/core/SQL/SQLite/11/select_networkExists.sql diff --git a/src/core/SQL/SQLite/10/select_networks_for_user.sql b/src/core/SQL/SQLite/11/select_networks_for_user.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_networks_for_user.sql rename to src/core/SQL/SQLite/11/select_networks_for_user.sql diff --git a/src/core/SQL/SQLite/10/select_persistent_channels.sql b/src/core/SQL/SQLite/11/select_persistent_channels.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_persistent_channels.sql rename to src/core/SQL/SQLite/11/select_persistent_channels.sql diff --git a/src/core/SQL/SQLite/10/select_servers_for_network.sql b/src/core/SQL/SQLite/11/select_servers_for_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_servers_for_network.sql rename to src/core/SQL/SQLite/11/select_servers_for_network.sql diff --git a/src/core/SQL/SQLite/11/select_user_setting.sql b/src/core/SQL/SQLite/11/select_user_setting.sql new file mode 100644 index 00000000..a5da306e --- /dev/null +++ b/src/core/SQL/SQLite/11/select_user_setting.sql @@ -0,0 +1,3 @@ +SELECT settingvalue +FROM user_setting +WHERE userid = :userid AND settingname = :settingname diff --git a/src/core/SQL/SQLite/10/select_userid.sql b/src/core/SQL/SQLite/11/select_userid.sql similarity index 100% rename from src/core/SQL/SQLite/10/select_userid.sql rename to src/core/SQL/SQLite/11/select_userid.sql diff --git a/src/core/SQL/SQLite/10/setup_000_quasseluser.sql b/src/core/SQL/SQLite/11/setup_000_quasseluser.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_000_quasseluser.sql rename to src/core/SQL/SQLite/11/setup_000_quasseluser.sql diff --git a/src/core/SQL/SQLite/10/setup_010_sender.sql b/src/core/SQL/SQLite/11/setup_010_sender.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_010_sender.sql rename to src/core/SQL/SQLite/11/setup_010_sender.sql diff --git a/src/core/SQL/SQLite/10/setup_020_network.sql b/src/core/SQL/SQLite/11/setup_020_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_020_network.sql rename to src/core/SQL/SQLite/11/setup_020_network.sql diff --git a/src/core/SQL/SQLite/10/setup_030_buffer.sql b/src/core/SQL/SQLite/11/setup_030_buffer.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_030_buffer.sql rename to src/core/SQL/SQLite/11/setup_030_buffer.sql diff --git a/src/core/SQL/SQLite/10/setup_040_buffer_idx.sql b/src/core/SQL/SQLite/11/setup_040_buffer_idx.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_040_buffer_idx.sql rename to src/core/SQL/SQLite/11/setup_040_buffer_idx.sql diff --git a/src/core/SQL/SQLite/10/setup_050_buffer_cname_idx.sql b/src/core/SQL/SQLite/11/setup_050_buffer_cname_idx.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_050_buffer_cname_idx.sql rename to src/core/SQL/SQLite/11/setup_050_buffer_cname_idx.sql diff --git a/src/core/SQL/SQLite/10/setup_060_backlog.sql b/src/core/SQL/SQLite/11/setup_060_backlog.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_060_backlog.sql rename to src/core/SQL/SQLite/11/setup_060_backlog.sql diff --git a/src/core/SQL/SQLite/10/setup_070_coreinfo.sql b/src/core/SQL/SQLite/11/setup_070_coreinfo.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_070_coreinfo.sql rename to src/core/SQL/SQLite/11/setup_070_coreinfo.sql diff --git a/src/core/SQL/SQLite/10/setup_080_ircservers.sql b/src/core/SQL/SQLite/11/setup_080_ircservers.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_080_ircservers.sql rename to src/core/SQL/SQLite/11/setup_080_ircservers.sql diff --git a/src/core/SQL/SQLite/10/setup_090_create_backlog_idx.sql b/src/core/SQL/SQLite/11/setup_090_create_backlog_idx.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_090_create_backlog_idx.sql rename to src/core/SQL/SQLite/11/setup_090_create_backlog_idx.sql diff --git a/src/core/SQL/SQLite/10/setup_100_create_backlog_idx2.sql b/src/core/SQL/SQLite/11/setup_100_create_backlog_idx2.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_100_create_backlog_idx2.sql rename to src/core/SQL/SQLite/11/setup_100_create_backlog_idx2.sql diff --git a/src/core/SQL/SQLite/10/setup_110_create_buffer_idx.sql b/src/core/SQL/SQLite/11/setup_110_create_buffer_idx.sql similarity index 100% rename from src/core/SQL/SQLite/10/setup_110_create_buffer_idx.sql rename to src/core/SQL/SQLite/11/setup_110_create_buffer_idx.sql diff --git a/src/core/SQL/SQLite/11/setup_120_create_user_setting.sql b/src/core/SQL/SQLite/11/setup_120_create_user_setting.sql new file mode 100644 index 00000000..fdfb4e09 --- /dev/null +++ b/src/core/SQL/SQLite/11/setup_120_create_user_setting.sql @@ -0,0 +1,6 @@ +CREATE TABLE user_setting ( + userid INTEGER NOT NULL, + settingname TEXT NOT NULL, + settingvalue BLOB, + PRIMARY KEY (userid, settingname) +) diff --git a/src/core/SQL/SQLite/11/setup_999_version.sql b/src/core/SQL/SQLite/11/setup_999_version.sql new file mode 100644 index 00000000..6365de56 --- /dev/null +++ b/src/core/SQL/SQLite/11/setup_999_version.sql @@ -0,0 +1 @@ +INSERT INTO coreinfo (key, value) VALUES ('schemaversion', 11) diff --git a/src/core/SQL/SQLite/10/update_buffer_lastseen.sql b/src/core/SQL/SQLite/11/update_buffer_lastseen.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_buffer_lastseen.sql rename to src/core/SQL/SQLite/11/update_buffer_lastseen.sql diff --git a/src/core/SQL/SQLite/10/update_buffer_name.sql b/src/core/SQL/SQLite/11/update_buffer_name.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_buffer_name.sql rename to src/core/SQL/SQLite/11/update_buffer_name.sql diff --git a/src/core/SQL/SQLite/10/update_buffer_persistent_channel.sql b/src/core/SQL/SQLite/11/update_buffer_persistent_channel.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_buffer_persistent_channel.sql rename to src/core/SQL/SQLite/11/update_buffer_persistent_channel.sql diff --git a/src/core/SQL/SQLite/10/update_buffer_set_channel_key.sql b/src/core/SQL/SQLite/11/update_buffer_set_channel_key.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_buffer_set_channel_key.sql rename to src/core/SQL/SQLite/11/update_buffer_set_channel_key.sql diff --git a/src/core/SQL/SQLite/10/update_network.sql b/src/core/SQL/SQLite/11/update_network.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_network.sql rename to src/core/SQL/SQLite/11/update_network.sql diff --git a/src/core/SQL/SQLite/10/update_network_connected.sql b/src/core/SQL/SQLite/11/update_network_connected.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_network_connected.sql rename to src/core/SQL/SQLite/11/update_network_connected.sql diff --git a/src/core/SQL/SQLite/11/update_user_setting.sql b/src/core/SQL/SQLite/11/update_user_setting.sql new file mode 100644 index 00000000..3585fbc9 --- /dev/null +++ b/src/core/SQL/SQLite/11/update_user_setting.sql @@ -0,0 +1,3 @@ +UPDATE user_setting +SET settingvalue = :settingvalue +WHERE userid = :userid AND settingname = :settingname diff --git a/src/core/SQL/SQLite/10/update_username.sql b/src/core/SQL/SQLite/11/update_username.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_username.sql rename to src/core/SQL/SQLite/11/update_username.sql diff --git a/src/core/SQL/SQLite/10/update_userpassword.sql b/src/core/SQL/SQLite/11/update_userpassword.sql similarity index 100% rename from src/core/SQL/SQLite/10/update_userpassword.sql rename to src/core/SQL/SQLite/11/update_userpassword.sql diff --git a/src/core/SQL/SQLite/11/upgrade_000_create_user_setting.sql b/src/core/SQL/SQLite/11/upgrade_000_create_user_setting.sql new file mode 100644 index 00000000..fdfb4e09 --- /dev/null +++ b/src/core/SQL/SQLite/11/upgrade_000_create_user_setting.sql @@ -0,0 +1,6 @@ +CREATE TABLE user_setting ( + userid INTEGER NOT NULL, + settingname TEXT NOT NULL, + settingvalue BLOB, + PRIMARY KEY (userid, settingname) +) diff --git a/src/core/SQL/SQLite/11/upgrade_999_version.sql b/src/core/SQL/SQLite/11/upgrade_999_version.sql new file mode 100644 index 00000000..68ec4b8a --- /dev/null +++ b/src/core/SQL/SQLite/11/upgrade_999_version.sql @@ -0,0 +1,3 @@ +UPDATE coreinfo +SET value = 11 +WHERE key = 'schemaversion' diff --git a/src/core/SQL/upgradeSchema.sh b/src/core/SQL/upgradeSchema.sh new file mode 100755 index 00000000..0fcb651b --- /dev/null +++ b/src/core/SQL/upgradeSchema.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +TARGET_DIR=$1 +if [ ! $TARGET_DIR ]; then + TARGET_DIR=`pwd` +fi + +if [[ ! -d $TARGET_DIR ]]; then + echo "No such directory $TARGET_DIR" + exit 1 +fi + +cd $TARGET_DIR + +CURRENT_VERSION=`ls | sort -n | tail -n1` + +if [ ! $CURRENT_VERSION ]; then + echo "no previous schema found to upgrade from" + exit 2 +fi + +((NEW_VERSION=$CURRENT_VERSION + 1)) + +mkdir $NEW_VERSION +svn add $NEW_VERSION +find $CURRENT_VERSION -depth 1 \! -name "upgrade_*" \! -name ".*" -exec svn mv {} $NEW_VERSION \; +svn cp ${CURRENT_VERSION}/upgrade_999_version.sql $NEW_VERSION diff --git a/src/core/core.cpp b/src/core/core.cpp index dad499a7..1ad9fe2c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -207,6 +207,16 @@ void Core::syncStorage() { } /*** Storage Access ***/ +void Core::setUserSetting(UserId userId, const QString &settingName, const QVariant &data) { + QMutexLocker locker(&mutex); + instance()->storage->setUserSetting(userId, settingName, data); +} + +QVariant Core::getUserSetting(UserId userId, const QString &settingName, const QVariant &data) { + QMutexLocker locker(&mutex); + return instance()->storage->getUserSetting(userId, settingName, data); +} + bool Core::createNetwork(UserId user, NetworkInfo &info) { QMutexLocker locker(&mutex); NetworkId networkId = instance()->storage->createNetwork(user, info); diff --git a/src/core/core.h b/src/core/core.h index 5a125a4f..8047598a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -59,6 +59,24 @@ class Core : public QObject { /*** Storage access ***/ // These methods are threadsafe. + //! Store a user setting persistently + /** + * \param userId The users Id + * \param settingName The Name of the Setting + * \param data The Value + */ + static void setUserSetting(UserId userId, const QString &settingName, const QVariant &data); + + //! Retrieve a persistent user setting + /** + * \param userId The users Id + * \param settingName The Name of the Setting + * \param default Value to return in case it's unset. + * \return the Value of the Setting or the default value if it is unset. + */ + static QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &data = QVariant()); + + //! Create a Network in the Storage and store it's Id in the given NetworkInfo /** \note This method is thredsafe. * diff --git a/src/core/corebufferviewconfig.cpp b/src/core/corebufferviewconfig.cpp index 49686c12..47e3337e 100644 --- a/src/core/corebufferviewconfig.cpp +++ b/src/core/corebufferviewconfig.cpp @@ -23,9 +23,11 @@ CoreBufferViewConfig::CoreBufferViewConfig(int bufferViewId, QObject *parent) : BufferViewConfig(bufferViewId, parent) { + setAllowClientUpdates(true); } -void CoreBufferViewConfig::requestSetBufferViewName(const QString &bufferViewName) { - qDebug() << "requestSetBufferViewName" << bufferViewName; - setBufferViewName(bufferViewName); +CoreBufferViewConfig::CoreBufferViewConfig(int bufferViewId, const QVariantMap &properties, QObject *parent) + : BufferViewConfig(bufferViewId, properties, parent) +{ + setAllowClientUpdates(true); } diff --git a/src/core/corebufferviewconfig.h b/src/core/corebufferviewconfig.h index 06f15cf2..b0d9e96c 100644 --- a/src/core/corebufferviewconfig.h +++ b/src/core/corebufferviewconfig.h @@ -28,11 +28,15 @@ class CoreBufferViewConfig : public BufferViewConfig { public: CoreBufferViewConfig(int bufferViewId, QObject *parent = 0); - + CoreBufferViewConfig(int bufferViewId, const QVariantMap &properties, QObject *parent = 0); + virtual const QMetaObject *syncMetaObject() const { return &BufferViewConfig::staticMetaObject; } public slots: - virtual void requestSetBufferViewName(const QString &bufferViewName); + virtual inline void requestSetBufferViewName(const QString &bufferViewName) { setBufferViewName(bufferViewName); } + virtual inline void requestRemoveBuffer(const BufferId &bufferId) { removeBuffer(bufferId); } + virtual inline void requestAddBuffer(const BufferId &bufferId, int pos) { addBuffer(bufferId, pos); } + virtual inline void requestMoveBuffer(const BufferId &bufferId, int pos) { moveBuffer(bufferId, pos); } }; #endif // COREBUFFERVIEWCONFIG_H diff --git a/src/core/corebufferviewmanager.cpp b/src/core/corebufferviewmanager.cpp index a23a775d..bf18feef 100644 --- a/src/core/corebufferviewmanager.cpp +++ b/src/core/corebufferviewmanager.cpp @@ -22,21 +22,39 @@ #include "corebufferviewconfig.h" -CoreBufferViewManager::CoreBufferViewManager(SignalProxy *proxy, QObject *parent) - : BufferViewManager(proxy, parent) +#include "core.h" +#include "coresession.h" + +CoreBufferViewManager::CoreBufferViewManager(SignalProxy *proxy, CoreSession *parent) + : BufferViewManager(proxy, parent), + _coreSession(parent) { - return; - // fill in some demo views + QVariantMap views = Core::getUserSetting(_coreSession->user(), "BufferViews").toMap(); + QVariantMap::iterator iter = views.begin(); + QVariantMap::iterator iterEnd = views.end(); CoreBufferViewConfig *config = 0; - for(int i = 0; i < 10; i++) { - config = new CoreBufferViewConfig(i); - config->setBufferViewName(QString("asdf%1").arg(i)); + while(iter != iterEnd) { + config = new CoreBufferViewConfig(iter.key().toInt(), iter.value().toMap(), this); addBufferViewConfig(config); + iter++; + } +} + +CoreBufferViewManager::~CoreBufferViewManager() { + QVariantMap views; + + BufferViewConfigHash::const_iterator iter = bufferViewConfigHash().constBegin(); + BufferViewConfigHash::const_iterator iterEnd = bufferViewConfigHash().constEnd(); + while(iter != iterEnd) { + views[QString::number((*iter)->bufferViewId())] = (*iter)->toVariantMap(); + iter++; } + + Core::setUserSetting(_coreSession->user(), "BufferViews", views); } -void CoreBufferViewManager::requestCreateBufferView(const QString &bufferViewName) { - // FIXME retreive new Id from database or whereever this stuff will be stored +void CoreBufferViewManager::requestCreateBufferView(const QVariantMap &properties) { + QString bufferViewName = properties["bufferViewName"].toString(); int maxId = -1; BufferViewConfigHash::const_iterator iter = bufferViewConfigHash().constBegin(); BufferViewConfigHash::const_iterator iterEnd = bufferViewConfigHash().constEnd(); @@ -51,7 +69,25 @@ void CoreBufferViewManager::requestCreateBufferView(const QString &bufferViewNam } maxId++; - CoreBufferViewConfig *config = new CoreBufferViewConfig(maxId); - config->setBufferViewName(bufferViewName); + CoreBufferViewConfig *config = new CoreBufferViewConfig(maxId, properties); addBufferViewConfig(config); } + +void CoreBufferViewManager::requestCreateBufferViews(const QVariantList &properties) { + QVariantList::const_iterator iter = properties.constBegin(); + QVariantList::const_iterator iterEnd = properties.constEnd(); + while(iter != iterEnd) { + requestCreateBufferView((*iter).toMap()); + iter++; + } +} + +void CoreBufferViewManager::requestDeleteBufferView(int bufferViewId) { + deleteBufferViewConfig(bufferViewId); +} + +void CoreBufferViewManager::requestDeleteBufferViews(const QVariantList &bufferViews) { + foreach(QVariant bufferView, bufferViews) { + deleteBufferViewConfig(bufferView.toInt()); + } +} diff --git a/src/core/corebufferviewmanager.h b/src/core/corebufferviewmanager.h index 235c9dcb..072b4558 100644 --- a/src/core/corebufferviewmanager.h +++ b/src/core/corebufferviewmanager.h @@ -23,16 +23,26 @@ #include "bufferviewmanager.h" +class CoreSession; + class CoreBufferViewManager : public BufferViewManager { Q_OBJECT public: - CoreBufferViewManager(SignalProxy *proxy, QObject *parent = 0); - + CoreBufferViewManager(SignalProxy *proxy, CoreSession *parent); + ~CoreBufferViewManager(); + virtual const QMetaObject *syncMetaObject() const { return &BufferViewManager::staticMetaObject; } public slots: - virtual void requestCreateBufferView(const QString &bufferViewName); + virtual void requestCreateBufferView(const QVariantMap &properties); + virtual void requestCreateBufferViews(const QVariantList &properties); + virtual void requestDeleteBufferView(int bufferViewId); + virtual void requestDeleteBufferViews(const QVariantList &bufferViews); + +private: + CoreSession *_coreSession; }; #endif // COREBUFFERVIEWMANAGER_H + diff --git a/src/core/sql.qrc b/src/core/sql.qrc index 2c806d49..8d38df09 100644 --- a/src/core/sql.qrc +++ b/src/core/sql.qrc @@ -3,66 +3,72 @@ ./SQL/SQLite/1/upgrade_000_drop_coreinfo.sql ./SQL/SQLite/1/upgrade_010_create_coreinfo.sql ./SQL/SQLite/1/upgrade_020_update_schemaversion.sql - ./SQL/SQLite/10/delete_backlog_by_uid.sql - ./SQL/SQLite/10/delete_backlog_for_buffer.sql - ./SQL/SQLite/10/delete_backlog_for_network.sql - ./SQL/SQLite/10/delete_buffer_for_bufferid.sql - ./SQL/SQLite/10/delete_buffers_by_uid.sql - ./SQL/SQLite/10/delete_buffers_for_network.sql - ./SQL/SQLite/10/delete_ircservers_for_network.sql - ./SQL/SQLite/10/delete_network.sql - ./SQL/SQLite/10/delete_networks_by_uid.sql - ./SQL/SQLite/10/delete_quasseluser.sql - ./SQL/SQLite/10/insert_buffer.sql - ./SQL/SQLite/10/insert_message.sql - ./SQL/SQLite/10/insert_network.sql - ./SQL/SQLite/10/insert_quasseluser.sql - ./SQL/SQLite/10/insert_sender.sql - ./SQL/SQLite/10/insert_server.sql - ./SQL/SQLite/10/select_authuser.sql - ./SQL/SQLite/10/select_buffer_by_id.sql - ./SQL/SQLite/10/select_buffer_lastseen_messages.sql - ./SQL/SQLite/10/select_bufferByName.sql - ./SQL/SQLite/10/select_bufferExists.sql - ./SQL/SQLite/10/select_buffers.sql - ./SQL/SQLite/10/select_connected_networks.sql - ./SQL/SQLite/10/select_messageRange.sql - ./SQL/SQLite/10/select_messages.sql - ./SQL/SQLite/10/select_messagesOffset.sql - ./SQL/SQLite/10/select_messagesSince.sql - ./SQL/SQLite/10/select_messagesSinceOffset.sql - ./SQL/SQLite/10/select_networkExists.sql - ./SQL/SQLite/10/select_networks_for_user.sql - ./SQL/SQLite/10/select_persistent_channels.sql - ./SQL/SQLite/10/select_servers_for_network.sql - ./SQL/SQLite/10/select_userid.sql - ./SQL/SQLite/10/setup_000_quasseluser.sql - ./SQL/SQLite/10/setup_010_sender.sql - ./SQL/SQLite/10/setup_020_network.sql - ./SQL/SQLite/10/setup_030_buffer.sql - ./SQL/SQLite/10/setup_040_buffer_idx.sql - ./SQL/SQLite/10/setup_050_buffer_cname_idx.sql - ./SQL/SQLite/10/setup_060_backlog.sql - ./SQL/SQLite/10/setup_070_coreinfo.sql - ./SQL/SQLite/10/setup_080_ircservers.sql - ./SQL/SQLite/10/setup_090_create_backlog_idx.sql - ./SQL/SQLite/10/setup_100_create_backlog_idx2.sql - ./SQL/SQLite/10/setup_110_create_buffer_idx.sql - ./SQL/SQLite/10/setup_999_version.sql - ./SQL/SQLite/10/update_buffer_lastseen.sql - ./SQL/SQLite/10/update_buffer_name.sql - ./SQL/SQLite/10/update_buffer_persistent_channel.sql - ./SQL/SQLite/10/update_buffer_set_channel_key.sql - ./SQL/SQLite/10/update_network.sql - ./SQL/SQLite/10/update_network_connected.sql - ./SQL/SQLite/10/update_username.sql - ./SQL/SQLite/10/update_userpassword.sql ./SQL/SQLite/10/upgrade_000_switch_to_msgid.sql ./SQL/SQLite/10/upgrade_010_rename_buffer_table.sql ./SQL/SQLite/10/upgrade_020_create_buffer_table.sql ./SQL/SQLite/10/upgrade_030_copy_buffer_table.sql ./SQL/SQLite/10/upgrade_040_drop_buffer_old_table.sql ./SQL/SQLite/10/upgrade_999_version.sql + ./SQL/SQLite/11/delete_backlog_by_uid.sql + ./SQL/SQLite/11/delete_backlog_for_buffer.sql + ./SQL/SQLite/11/delete_backlog_for_network.sql + ./SQL/SQLite/11/delete_buffer_for_bufferid.sql + ./SQL/SQLite/11/delete_buffers_by_uid.sql + ./SQL/SQLite/11/delete_buffers_for_network.sql + ./SQL/SQLite/11/delete_ircservers_for_network.sql + ./SQL/SQLite/11/delete_network.sql + ./SQL/SQLite/11/delete_networks_by_uid.sql + ./SQL/SQLite/11/delete_quasseluser.sql + ./SQL/SQLite/11/insert_buffer.sql + ./SQL/SQLite/11/insert_message.sql + ./SQL/SQLite/11/insert_network.sql + ./SQL/SQLite/11/insert_quasseluser.sql + ./SQL/SQLite/11/insert_sender.sql + ./SQL/SQLite/11/insert_server.sql + ./SQL/SQLite/11/insert_user_setting.sql + ./SQL/SQLite/11/select_authuser.sql + ./SQL/SQLite/11/select_buffer_by_id.sql + ./SQL/SQLite/11/select_buffer_lastseen_messages.sql + ./SQL/SQLite/11/select_bufferByName.sql + ./SQL/SQLite/11/select_bufferExists.sql + ./SQL/SQLite/11/select_buffers.sql + ./SQL/SQLite/11/select_connected_networks.sql + ./SQL/SQLite/11/select_messageRange.sql + ./SQL/SQLite/11/select_messages.sql + ./SQL/SQLite/11/select_messagesOffset.sql + ./SQL/SQLite/11/select_messagesSince.sql + ./SQL/SQLite/11/select_messagesSinceOffset.sql + ./SQL/SQLite/11/select_networkExists.sql + ./SQL/SQLite/11/select_networks_for_user.sql + ./SQL/SQLite/11/select_persistent_channels.sql + ./SQL/SQLite/11/select_servers_for_network.sql + ./SQL/SQLite/11/select_user_setting.sql + ./SQL/SQLite/11/select_userid.sql + ./SQL/SQLite/11/setup_000_quasseluser.sql + ./SQL/SQLite/11/setup_010_sender.sql + ./SQL/SQLite/11/setup_020_network.sql + ./SQL/SQLite/11/setup_030_buffer.sql + ./SQL/SQLite/11/setup_040_buffer_idx.sql + ./SQL/SQLite/11/setup_050_buffer_cname_idx.sql + ./SQL/SQLite/11/setup_060_backlog.sql + ./SQL/SQLite/11/setup_070_coreinfo.sql + ./SQL/SQLite/11/setup_080_ircservers.sql + ./SQL/SQLite/11/setup_090_create_backlog_idx.sql + ./SQL/SQLite/11/setup_100_create_backlog_idx2.sql + ./SQL/SQLite/11/setup_110_create_buffer_idx.sql + ./SQL/SQLite/11/setup_120_create_user_setting.sql + ./SQL/SQLite/11/setup_999_version.sql + ./SQL/SQLite/11/update_buffer_lastseen.sql + ./SQL/SQLite/11/update_buffer_name.sql + ./SQL/SQLite/11/update_buffer_persistent_channel.sql + ./SQL/SQLite/11/update_buffer_set_channel_key.sql + ./SQL/SQLite/11/update_network.sql + ./SQL/SQLite/11/update_network_connected.sql + ./SQL/SQLite/11/update_user_setting.sql + ./SQL/SQLite/11/update_username.sql + ./SQL/SQLite/11/update_userpassword.sql + ./SQL/SQLite/11/upgrade_000_create_user_setting.sql + ./SQL/SQLite/11/upgrade_999_version.sql ./SQL/SQLite/2/upgrade_000_drop_buffergroup.sql ./SQL/SQLite/2/upgrade_010_update_schemaversion.sql ./SQL/SQLite/3/upgrade_000_update_backlog_flags.sql diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index b1d3d268..ea19ca96 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -133,6 +133,49 @@ void SqliteStorage::delUser(UserId user) { emit userRemoved(user); } +void SqliteStorage::setUserSetting(UserId userId, const QString &settingName, const QVariant &data) { + QByteArray rawData; + QDataStream out(&rawData, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_2); + out << data; + + QSqlQuery query(logDb()); + query.prepare(queryString("insert_user_setting")); + query.bindValue(":userid", userId.toInt()); + query.bindValue(":settingname", settingName); + query.bindValue(":settingvalue", rawData); + query.exec(); + + if(query.lastError().isValid()) { + QSqlQuery updateQuery(logDb()); + updateQuery.prepare(queryString("update_user_setting")); + updateQuery.bindValue(":userid", userId.toInt()); + updateQuery.bindValue(":settingname", settingName); + updateQuery.bindValue(":settingvalue", rawData); + updateQuery.exec(); + } + +} + +QVariant SqliteStorage::getUserSetting(UserId userId, const QString &settingName, const QVariant &defaultData) { + QSqlQuery query(logDb()); + query.prepare(queryString("select_user_setting")); + query.bindValue(":userid", userId.toInt()); + query.bindValue(":settingname", settingName); + query.exec(); + + if(query.first()) { + QVariant data; + QByteArray rawData = query.value(0).toByteArray(); + QDataStream in(&rawData, QIODevice::ReadOnly); + in.setVersion(QDataStream::Qt_4_2); + in >> data; + return data; + } else { + return defaultData; + } +} + NetworkId SqliteStorage::createNetwork(UserId user, const NetworkInfo &info) { NetworkId networkId; QSqlQuery query(logDb()); diff --git a/src/core/sqlitestorage.h b/src/core/sqlitestorage.h index 66d205f5..597ca23e 100644 --- a/src/core/sqlitestorage.h +++ b/src/core/sqlitestorage.h @@ -50,6 +50,9 @@ public slots: virtual void renameUser(UserId user, const QString &newName); virtual UserId validateUser(const QString &user, const QString &password); virtual void delUser(UserId user); + virtual void setUserSetting(UserId userId, const QString &settingName, const QVariant &data); + virtual QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &defaultData = QVariant()); + /* Network handling */ virtual NetworkId createNetwork(UserId user, const NetworkInfo &info); diff --git a/src/core/storage.h b/src/core/storage.h index 1ce0079b..964548d5 100644 --- a/src/core/storage.h +++ b/src/core/storage.h @@ -107,6 +107,23 @@ class Storage : public QObject { */ virtual void delUser(UserId user) = 0; + //! Store a user setting persistently + /** + * \param userId The users Id + * \param settingName The Name of the Setting + * \param data The Value + */ + virtual void setUserSetting(UserId userId, const QString &settingName, const QVariant &data) = 0; + + //! Retrieve a persistent user setting + /** + * \param userId The users Id + * \param settingName The Name of the Setting + * \param default Value to return in case it's unset. + * \return the Value of the Setting or the default value if it is unset. + */ + virtual QVariant getUserSetting(UserId userId, const QString &settingName, const QVariant &data = QVariant()) = 0; + /* Network handling */ //! Create a new Network in the storage backend and return it unique Id diff --git a/src/qtui/coreconnectdlg.cpp b/src/qtui/coreconnectdlg.cpp index 909592e0..4811e2e0 100644 --- a/src/qtui/coreconnectdlg.cpp +++ b/src/qtui/coreconnectdlg.cpp @@ -28,9 +28,14 @@ #include "clientsyncer.h" #include "coreconfigwizard.h" -CoreConnectDlg::CoreConnectDlg(QWidget *parent, bool autoconnect) : QDialog(parent) { +CoreConnectDlg::CoreConnectDlg(QWidget *parent, bool autoconnect) + : QDialog(parent) +{ ui.setupUi(this); + // make it look more native under Mac OS X: + setWindowFlags(Qt::Sheet); + clientSyncer = new ClientSyncer(this); wizard = 0; diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 0b37fc52..cf283e48 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -22,6 +22,9 @@ #include "aboutdlg.h" #include "chatwidget.h" #include "bufferview.h" +#include "bufferviewconfig.h" +#include "bufferviewfilter.h" +#include "bufferviewmanager.h" #include "chatline-old.h" #include "client.h" #include "clientbacklogmanager.h" @@ -157,39 +160,68 @@ void MainWin::setupMenus() { actionEditNetworks = new QAction(QIcon(":/22x22/actions/configure"), tr("Edit &Networks..."), this); ui.menuNetworks->addAction(actionEditNetworks); connect(actionEditNetworks, SIGNAL(triggered()), this, SLOT(showNetworkDlg())); + connect(ui.actionManageViews, SIGNAL(triggered()), this, SLOT(showManageViewsDlg())); } void MainWin::setupViews() { - BufferModel *model = Client::bufferModel(); - - addBufferView(tr("All Buffers"), model, BufferViewFilter::AllNets, QList()); - addBufferView(tr("All Channels"), model, BufferViewFilter::AllNets|BufferViewFilter::NoQueries|BufferViewFilter::NoServers, QList()); - addBufferView(tr("All Queries"), model, BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoServers, QList()); - addBufferView(tr("All Networks"), model, BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoQueries, QList()); - addBufferView(tr("Full Custom"), model, BufferViewFilter::FullCustom, QList()); + QAction *separator = ui.menuViews->addSeparator(); + separator->setData("__EOBV__"); + addBufferView(); +} - ui.menuViews->addSeparator(); +void MainWin::addBufferView(int bufferViewConfigId) { + addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewConfigId)); } -QDockWidget *MainWin::addBufferView(const QString &viewname, QAbstractItemModel *model, const BufferViewFilter::Modes &mode, const QList &nets) { - QDockWidget *dock = new QDockWidget(viewname, this); - dock->setObjectName(QString("ViewDock-" + viewname)); // should be unique for mainwindow state! - dock->setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); +void MainWin::addBufferView(BufferViewConfig *config) { + BufferViewDock *dock; + if(config) + dock = new BufferViewDock(config, this); + else + dock = new BufferViewDock(this); //create the view and initialize it's filter BufferView *view = new BufferView(dock); + view->setFilteredModel(Client::bufferModel(), config); view->show(); - view->setFilteredModel(model, mode, nets); + Client::bufferModel()->synchronizeView(view); + dock->setWidget(view); dock->show(); addDockWidget(Qt::LeftDockWidgetArea, dock); - ui.menuViews->addAction(dock->toggleViewAction()); + QAction *endOfBufferViews = 0; + foreach(QAction *action, ui.menuViews->actions()) { + if(action->data().toString() == "__EOBV__") { + endOfBufferViews = action; + break; + } + } + Q_CHECK_PTR(endOfBufferViews); + ui.menuViews->insertAction(endOfBufferViews, dock->toggleViewAction()); - netViews.append(dock); - return dock; + _netViews.append(dock); +} + +void MainWin::removeBufferView(int bufferViewConfigId) { + QVariant actionData; + BufferViewDock *dock; + foreach(QAction *action, ui.menuViews->actions()) { + actionData = action->data(); + if(!actionData.isValid()) + continue; + + if(actionData.toString() == "__EOBV__") + break; + + dock = qobject_cast(action->parent()); + if(dock && actionData.toInt() != bufferViewConfigId) { + removeAction(action); + dock->deleteLater(); + } + } } void MainWin::setupSettingsDlg() { @@ -203,7 +235,17 @@ void MainWin::setupSettingsDlg() { //Category: General settingsDlg->registerSettingsPage(new IdentitiesSettingsPage(settingsDlg)); settingsDlg->registerSettingsPage(new NetworksSettingsPage(settingsDlg)); - // settingsDlg->registerSettingsPage(new BufferViewSettingsPage(settingsDlg)); + settingsDlg->registerSettingsPage(new BufferViewSettingsPage(settingsDlg)); +} + +void MainWin::showNetworkDlg() { + SettingsPageDlg dlg(new NetworksSettingsPage(this), this); + dlg.exec(); +} + +void MainWin::showManageViewsDlg() { + SettingsPageDlg dlg(new BufferViewSettingsPage(this), this); + dlg.exec(); } void MainWin::setupNickWidget() { @@ -349,6 +391,11 @@ void MainWin::changeTopic(const QString &topic) { } void MainWin::connectedToCore() { + Q_CHECK_PTR(Client::bufferViewManager()); + connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int))); + connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigDeleted(int)), this, SLOT(removeBufferView(int))); + connect(Client::bufferViewManager(), SIGNAL(initDone()), this, SLOT(loadLayout())); + foreach(BufferInfo id, Client::allBufferInfos()) { Client::backlogManager()->requestBacklog(id.bufferId(), 500, -1); } @@ -366,6 +413,12 @@ void MainWin::connectedToCore() { sslLabel->setPixmap(QPixmap::fromImage(QImage(":/16x16/status/no-ssl"))); } +void MainWin::loadLayout() { + QtUiSettings s; + int accountId = Client::currentCoreAccount().toInt(); + restoreState(s.value(QString("MainWinState-%1").arg(accountId)).toByteArray(), accountId); +} + void MainWin::securedConnection() { // todo: make status bar entry qDebug() << "secured the connection"; @@ -374,6 +427,27 @@ void MainWin::securedConnection() { } void MainWin::disconnectedFromCore() { + // save core specific layout and remove bufferviews; + QtUiSettings s; + int accountId = Client::currentCoreAccount().toInt(); + s.setValue(QString("MainWinState-%1").arg(accountId) , saveState(accountId)); + QVariant actionData; + BufferViewDock *dock; + foreach(QAction *action, ui.menuViews->actions()) { + actionData = action->data(); + if(!actionData.isValid()) + continue; + + if(actionData.toString() == "__EOBV__") + break; + + dock = qobject_cast(action->parent()); + if(dock && actionData.toInt() != -1) { + removeAction(action); + dock->deleteLater(); + } + } + ui.menuViews->setEnabled(false); //ui.menuCore->setEnabled(false); ui.actionDisconnectCore->setEnabled(false); @@ -518,11 +592,6 @@ void MainWin::makeTrayIconBlink() { } -void MainWin::showNetworkDlg() { - SettingsPageDlg dlg(new NetworksSettingsPage(this), this); - dlg.exec(); -} - void MainWin::clientNetworkCreated(NetworkId id) { const Network *net = Client::network(id); QAction *act = new QAction(net->networkName(), this); diff --git a/src/qtui/mainwin.h b/src/qtui/mainwin.h index c2cdfce0..01903456 100644 --- a/src/qtui/mainwin.h +++ b/src/qtui/mainwin.h @@ -24,7 +24,6 @@ #include "ui_mainwin.h" #include "qtui.h" -#include "bufferviewfilter.h" #include #include @@ -32,12 +31,14 @@ class ServerListDlg; class CoreConnectDlg; class Buffer; +class BufferViewConfig; class SettingsDlg; class QtUi; class Message; class NickListWidget; class DebugConsole; + //!\brief The main window of Quassel's QtUi. class MainWin : public QMainWindow { Q_OBJECT @@ -47,7 +48,7 @@ class MainWin : public QMainWindow { virtual ~MainWin(); void init(); - QDockWidget *addBufferView(const QString &, QAbstractItemModel *, const BufferViewFilter::Modes &, const QList &); + void addBufferView(BufferViewConfig *config = 0); AbstractUiMsg *layoutMsg(const Message &); void displayTrayIconMessage(const QString &title, const QString &message); @@ -68,9 +69,12 @@ class MainWin : public QMainWindow { void systrayActivated( QSystemTrayIcon::ActivationReason ); private slots: + void addBufferView(int bufferViewConfigId); + void removeBufferView(int bufferViewConfigId); void receiveMessage(const Message &msg); void showSettingsDlg(); void showNetworkDlg(); + void showManageViewsDlg(); void showAboutDlg(); void showDebugConsole(); @@ -86,6 +90,8 @@ class MainWin : public QMainWindow { void makeTrayIconBlink(); void saveStatusBarStatus(bool enabled); + void loadLayout(); + signals: void connectToCore(const QVariantMap &connInfo); void disconnectFromCore(); @@ -127,7 +133,7 @@ class MainWin : public QMainWindow { BufferId currentBuffer; QString currentProfile; - QList netViews; + QList _netViews; NickListWidget *nickListWidget; QAction *actionEditNetworks; diff --git a/src/qtui/settingspagedlg.cpp b/src/qtui/settingspagedlg.cpp index 2c817a96..7bac0ef7 100644 --- a/src/qtui/settingspagedlg.cpp +++ b/src/qtui/settingspagedlg.cpp @@ -20,10 +20,16 @@ #include "settingspagedlg.h" -SettingsPageDlg::SettingsPageDlg(SettingsPage *page, QWidget *parent) : QDialog(parent) { +SettingsPageDlg::SettingsPageDlg(SettingsPage *page, QWidget *parent) + : QDialog(parent) +{ ui.setupUi(this); _currentPage = page; page->setParent(this); + + // make it look more native under Mac OS X: + setWindowFlags(Qt::Sheet); + ui.pageTitle->setText(page->title()); // make the scrollarea behave sanely diff --git a/src/qtui/settingspages/bufferviewsettingspage.cpp b/src/qtui/settingspages/bufferviewsettingspage.cpp index 3fe64dff..9e959960 100644 --- a/src/qtui/settingspages/bufferviewsettingspage.cpp +++ b/src/qtui/settingspages/bufferviewsettingspage.cpp @@ -20,17 +20,40 @@ #include "bufferviewsettingspage.h" +#include + #include "client.h" -#include "bufferviewmanager.h" +#include "network.h" #include "bufferviewconfig.h" +#include "bufferviewfilter.h" +#include "bufferviewmanager.h" +#include "buffermodel.h" +#include "networkmodel.h" BufferViewSettingsPage::BufferViewSettingsPage(QWidget *parent) - : SettingsPage(tr("General"), tr("Buffer Views"), parent) + : SettingsPage(tr("General"), tr("Buffer Views"), parent), + _ignoreWidgetChanges(false) { ui.setupUi(this); reset(); + + ui.bufferViewList->setSortingEnabled(true); + ui.settingsGroupBox->setEnabled(false); + ui.bufferViewPreview->setEnabled(false); + setEnabled(Client::isConnected()); // need a core connection! connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool))); + connect(ui.bufferViewList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + this, SLOT(bufferViewSelectionChanged(const QItemSelection &, const QItemSelection &))); + + connect(ui.onlyStatusBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.onlyChannelBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.onlyQueryBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.addNewBuffersAutomatically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.sortAlphabetically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.hideInactiveBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged())); + connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged())); + connect(ui.minimumActivitySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged())); } BufferViewSettingsPage::~BufferViewSettingsPage() { @@ -39,14 +62,12 @@ BufferViewSettingsPage::~BufferViewSettingsPage() { void BufferViewSettingsPage::reset() { ui.bufferViewList->clear(); - _viewToListPos.clear(); - _listPosToView.clear(); QHash::iterator changedConfigIter = _changedBufferViews.begin(); QHash::iterator changedConfigIterEnd = _changedBufferViews.end(); BufferViewConfig *config; while(changedConfigIter != changedConfigIterEnd) { - config = (*changedConfigIter); + config = changedConfigIter.value(); changedConfigIter = _changedBufferViews.erase(changedConfigIter); config->deleteLater(); } @@ -59,6 +80,8 @@ void BufferViewSettingsPage::reset() { config->deleteLater(); } + _deleteBufferViews.clear(); + setChangedState(false); } @@ -72,9 +95,62 @@ void BufferViewSettingsPage::load() { foreach(BufferViewConfig *bufferViewConfig, bufferViewConfigs) { addBufferView(bufferViewConfig); } + + _ignoreWidgetChanges = true; + // load network selector + ui.networkSelector->clear(); + ui.networkSelector->addItem("All"); + ui.networkSelector->setItemData(0, qVariantFromValue(NetworkId())); + const Network *net; + foreach(NetworkId netId, Client::networkIds()) { + net = Client::network(netId); + ui.networkSelector->addItem(net->networkName()); + ui.networkSelector->setItemData(ui.networkSelector->count() - 1, qVariantFromValue(net->networkId())); + } + _ignoreWidgetChanges = false; + + ui.bufferViewList->setCurrentRow(0); } void BufferViewSettingsPage::save() { + setEnabled(false); + QVariantList newConfigs; + QVariantList deleteConfigs; + QVariantList changedConfigs; + + foreach(int bufferId, _deleteBufferViews) { + deleteConfigs << bufferId; + } + _deleteBufferViews.clear(); + if(Client::bufferViewManager()) { + Client::bufferViewManager()->requestDeleteBufferViews(deleteConfigs); + } + + QHash::iterator changedConfigIter = _changedBufferViews.begin(); + QHash::iterator changedConfigIterEnd = _changedBufferViews.end(); + BufferViewConfig *config, *changedConfig; + while(changedConfigIter != changedConfigIterEnd) { + config = changedConfigIter.key(); + changedConfig = changedConfigIter.value(); + changedConfigIter = _changedBufferViews.erase(changedConfigIter); + config->requestUpdate(changedConfig->toVariantMap()); + changedConfig->deleteLater(); + } + + QList::iterator newConfigIter = _newBufferViews.begin(); + QList::iterator newConfigIterEnd = _newBufferViews.end(); + while(newConfigIter != newConfigIterEnd) { + config = *newConfigIter; + newConfigIter = _newBufferViews.erase(newConfigIter); + newConfigs << config->toVariantMap(); + config->deleteLater(); + } + if(Client::bufferViewManager()) { + Client::bufferViewManager()->requestCreateBufferViews(newConfigs); + } + + load(); + setEnabled(true); } void BufferViewSettingsPage::coreConnectionStateChanged(bool state) { @@ -88,10 +164,10 @@ void BufferViewSettingsPage::coreConnectionStateChanged(bool state) { } void BufferViewSettingsPage::addBufferView(BufferViewConfig *config) { - _viewToListPos[config->bufferViewId()] = ui.bufferViewList->count(); - _listPosToView[ui.bufferViewList->count()] = config->bufferViewId(); - ui.bufferViewList->addItem(config->bufferViewName()); + QListWidgetItem *item = new QListWidgetItem(config->bufferViewName(), ui.bufferViewList); + item->setData(Qt::UserRole, qVariantFromValue(qobject_cast(config))); connect(config, SIGNAL(updatedRemotely()), this, SLOT(updateBufferView())); + connect(config, SIGNAL(destroyed()), this, SLOT(bufferViewDeleted())); } void BufferViewSettingsPage::addBufferView(int bufferViewId) { @@ -99,27 +175,57 @@ void BufferViewSettingsPage::addBufferView(int bufferViewId) { addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewId)); } +void BufferViewSettingsPage::bufferViewDeleted() { + BufferViewConfig *config = static_cast(sender()); + QObject *obj; + for(int i = 0; i < ui.bufferViewList->count(); i++) { + obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value(); + if(config == static_cast(obj)) { + QListWidgetItem *item = ui.bufferViewList->takeItem(i); + delete item; + return; + } + } +} + void BufferViewSettingsPage::newBufferView(const QString &bufferViewName) { // id's of newly created bufferviews are negative (-1, -2... -n) int fakeId = -1 * (_newBufferViews.count() + 1); BufferViewConfig *config = new BufferViewConfig(fakeId); config->setBufferViewName(bufferViewName); + + QList bufferIds; + if(config->addNewBuffersAutomatically()) { + foreach(BufferInfo bufferInfo, Client::allBufferInfos()) { + bufferIds << bufferInfo.bufferId(); + } + if(config->sortAlphabetically()) + qSort(bufferIds.begin(), bufferIds.end(), bufferIdLessThan); + } + config->initSetBufferList(bufferIds); + _newBufferViews << config; addBufferView(config); + ui.bufferViewList->setCurrentRow(listPos(config)); } int BufferViewSettingsPage::listPos(BufferViewConfig *config) { - if(_viewToListPos.contains(config->bufferViewId())) - return _viewToListPos[config->bufferViewId()]; - else - return -1; + QObject *obj; + for(int i = 0; i < ui.bufferViewList->count(); i++) { + obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value(); + if(config == qobject_cast(obj)) + return i; + } + return -1; } -int BufferViewSettingsPage::bufferViewId(int listPos) { - if(_listPosToView.contains(listPos)) - return _listPosToView[listPos]; - else - return -1; +BufferViewConfig *BufferViewSettingsPage::bufferView(int listPos) { + if(listPos < ui.bufferViewList->count() && listPos >= 0) { + QObject *obj = ui.bufferViewList->item(listPos)->data(Qt::UserRole).value(); + return qobject_cast(obj); + } else { + return 0; + } } void BufferViewSettingsPage::updateBufferView() { @@ -133,6 +239,8 @@ void BufferViewSettingsPage::updateBufferView() { return; } ui.bufferViewList->item(itemPos)->setText(config->bufferViewName()); + if(itemPos == ui.bufferViewList->currentRow()) + loadConfig(config); } void BufferViewSettingsPage::on_addBufferView_clicked() { @@ -158,7 +266,7 @@ void BufferViewSettingsPage::on_renameBufferView_clicked() { if(!Client::bufferViewManager()) return; - BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(bufferViewId(ui.bufferViewList->currentRow())); + BufferViewConfig *config = bufferView(ui.bufferViewList->currentRow()); if(!config) return; @@ -171,16 +279,159 @@ void BufferViewSettingsPage::on_renameBufferView_clicked() { if(dlg.exec() == QDialog::Accepted) { BufferViewConfig *changedConfig = cloneConfig(config); changedConfig->setBufferViewName(dlg.bufferViewName()); + ui.bufferViewList->item(listPos(config))->setText(dlg.bufferViewName()); changed(); } } +void BufferViewSettingsPage::on_deleteBufferView_clicked() { + if(ui.bufferViewList->selectedItems().isEmpty()) + return; + + QListWidgetItem *currentItem = ui.bufferViewList->item(ui.bufferViewList->currentRow()); + QString viewName = currentItem->text(); + int viewId = bufferView(ui.bufferViewList->currentRow())->bufferViewId(); + int ret = QMessageBox::question(this, tr("Delete Buffer View?"), + tr("Do you really want to delete the buffer view \"%1\"?").arg(viewName), + QMessageBox::Yes|QMessageBox::No, QMessageBox::No); + + if(ret == QMessageBox::Yes) { + ui.bufferViewList->removeItemWidget(currentItem); + delete currentItem; + if(viewId >= 0) + _deleteBufferViews << viewId; + changed(); + } +} + +void BufferViewSettingsPage::bufferViewSelectionChanged(const QItemSelection ¤t, const QItemSelection &previous) { + Q_UNUSED(previous) + + if(!current.isEmpty()) { + ui.settingsGroupBox->setEnabled(true); + ui.bufferViewPreview->setEnabled(true); + + loadConfig(configForDisplay(bufferView(ui.bufferViewList->currentRow()))); + } else { + ui.settingsGroupBox->setEnabled(false); + ui.bufferViewPreview->setEnabled(false); + } +} + +void BufferViewSettingsPage::loadConfig(BufferViewConfig *config) { + if(!config) + return; + + _ignoreWidgetChanges = true; + ui.onlyStatusBuffers->setChecked(BufferInfo::StatusBuffer & config->allowedBufferTypes()); + ui.onlyChannelBuffers->setChecked(BufferInfo::ChannelBuffer & config->allowedBufferTypes()); + ui.onlyQueryBuffers->setChecked(BufferInfo::QueryBuffer & config->allowedBufferTypes()); + ui.addNewBuffersAutomatically->setChecked(config->addNewBuffersAutomatically()); + ui.sortAlphabetically->setChecked(config->sortAlphabetically()); + ui.hideInactiveBuffers->setChecked(config->hideInactiveBuffers()); + + int networkIndex = 0; + for(int i = 0; i < ui.networkSelector->count(); i++) { + if(ui.networkSelector->itemData(i).value() == config->networkId()) { + networkIndex = i; + break; + } + } + ui.networkSelector->setCurrentIndex(networkIndex); + + int activityIndex = 0; + int minimumActivity = config->minimumActivity(); + while(minimumActivity) { + activityIndex++; + minimumActivity = minimumActivity >> 1; + } + ui.minimumActivitySelector->setCurrentIndex(activityIndex); + + ui.bufferViewPreview->setFilteredModel(Client::bufferModel(), config); + + _ignoreWidgetChanges = false; +} + +void BufferViewSettingsPage::saveConfig(BufferViewConfig *config) { + if(!config) + return; + + int allowedBufferTypes = 0; + if(ui.onlyStatusBuffers->isChecked()) + allowedBufferTypes |= BufferInfo::StatusBuffer; + if(ui.onlyChannelBuffers->isChecked()) + allowedBufferTypes |= BufferInfo::ChannelBuffer; + if(ui.onlyQueryBuffers->isChecked()) + allowedBufferTypes |= BufferInfo::QueryBuffer; + config->setAllowedBufferTypes(allowedBufferTypes); + + config->setAddNewBuffersAutomatically(ui.addNewBuffersAutomatically->isChecked()); + config->setSortAlphabetically(ui.sortAlphabetically->isChecked()); + config->setHideInactiveBuffers(ui.hideInactiveBuffers->isChecked()); + config->setNetworkId(ui.networkSelector->itemData(ui.networkSelector->currentIndex()).value()); + + int minimumActivity = 0; + if(ui.minimumActivitySelector->currentIndex() > 0) + minimumActivity = 1 << (ui.minimumActivitySelector->currentIndex() - 1); + config->setMinimumActivity(minimumActivity); + + if(_newBufferViews.contains(config)) { + QList bufferIds; + if(config->addNewBuffersAutomatically()) { + foreach(BufferInfo bufferInfo, Client::allBufferInfos()) { + bufferIds << bufferInfo.bufferId(); + } + if(config->sortAlphabetically()) + qSort(bufferIds.begin(), bufferIds.end(), bufferIdLessThan); + } + config->initSetBufferList(bufferIds); + } +} + +void BufferViewSettingsPage::widgetHasChanged() { + if(_ignoreWidgetChanges) + return; + setChangedState(testHasChanged()); +} + +bool BufferViewSettingsPage::testHasChanged() { + saveConfig(cloneConfig(bufferView(ui.bufferViewList->currentRow()))); + + if(!_newBufferViews.isEmpty()) + return true; + + bool changed = false; + QHash::iterator iter = _changedBufferViews.begin(); + QHash::iterator iterEnd = _changedBufferViews.end(); + while(iter != iterEnd) { + if(&(iter.key()) == &(iter.value())) { + iter.value()->deleteLater(); + _changedBufferViews.erase(iter); + } else { + changed = true; + iter++; + } + } + return changed; +} + BufferViewConfig *BufferViewSettingsPage::cloneConfig(BufferViewConfig *config) { + if(!config || config->bufferViewId() < 0) + return config; + if(_changedBufferViews.contains(config)) return _changedBufferViews[config]; BufferViewConfig *changedConfig = new BufferViewConfig(-1, this); changedConfig->fromVariantMap(config->toVariantMap()); + _changedBufferViews[config] = changedConfig; + + // if this is the currently displayed view we have to change the config of the preview filter + BufferViewFilter *filter = qobject_cast(ui.bufferViewPreview->model()); + if(filter && filter->config() == config) + filter->setConfig(changedConfig); + ui.bufferViewPreview->setConfig(changedConfig); + return changedConfig; } diff --git a/src/qtui/settingspages/bufferviewsettingspage.h b/src/qtui/settingspages/bufferviewsettingspage.h index 0c733587..bf081777 100644 --- a/src/qtui/settingspages/bufferviewsettingspage.h +++ b/src/qtui/settingspages/bufferviewsettingspage.h @@ -25,6 +25,8 @@ #include "ui_bufferviewsettingspage.h" #include "ui_buffervieweditdlg.h" +#include + class BufferViewConfig; class BufferViewSettingsPage : public SettingsPage { @@ -44,29 +46,38 @@ private slots: void addBufferView(BufferViewConfig *config); void addBufferView(int bufferViewId); + void bufferViewDeleted(); void newBufferView(const QString &bufferViewName); void updateBufferView(); void on_addBufferView_clicked(); void on_renameBufferView_clicked(); + void on_deleteBufferView_clicked(); + void bufferViewSelectionChanged(const QItemSelection ¤t, const QItemSelection &previous); + + void widgetHasChanged(); private: Ui::BufferViewSettingsPage ui; - - // mappings for bufferViewId to position in the list and vice versa - QHash _viewToListPos; - QHash _listPosToView; + bool _ignoreWidgetChanges; // list of bufferviews to create QList _newBufferViews; + // list of buferViews to delete + QList _deleteBufferViews; + // Hash of pointers to cloned bufferViewConfigs holding the changes QHash _changedBufferViews; int listPos(BufferViewConfig *config); - int bufferViewId(int listPos); + BufferViewConfig *bufferView(int listPos); BufferViewConfig *cloneConfig(BufferViewConfig *config); BufferViewConfig *configForDisplay(BufferViewConfig *config); + + void loadConfig(BufferViewConfig *config); + void saveConfig(BufferViewConfig *config); + bool testHasChanged(); }; diff --git a/src/qtui/settingspages/bufferviewsettingspage.ui b/src/qtui/settingspages/bufferviewsettingspage.ui index 161ecaa1..0131e08a 100644 --- a/src/qtui/settingspages/bufferviewsettingspage.ui +++ b/src/qtui/settingspages/bufferviewsettingspage.ui @@ -5,8 +5,8 @@ 0 0 - 507 - 485 + 672 + 529 @@ -75,7 +75,7 @@ - + Buffer View Settings @@ -85,12 +85,18 @@ - Show only Buffers from: + Network: - + + + + All + + + @@ -101,21 +107,21 @@ - + Status Buffers - + Channel Buffers - + Query Buffers @@ -125,19 +131,57 @@ - + + + Hide inactive Buffers + + + + + Add new Buffers automatically - + + + Sort alphabetically + + + + + - Sort Buffers alphabetically + Minimum Activity: + + + + + No Activity + + + + + Other Activity + + + + + New Message + + + + + Highlight + + + + @@ -154,8 +198,29 @@ + + + + + + Preview: + + + + + + + + + + + BufferView + QTreeView +
bufferview.h
+
+
diff --git a/src/qtui/ui/mainwin.ui b/src/qtui/ui/mainwin.ui index cd048088..3e49f7c5 100644 --- a/src/qtui/ui/mainwin.ui +++ b/src/qtui/ui/mainwin.ui @@ -13,14 +13,6 @@ MainWindow - - - 0 - 27 - 800 - 549 - - 0 @@ -28,10 +20,16 @@ - - 6 + + 0 + + + 0 + + + 0 - + 0 @@ -45,7 +43,7 @@ 0 0 800 - 27 + 22 @@ -101,16 +99,7 @@ - - - - 0 - 576 - 800 - 24 - - - + false @@ -164,8 +153,7 @@ - - :/22x22/actions/oxygen/22x22/actions/application-exit.png:/22x22/actions/oxygen/22x22/actions/application-exit.png + :/22x22/actions/oxygen/22x22/actions/application-exit.png Quit... @@ -181,9 +169,7 @@ - - - + Configure Quassel... @@ -194,7 +180,7 @@ - false + true Manage Views... @@ -210,8 +196,7 @@ true - - :/icons/quassel-icon.png:/icons/quassel-icon.png + :/icons/quassel-icon.png About Quassel IRC... @@ -242,9 +227,7 @@ false - - - + Disconnect from Core @@ -255,9 +238,7 @@ false - - - + Connect to Core... diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index 8ed210f5..598686ec 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.cpp @@ -18,16 +18,26 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "client.h" -#include "buffersyncer.h" #include "bufferview.h" -#include "networkmodel.h" + +#include "bufferviewfilter.h" +#include "buffersyncer.h" +#include "client.h" #include "network.h" +#include "networkmodel.h" #include "uisettings.h" #include "global.h" +#include +#include +#include +#include +#include +#include +#include + /***************************************** * The TreeView showing the Buffers *****************************************/ @@ -66,16 +76,12 @@ void BufferView::init() { #endif } -void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QList nets) { - BufferViewFilter *filter = new BufferViewFilter(model, mode, nets); - setModel(filter); - connect(this, SIGNAL(removeBuffer(const QModelIndex &)), filter, SLOT(removeBuffer(const QModelIndex &))); -} - void BufferView::setModel(QAbstractItemModel *model) { delete selectionModel(); QTreeView::setModel(model); init(); + if(!model) + return; // remove old Actions QList oldactions = header()->actions(); @@ -98,6 +104,59 @@ void BufferView::setModel(QAbstractItemModel *model) { } +void BufferView::setFilteredModel(QAbstractItemModel *model_, BufferViewConfig *config) { + BufferViewFilter *filter = qobject_cast(model()); + if(filter) { + filter->setConfig(config); + setConfig(config); + return; + } + + if(model()) { + disconnect(this, 0, model(), 0); + } + + if(!model_) { + setModel(model_); + } else { + BufferViewFilter *filter = new BufferViewFilter(model_, config); + setModel(filter); + connect(this, SIGNAL(removeBuffer(const QModelIndex &)), filter, SLOT(removeBuffer(const QModelIndex &))); + } + setConfig(config); +} + +void BufferView::setConfig(BufferViewConfig *config) { + if(_config == config) + return; + + if(_config) { + disconnect(_config, 0, this, 0); + } + + _config = config; + if(config) { + connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(setRootIndexForNetworkId(const NetworkId &))); + setRootIndexForNetworkId(config->networkId()); + } else { + setRootIndex(QModelIndex()); + } +} + +void BufferView::setRootIndexForNetworkId(const NetworkId &networkId) { + if(!networkId.isValid() || !model()) { + setRootIndex(QModelIndex()); + } else { + int networkCount = model()->rowCount(); + QModelIndex child; + for(int i = 0; i < networkCount; i++) { + child = model()->index(i, 0); + if(networkId == model()->data(child, NetworkModel::NetworkIdRole).value()) + setRootIndex(child); + } + } +} + void BufferView::joinChannel(const QModelIndex &index) { BufferInfo::Type bufferType = (BufferInfo::Type)index.data(NetworkModel::BufferTypeRole).value(); @@ -299,7 +358,7 @@ void BufferView::wheelEvent(QWheelEvent* event) { QSize BufferView::sizeHint() const { - return QSize(120, 50); + return QTreeView::sizeHint(); if(!model()) return QTreeView::sizeHint(); @@ -314,3 +373,28 @@ QSize BufferView::sizeHint() const { } return QSize(columnSize, 50); } + +// ============================== +// BufferView Dock +// ============================== +BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) + : QDockWidget(config->bufferViewName(), parent) +{ + setObjectName("BufferViewDock-" + QString::number(config->bufferViewId())); + toggleViewAction()->setData(config->bufferViewId()); + setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); + connect(config, SIGNAL(bufferViewNameSet(const QString &)), this, SLOT(bufferViewRenamed(const QString &))); +} + +BufferViewDock::BufferViewDock(QWidget *parent) + : QDockWidget(tr("All Buffers"), parent) +{ + setObjectName("BufferViewDock--1"); + toggleViewAction()->setData((int)-1); + setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); +} + +void BufferViewDock::bufferViewRenamed(const QString &newName) { + setWindowTitle(newName); + toggleViewAction()->setText(newName); +} diff --git a/src/uisupport/bufferview.h b/src/uisupport/bufferview.h index ae1bb37a..0f1b502f 100644 --- a/src/uisupport/bufferview.h +++ b/src/uisupport/bufferview.h @@ -18,13 +18,17 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _BUFFERVIEW_H_ -#define _BUFFERVIEW_H_ +#ifndef BUFFERVIEW_H_ +#define BUFFERVIEW_H_ -#include -#include +#include +#include +#include +#include -#include "bufferviewfilter.h" +#include "bufferviewconfig.h" + +#include "types.h" /***************************************** * The TreeView showing the Buffers @@ -35,8 +39,15 @@ class BufferView : public QTreeView { public: BufferView(QWidget *parent = 0); void init(); + void setModel(QAbstractItemModel *model); - void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QList nets); + void setFilteredModel(QAbstractItemModel *model, BufferViewConfig *config); + + void setConfig(BufferViewConfig *config); + inline BufferViewConfig *config() { return _config; } + +public slots: + void setRootIndexForNetworkId(const NetworkId &networkId); signals: void removeBuffer(const QModelIndex &); @@ -53,8 +64,24 @@ private slots: void toggleHeader(bool checked); void showContextMenu(const QPoint &); +private: + QPointer _config; }; +// ============================== +// BufferView Dock +// ============================== +class BufferViewDock : public QDockWidget { + Q_OBJECT + +public: + BufferViewDock(BufferViewConfig *config, QWidget *parent); + BufferViewDock(QWidget *parent); + +public slots: + void bufferViewRenamed(const QString &newName); +}; + #endif diff --git a/src/uisupport/bufferviewfilter.cpp b/src/uisupport/bufferviewfilter.cpp index a4ece414..896bd116 100644 --- a/src/uisupport/bufferviewfilter.cpp +++ b/src/uisupport/bufferviewfilter.cpp @@ -22,6 +22,7 @@ #include +#include "client.h" #include "networkmodel.h" #include "uisettings.h" @@ -29,113 +30,148 @@ /***************************************** * The Filter for the Tree View *****************************************/ -BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, const Modes &filtermode, const QList &nets) +BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, BufferViewConfig *config) : QSortFilterProxyModel(model), - mode(filtermode), - networks(QSet::fromList(nets)) + _config(0) { + setConfig(config); setSourceModel(model); - setSortCaseSensitivity(Qt::CaseInsensitive); + // setSortCaseSensitivity(Qt::CaseInsensitive); + setDynamicSortFilter(true); +} + +void BufferViewFilter::setConfig(BufferViewConfig *config) { + if(_config == config) + return; + + if(_config) { + disconnect(_config, 0, this, 0); + } + + _config = config; + if(config) { + connect(config, SIGNAL(bufferViewNameSet(const QString &)), this, SLOT(invalidate())); + connect(config, SIGNAL(networkIdSet(const NetworkId &)), this, SLOT(invalidate())); + connect(config, SIGNAL(addNewBuffersAutomaticallySet(bool)), this, SLOT(invalidate())); + connect(config, SIGNAL(sortAlphabeticallySet(bool)), this, SLOT(invalidate())); + connect(config, SIGNAL(hideInactiveBuffersSet(bool)), this, SLOT(invalidate())); + connect(config, SIGNAL(allowedBufferTypesSet(int)), this, SLOT(invalidate())); + connect(config, SIGNAL(minimumActivitySet(int)), this, SLOT(invalidate())); + connect(config, SIGNAL(bufferListSet()), this, SLOT(invalidate())); + connect(config, SIGNAL(bufferAdded(const BufferId &, int)), this, SLOT(invalidate())); + connect(config, SIGNAL(bufferMoved(const BufferId &, int)), this, SLOT(invalidate())); + connect(config, SIGNAL(bufferRemoved(const BufferId &)), this, SLOT(invalidate())); + } + invalidate(); } Qt::ItemFlags BufferViewFilter::flags(const QModelIndex &index) const { Qt::ItemFlags flags = mapToSource(index).flags(); - if(mode & FullCustom) { - if(index == QModelIndex() || index.parent() == QModelIndex()) - flags |= Qt::ItemIsDropEnabled; - } + if(_config && index == QModelIndex() || index.parent() == QModelIndex()) + flags |= Qt::ItemIsDropEnabled; return flags; } bool BufferViewFilter::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { - // drops have to occur in the open field - if(parent != QModelIndex()) + if(!config() || !NetworkModel::mimeContainsBufferList(data)) return QSortFilterProxyModel::dropMimeData(data, action, row, column, parent); - if(!NetworkModel::mimeContainsBufferList(data)) - return false; + NetworkId droppedNetworkId; + if(parent.data(NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType) + droppedNetworkId = parent.data(NetworkModel::NetworkIdRole).value(); QList< QPair > bufferList = NetworkModel::mimeDataToBufferList(data); - - NetworkId netId; BufferId bufferId; + NetworkId networkId; + int pos; for(int i = 0; i < bufferList.count(); i++) { - netId = bufferList[i].first; + networkId = bufferList[i].first; bufferId = bufferList[i].second; - if(!networks.contains(netId)) { - networks << netId; + if(droppedNetworkId == networkId) { + if(row < rowCount(parent)) { + BufferId beforeBufferId = parent.child(row, 0).data(NetworkModel::BufferIdRole).value(); + pos = config()->bufferList().indexOf(beforeBufferId); + } else { + pos = config()->bufferList().count(); + } + + if(config()->bufferList().contains(bufferId)) { + if(config()->bufferList().indexOf(bufferId) < pos) + pos--; + config()->requestMoveBuffer(bufferId, pos); + } else { + config()->requestAddBuffer(bufferId, pos); + } + + } else { + addBuffer(bufferId); } - addBuffer(bufferId); } return true; } -void BufferViewFilter::addBuffer(const BufferId &bufferuid) { - if(!buffers.contains(bufferuid)) { - buffers << bufferuid; - invalidateFilter(); - } -} - -void BufferViewFilter::removeBuffer(const QModelIndex &index) { - if(!(mode & FullCustom)) - return; // only custom buffers can be customized... obviously... :) +void BufferViewFilter::addBuffer(const BufferId &bufferId) { + if(config()->bufferList().contains(bufferId)) + return; - if(index.parent() == QModelIndex()) - return; // only child elements can be deleted - - bool lastBuffer = (rowCount(index.parent()) == 1); - NetworkId netId = index.data(NetworkModel::NetworkIdRole).value(); - BufferId bufferuid = index.data(NetworkModel::BufferIdRole).value(); - - if(buffers.contains(bufferuid)) { - buffers.remove(bufferuid); + int pos = config()->bufferList().count(); + bool lt; + for(int i = 0; i < config()->bufferList().count(); i++) { + if(config() && config()->sortAlphabetically()) + lt = bufferIdLessThan(bufferId, config()->bufferList()[i]); + else + lt = bufferId < config()->bufferList()[i]; - if(lastBuffer) { - networks.remove(netId); - Q_ASSERT(!networks.contains(netId)); + if(lt) { + pos = i; + break; } - - invalidateFilter(); } + config()->requestAddBuffer(bufferId, pos); +} + +void BufferViewFilter::removeBuffer(const QModelIndex &index) { + if(!config()) + return; + BufferId bufferId = data(index, NetworkModel::BufferIdRole).value(); + config()->requestRemoveBuffer(bufferId); } bool BufferViewFilter::filterAcceptBuffer(const QModelIndex &source_bufferIndex) const { - BufferInfo::Type bufferType = (BufferInfo::Type) source_bufferIndex.data(NetworkModel::BufferTypeRole).toInt(); + if(!_config) + return true; - if((mode & NoChannels) && bufferType == BufferInfo::ChannelBuffer) + if(!(_config->allowedBufferTypes() & (BufferInfo::Type)source_bufferIndex.data(NetworkModel::BufferTypeRole).toInt())) return false; - if((mode & NoQueries) && bufferType == BufferInfo::QueryBuffer) - return false; - if((mode & NoServers) && bufferType == BufferInfo::StatusBuffer) + + if(_config->hideInactiveBuffers() && !source_bufferIndex.data(NetworkModel::ItemActiveRole).toBool()) return false; -// bool isActive = source_bufferIndex.data(NetworkModel::BufferActiveRole).toBool(); -// if((mode & NoActive) && isActive) -// return false; -// if((mode & NoInactive) && !isActive) -// return false; + if(_config->minimumActivity() > source_bufferIndex.data(NetworkModel::BufferActivityRole).toInt()) + return false; - if((mode & FullCustom)) { - BufferId bufferuid = source_bufferIndex.data(NetworkModel::BufferIdRole).value(); - return buffers.contains(bufferuid); - } - - return true; + BufferId bufferId = sourceModel()->data(source_bufferIndex, NetworkModel::BufferIdRole).value(); + return _config->bufferList().contains(bufferId); } bool BufferViewFilter::filterAcceptNetwork(const QModelIndex &source_index) const { - NetworkId net = source_index.data(NetworkModel::NetworkIdRole).value(); - return !((mode & (SomeNets | FullCustom)) && !networks.contains(net)); + if(!config()) + return true; + + if(!config()->networkId().isValid()) { + return true; + } else { + return config()->networkId() == sourceModel()->data(source_index, NetworkModel::NetworkIdRole).value(); + } } bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { QModelIndex child = sourceModel()->index(source_row, 0, source_parent); if(!child.isValid()) { - qDebug() << "filterAcceptsRow has been called with an invalid Child"; + qWarning() << "filterAcceptsRow has been called with an invalid Child"; return false; } @@ -145,14 +181,35 @@ bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &sourc return filterAcceptBuffer(child); } -bool BufferViewFilter::lessThan(const QModelIndex &left, const QModelIndex &right) const { - int lefttype = left.data(NetworkModel::BufferTypeRole).toInt(); - int righttype = right.data(NetworkModel::BufferTypeRole).toInt(); +bool BufferViewFilter::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { + int itemType = sourceModel()->data(source_left, NetworkModel::ItemTypeRole).toInt(); + switch(itemType) { + case NetworkModel::NetworkItemType: + return networkLessThan(source_left, source_right); + case NetworkModel::BufferItemType: + return bufferLessThan(source_left, source_right); + default: + return QSortFilterProxyModel::lessThan(source_left, source_right); + } +} - if(lefttype != righttype) - return lefttype < righttype; +bool BufferViewFilter::bufferLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { + BufferId leftBufferId = sourceModel()->data(source_left, NetworkModel::BufferIdRole).value(); + BufferId rightBufferId = sourceModel()->data(source_right, NetworkModel::BufferIdRole).value(); + if(config()) { + return config()->bufferList().indexOf(leftBufferId) < config()->bufferList().indexOf(rightBufferId); + } else + return leftBufferId < rightBufferId; +} + +bool BufferViewFilter::networkLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { + NetworkId leftNetworkId = sourceModel()->data(source_left, NetworkModel::NetworkIdRole).value(); + NetworkId rightNetworkId = sourceModel()->data(source_right, NetworkModel::NetworkIdRole).value(); + + if(config() && config()->sortAlphabetically()) + return QSortFilterProxyModel::lessThan(source_left, source_right); else - return QSortFilterProxyModel::lessThan(left, right); + return leftNetworkId < rightNetworkId; } QVariant BufferViewFilter::data(const QModelIndex &index, int role) const { @@ -185,3 +242,25 @@ QVariant BufferViewFilter::foreground(const QModelIndex &index) const { return noActivity; } + + +// ****************************** +// Helper +// ****************************** +bool bufferIdLessThan(const BufferId &left, const BufferId &right) { + Q_CHECK_PTR(Client::networkModel()); + if(!Client::networkModel()) + return true; + + QModelIndex leftIndex = Client::networkModel()->bufferIndex(left); + QModelIndex rightIndex = Client::networkModel()->bufferIndex(right); + + int leftType = Client::networkModel()->data(leftIndex, NetworkModel::BufferTypeRole).toInt(); + int rightType = Client::networkModel()->data(rightIndex, NetworkModel::BufferTypeRole).toInt(); + + if(leftType != rightType) + return leftType < rightType; + else + return Client::networkModel()->data(leftIndex, Qt::DisplayRole).toString() < Client::networkModel()->data(rightIndex, Qt::DisplayRole).toString(); +} + diff --git a/src/uisupport/bufferviewfilter.h b/src/uisupport/bufferviewfilter.h index f27352e7..581cd6c9 100644 --- a/src/uisupport/bufferviewfilter.h +++ b/src/uisupport/bufferviewfilter.h @@ -18,15 +18,17 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _BUFFERVIEWFILTER_H_ -#define _BUFFERVIEWFILTER_H_ +#ifndef BUFFERVIEWFILTER_H_ +#define BUFFERVIEWFILTER_H_ -#include #include -#include +#include +#include #include -// #include "buffer.h" +#include + #include "types.h" +#include "bufferviewconfig.h" /***************************************** * Buffer View Filter @@ -47,32 +49,35 @@ public: }; Q_DECLARE_FLAGS(Modes, Mode); - BufferViewFilter(QAbstractItemModel *model, const Modes &mode, const QList &nets); + BufferViewFilter(QAbstractItemModel *model, BufferViewConfig *config = 0); virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); QVariant data(const QModelIndex &index, int role) const; QVariant foreground(const QModelIndex &index) const; - + + void setConfig(BufferViewConfig *config); + inline BufferViewConfig *config() const { return _config; } + public slots: void removeBuffer(const QModelIndex &); protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - bool lessThan(const QModelIndex &, const QModelIndex &) const; - + bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; + bool bufferLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; + bool networkLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; + private: - Modes mode; - QSet networks; - QSet buffers; + QPointer _config; bool filterAcceptBuffer(const QModelIndex &) const; bool filterAcceptNetwork(const QModelIndex &) const; void addBuffer(const BufferId &); - }; Q_DECLARE_OPERATORS_FOR_FLAGS(BufferViewFilter::Modes) -#endif +bool bufferIdLessThan(const BufferId &, const BufferId &); +#endif // BUFFERVIEWFILTER_H_ diff --git a/version.inc b/version.inc index a294d206..7b7b91ea 100644 --- a/version.inc +++ b/version.inc @@ -5,14 +5,14 @@ quasselVersion = "0.2.0-beta1-pre"; quasselDate = "2008-04-13"; - quasselBuild = 729; + quasselBuild = 731; //! Minimum client build number the core needs - clientBuildNeeded = 642; + clientBuildNeeded = 731; clientVersionNeeded = quasselVersion; //! Minimum core build number the client needs - coreBuildNeeded = 642; + coreBuildNeeded = 731; coreVersionNeeded = quasselVersion; }