void Client::init() {
_currentCoreAccount = 0;
_networkModel = new NetworkModel(this);
+
connect(this, SIGNAL(bufferUpdated(BufferInfo)),
_networkModel, SLOT(bufferUpdated(BufferInfo)));
connect(this, SIGNAL(networkRemoved(NetworkId)),
void Client::disconnectFromCore() {
if(!isConnected())
return;
+ _connectedToCore = false;
if(socket) {
socket->close();
socket->deleteLater();
}
- _connectedToCore = false;
_syncedToCore = false;
setCurrentCoreAccount(0);
emit disconnected();
_bufferViewManager->deleteLater();
_bufferViewManager = 0;
}
-
+
_networkModel->clear();
QHash<BufferId, Buffer *>::iterator bufferIter = _buffers.begin();
this, SLOT(attachIrcChannel(QString)));
connect(network, SIGNAL(connectedSet(bool)),
this, SIGNAL(dataChanged()));
-
+ connect(network, SIGNAL(destroyed()),
+ this, SIGNAL(dataChanged()));
+
emit dataChanged();
}
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 {
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 &)));
}
}
else
parentItem = static_cast<AbstractTreeItem*>(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<AbstractTreeItem *>(parent.internalPointer())->child(parent.column(), parent.row()))
-// return child->columnCount();
-// else
-// return static_cast<AbstractTreeItem*>(parent.internalPointer())->columnCount();
-// } else {
-// return rootItem->columnCount();
-// }
- return rootItem->columnCount();
+// AbstractTreeItem *parentItem;
+// if(!parent.isValid())
+// parentItem = rootItem;
+// else
+// parentItem = static_cast<AbstractTreeItem*>(parent.internalPointer());
+// return parentItem->columnCount();
}
QVariant TreeModel::data(const QModelIndex &index, int role) const {
return QVariant();
AbstractTreeItem *item = static_cast<AbstractTreeItem *>(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);
}
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const {
- AbstractTreeItem *item;
- if(!index.isValid())
- item = rootItem;
- else
- item = static_cast<AbstractTreeItem *>(index.internalPointer());
- return item->flags();
+ if(!index.isValid()) {
+ return rootItem->flags() & Qt::ItemIsDropEnabled;
+ } else {
+ AbstractTreeItem *item = static_cast<AbstractTreeItem *>(index.internalPointer());
+ return item->flags();
+ }
}
QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const {
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<AbstractTreeItem *>(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();
}
parentItem = static_cast<AbstractTreeItem *>(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;
parentItem = static_cast<AbstractTreeItem *>(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;
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;
+ }
+}
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;
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
#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));
}
_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<BufferId>();
+ }
+
+ emit bufferListSet();
+}
+
+void BufferViewConfig::initSetBufferList(const QList<BufferId> &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);
+}
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; }
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<BufferId> &bufferList() const { return _buffers; }
+ QVariantList initBufferList() const;
+ void initSetBufferList(const QVariantList &buffers);
+ void initSetBufferList(const QList<BufferId> &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:
NetworkId _networkId;
bool _addNewBuffersAutomatically;
bool _sortAlphabetically;
+ bool _hideInactiveBuffers;
+ int _allowedBufferTypes;
+ int _minimumActivity;
+ QList<BufferId> _buffers;
};
#endif // BUFFERVIEWCONFIG_H
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();
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<int, BufferViewConfig *> BufferViewConfigHash;
#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 {
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"
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++;
}
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);
+}
//! 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;
};
+++ /dev/null
-INSERT INTO coreinfo (key, value) VALUES ('schemaversion', 10)
--- /dev/null
+INSERT INTO user_setting (userid, settingname, settingvalue)
+VALUES (:userid, :settingname, :settingvalue)
--- /dev/null
+SELECT settingvalue
+FROM user_setting
+WHERE userid = :userid AND settingname = :settingname
--- /dev/null
+CREATE TABLE user_setting (
+ userid INTEGER NOT NULL,
+ settingname TEXT NOT NULL,
+ settingvalue BLOB,
+ PRIMARY KEY (userid, settingname)
+)
--- /dev/null
+INSERT INTO coreinfo (key, value) VALUES ('schemaversion', 11)
--- /dev/null
+UPDATE user_setting
+SET settingvalue = :settingvalue
+WHERE userid = :userid AND settingname = :settingname
--- /dev/null
+CREATE TABLE user_setting (
+ userid INTEGER NOT NULL,
+ settingname TEXT NOT NULL,
+ settingvalue BLOB,
+ PRIMARY KEY (userid, settingname)
+)
--- /dev/null
+UPDATE coreinfo
+SET value = 11
+WHERE key = 'schemaversion'
--- /dev/null
+#!/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
}
/*** 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);
/*** 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.
*
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);
}
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
#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();
}
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());
+ }
+}
#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
+
<file>./SQL/SQLite/1/upgrade_000_drop_coreinfo.sql</file>
<file>./SQL/SQLite/1/upgrade_010_create_coreinfo.sql</file>
<file>./SQL/SQLite/1/upgrade_020_update_schemaversion.sql</file>
- <file>./SQL/SQLite/10/delete_backlog_by_uid.sql</file>
- <file>./SQL/SQLite/10/delete_backlog_for_buffer.sql</file>
- <file>./SQL/SQLite/10/delete_backlog_for_network.sql</file>
- <file>./SQL/SQLite/10/delete_buffer_for_bufferid.sql</file>
- <file>./SQL/SQLite/10/delete_buffers_by_uid.sql</file>
- <file>./SQL/SQLite/10/delete_buffers_for_network.sql</file>
- <file>./SQL/SQLite/10/delete_ircservers_for_network.sql</file>
- <file>./SQL/SQLite/10/delete_network.sql</file>
- <file>./SQL/SQLite/10/delete_networks_by_uid.sql</file>
- <file>./SQL/SQLite/10/delete_quasseluser.sql</file>
- <file>./SQL/SQLite/10/insert_buffer.sql</file>
- <file>./SQL/SQLite/10/insert_message.sql</file>
- <file>./SQL/SQLite/10/insert_network.sql</file>
- <file>./SQL/SQLite/10/insert_quasseluser.sql</file>
- <file>./SQL/SQLite/10/insert_sender.sql</file>
- <file>./SQL/SQLite/10/insert_server.sql</file>
- <file>./SQL/SQLite/10/select_authuser.sql</file>
- <file>./SQL/SQLite/10/select_buffer_by_id.sql</file>
- <file>./SQL/SQLite/10/select_buffer_lastseen_messages.sql</file>
- <file>./SQL/SQLite/10/select_bufferByName.sql</file>
- <file>./SQL/SQLite/10/select_bufferExists.sql</file>
- <file>./SQL/SQLite/10/select_buffers.sql</file>
- <file>./SQL/SQLite/10/select_connected_networks.sql</file>
- <file>./SQL/SQLite/10/select_messageRange.sql</file>
- <file>./SQL/SQLite/10/select_messages.sql</file>
- <file>./SQL/SQLite/10/select_messagesOffset.sql</file>
- <file>./SQL/SQLite/10/select_messagesSince.sql</file>
- <file>./SQL/SQLite/10/select_messagesSinceOffset.sql</file>
- <file>./SQL/SQLite/10/select_networkExists.sql</file>
- <file>./SQL/SQLite/10/select_networks_for_user.sql</file>
- <file>./SQL/SQLite/10/select_persistent_channels.sql</file>
- <file>./SQL/SQLite/10/select_servers_for_network.sql</file>
- <file>./SQL/SQLite/10/select_userid.sql</file>
- <file>./SQL/SQLite/10/setup_000_quasseluser.sql</file>
- <file>./SQL/SQLite/10/setup_010_sender.sql</file>
- <file>./SQL/SQLite/10/setup_020_network.sql</file>
- <file>./SQL/SQLite/10/setup_030_buffer.sql</file>
- <file>./SQL/SQLite/10/setup_040_buffer_idx.sql</file>
- <file>./SQL/SQLite/10/setup_050_buffer_cname_idx.sql</file>
- <file>./SQL/SQLite/10/setup_060_backlog.sql</file>
- <file>./SQL/SQLite/10/setup_070_coreinfo.sql</file>
- <file>./SQL/SQLite/10/setup_080_ircservers.sql</file>
- <file>./SQL/SQLite/10/setup_090_create_backlog_idx.sql</file>
- <file>./SQL/SQLite/10/setup_100_create_backlog_idx2.sql</file>
- <file>./SQL/SQLite/10/setup_110_create_buffer_idx.sql</file>
- <file>./SQL/SQLite/10/setup_999_version.sql</file>
- <file>./SQL/SQLite/10/update_buffer_lastseen.sql</file>
- <file>./SQL/SQLite/10/update_buffer_name.sql</file>
- <file>./SQL/SQLite/10/update_buffer_persistent_channel.sql</file>
- <file>./SQL/SQLite/10/update_buffer_set_channel_key.sql</file>
- <file>./SQL/SQLite/10/update_network.sql</file>
- <file>./SQL/SQLite/10/update_network_connected.sql</file>
- <file>./SQL/SQLite/10/update_username.sql</file>
- <file>./SQL/SQLite/10/update_userpassword.sql</file>
<file>./SQL/SQLite/10/upgrade_000_switch_to_msgid.sql</file>
<file>./SQL/SQLite/10/upgrade_010_rename_buffer_table.sql</file>
<file>./SQL/SQLite/10/upgrade_020_create_buffer_table.sql</file>
<file>./SQL/SQLite/10/upgrade_030_copy_buffer_table.sql</file>
<file>./SQL/SQLite/10/upgrade_040_drop_buffer_old_table.sql</file>
<file>./SQL/SQLite/10/upgrade_999_version.sql</file>
+ <file>./SQL/SQLite/11/delete_backlog_by_uid.sql</file>
+ <file>./SQL/SQLite/11/delete_backlog_for_buffer.sql</file>
+ <file>./SQL/SQLite/11/delete_backlog_for_network.sql</file>
+ <file>./SQL/SQLite/11/delete_buffer_for_bufferid.sql</file>
+ <file>./SQL/SQLite/11/delete_buffers_by_uid.sql</file>
+ <file>./SQL/SQLite/11/delete_buffers_for_network.sql</file>
+ <file>./SQL/SQLite/11/delete_ircservers_for_network.sql</file>
+ <file>./SQL/SQLite/11/delete_network.sql</file>
+ <file>./SQL/SQLite/11/delete_networks_by_uid.sql</file>
+ <file>./SQL/SQLite/11/delete_quasseluser.sql</file>
+ <file>./SQL/SQLite/11/insert_buffer.sql</file>
+ <file>./SQL/SQLite/11/insert_message.sql</file>
+ <file>./SQL/SQLite/11/insert_network.sql</file>
+ <file>./SQL/SQLite/11/insert_quasseluser.sql</file>
+ <file>./SQL/SQLite/11/insert_sender.sql</file>
+ <file>./SQL/SQLite/11/insert_server.sql</file>
+ <file>./SQL/SQLite/11/insert_user_setting.sql</file>
+ <file>./SQL/SQLite/11/select_authuser.sql</file>
+ <file>./SQL/SQLite/11/select_buffer_by_id.sql</file>
+ <file>./SQL/SQLite/11/select_buffer_lastseen_messages.sql</file>
+ <file>./SQL/SQLite/11/select_bufferByName.sql</file>
+ <file>./SQL/SQLite/11/select_bufferExists.sql</file>
+ <file>./SQL/SQLite/11/select_buffers.sql</file>
+ <file>./SQL/SQLite/11/select_connected_networks.sql</file>
+ <file>./SQL/SQLite/11/select_messageRange.sql</file>
+ <file>./SQL/SQLite/11/select_messages.sql</file>
+ <file>./SQL/SQLite/11/select_messagesOffset.sql</file>
+ <file>./SQL/SQLite/11/select_messagesSince.sql</file>
+ <file>./SQL/SQLite/11/select_messagesSinceOffset.sql</file>
+ <file>./SQL/SQLite/11/select_networkExists.sql</file>
+ <file>./SQL/SQLite/11/select_networks_for_user.sql</file>
+ <file>./SQL/SQLite/11/select_persistent_channels.sql</file>
+ <file>./SQL/SQLite/11/select_servers_for_network.sql</file>
+ <file>./SQL/SQLite/11/select_user_setting.sql</file>
+ <file>./SQL/SQLite/11/select_userid.sql</file>
+ <file>./SQL/SQLite/11/setup_000_quasseluser.sql</file>
+ <file>./SQL/SQLite/11/setup_010_sender.sql</file>
+ <file>./SQL/SQLite/11/setup_020_network.sql</file>
+ <file>./SQL/SQLite/11/setup_030_buffer.sql</file>
+ <file>./SQL/SQLite/11/setup_040_buffer_idx.sql</file>
+ <file>./SQL/SQLite/11/setup_050_buffer_cname_idx.sql</file>
+ <file>./SQL/SQLite/11/setup_060_backlog.sql</file>
+ <file>./SQL/SQLite/11/setup_070_coreinfo.sql</file>
+ <file>./SQL/SQLite/11/setup_080_ircservers.sql</file>
+ <file>./SQL/SQLite/11/setup_090_create_backlog_idx.sql</file>
+ <file>./SQL/SQLite/11/setup_100_create_backlog_idx2.sql</file>
+ <file>./SQL/SQLite/11/setup_110_create_buffer_idx.sql</file>
+ <file>./SQL/SQLite/11/setup_120_create_user_setting.sql</file>
+ <file>./SQL/SQLite/11/setup_999_version.sql</file>
+ <file>./SQL/SQLite/11/update_buffer_lastseen.sql</file>
+ <file>./SQL/SQLite/11/update_buffer_name.sql</file>
+ <file>./SQL/SQLite/11/update_buffer_persistent_channel.sql</file>
+ <file>./SQL/SQLite/11/update_buffer_set_channel_key.sql</file>
+ <file>./SQL/SQLite/11/update_network.sql</file>
+ <file>./SQL/SQLite/11/update_network_connected.sql</file>
+ <file>./SQL/SQLite/11/update_user_setting.sql</file>
+ <file>./SQL/SQLite/11/update_username.sql</file>
+ <file>./SQL/SQLite/11/update_userpassword.sql</file>
+ <file>./SQL/SQLite/11/upgrade_000_create_user_setting.sql</file>
+ <file>./SQL/SQLite/11/upgrade_999_version.sql</file>
<file>./SQL/SQLite/2/upgrade_000_drop_buffergroup.sql</file>
<file>./SQL/SQLite/2/upgrade_010_update_schemaversion.sql</file>
<file>./SQL/SQLite/3/upgrade_000_update_backlog_flags.sql</file>
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());
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);
*/
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
#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;
#include "aboutdlg.h"
#include "chatwidget.h"
#include "bufferview.h"
+#include "bufferviewconfig.h"
+#include "bufferviewfilter.h"
+#include "bufferviewmanager.h"
#include "chatline.h"
#include "chatline-old.h"
#include "client.h"
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<NetworkId>());
- addBufferView(tr("All Channels"), model, BufferViewFilter::AllNets|BufferViewFilter::NoQueries|BufferViewFilter::NoServers, QList<NetworkId>());
- addBufferView(tr("All Queries"), model, BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoServers, QList<NetworkId>());
- addBufferView(tr("All Networks"), model, BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoQueries, QList<NetworkId>());
- addBufferView(tr("Full Custom"), model, BufferViewFilter::FullCustom, QList<NetworkId>());
+ 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<NetworkId> &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<BufferViewDock *>(action->parent());
+ if(dock && actionData.toInt() != bufferViewConfigId) {
+ removeAction(action);
+ dock->deleteLater();
+ }
+ }
}
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() {
}
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);
}
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";
}
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<BufferViewDock *>(action->parent());
+ if(dock && actionData.toInt() != -1) {
+ removeAction(action);
+ dock->deleteLater();
+ }
+ }
+
ui.menuViews->setEnabled(false);
//ui.menuCore->setEnabled(false);
ui.actionDisconnectCore->setEnabled(false);
}
-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);
#include "ui_mainwin.h"
#include "qtui.h"
-#include "bufferviewfilter.h"
#include <QSystemTrayIcon>
#include <QTimer>
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
virtual ~MainWin();
void init();
- QDockWidget *addBufferView(const QString &, QAbstractItemModel *, const BufferViewFilter::Modes &, const QList<NetworkId> &);
+ void addBufferView(BufferViewConfig *config = 0);
AbstractUiMsg *layoutMsg(const Message &);
void displayTrayIconMessage(const QString &title, const QString &message);
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();
void makeTrayIconBlink();
void saveStatusBarStatus(bool enabled);
+ void loadLayout();
+
signals:
void connectToCore(const QVariantMap &connInfo);
void disconnectFromCore();
BufferId currentBuffer;
QString currentProfile;
- QList<QDockWidget *> netViews;
+ QList<QDockWidget *> _netViews;
NickListWidget *nickListWidget;
QAction *actionEditNetworks;
#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
#include "bufferviewsettingspage.h"
+#include <QMessageBox>
+
#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() {
void BufferViewSettingsPage::reset() {
ui.bufferViewList->clear();
- _viewToListPos.clear();
- _listPosToView.clear();
QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
BufferViewConfig *config;
while(changedConfigIter != changedConfigIterEnd) {
- config = (*changedConfigIter);
+ config = changedConfigIter.value();
changedConfigIter = _changedBufferViews.erase(changedConfigIter);
config->deleteLater();
}
config->deleteLater();
}
+ _deleteBufferViews.clear();
+
setChangedState(false);
}
foreach(BufferViewConfig *bufferViewConfig, bufferViewConfigs) {
addBufferView(bufferViewConfig);
}
+
+ _ignoreWidgetChanges = true;
+ // load network selector
+ ui.networkSelector->clear();
+ ui.networkSelector->addItem("All");
+ ui.networkSelector->setItemData(0, qVariantFromValue<NetworkId>(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<NetworkId>(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<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
+ QHash<BufferViewConfig *, BufferViewConfig *>::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<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
+ QList<BufferViewConfig *>::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) {
}
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 *>(qobject_cast<QObject *>(config)));
connect(config, SIGNAL(updatedRemotely()), this, SLOT(updateBufferView()));
+ connect(config, SIGNAL(destroyed()), this, SLOT(bufferViewDeleted()));
}
void BufferViewSettingsPage::addBufferView(int bufferViewId) {
addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewId));
}
+void BufferViewSettingsPage::bufferViewDeleted() {
+ BufferViewConfig *config = static_cast<BufferViewConfig *>(sender());
+ QObject *obj;
+ for(int i = 0; i < ui.bufferViewList->count(); i++) {
+ obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
+ if(config == static_cast<BufferViewConfig *>(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<BufferId> 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<QObject *>();
+ if(config == qobject_cast<BufferViewConfig *>(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<QObject *>();
+ return qobject_cast<BufferViewConfig *>(obj);
+ } else {
+ return 0;
+ }
}
void BufferViewSettingsPage::updateBufferView() {
return;
}
ui.bufferViewList->item(itemPos)->setText(config->bufferViewName());
+ if(itemPos == ui.bufferViewList->currentRow())
+ loadConfig(config);
}
void BufferViewSettingsPage::on_addBufferView_clicked() {
if(!Client::bufferViewManager())
return;
- BufferViewConfig *config = Client::bufferViewManager()->bufferViewConfig(bufferViewId(ui.bufferViewList->currentRow()));
+ BufferViewConfig *config = bufferView(ui.bufferViewList->currentRow());
if(!config)
return;
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<NetworkId>() == 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<NetworkId>());
+
+ int minimumActivity = 0;
+ if(ui.minimumActivitySelector->currentIndex() > 0)
+ minimumActivity = 1 << (ui.minimumActivitySelector->currentIndex() - 1);
+ config->setMinimumActivity(minimumActivity);
+
+ if(_newBufferViews.contains(config)) {
+ QList<BufferId> 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<BufferViewConfig *, BufferViewConfig *>::iterator iter = _changedBufferViews.begin();
+ QHash<BufferViewConfig *, BufferViewConfig *>::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<BufferViewFilter *>(ui.bufferViewPreview->model());
+ if(filter && filter->config() == config)
+ filter->setConfig(changedConfig);
+ ui.bufferViewPreview->setConfig(changedConfig);
+
return changedConfig;
}
#include "ui_bufferviewsettingspage.h"
#include "ui_buffervieweditdlg.h"
+#include <QItemSelection>
+
class BufferViewConfig;
class BufferViewSettingsPage : public SettingsPage {
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<int, int> _viewToListPos;
- QHash<int, int> _listPosToView;
+ bool _ignoreWidgetChanges;
// list of bufferviews to create
QList<BufferViewConfig *> _newBufferViews;
+ // list of buferViews to delete
+ QList<int> _deleteBufferViews;
+
// Hash of pointers to cloned bufferViewConfigs holding the changes
QHash<BufferViewConfig *, BufferViewConfig *> _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();
};
<rect>
<x>0</x>
<y>0</y>
- <width>507</width>
- <height>485</height>
+ <width>672</width>
+ <height>529</height>
</rect>
</property>
<property name="windowTitle" >
</layout>
</item>
<item>
- <widget class="QGroupBox" name="groupBox" >
+ <widget class="QGroupBox" name="settingsGroupBox" >
<property name="title" >
<string>Buffer View Settings</string>
</property>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
- <string>Show only Buffers from:</string>
+ <string>Network:</string>
</property>
</widget>
</item>
<item>
- <widget class="QComboBox" name="comboBox" />
+ <widget class="QComboBox" name="networkSelector" >
+ <item>
+ <property name="text" >
+ <string>All</string>
+ </property>
+ </item>
+ </widget>
</item>
</layout>
</item>
</property>
<layout class="QVBoxLayout" >
<item>
- <widget class="QCheckBox" name="checkBox" >
+ <widget class="QCheckBox" name="onlyStatusBuffers" >
<property name="text" >
<string>Status Buffers</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_2" >
+ <widget class="QCheckBox" name="onlyChannelBuffers" >
<property name="text" >
<string>Channel Buffers</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_3" >
+ <widget class="QCheckBox" name="onlyQueryBuffers" >
<property name="text" >
<string>Query Buffers</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_4" >
+ <widget class="QCheckBox" name="hideInactiveBuffers" >
+ <property name="text" >
+ <string>Hide inactive Buffers</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="addNewBuffersAutomatically" >
<property name="text" >
<string>Add new Buffers automatically</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_5" >
+ <widget class="QCheckBox" name="sortAlphabetically" >
+ <property name="text" >
+ <string>Sort alphabetically</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3" >
<property name="text" >
- <string>Sort Buffers alphabetically</string>
+ <string>Minimum Activity:</string>
</property>
</widget>
</item>
+ <item>
+ <widget class="QComboBox" name="minimumActivitySelector" >
+ <item>
+ <property name="text" >
+ <string>No Activity</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Other Activity</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>New Message</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Highlight</string>
+ </property>
+ </item>
+ </widget>
+ </item>
<item>
<spacer>
<property name="orientation" >
</layout>
</widget>
</item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Preview:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="BufferView" name="bufferViewPreview" />
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>BufferView</class>
+ <extends>QTreeView</extends>
+ <header>bufferview.h</header>
+ </customwidget>
+ </customwidgets>
<resources>
<include location="../../icons/icons.qrc" />
</resources>
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>27</y>
- <width>800</width>
- <height>549</height>
- </rect>
- </property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" >
- <property name="spacing" >
- <number>6</number>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
</property>
- <property name="margin" >
+ <property name="bottomMargin" >
<number>0</number>
</property>
<item>
<x>0</x>
<y>0</y>
<width>800</width>
- <height>27</height>
+ <height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<addaction name="menuDebug" />
<addaction name="menuHelp" />
</widget>
- <widget class="QStatusBar" name="statusbar" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>576</y>
- <width>800</width>
- <height>24</height>
- </rect>
- </property>
- </widget>
+ <widget class="QStatusBar" name="statusbar" />
<action name="actionNetworkList" >
<property name="enabled" >
<bool>false</bool>
</action>
<action name="actionQuit" >
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >
- <normaloff>:/22x22/actions/oxygen/22x22/actions/application-exit.png</normaloff>:/22x22/actions/oxygen/22x22/actions/application-exit.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/application-exit.png</iconset>
</property>
<property name="text" >
<string>Quit...</string>
</action>
<action name="actionSettingsDlg" >
<property name="icon" >
- <iconset>
- <normaloff/>
- </iconset>
+ <iconset/>
</property>
<property name="text" >
<string>Configure Quassel...</string>
</action>
<action name="actionManageViews" >
<property name="enabled" >
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="text" >
<string>Manage Views...</string>
<bool>true</bool>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >
- <normaloff>:/icons/quassel-icon.png</normaloff>:/icons/quassel-icon.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >:/icons/quassel-icon.png</iconset>
</property>
<property name="text" >
<string>About Quassel IRC...</string>
<bool>false</bool>
</property>
<property name="icon" >
- <iconset>
- <normaloff/>
- </iconset>
+ <iconset/>
</property>
<property name="text" >
<string>Disconnect from Core</string>
<bool>false</bool>
</property>
<property name="icon" >
- <iconset>
- <normaloff/>
- </iconset>
+ <iconset/>
</property>
<property name="text" >
<string>Connect to Core...</string>
* 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 <QAction>
+#include <QFlags>
+#include <QHeaderView>
+#include <QInputDialog>
+#include <QLineEdit>
+#include <QMenu>
+#include <QMessageBox>
+
/*****************************************
* The TreeView showing the Buffers
*****************************************/
#endif
}
-void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QList<NetworkId> 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<QAction *> oldactions = header()->actions();
}
+void BufferView::setFilteredModel(QAbstractItemModel *model_, BufferViewConfig *config) {
+ BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(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<NetworkId>())
+ setRootIndex(child);
+ }
+ }
+}
+
void BufferView::joinChannel(const QModelIndex &index) {
BufferInfo::Type bufferType = (BufferInfo::Type)index.data(NetworkModel::BufferTypeRole).value<int>();
QSize BufferView::sizeHint() const {
- return QSize(120, 50);
+ return QTreeView::sizeHint();
if(!model())
return QTreeView::sizeHint();
}
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);
+}
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#ifndef _BUFFERVIEW_H_
-#define _BUFFERVIEW_H_
+#ifndef BUFFERVIEW_H_
+#define BUFFERVIEW_H_
-#include <QtGui>
-#include <QFlags>
+#include <QDockWidget>
+#include <QModelIndex>
+#include <QTreeView>
+#include <QPointer>
-#include "bufferviewfilter.h"
+#include "bufferviewconfig.h"
+
+#include "types.h"
/*****************************************
* The TreeView showing the Buffers
public:
BufferView(QWidget *parent = 0);
void init();
+
void setModel(QAbstractItemModel *model);
- void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QList<NetworkId> 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 &);
void toggleHeader(bool checked);
void showContextMenu(const QPoint &);
+private:
+ QPointer<BufferViewConfig> _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
#include <QColor>
+#include "client.h"
#include "networkmodel.h"
#include "uisettings.h"
/*****************************************
* The Filter for the Tree View
*****************************************/
-BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, const Modes &filtermode, const QList<NetworkId> &nets)
+BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, BufferViewConfig *config)
: QSortFilterProxyModel(model),
- mode(filtermode),
- networks(QSet<NetworkId>::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<NetworkId>();
QList< QPair<NetworkId, BufferId> > 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<BufferId>();
+ 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<NetworkId>();
- BufferId bufferuid = index.data(NetworkModel::BufferIdRole).value<BufferId>();
-
- 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<BufferId>();
+ 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<BufferId>();
- return buffers.contains(bufferuid);
- }
-
- return true;
+ BufferId bufferId = sourceModel()->data(source_bufferIndex, NetworkModel::BufferIdRole).value<BufferId>();
+ return _config->bufferList().contains(bufferId);
}
bool BufferViewFilter::filterAcceptNetwork(const QModelIndex &source_index) const {
- NetworkId net = source_index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
- 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<NetworkId>();
+ }
}
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;
}
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>();
+ BufferId rightBufferId = sourceModel()->data(source_right, NetworkModel::BufferIdRole).value<BufferId>();
+ 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>();
+ NetworkId rightNetworkId = sourceModel()->data(source_right, NetworkModel::NetworkIdRole).value<NetworkId>();
+
+ 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 {
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();
+}
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#ifndef _BUFFERVIEWFILTER_H_
-#define _BUFFERVIEWFILTER_H_
+#ifndef BUFFERVIEWFILTER_H_
+#define BUFFERVIEWFILTER_H_
-#include <QFlags>
#include <QDropEvent>
-#include <QSortFilterProxyModel>
+#include <QFlags>
+#include <QPointer>
#include <QSet>
-// #include "buffer.h"
+#include <QSortFilterProxyModel>
+
#include "types.h"
+#include "bufferviewconfig.h"
/*****************************************
* Buffer View Filter
};
Q_DECLARE_FLAGS(Modes, Mode);
- BufferViewFilter(QAbstractItemModel *model, const Modes &mode, const QList<NetworkId> &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<NetworkId> networks;
- QSet<BufferId> buffers;
+ QPointer<BufferViewConfig> _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_
quasselVersion = "0.2.0-beta1-pre";
quasselDate = "2008-04-13";
- quasselBuild = 729;
+ quasselBuild = 733;
//! 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;
}