From 6fc26e28a07a2b6bbc60ee786514a802e628d6d3 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Mon, 18 Jun 2007 15:09:21 +0000 Subject: [PATCH 01/16] Changed the BufferView System to a MVC Design Pattern --- gui/CMakeLists.txt | 6 +- gui/buffer.cpp | 7 + gui/buffer.h | 12 ++ gui/bufferview.cpp | 203 ++++++------------- gui/bufferview.h | 118 +++++------ gui/bufferviewwidget.cpp | 403 +++++++++++++++++++++++++++++++++++++ gui/bufferviewwidget.h | 168 ++++++++++++++++ gui/mainwin.cpp | 57 +++--- gui/mainwin.h | 8 +- gui/ui/bufferviewwidget.ui | 25 +-- 10 files changed, 745 insertions(+), 262 deletions(-) create mode 100644 gui/bufferviewwidget.cpp create mode 100644 gui/bufferviewwidget.h diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 91ff392c..f118eae7 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,11 +1,11 @@ SET(gui_SRCS chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp buffer.cpp bufferwidget.cpp - identities.cpp coreconnectdlg.cpp guiproxy.cpp bufferview.cpp style.cpp settingsdlg.cpp settingspages.cpp) + identities.cpp coreconnectdlg.cpp guiproxy.cpp bufferview.cpp bufferviewwidget.cpp style.cpp settingsdlg.cpp settingspages.cpp) SET(gui_HDRS style.h) SET(gui_MOCS chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h - guiproxy.h bufferview.h buffer.h bufferwidget.h settingsdlg.h settingspages.h) + guiproxy.h bufferview.h buffer.h bufferwidget.h bufferviewwidget.h settingsdlg.h settingspages.h) SET(gui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui - bufferview.ui bufferwidget.ui settingsdlg.ui + bufferviewwidget.ui bufferwidget.ui settingsdlg.ui buffermgmntsettingspage.ui connectionsettingspage.ui) # This prepends ui/ to the UIC names, so we don't have to do this ourselves. diff --git a/gui/buffer.cpp b/gui/buffer.cpp index 9c9726e1..cf764c1b 100644 --- a/gui/buffer.cpp +++ b/gui/buffer.cpp @@ -67,6 +67,13 @@ void Buffer::init() { } +QString Buffer::displayName() { + if(bufferType() == ServerBuffer) + return tr("status"); + else + return bufferName(); +} + void Buffer::setActive(bool a) { if(a != active) { active = a; diff --git a/gui/buffer.h b/gui/buffer.h index 7738ebe1..944b07cc 100644 --- a/gui/buffer.h +++ b/gui/buffer.h @@ -49,16 +49,27 @@ class Buffer : public QObject { static void init(); enum Type { ServerBuffer, ChannelBuffer, QueryBuffer }; + + enum Activity { + NoActivity = 0x00, + OtherActivity = 0x01, + NewMessage = 0x02, + Highlight = 0x40 + }; + Q_DECLARE_FLAGS(ActivityLevel, Activity) + Type bufferType() { return type; } bool isActive() { return active; } QString networkName() { return _networkName; } QString bufferName() { return _bufferName; } + QString displayName(); BufferId bufferId() { return id; } QList contents() { return lines; } VarMap nickList() { return nicks; } QString topic() { return _topic; } QString ownNick() { return _ownNick; } + bool isStatusBuffer() { return bufferType() == ServerBuffer; } signals: void userInput(BufferId, QString); @@ -104,5 +115,6 @@ class Buffer : public QObject { QList lines; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(Buffer::ActivityLevel) #endif diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index f49898cf..e0923cff 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -18,171 +18,82 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "global.h" #include "bufferview.h" - -BufferViewWidget::BufferViewWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - - //setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); -} - - -QSize BufferViewWidget::sizeHint() const { - return QSize(150,100); - -} - -/**************************************************************************/ - -BufferView::BufferView(QString n, int m, QStringList nets, QWidget *parent) : QDockWidget(parent) { - setObjectName(QString("View-"+n)); // should be unique for mainwindow state! - name = n; mode = m; - setWindowTitle(name); +#include "bufferviewwidget.h" + +/***************************************** +* The TreeView showing the Buffers +*****************************************/ +BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, Modes filtermode, QStringList nets, QObject *parent) : QSortFilterProxyModel(parent) { + setSourceModel(model); + mode = filtermode; networks = nets; - currentBuffer = 0; - setWidget(new BufferViewWidget(this)); - tree = qobject_cast(widget())->tree(); - tree->header()->hide(); - tree->setSortingEnabled(true); - tree->setRootIsDecorated(true); - tree->setIndentation(10); - //tree->setAnimated(true); - connect(tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(itemClicked(QTreeWidgetItem*))); - connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*))); - connect(this, SIGNAL(fakeUserInput(BufferId, QString)), guiProxy, SLOT(gsUserInput(BufferId, QString))); + connect(model, SIGNAL(invalidateFilter()), this, SLOT(invalidateMe())); + connect(model, SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), this, SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); + + connect(this, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), model, SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); + connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model, SLOT(doubleClickReceived(const QModelIndex &))); } -void BufferView::setBuffers(QList buffers) { - tree->clear(); bufitems.clear(); netitems.clear(); - foreach(Buffer *b, buffers) { - bufferUpdated(b); - } +void BufferViewFilter::invalidateMe() { + invalidateFilter(); } -void BufferView::bufferUpdated(Buffer *b) { - if(bufitems.contains(b)) { - // FIXME this looks ugly - /* - this is actually fugly! :) - EgS - if anyone else wonders what this does: it takes the TreeItem related to the buffer out of the parents child list - therefore we need to know the childs index - */ - QTreeWidgetItem *item = bufitems[b]->parent()->takeChild(bufitems[b]->parent()->indexOfChild(bufitems[b])); - delete item; - bufitems.remove(b); - } - if(shouldShow(b)) { - QString net = b->networkName(); - QString buf = b->bufferName(); - QTreeWidgetItem *item; - QStringList label; - if(b->bufferType() == Buffer::ServerBuffer) label << tr("Status"); - else label << buf; - if((mode & SomeNets) || ( mode & AllNets)) { - if(!netitems.contains(net)) { - netitems[net] = new QTreeWidgetItem(tree, QStringList(net)); - netitems[net]->setFlags(Qt::ItemIsEnabled); - } - QTreeWidgetItem *ni = netitems[net]; - ni->setExpanded(true); - ni->setFlags(Qt::ItemIsEnabled); - item = new QTreeWidgetItem(ni, label); - } else { - item = new QTreeWidgetItem(label); - } - //item->setFlags(Qt::ItemIsEnabled); - bufitems[b] = item; - // TODO Use style engine! - if(!b->isActive()) { - item->setForeground(0, QColor("grey")); - } - if(b == currentBuffer) { - // this fixes the multiple simultaneous selections - emit bufferSelected(b); - //item->setSelected(true); - } - } - foreach(QString key, netitems.keys()) { - if(!netitems[key]->childCount()) { - delete netitems[key]; - QTreeWidgetItem *item = netitems[key]->parent()->takeChild(netitems[key]->parent()->indexOfChild(netitems[key])); - delete item; - netitems.remove(key); - } - } +void BufferViewFilter::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { + emit updateSelection(mapFromSource(index), command); } -void BufferView::bufferActivity(uint level, Buffer *b) { - QColor c; - if(bufitems.contains(b) and b != currentBuffer) { - if(level & Highlight) { - c = QColor(Qt::red); - } else if(level & NewMessage) { - c = QColor(Qt::darkYellow); - } else if(level & OtherActivity) { - c = QColor(Qt::darkGreen); - } - bufitems[b]->setForeground(0, c); - } +void BufferViewFilter::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { + emit currentChanged(mapToSource(current), mapToSource(previous)); } -void BufferView::clearActivity(Buffer *b) { - QColor c; - // it should be sane not to check if b is in bufitems since we just checked before calling this function - if(b->isActive()) { - c = QColor(Qt::black); - } else { - c = QColor(Qt::gray); - } - bufitems[b]->setForeground(0, c); +void BufferViewFilter::doubleClickReceived(const QModelIndex &clicked) { + emit doubleClicked(mapToSource(clicked)); } -bool BufferView::shouldShow(Buffer *b) { - // bool f = false; - if((mode & NoActive) && b->isActive()) return false; - if((mode & NoInactive) && !b->isActive()) return false; - if((mode & NoChannels) && b->bufferType() == Buffer::ChannelBuffer) return false; - if((mode & NoQueries) && b->bufferType() == Buffer::QueryBuffer) return false; - if((mode & NoServers) && b->bufferType() == Buffer::ServerBuffer) return false; - if((mode & SomeNets) && !networks.contains(b->networkName())) return false; +bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { + QModelIndex child = source_parent.child(source_row, 0); + if(!child.isValid()) + return true; // can't imagine this case but true sounds good :) + + Buffer::Type bufferType = (Buffer::Type) child.data(BufferTreeModel::BufferTypeRole).toInt(); + if((mode & NoChannels) && bufferType == Buffer::ChannelBuffer) return false; + if((mode & NoQueries) && bufferType == Buffer::QueryBuffer) return false; + if((mode & NoServers) && bufferType == Buffer::ServerBuffer) return false; + + bool isActive = child.data(BufferTreeModel::BufferActiveRole).toBool(); + if((mode & NoActive) && isActive) return false; + if((mode & NoInactive) && !isActive) return false; + + QString net = child.data(Qt::DisplayRole).toString(); + if((mode & SomeNets) && !networks.contains(net)) return false; + return true; } -void BufferView::bufferDestroyed(Buffer *b) { - +/***************************************** +* The TreeView showing the Buffers +*****************************************/ +BufferView::BufferView(QWidget *parent) : QTreeView(parent) { } -void BufferView::itemClicked(QTreeWidgetItem *item) { - Buffer *b = bufitems.key(item); - if(b) { - // there is a buffer associated with the item (aka: status/channel/query) - emit bufferSelected(b); - } else { - // network item - item->setExpanded(!item->isExpanded()); - } +void BufferView::init() { + setIndentation(10); + header()->hide(); + header()->hideSection(1); + + setDragEnabled(true); + setAcceptDrops(true); + setDropIndicatorShown(true); + + connect(selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), model(), SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); + connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model(), SLOT(doubleClickReceived(const QModelIndex &))); + connect(model(), SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), selectionModel(), SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); } -void BufferView::itemDoubleClicked(QTreeWidgetItem *item) { - Buffer *b = bufitems.key(item); - if(b && Buffer::ChannelBuffer == b->bufferType()) { - emit fakeUserInput(b->bufferId(), QString("/join " + b->bufferName())); - emit bufferSelected(b); - } +void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets) { + BufferViewFilter *filter = new BufferViewFilter(model, mode, nets); + setModel(filter); } -void BufferView::selectBuffer(Buffer *b) { - QTreeWidgetItem *item = 0; - if(bufitems.contains(b)) item = bufitems[b]; - QList sel = tree->selectedItems(); - foreach(QTreeWidgetItem *i, sel) { if(i != item) i->setSelected(false); } - if(item) { - item->setSelected(true); - clearActivity(b); - currentBuffer = b; - } else { - currentBuffer = 0; - } -} diff --git a/gui/bufferview.h b/gui/bufferview.h index a76e3272..49f3a809 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -18,86 +18,64 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _BUFFERVIEW_H_ -#define _BUFFERVIEW_H_ +#ifndef _BUFFERVIEWWIDGET_H_ +#define _BUFFERVIEWWIDGET_H_ #include -#include "ui_bufferview.h" -#include "guiproxy.h" +#include #include "buffer.h" -typedef QHash > BufferHash; - -class BufferViewWidget : public QWidget { +/***************************************** + * Buffer View Filter + *****************************************/ +class BufferViewFilter : public QSortFilterProxyModel { Q_OBJECT + +public: + enum Mode { + NoActive = 0x01, + NoInactive = 0x02, + SomeNets = 0x04, + AllNets = 0x08, + NoChannels = 0x10, + NoQueries = 0x20, + NoServers = 0x40 + }; + Q_DECLARE_FLAGS(Modes, Mode) + + BufferViewFilter(QAbstractItemModel *model, Modes mode, QStringList nets, QObject *parent = 0); + +public slots: + void invalidateMe(); + void changeCurrent(const QModelIndex &, const QModelIndex &); + void doubleClickReceived(const QModelIndex &); + void select(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +signals: + void currentChanged(const QModelIndex &, const QModelIndex &); + void doubleClicked(const QModelIndex &); + void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +private: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - public: - BufferViewWidget(QWidget *parent = 0); - - QTreeWidget *tree() { return ui.tree; } - - virtual QSize sizeHint () const; - - signals: - void bufferSelected(QString net, QString buf); - - private slots: - - - private: - Ui::BufferViewWidget ui; - + Modes mode; + QStringList networks; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(BufferViewFilter::Modes) -class BufferView : public QDockWidget { +/***************************************** + * The TreeView showing the Buffers + *****************************************/ +class BufferView : public QTreeView { Q_OBJECT - - public: - enum Mode { - NoActive = 0x01, NoInactive = 0x02, - SomeNets = 0x04, AllNets = 0x08, - NoChannels = 0x10, NoQueries = 0x20, NoServers = 0x40 - }; - enum ActivityLevel { - NoActivity = 0x00, OtherActivity = 0x01, - NewMessage = 0x02, Highlight = 0x40 - }; - - BufferView(QString name, int mode, QStringList nets = QStringList(), QWidget *parent = 0); - void setMode(int mode, QStringList nets = QStringList()); - void setName(QString name); - - - public slots: - void bufferUpdated(Buffer *); - void bufferActivity(uint, Buffer *); - void bufferDestroyed(Buffer *); - void setBuffers(QList); - void selectBuffer(Buffer *); - - signals: - void bufferSelected(Buffer *); - void fakeUserInput(BufferId, QString); - - private slots: - void itemClicked(QTreeWidgetItem *item); - void itemDoubleClicked(QTreeWidgetItem *item); - - private: - int mode; - QString name; - QStringList networks; - Buffer *currentBuffer; - //QHash > buffers; - QHash bufitems; - QHash netitems; - //QHash > items; - QTreeWidget *tree; - - bool shouldShow(Buffer *); - void clearActivity(Buffer *); +public: + BufferView(QWidget *parent = 0); + void init(); + void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets); + }; -#endif +#endif \ No newline at end of file diff --git a/gui/bufferviewwidget.cpp b/gui/bufferviewwidget.cpp new file mode 100644 index 00000000..31023f74 --- /dev/null +++ b/gui/bufferviewwidget.cpp @@ -0,0 +1,403 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "global.h" +#include "bufferviewwidget.h" + +/***************************************** + * Buffer Items stored in the Tree Model + *****************************************/ +TreeItem::TreeItem(QList &data, TreeItem *parent) { + itemData = data; + parentItem = parent; + foreground = Qt::black; +} + +TreeItem::TreeItem(TreeItem *parent) { + itemData = QList(); + parentItem = parent; + foreground = Qt::black; +} + +TreeItem::~TreeItem() { + qDeleteAll(childItems); +} + +void TreeItem::appendChild(TreeItem *item) { + childItems.append(item); +} + +void TreeItem::removeChild(int row) { + childItems.removeAt(row); +} + +TreeItem *TreeItem::child(int row) { + return childItems.value(row); +} + +int TreeItem::childCount() const { + return childItems.count(); +} + +int TreeItem::row() const { + if(parentItem) + return parentItem->childItems.indexOf(const_cast(this)); + else + return 0; +} + +TreeItem *TreeItem::parent() { + return parentItem; +} + +int TreeItem::columnCount() const { + return itemData.count(); +} + +void TreeItem::setForeground(QColor newcolor) { + foreground = newcolor; +} + +QVariant TreeItem::data(int column, int role) const { + switch(role) { + case Qt::DisplayRole: + if(column < itemData.count()) + return itemData[column]; + else + return QVariant(); + + case Qt::ForegroundRole: + return foreground; + + default: + return QVariant(); + + } +} + +/***************************************** +* Fancy Buffer Items +*****************************************/ +BufferTreeItem::BufferTreeItem(Buffer *buffer, TreeItem *parent) : TreeItem(parent) { + buf = buffer; + activity = Buffer::NoActivity; +} + +void BufferTreeItem::setActivity(const Buffer::ActivityLevel &level) { + activity = level; +} + +QString BufferTreeItem::text(int column) const { + switch(column) { + case 0: + return buf->displayName(); + case 1: + return buf->networkName(); + default: + return QString(); + } +} + +QColor BufferTreeItem::foreground(int column) const { + // for the time beeing we ignore the column :) + if(activity & Buffer::Highlight) { + return QColor(Qt::red); + } else if(activity & Buffer::NewMessage) { + return QColor(Qt::darkYellow); + } else if(activity & Buffer::OtherActivity) { + return QColor(Qt::darkGreen); + } else { + if(buf->isActive()) + return QColor(Qt::black); + else + return QColor(Qt::gray); + } +} + + +QVariant BufferTreeItem::data(int column, int role) const { + switch(role) { + case Qt::DisplayRole: + return text(column); + case Qt::ForegroundRole: + return foreground(column); + case BufferTreeModel::BufferTypeRole: + return buf->bufferType(); + case BufferTreeModel::BufferActiveRole: + return buf->isActive(); + default: + return QVariant(); + } +} + +/***************************************** + * BufferTreeModel + *****************************************/ +BufferTreeModel::BufferTreeModel(QObject *parent) : QAbstractItemModel(parent) { + QList rootData; + rootData << "Buffer" << "Network"; + rootItem = new TreeItem(rootData, 0); + + connect(this, SIGNAL(fakeUserInput(BufferId, QString)), guiProxy, SLOT(gsUserInput(BufferId, QString))); +} + +BufferTreeModel::~BufferTreeModel() { + delete rootItem; +} + +QModelIndex BufferTreeModel::index(int row, int column, const QModelIndex &parent) const { + if(!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeItem *parentItem; + + if(!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + TreeItem *childItem = parentItem->child(row); + if(childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex BufferTreeModel::parent(const QModelIndex &index) const { + if(!index.isValid()) + return QModelIndex(); + + TreeItem *childItem = static_cast(index.internalPointer()); + TreeItem *parentItem = childItem->parent(); + + if(parentItem == rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int BufferTreeModel::rowCount(const QModelIndex &parent) const { + TreeItem *parentItem; + if(parent.column() > 0) + return 0; + + if(!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->childCount(); +} + +int BufferTreeModel::columnCount(const QModelIndex &parent) const { + if(parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return rootItem->columnCount(); +} + +QVariant BufferTreeModel::data(const QModelIndex &index, int role) const { + if(!index.isValid()) + return QVariant(); + + TreeItem *item = static_cast(index.internalPointer()); + return item->data(index.column(), role); +} + +Qt::ItemFlags BufferTreeModel::flags(const QModelIndex &index) const { + if(!index.isValid()) + return 0; + + // I think this is pretty ugly.. + if(isBufferIndex(index)) { + Buffer *buffer = getBufferByIndex(index); + if(buffer->bufferType() == Buffer::QueryBuffer) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + else + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + } +} + +QVariant BufferTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return rootItem->data(section, role); + else + return QVariant(); +} + +bool BufferTreeModel::removeRow(int row, const QModelIndex &parent) { + beginRemoveRows(parent, row, row); + TreeItem *item = static_cast(parent.internalPointer()); + item->removeChild(row); + endRemoveRows(); + return true; +} + +bool BufferTreeModel::isBufferIndex(const QModelIndex &index) const { + return parent(index) != QModelIndex(); +} + +Buffer *BufferTreeModel::getBufferByIndex(const QModelIndex &index) const { + BufferTreeItem *item = static_cast(index.internalPointer()); + return item->buffer(); +} + +QModelIndex BufferTreeModel::getOrCreateNetworkItemIndex(Buffer *buffer) { + QString net = buffer->networkName(); + + if(networkItem.contains(net)) { + return index(networkItem[net]->row(), 0); + } else { + QList data; + data << net << ""; + + int nextRow = rootItem->childCount(); + + beginInsertRows(QModelIndex(), nextRow, nextRow); + rootItem->appendChild(new TreeItem(data, rootItem)); + endInsertRows(); + + networkItem[net] = rootItem->child(nextRow); + return index(nextRow, 0); + } +} + +QModelIndex BufferTreeModel::getOrCreateBufferItemIndex(Buffer *buffer) { + QModelIndex networkItemIndex = getOrCreateNetworkItemIndex(buffer); + + if(bufferItem.contains(buffer)) { + return index(bufferItem[buffer]->row(), 0, networkItemIndex); + } else { + // first we determine the parent of the new Item + TreeItem *networkItem = static_cast(networkItemIndex.internalPointer()); + + int nextRow = networkItem->childCount(); + + beginInsertRows(networkItemIndex, nextRow, nextRow); + networkItem->appendChild(new BufferTreeItem(buffer, networkItem)); + endInsertRows(); + + bufferItem[buffer] = static_cast(networkItem->child(nextRow)); + return index(nextRow, 0, networkItemIndex); + } +} + +QStringList BufferTreeModel::mimeTypes() const { + QStringList types; + types << "application/Quassel/BufferItem/row" + << "application/Quassel/BufferItem/network"; + return types; +} + +QMimeData *BufferTreeModel::mimeData(const QModelIndexList &indexes) const { + QMimeData *mimeData = new QMimeData(); + + QModelIndex index = indexes.first(); + + mimeData->setData("application/Quassel/BufferItem/row", QByteArray::number(index.row())); + mimeData->setData("application/Quassel/BufferItem/network", getBufferByIndex(index)->networkName().toUtf8()); + return mimeData; +} + +bool BufferTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { + int sourcerow = data->data("application/Quassel/BufferItem/row").toInt(); + QString network = QString::fromUtf8(data->data("application/Quassel/BufferItem/network")); + + if(!networkItem.contains(network)) + return false; + + if(!isBufferIndex(parent)) // dropping at a network -> no merging needed + return false; + + Buffer *sourceBuffer = static_cast(networkItem[network]->child(sourcerow))->buffer(); + Buffer *targetBuffer = getBufferByIndex(parent); + + qDebug() << "merging" << sourceBuffer->bufferName() << "with" << targetBuffer->bufferName(); + bufferItem.remove(getBufferByIndex(parent)); + removeRow(parent.row(), BufferTreeModel::parent(parent)); + + return true; +} + +void BufferTreeModel::bufferUpdated(Buffer *buffer) { + QModelIndex itemindex = getOrCreateBufferItemIndex(buffer); + emit invalidateFilter(); + emit dataChanged(itemindex, itemindex); +} + +// This Slot indicates that the user has selected a different buffer in the gui +void BufferTreeModel::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { + if(isBufferIndex(current)) { + currentBuffer = getBufferByIndex(current); + bufferActivity(Buffer::NoActivity, currentBuffer); + emit bufferSelected(currentBuffer); + } +} + +// we received a double click on a buffer, so we're going to join it +void BufferTreeModel::doubleClickReceived(const QModelIndex &clicked) { + if(isBufferIndex(clicked)) { + Buffer *buffer = getBufferByIndex(clicked); + if(!buffer->isStatusBuffer()) + emit fakeUserInput(buffer->bufferId(), QString("/join " + buffer->bufferName())); + } + +} + +void BufferTreeModel::bufferActivity(Buffer::ActivityLevel level, Buffer *buffer) { + if(bufferItem.contains(buffer) and buffer != currentBuffer) + bufferItem[buffer]->setActivity(level); + else + bufferItem[buffer]->setActivity(Buffer::NoActivity); + bufferUpdated(buffer); +} + +void BufferTreeModel::selectBuffer(Buffer *buffer) { + QModelIndex index = getOrCreateBufferItemIndex(buffer); + emit updateSelection(index, QItemSelectionModel::ClearAndSelect); +} + + +/***************************************** + * This Widget Contains the BufferView + *****************************************/ +BufferViewWidget::BufferViewWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + +QSize BufferViewWidget::sizeHint() const { + return QSize(150,100); +} + + +/***************************************** + * Dock and API for the BufferViews + *****************************************/ +BufferViewDock::BufferViewDock(QAbstractItemModel *model, QString viewname, BufferViewFilter::Modes mode, QStringList nets, QWidget *parent) : QDockWidget(parent) { + setObjectName(QString("View-" + viewname)); // should be unique for mainwindow state! + setWindowTitle(viewname); + + BufferViewWidget *viewWidget = new BufferViewWidget(this); + viewWidget->treeView()->setFilteredModel(model, mode, nets); + viewWidget->treeView()->init(); + setWidget(viewWidget); +} diff --git a/gui/bufferviewwidget.h b/gui/bufferviewwidget.h new file mode 100644 index 00000000..a14d173d --- /dev/null +++ b/gui/bufferviewwidget.h @@ -0,0 +1,168 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BUFFERVIEW_H_ +#define _BUFFERVIEW_H_ + +#include +#include + +#include "guiproxy.h" +#include "buffer.h" +#include "ui_bufferviewwidget.h" +#include "bufferview.h" + +/***************************************** + * general item used in the Tree Model + *****************************************/ +class TreeItem { +public: + TreeItem(QList &data, TreeItem *parent = 0); + TreeItem(TreeItem *parent = 0); + virtual ~TreeItem(); + + void appendChild(TreeItem *child); + void removeChild(int row); + + TreeItem *child(int row); + int childCount() const; + int columnCount() const; + virtual QVariant data(int column, int role) const; + int row() const; + TreeItem *parent(); + + void setForeground(QColor); + +private: + QList childItems; + TreeItem *parentItem; + QList itemData; + + QColor foreground; +}; + + +/***************************************** + * Fancy Buffer Items + *****************************************/ +class BufferTreeItem : public TreeItem{ +public: + BufferTreeItem(Buffer *, TreeItem *parent = 0); + QVariant data(int column, int role) const; + Buffer *buffer() const { return buf; } + void setActivity(const Buffer::ActivityLevel &); + +private: + QString text(int column) const; + QColor foreground(int column) const; + Buffer *buf; + Buffer::ActivityLevel activity; +}; + + +/***************************************** + * BufferTreeModel + *****************************************/ +class BufferTreeModel : public QAbstractItemModel { + Q_OBJECT + +public: + enum myRoles { + BufferTypeRole = Qt::UserRole, + BufferActiveRole + }; + + + BufferTreeModel(QObject *parent = 0); + ~BufferTreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + void clearActivity(Buffer *buffer); + +public slots: + void bufferUpdated(Buffer *); + void changeCurrent(const QModelIndex &, const QModelIndex &); + void selectBuffer(Buffer *buffer); + void doubleClickReceived(const QModelIndex &); + void bufferActivity(Buffer::ActivityLevel, Buffer *buffer); + +signals: + void bufferSelected(Buffer *); + void invalidateFilter(); + void fakeUserInput(BufferId, QString); + void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +private: + bool isBufferIndex(const QModelIndex &) const; + Buffer *getBufferByIndex(const QModelIndex &) const; + QModelIndex getOrCreateNetworkItemIndex(Buffer *buffer); + QModelIndex getOrCreateBufferItemIndex(Buffer *buffer); + + bool removeRow(int row, const QModelIndex &parent = QModelIndex()); + + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &) const; + bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &); + TreeItem *rootItem; + + QHash networkItem; + QHash bufferItem; + Buffer *currentBuffer; +}; + + + + +/***************************************** + * This Widget Contains the BufferView + *****************************************/ +class BufferViewWidget : public QWidget { + Q_OBJECT + +public: + BufferViewWidget(QWidget *parent = 0); + virtual QSize sizeHint () const; + BufferView *treeView() { return ui.treeView; } + +private: + Ui::BufferViewWidget ui; + +}; + + +/***************************************** + * Dock and API for the BufferViews + *****************************************/ +class BufferViewDock : public QDockWidget { + Q_OBJECT + +public: + BufferViewDock(QAbstractItemModel *model, QString name, BufferViewFilter::Modes mode, QStringList nets = QStringList(), QWidget *parent = 0); +}; + + +#endif diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 7c4eb517..0a691214 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -29,7 +29,7 @@ #include "mainwin.h" #include "buffer.h" -#include "bufferview.h" +#include "bufferviewwidget.h" #include "serverlist.h" #include "coreconnectdlg.h" #include "settingsdlg.h" @@ -153,32 +153,41 @@ void MainWin::setupMenus() { } void MainWin::setupViews() { - BufferView *all = new BufferView(tr("All Buffers"), BufferView::AllNets); - registerBufferView(all); - addDockWidget(Qt::LeftDockWidgetArea, all); - BufferView *allchans = new BufferView(tr("All Channels"), BufferView::AllNets|BufferView::NoQueries|BufferView::NoServers); - registerBufferView(allchans); - addDockWidget(Qt::LeftDockWidgetArea, allchans); - BufferView *allqrys = new BufferView(tr("All Queries"), BufferView::AllNets|BufferView::NoChannels|BufferView::NoServers); - registerBufferView(allqrys); - addDockWidget(Qt::RightDockWidgetArea, allqrys); - BufferView *allnets = new BufferView(tr("All Networks"), BufferView::AllNets|BufferView::NoChannels|BufferView::NoQueries); - registerBufferView(allnets); - addDockWidget(Qt::RightDockWidgetArea, allnets); + BufferTreeModel *model = new BufferTreeModel(); + connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); + connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); + connect(this, SIGNAL(bufferUpdated(Buffer *)), model, SLOT(bufferUpdated(Buffer *))); + connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), model, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); + + BufferViewDock *all = new BufferViewDock(model, tr("All Buffers"), BufferViewFilter::AllNets); + registerBufferViewDock(all); + + BufferViewDock *allchans = new BufferViewDock(model, tr("All Channels"), BufferViewFilter::AllNets|BufferViewFilter::NoQueries|BufferViewFilter::NoServers); + registerBufferViewDock(allchans); + + BufferViewDock *allqrys = new BufferViewDock(model, tr("All Queries"), BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoServers); + registerBufferViewDock(allqrys); + + + BufferViewDock *allnets = new BufferViewDock(model, tr("All Networks"), BufferViewFilter::AllNets|BufferViewFilter::NoChannels|BufferViewFilter::NoQueries); + registerBufferViewDock(allnets); + ui.menuViews->addSeparator(); } -void MainWin::registerBufferView(BufferView *view) { +void MainWin::registerBufferViewDock(BufferViewDock *dock) { + addDockWidget(Qt::LeftDockWidgetArea, dock); + dock->setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); + netViews.append(dock); + ui.menuViews->addAction(dock->toggleViewAction()); + + /* connect(this, SIGNAL(bufferSelected(Buffer *)), view, SLOT(selectBuffer(Buffer *))); - connect(this, SIGNAL(bufferUpdated(Buffer *)), view, SLOT(bufferUpdated(Buffer *))); - connect(this, SIGNAL(bufferActivity(uint, Buffer *)), view, SLOT(bufferActivity(uint, Buffer *))); connect(this, SIGNAL(bufferDestroyed(Buffer *)), view, SLOT(bufferDestroyed(Buffer *))); connect(view, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); view->setBuffers(buffers.values()); - view->setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); - netViews.append(view); - ui.menuViews->addAction(view->toggleViewAction()); + */ } void MainWin::showServerList() { @@ -305,17 +314,19 @@ void MainWin::recvMessage(Message msg) { b = getBuffer(net, msg.target); } */ + + Buffer *b = getBuffer(msg.buffer); - uint level = BufferView::OtherActivity; + Buffer::ActivityLevel level = Buffer::OtherActivity; if(msg.type == Message::Plain or msg.type == Message::Notice){ - level |= BufferView::NewMessage; + level |= Buffer::NewMessage; } if(msg.flags & Message::Highlight){ - level |= BufferView::Highlight; + level |= Buffer::Highlight; } - emit bufferActivity(level, b); + //b->displayMsg(msg); b->appendChatLine(new ChatLine(msg)); } diff --git a/gui/mainwin.h b/gui/mainwin.h index df7154c0..8092395c 100644 --- a/gui/mainwin.h +++ b/gui/mainwin.h @@ -30,7 +30,7 @@ class ServerListDlg; class CoreConnectDlg; -class BufferView; +class BufferViewDock; class Buffer; class BufferWidget; class SettingsDlg; @@ -50,7 +50,7 @@ class MainWin : public QMainWindow { ~MainWin(); void init(); - void registerBufferView(BufferView *); + void registerBufferViewDock(BufferViewDock *); protected: void closeEvent(QCloseEvent *event); @@ -59,7 +59,7 @@ class MainWin : public QMainWindow { void sendInput(BufferId, QString message); void bufferSelected(Buffer *); void bufferUpdated(Buffer *); - void bufferActivity(uint, Buffer *); + void bufferActivity(Buffer::ActivityLevel, Buffer *); void bufferDestroyed(Buffer *); void backlogReceived(Buffer *, QList); void requestBacklog(BufferId, QVariant, QVariant); @@ -124,7 +124,7 @@ class MainWin : public QMainWindow { //QHash > coreBackLog; QList coreBuffers; - QList netViews; + QList netViews; QTimer *layoutTimer; QList layoutQueue; diff --git a/gui/ui/bufferviewwidget.ui b/gui/ui/bufferviewwidget.ui index 1eaebe32..c1efab78 100644 --- a/gui/ui/bufferviewwidget.ui +++ b/gui/ui/bufferviewwidget.ui @@ -34,28 +34,21 @@ 0 - - - - 5 - 5 - 0 - 0 - - - - - 16777215 - 16777215 - - + - false + true + + + BufferView + QTreeView +
bufferview.h
+
+
-- 2.20.1 From 62f292ad143923a3b774b9bd14f83f3b640c0cb8 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Mon, 18 Jun 2007 19:47:01 +0000 Subject: [PATCH 02/16] Minor Update: - some minor fixes - preparation for query merging and custom views --- gui/bufferview.cpp | 9 +++++++++ gui/bufferview.h | 3 +++ gui/bufferviewwidget.cpp | 11 ++++++++++- gui/mainwin.cpp | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index e0923cff..4045f206 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -97,3 +97,12 @@ void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::M setModel(filter); } +void BufferView::setModel(QAbstractItemModel *model) { + QTreeView::setModel(model); + init(); +} + +void BufferView::dragEnterEvent(QDragEnterEvent *event) { + // not yet needed... this will be usefull to keep track of the active view when customizing them with drag and drop + QTreeView::dragEnterEvent(event); +} diff --git a/gui/bufferview.h b/gui/bufferview.h index 49f3a809..0dea9bbe 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -73,8 +73,11 @@ class BufferView : public QTreeView { public: BufferView(QWidget *parent = 0); void init(); + void setModel(QAbstractItemModel *model); void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets); + void dragEnterEvent(QDragEnterEvent *); + }; diff --git a/gui/bufferviewwidget.cpp b/gui/bufferviewwidget.cpp index 31023f74..e21b98ba 100644 --- a/gui/bufferviewwidget.cpp +++ b/gui/bufferviewwidget.cpp @@ -331,6 +331,16 @@ bool BufferTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, Buffer *sourceBuffer = static_cast(networkItem[network]->child(sourcerow))->buffer(); Buffer *targetBuffer = getBufferByIndex(parent); + if(sourceBuffer == targetBuffer) // we won't merge with ourself :) + return false; + + + if(QMessageBox::warning(static_cast(QObject::parent()), + tr("Merge Buffers?"), + tr("Do you really want to merge the following Buffers?
%1.%2
%3.%4").arg(sourceBuffer->networkName()).arg(sourceBuffer->bufferName()).arg(targetBuffer->networkName()).arg(targetBuffer->bufferName()), + QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) + return false; + qDebug() << "merging" << sourceBuffer->bufferName() << "with" << targetBuffer->bufferName(); bufferItem.remove(getBufferByIndex(parent)); removeRow(parent.row(), BufferTreeModel::parent(parent)); @@ -398,6 +408,5 @@ BufferViewDock::BufferViewDock(QAbstractItemModel *model, QString viewname, Buff BufferViewWidget *viewWidget = new BufferViewWidget(this); viewWidget->treeView()->setFilteredModel(model, mode, nets); - viewWidget->treeView()->init(); setWidget(viewWidget); } diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 0a691214..1e88be01 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -153,7 +153,7 @@ void MainWin::setupMenus() { } void MainWin::setupViews() { - BufferTreeModel *model = new BufferTreeModel(); + BufferTreeModel *model = new BufferTreeModel(this); connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); connect(this, SIGNAL(bufferUpdated(Buffer *)), model, SLOT(bufferUpdated(Buffer *))); -- 2.20.1 From 7ec4585cecc74ce8d9a94b0e52f00a96d105e79e Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 00:50:42 +0000 Subject: [PATCH 03/16] Big update this time - Core has been redesigned to be multi-user capable. At least partly. (BR #42) * Architecture changes mostly complete: - Core has been split in Core (static) and CoreSession (per-user objects) - Connection stuff has been moved out of CoreProxy into Core - Lots of cleanups, and we have finally real singletons! - Global is now (externally) a static class -- changes throughout the code * Monolithic Quassel works (or at least it seems to) * Standalone Core and GUI disabled for now: - While most of the new infrastructure is in place in Core, we still need GUI stuff for auth (BR #17) - Syncing with Core as well as getting session states not done yet Next steps will include the redesign of the GUI to make that cleaner as well (BR #41) --- CMakeLists.txt | 4 + Quassel.kdevelop.filelist | 44 +++--- core/core.cpp | 295 +++++++++++++++++++++++++++++++++----- core/core.h | 97 ++++++++++++- core/coreproxy.cpp | 91 ++---------- core/coreproxy.h | 17 +-- core/server.cpp | 6 +- core/server.h | 6 +- core/sqlitestorage.cpp | 3 +- core/storage.h | 3 + gui/bufferview.h | 3 +- gui/coreconnectdlg.cpp | 2 +- gui/guiproxy.h | 3 +- gui/identities.cpp | 12 +- gui/identities.h | 2 +- gui/mainwin.cpp | 2 +- gui/serverlist.cpp | 26 ++-- main/global.cpp | 66 ++++++--- main/global.h | 44 +++--- main/main_mono.cpp | 27 ++-- 20 files changed, 529 insertions(+), 224 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a365e5e..d2a89fd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,10 @@ IF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) MESSAGE(FATAL_ERROR "\nYou have not selected which parts of Quassel I should build. Aborting.\nRun 'cmake -DBUILD=', where contains one or more of 'core', 'gui' or 'monolithic', or 'all' to build everything.\n") ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) +IF(BUILD_CORE OR BUILD_GUI) + MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n") +ENDIF(BUILD_CORE OR BUILD_GUI) + SET(CMAKE_BUILD_TYPE Debug) # Define files diff --git a/Quassel.kdevelop.filelist b/Quassel.kdevelop.filelist index 4924499c..8fb3b40f 100644 --- a/Quassel.kdevelop.filelist +++ b/Quassel.kdevelop.filelist @@ -1,26 +1,16 @@ # KDevelop Custom Project File List -network/server.h -network/server.cpp core/core.cpp core/CMakeLists.txt core/core.h -gui/channelwidget.cpp -gui/channelwidget.h gui/CMakeLists.txt -gui/identitiesdlg.ui -gui/identitieseditdlg.ui gui/mainwin.cpp gui/mainwin.h -gui/networkeditdlg.ui -gui/nickeditdlg.ui gui/serverlist.cpp gui/serverlist.h -gui/serverlistdlg.ui images/iconmap.xml images/icons.qrc main/main_core.cpp main/main_mono.cpp -network/CMakeLists.txt CMakeLists.txt COPYING Doxyfile @@ -32,7 +22,6 @@ core/coreproxy.cpp core/coreproxy.h main/util.cpp main/util.h -gui/coreconnectdlg.ui gui/coreconnectdlg.cpp gui/coreconnectdlg.h main/proxy_common.h @@ -40,11 +29,8 @@ main/CMakeLists.txt images/qirc-icon.png main/global.cpp main/global.h -gui/channelwidget-old.ui gui/identities.cpp gui/identities.h -network/buffer.cpp -network/buffer.h gui/channelwidgetinput.h gui/channelwidgetinput.cpp plugins/plugin.h @@ -55,14 +41,11 @@ gui/ui/identitieseditdlg.ui gui/ui/ircwidget.ui gui/ui/mainwin.ui gui/ui/networkeditdlg.ui -gui/ui/networkwidget.ui gui/ui/nickeditdlg.ui gui/ui/servereditdlg.ui gui/ui/serverlistdlg.ui gui/ui/settingsdlg.ui gui/ui/bufferview.ui -gui/bufferview.cpp -gui/bufferview.h gui/buffer.cpp gui/buffer.h main/message.cpp @@ -74,3 +57,30 @@ gui/chatwidget.cpp gui/chatwidget.h gui/style.cpp gui/style.h +main/logger.cpp +main/logger.h +templates/cpp +templates/h +gui/bufferwidget.h +gui/bufferwidget.cpp +main/settings.cpp +main/settings.h +gui/settingsdlg.h +gui/settingsdlg.cpp +gui/settingspages.cpp +gui/settingspages.h +gui/bufferview.cpp +gui/bufferview.h +core/backlog.cpp +core/backlog.h +ChangeLog +core/storage.cpp +core/storage.h +core/sqlitestorage.cpp +dev-notes +dev-notes/builtin_cmds.obsolete.cpp +gui +gui/tabcompleter.cpp +gui/tabcompleter.h +core +core/sqlitestorage.h diff --git a/core/core.cpp b/core/core.cpp index 821ec2a5..b1815d9c 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005/06 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel IRC Development Team * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -28,28 +28,212 @@ #include #include +Core *Core::instanceptr = 0; + +Core * Core::instance() { + if(instanceptr) return instanceptr; + instanceptr = new Core(); + instanceptr->init(); + return instanceptr; +} + +void Core::destroy() { + delete instanceptr; + instanceptr = 0; +} + Core::Core() { - if(core) qFatal("Trying to instantiate more than one Core object!"); +} + +void Core::init() { if(!SqliteStorage::isAvailable()) { qFatal("Sqlite is currently required! Please make sure your Qt library has sqlite support enabled."); } //SqliteStorage::init(); storage = new SqliteStorage(); - user = storage->validateUser("Default", "password"); - if(!user) user = storage->addUser("Default", "password"); - Q_ASSERT(user); + connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateGlobalData(UserId, QString))); + connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); + //startListening(); // FIXME + if(Global::runMode == Global::Monolithic) { // TODO Make GUI user configurable + guiUser = storage->validateUser("Default", "password"); + if(!guiUser) guiUser = storage->addUser("Default", "password"); + Q_ASSERT(guiUser); + Global::setGuiUser(guiUser); + createSession(guiUser); + } else guiUser = 0; - connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); - connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); - connect(coreProxy, SIGNAL(gsUserInput(BufferId, QString)), this, SLOT(msgFromGUI(BufferId, QString))); - connect(coreProxy, SIGNAL(gsImportBacklog()), storage, SLOT(importOldBacklog())); - connect(coreProxy, SIGNAL(gsRequestBacklog(BufferId, QVariant, QVariant)), this, SLOT(sendBacklog(BufferId, QVariant, QVariant))); - connect(this, SIGNAL(displayMsg(Message)), coreProxy, SLOT(csDisplayMsg(Message))); - connect(this, SIGNAL(displayStatusMsg(QString, QString)), coreProxy, SLOT(csDisplayStatusMsg(QString, QString))); - connect(this, SIGNAL(backlogData(BufferId, QList, bool)), coreProxy, SLOT(csBacklogData(BufferId, QList, bool))); - connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); - connect(this, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); + // Read global settings from config file + QSettings s; + s.beginGroup("Global"); + foreach(QString unum, s.childGroups()) { + UserId uid = unum.toUInt(); + s.beginGroup(unum); + foreach(QString key, s.childKeys()) { + Global::updateData(uid, key, s.value(key)); + } + s.endGroup(); + } + s.endGroup(); +} + +Core::~Core() { + foreach(QTcpSocket *sock, validClients.keys()) { + delete sock; + } + qDeleteAll(sessions); + delete storage; +} + +CoreSession *Core::session(UserId uid) { + Core *core = instance(); + if(core->sessions.contains(uid)) return core->sessions[uid]; + else return 0; +} + +CoreSession *Core::guiSession() { + Core *core = instance(); + if(core->guiUser && core->sessions.contains(core->guiUser)) return core->sessions[core->guiUser]; + else return 0; +} + +CoreSession *Core::createSession(UserId uid) { + Core *core = instance(); + Q_ASSERT(!core->sessions.contains(uid)); + CoreSession *sess = new CoreSession(uid, core->storage); + core->sessions[uid] = sess; + connect(sess, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), core, SLOT(recvProxySignal(CoreSignal, QVariant, QVariant, QVariant))); + return sess; +} + + +bool Core::startListening(uint port) { + if(!server.listen(QHostAddress::Any, port)) { + qWarning(QString(QString("Could not open GUI client port %1: %2").arg(port).arg(server.errorString())).toAscii()); + return false; + } + qDebug() << "Listening for GUI clients on port" << server.serverPort(); + return true; +} + +void Core::stopListening() { + server.close(); + qDebug() << "No longer listening for GUI clients."; +} + +void Core::incomingConnection() { + // TODO implement SSL + QTcpSocket *socket = server.nextPendingConnection(); + connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected())); + connect(socket, SIGNAL(readyRead()), this, SLOT(clientHasData())); + blockSizes.insert(socket, (quint32)0); + qDebug() << "Client connected from " << socket->peerAddress().toString(); +} + +void Core::clientHasData() { + QTcpSocket *socket = dynamic_cast(sender()); + Q_ASSERT(socket && blockSizes.contains(socket)); + quint32 bsize = blockSizes.value(socket); + QVariant item; + while(readDataFromDevice(socket, bsize, item)) { + if(validClients.contains(socket)) { + QList sigdata = item.toList(); + if((GUISignal)sigdata[0].toInt() == GS_UPDATE_GLOBAL_DATA) { + processClientUpdate(socket, sigdata[1].toString(), sigdata[2]); + } else { + sessions[validClients[socket]]->processSignal((GUISignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + } + } else { + // we need to auth the client + try { + processClientInit(socket, item); + } catch(Storage::AuthError) { + qWarning() << "Authentification error!"; // FIXME + socket->close(); + return; + } catch(Exception e) { + qWarning() << "Client init error:" << e.msg(); + socket->close(); + return; + } + } + blockSizes[socket] = bsize = 0; + } + blockSizes[socket] = bsize; +} + +void Core::clientDisconnected() { + QTcpSocket *socket = dynamic_cast(sender()); + blockSizes.remove(socket); + validClients.remove(socket); + qDebug() << "Client disconnected."; + // TODO remove unneeded sessions - if necessary/possible... +} + +void Core::processClientInit(QTcpSocket *socket, const QVariant &v) { + VarMap msg = v.toMap(); + if(msg["GUIProtocol"].toUInt() != GUI_PROTOCOL) { + //qWarning() << "Client version mismatch."; + throw Exception("GUI client version mismatch"); + } + // Auth + UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString()); // throws exception if this failed + + // Find or create session for validated user + CoreSession *sess; + if(sessions.contains(uid)) sess = sessions[uid]; + else { + sess = createSession(uid); + validClients[socket] = uid; + } + VarMap reply; + VarMap coreData; + // FIXME + QStringList dataKeys = Global::keys(uid); + QString key; + foreach(key, dataKeys) { + coreData[key] = Global::data(key); + } + reply["CoreData"] = coreData; + reply["SessionState"] = sess->sessionState(); + QList sigdata; + sigdata.append(CS_CORE_STATE); sigdata.append(QVariant(reply)); sigdata.append(QVariant()); sigdata.append(QVariant()); + writeDataToDevice(socket, QVariant(sigdata)); + sess->sendServerStates(); +} + +void Core::processClientUpdate(QTcpSocket *socket, QString key, const QVariant &data) { + UserId uid = validClients[socket]; + Global::updateData(uid, key, data); + QList sigdata; + sigdata.append(CS_UPDATE_GLOBAL_DATA); sigdata.append(key); sigdata.append(data); sigdata.append(QVariant()); + foreach(QTcpSocket *s, validClients.keys()) { + if(validClients[s] == uid && s != socket) writeDataToDevice(s, QVariant(sigdata)); + } +} + +void Core::updateGlobalData(UserId uid, QString key) { + QVariant data = Global::data(uid, key); + QList sigdata; + sigdata.append(CS_UPDATE_GLOBAL_DATA); sigdata.append(key); sigdata.append(data); sigdata.append(QVariant()); + foreach(QTcpSocket *socket, validClients.keys()) { + if(validClients[socket] == uid) writeDataToDevice(socket, QVariant(sigdata)); + } +} + +void Core::recvProxySignal(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + CoreSession *sess = qobject_cast(sender()); + Q_ASSERT(sess); + UserId uid = sess->userId(); + QList sigdata; + sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3); + //qDebug() << "Sending signal: " << sigdata; + foreach(QTcpSocket *socket, validClients.keys()) { + if(validClients[socket] == uid) writeDataToDevice(socket, QVariant(sigdata)); + } +} + +/* // Read global settings from config file QSettings s; s.beginGroup("Global"); @@ -65,30 +249,56 @@ Core::Core() { connect(global, SIGNAL(dataPutLocally(QString)), SLOT(globalDataUpdated(QString))); } + */ + +CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_storage) { + coreProxy = new CoreProxy(); + connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); + + connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); + connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); + connect(coreProxy, SIGNAL(gsUserInput(BufferId, QString)), this, SLOT(msgFromGui(BufferId, QString))); + connect(coreProxy, SIGNAL(gsImportBacklog()), storage, SLOT(importOldBacklog())); + connect(coreProxy, SIGNAL(gsRequestBacklog(BufferId, QVariant, QVariant)), this, SLOT(sendBacklog(BufferId, QVariant, QVariant))); + connect(this, SIGNAL(displayMsg(Message)), coreProxy, SLOT(csDisplayMsg(Message))); + connect(this, SIGNAL(displayStatusMsg(QString, QString)), coreProxy, SLOT(csDisplayStatusMsg(QString, QString))); + connect(this, SIGNAL(backlogData(BufferId, QList, bool)), coreProxy, SLOT(csBacklogData(BufferId, QList, bool))); + connect(this, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); + connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); + connect(Global::instance(), SIGNAL(dataUpdatedRemotely(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); + connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); + +} + +CoreSession::~CoreSession() { -Core::~Core() { - //foreach(Server *s, servers) { - // delete s; - //} - delete storage; } -void Core::globalDataUpdated(QString key) { - QVariant data = global->getData(key); +UserId CoreSession::userId() { + return user; +} + +void CoreSession::processSignal(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + coreProxy->recv(sig, arg1, arg2, arg3); +} + +void CoreSession::globalDataUpdated(UserId uid, QString key) { + Q_ASSERT(uid == userId()); + QVariant data = Global::data(userId(), key); QSettings s; - s.setValue(QString("Global/")+key, data); + s.setValue(QString("Global/%1/").arg(userId())+key, data); } -void Core::connectToIrc(QStringList networks) { +void CoreSession::connectToIrc(QStringList networks) { foreach(QString net, networks) { if(servers.contains(net)) { } else { - Server *server = new Server(net); + Server *server = new Server(userId(), net); connect(this, SIGNAL(serverStateRequested()), server, SLOT(sendState())); connect(this, SIGNAL(connectToIrc(QString)), server, SLOT(connectToIrc(QString))); connect(this, SIGNAL(disconnectFromIrc(QString)), server, SLOT(disconnectFromIrc(QString))); - connect(this, SIGNAL(msgFromGUI(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString))); + connect(this, SIGNAL(msgFromGui(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString))); connect(server, SIGNAL(serverState(QString, VarMap)), coreProxy, SLOT(csServerState(QString, VarMap))); //connect(server, SIGNAL(displayMsg(Message)), this, SLOT(recvMessageFromServer(Message))); connect(server, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8)), this, SLOT(recvMessageFromServer(Message::Type, QString, QString, QString, quint8))); @@ -101,7 +311,7 @@ void Core::connectToIrc(QStringList networks) { connect(server, SIGNAL(nickUpdated(QString, QString, VarMap)), coreProxy, SLOT(csNickUpdated(QString, QString, VarMap))); connect(server, SIGNAL(ownNickSet(QString, QString)), coreProxy, SLOT(csOwnNickSet(QString, QString))); connect(server, SIGNAL(queryRequested(QString, QString)), coreProxy, SLOT(csQueryRequested(QString, QString))); - // add error handling + // TODO add error handling connect(server, SIGNAL(connected(QString)), coreProxy, SLOT(csServerConnected(QString))); connect(server, SIGNAL(disconnected(QString)), this, SLOT(serverDisconnected(QString))); @@ -112,20 +322,20 @@ void Core::connectToIrc(QStringList networks) { } } -void Core::serverDisconnected(QString net) { +void CoreSession::serverDisconnected(QString net) { delete servers[net]; servers.remove(net); coreProxy->csServerDisconnected(net); } -void Core::msgFromGUI(BufferId bufid, QString msg) { - emit msgFromGUI(bufid.network(), bufid.buffer(), msg); +void CoreSession::msgFromGui(BufferId bufid, QString msg) { + emit msgFromGui(bufid.network(), bufid.buffer(), msg); } // ALL messages coming pass through these functions before going to the GUI. // So this is the perfect place for storing the backlog and log stuff. -void Core::recvMessageFromServer(Message::Type type, QString target, QString text, QString sender, quint8 flags) { +void CoreSession::recvMessageFromServer(Message::Type type, QString target, QString text, QString sender, quint8 flags) { Server *s = qobject_cast(this->sender()); Q_ASSERT(s); BufferId buf; @@ -140,17 +350,32 @@ void Core::recvMessageFromServer(Message::Type type, QString target, QString tex emit displayMsg(msg); } -void Core::recvStatusMsgFromServer(QString msg) { +void CoreSession::recvStatusMsgFromServer(QString msg) { Server *s = qobject_cast(sender()); Q_ASSERT(s); emit displayStatusMsg(s->getNetwork(), msg); } -QList Core::getBuffers() { + +QList CoreSession::buffers() const { return storage->requestBuffers(user); } -void Core::sendBacklog(BufferId id, QVariant v1, QVariant v2) { + +QVariant CoreSession::sessionState() { + VarMap v; + QList bufs; + foreach(BufferId id, storage->requestBuffers(user)) { bufs.append(QVariant::fromValue(id)); } + v["Buffers"] = bufs; + + return v; +} + +void CoreSession::sendServerStates() { + emit serverStateRequested(); +} + +void CoreSession::sendBacklog(BufferId id, QVariant v1, QVariant v2) { QList log; QList msglist; if(v1.type() == QVariant::DateTime) { @@ -172,4 +397,4 @@ void Core::sendBacklog(BufferId id, QVariant v1, QVariant v2) { } -Core *core = 0; +//Core *core = 0; diff --git a/core/core.h b/core/core.h index a90a8f6f..400c21eb 100644 --- a/core/core.h +++ b/core/core.h @@ -21,16 +21,105 @@ #ifndef _CORE_H_ #define _CORE_H_ -#include #include #include #include #include "server.h" -#include "backlog.h" #include "storage.h" #include "global.h" +#include "coreproxy.h" + +class CoreSession; +class Core : public QObject { + Q_OBJECT + + public: + static Core * instance(); + static void destroy(); + + static CoreSession * session(UserId); + static CoreSession * guiSession(); + static CoreSession * createSession(UserId); + + private slots: + void recvProxySignal(CoreSignal, QVariant, QVariant, QVariant); + bool startListening(uint port = 4242); + void stopListening(); + void incomingConnection(); + void clientHasData(); + void clientDisconnected(); + void updateGlobalData(UserId, QString); + + private: + Core(); + ~Core(); + void init(); + static Core *instanceptr; + + void processClientInit(QTcpSocket *socket, const QVariant &v); + void processClientUpdate(QTcpSocket *socket, QString key, const QVariant &data); + + UserId guiUser; + QHash sessions; + Storage *storage; + + QTcpServer server; // TODO: implement SSL + QHash validClients; + QHash blockSizes; +}; + +class CoreSession : public QObject { + Q_OBJECT + + public: + CoreSession(UserId, Storage *); + ~CoreSession(); + + QList buffers() const; + inline UserId userId(); + QVariant sessionState(); + CoreProxy *proxy(); + + public slots: + void connectToIrc(QStringList); + void processSignal(GUISignal, QVariant, QVariant, QVariant); + void sendBacklog(BufferId, QVariant, QVariant); + void msgFromGui(BufferId, QString message); + void sendServerStates(); + + signals: + void proxySignal(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + + void msgFromGui(QString net, QString buf, QString message); + void displayMsg(Message message); + void displayStatusMsg(QString, QString); + + void connectToIrc(QString net); + void disconnectFromIrc(QString net); + void serverStateRequested(); + + void backlogData(BufferId, QList, bool done); + + void bufferIdUpdated(BufferId); + + private slots: + //void recvProxySignal(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + void globalDataUpdated(UserId, QString); + void recvStatusMsgFromServer(QString msg); + void recvMessageFromServer(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None); + void serverDisconnected(QString net); + + private: + CoreProxy *coreProxy; + Storage *storage; + QHash servers; + UserId user; + +}; + +/* class Core : public QObject { Q_OBJECT @@ -71,6 +160,8 @@ class Core : public QObject { }; -extern Core *core; +*/ +//extern Core *core; + #endif diff --git a/core/coreproxy.cpp b/core/coreproxy.cpp index 5ae8d961..c6325eef 100644 --- a/core/coreproxy.cpp +++ b/core/coreproxy.cpp @@ -26,88 +26,11 @@ #include "core.h" CoreProxy::CoreProxy() { - if(coreProxy) qFatal("Trying to instantiate more than one CoreProxy object!"); - coreProxy = this; - core = new Core(); - - connect(global, SIGNAL(dataPutLocally(QString)), this, SLOT(updateGlobalData(QString))); - connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); - if(!server.listen(QHostAddress::Any, 4242)) { - qFatal(QString(QString("Could not open GUI client port %1: %2").arg(4242).arg(server.errorString())).toAscii()); - } - qDebug() << "Listening for GUI clients on port" << server.serverPort() << "."; -} - -void CoreProxy::incomingConnection() { - QTcpSocket *socket = server.nextPendingConnection(); - connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected())); - connect(socket, SIGNAL(readyRead()), this, SLOT(clientHasData())); - clients.append(socket); - blockSizes.insert(socket, (quint32)0); - qDebug() << "Client connected from " << socket->peerAddress().toString(); -} - -void CoreProxy::clientHasData() { - QTcpSocket *socket = dynamic_cast(sender()); - Q_ASSERT(socket && blockSizes.contains(socket)); - quint32 bsize = blockSizes.value(socket); - QVariant item; - while(readDataFromDevice(socket, bsize, item)) { - QList sigdata = item.toList(); - Q_ASSERT(sigdata.size() == 4); - switch((GUISignal)sigdata[0].toInt()) { - case GS_CLIENT_INIT: processClientInit(socket, sigdata[1]); break; - case GS_UPDATE_GLOBAL_DATA: processClientUpdate(socket, sigdata[1].toString(), sigdata[2]); break; - //case GS_CLIENT_READY: processClientReady(sigdata[1], sigdata[2], sigdata[3]); break; - default: recv((GUISignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); break; - } - blockSizes[socket] = bsize = 0; - } - blockSizes[socket] = bsize; -} - -void CoreProxy::clientDisconnected() { - QTcpSocket *socket = dynamic_cast(sender()); - blockSizes.remove(socket); - clients.removeAll(socket); - qDebug() << "Client disconnected."; -} - -void CoreProxy::processClientInit(QTcpSocket *socket, const QVariant &v) { - VarMap msg = v.toMap(); - if(msg["GUIProtocol"].toUInt() != GUI_PROTOCOL) { - qDebug() << "Client version mismatch. Disconnecting."; - socket->close(); - return; - } - VarMap reply; - VarMap coreData; - QStringList dataKeys = global->getKeys(); - QString key; - foreach(key, dataKeys) { - coreData[key] = global->getData(key); - } - reply["CoreData"] = coreData; - /* - VarMap bl; - QHash > log = core->getBackLog(); - foreach(QString net, log.keys()) { - QByteArray buf; - QDataStream out(&buf, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_2); - foreach(Message msg, log[net]) { out << msg; } - bl[net] = buf; - } - reply["CoreBackLog"] = bl; - */ - QList bufs; - foreach(BufferId id, core->getBuffers()) { bufs.append(QVariant::fromValue(id)); } - reply["CoreBuffers"] = bufs; - QList sigdata; - sigdata.append(CS_CORE_STATE); sigdata.append(QVariant(reply)); sigdata.append(QVariant()); sigdata.append(QVariant()); - writeDataToDevice(socket, QVariant(sigdata)); - emit requestServerStates(); +// connect(global, SIGNAL(dataPutLocally(QString)), this, SLOT(updateGlobalData(QString))); +// connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); } +/* void CoreProxy::processClientUpdate(QTcpSocket *socket, QString key, QVariant data) { global->updateData(key, data); QList sigdata; @@ -122,9 +45,11 @@ void CoreProxy::updateGlobalData(QString key) { QVariant data = global->getData(key); emit csUpdateGlobalData(key, data); } +*/ +/* void CoreProxy::send(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { - sendToGUI(sig, arg1, arg2, arg3); + QList sigdata; sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3); //qDebug() << "Sending signal: " << sigdata; @@ -133,6 +58,7 @@ void CoreProxy::send(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3 writeDataToDevice(socket, QVariant(sigdata)); } } +*/ void CoreProxy::recv(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { //qDebug() << "[CORE] Received signal" << sig << ":" << arg1< clients; - QHash blockSizes; friend class GUIProxy; }; -extern CoreProxy *coreProxy; +//extern CoreProxy *coreProxy; diff --git a/core/server.cpp b/core/server.cpp index 74f9c7ad..ca878d12 100644 --- a/core/server.cpp +++ b/core/server.cpp @@ -26,7 +26,7 @@ #include #include -Server::Server(QString net) : network(net) { +Server::Server(UserId uid, QString net) : user(uid), network(net) { QString MQUOTE = QString('\020'); ctcpMDequoteHash[MQUOTE + '0'] = QString('\000'); ctcpMDequoteHash[MQUOTE + 'n'] = QString('\n'); @@ -67,8 +67,8 @@ void Server::sendState() { void Server::connectToIrc(QString net) { if(net != network) return; // not me! - networkSettings = global->getData("Networks").toMap()[net].toMap(); - identity = global->getData("Identities").toMap()[networkSettings["Identity"].toString()].toMap(); + networkSettings = Global::data(user, "Networks").toMap()[net].toMap(); + identity = Global::data(user, "Identities").toMap()[networkSettings["Identity"].toString()].toMap(); QList servers = networkSettings["Servers"].toList(); QString host = servers[0].toMap()["Address"].toString(); quint16 port = servers[0].toMap()["Port"].toUInt(); diff --git a/core/server.h b/core/server.h index d4fbfd2f..c17b4d0f 100644 --- a/core/server.h +++ b/core/server.h @@ -41,11 +41,12 @@ class Server : public QThread { Q_OBJECT public: - Server(QString network); + Server(UserId uid, QString network); ~Server(); + UserId userId() const { return user; } // serverState state(); - bool isConnected() { return socket.state() == QAbstractSocket::ConnectedState; } + bool isConnected() const { return socket.state() == QAbstractSocket::ConnectedState; } QString getNetwork() { return network; } QStringList providesUserHandlers(); @@ -143,6 +144,7 @@ class Server : public QThread { void defaultCtcpHandler(CtcpType ctcptype, QString prefix, QString cmd, QString target, QString param); private: + UserId user; QString network; QTcpSocket socket; //QHash buffers; diff --git a/core/sqlitestorage.cpp b/core/sqlitestorage.cpp index b45f1858..af5767dd 100644 --- a/core/sqlitestorage.cpp +++ b/core/sqlitestorage.cpp @@ -233,7 +233,8 @@ UserId SqliteStorage::validateUser(QString user, QString password) { if(query.first()) { return query.value(0).toUInt(); } else { - return 0; + throw AuthError(); + //return 0; } } diff --git a/core/storage.h b/core/storage.h index 31b2b09e..e0d24a9c 100644 --- a/core/storage.h +++ b/core/storage.h @@ -150,6 +150,9 @@ class Storage : public QObject { //! Sent if a new BufferId is created, or an existing one changed somehow. void bufferIdUpdated(BufferId); + public: + /* Exceptions */ + struct AuthError : public Exception {}; protected: // Old stuff, just for importing old file-based data diff --git a/gui/bufferview.h b/gui/bufferview.h index 0dea9bbe..307505e8 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -81,4 +81,5 @@ public: }; -#endif \ No newline at end of file +#endif + diff --git a/gui/coreconnectdlg.cpp b/gui/coreconnectdlg.cpp index 9cf41a49..b465ae18 100644 --- a/gui/coreconnectdlg.cpp +++ b/gui/coreconnectdlg.cpp @@ -74,7 +74,7 @@ void CoreConnectDlg::coreConnected() { ui.progressBar->show(); VarMap initmsg; initmsg["GUIProtocol"] = GUI_PROTOCOL; - guiProxy->send(GS_CLIENT_INIT, QVariant(initmsg)); + // FIXME guiProxy->send(GS_CLIENT_INIT, QVariant(initmsg)); } void CoreConnectDlg::coreConnectionError(QString err) { diff --git a/gui/guiproxy.h b/gui/guiproxy.h index 6e84b570..aeb12f3f 100644 --- a/gui/guiproxy.h +++ b/gui/guiproxy.h @@ -79,8 +79,9 @@ class GUIProxy : public QObject { void recvPartialItem(quint32 avail, quint32 size); - public: void send(GUISignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + + public slots: void recv(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); private slots: diff --git a/gui/identities.cpp b/gui/identities.cpp index 873039ff..31617179 100644 --- a/gui/identities.cpp +++ b/gui/identities.cpp @@ -22,11 +22,11 @@ IdentitiesDlg::IdentitiesDlg(QWidget *parent, QString selected) : QDialog(parent) { ui.setupUi(this); - connect(global, SIGNAL(dataUpdatedRemotely(QString)), this, SLOT(globalDataUpdated(QString))); + connect(Global::instance(), SIGNAL(dataUpdatedRemotely(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); connect(ui.enableAutoAway, SIGNAL(stateChanged(int)), this, SLOT(autoAwayChecked())); - identities = global->getData("Identities").toMap(); + identities = Global::data("Identities").toMap(); foreach(QString name, identities.keys()) { nameMapping[name] = name; } @@ -55,7 +55,7 @@ IdentitiesDlg::IdentitiesDlg(QWidget *parent, QString selected) : QDialog(parent } /* this needs more work! mapping? */ -void IdentitiesDlg::globalDataUpdated(QString key) { +void IdentitiesDlg::globalDataUpdated(UserId, QString key) { if(key == "Identities") { if(QMessageBox::warning(this, tr("Data changed remotely!"), tr("Some other GUI client changed the identities data!
" "Apply updated settings, losing all changes done locally?"), @@ -236,9 +236,9 @@ void IdentitiesDlg::accept() { updateIdentity(getCurIdentity()); QString result = checkValidity(); if(result.length() == 0) { - global->putData("Identities", identities); + Global::putData("Identities", identities); // We have to care about renamed identities and update the network list appropriately... - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); foreach(QString netname, networks.keys()) { VarMap net = networks[netname].toMap(); if(nameMapping.contains(net["Identity"].toString())) { @@ -246,7 +246,7 @@ void IdentitiesDlg::accept() { } else net["Identity"] = "Default"; networks[netname] = net; } - global->putData("Networks", networks); + Global::putData("Networks", networks); QDialog::accept(); } else { QMessageBox::warning(this, tr("Invalid Identity!"), diff --git a/gui/identities.h b/gui/identities.h index d528d9de..81fffd6e 100644 --- a/gui/identities.h +++ b/gui/identities.h @@ -54,7 +54,7 @@ class IdentitiesDlg : public QDialog { void editIdentities(); - void globalDataUpdated(QString); + void globalDataUpdated(UserId, QString); private: Ui::IdentitiesDlg ui; diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 1e88be01..08792035 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -40,7 +40,7 @@ LayoutThread *layoutThread; MainWin::MainWin() : QMainWindow() { ui.setupUi(this); //widget = 0; - qDebug() << "Available DB drivers: " << QSqlDatabase::drivers (); + //qDebug() << "Available DB drivers: " << QSqlDatabase::drivers (); setWindowTitle("Quassel IRC"); //setWindowTitle("Κυασελ Εγαρζη"); setWindowIcon(QIcon(":/qirc-icon.png")); diff --git a/gui/serverlist.cpp b/gui/serverlist.cpp index f49708ca..855056c2 100644 --- a/gui/serverlist.cpp +++ b/gui/serverlist.cpp @@ -39,12 +39,12 @@ ServerListDlg::ServerListDlg(QWidget *parent) : QDialog(parent) { settings.endGroup(); // check if we already have a valid identity - if(!global->getData("Identities", VarMap()).toMap().contains("Default")) editIdentities(true); + if(!Global::data("Identities", VarMap()).toMap().contains("Default")) editIdentities(true); connect(this, SIGNAL(requestConnect(QStringList)), guiProxy, SLOT(gsRequestConnect(QStringList))); // Autoconnect QStringList list; - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); foreach(QString net, networks.keys()) { if(networks[net].toMap()["AutoConnect"].toBool()) { list << net; @@ -58,7 +58,7 @@ ServerListDlg::~ServerListDlg() { } void ServerListDlg::updateNetworkTree() { - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); //QStringList headers; //headers << "Network" << "Autoconnect"; ui.networkTree->clear(); @@ -110,23 +110,23 @@ bool ServerListDlg::showOnStartup() { void ServerListDlg::on_addButton_clicked() { NetworkEditDlg dlg(this, VarMap()); if(dlg.exec() == QDialog::Accepted) { - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); VarMap net = dlg.getNetwork(); networks[net["Name"].toString()] = net; - global->putData("Networks", networks); + Global::putData("Networks", networks); updateNetworkTree(); } } void ServerListDlg::on_editButton_clicked() { QString curnet = ui.networkTree->currentItem()->text(0); - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); NetworkEditDlg dlg(this, networks[curnet].toMap()); if(dlg.exec() == QDialog::Accepted) { VarMap net = dlg.getNetwork(); networks.remove(curnet); networks[net["Name"].toString()] = net; - global->putData("Networks", networks); + Global::putData("Networks", networks); updateNetworkTree(); } } @@ -134,12 +134,12 @@ void ServerListDlg::on_editButton_clicked() { void ServerListDlg::on_deleteButton_clicked() { if(QMessageBox::warning(this, tr("Remove Network?"), tr("Are you sure you want to delete the selected network(s)?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - VarMap networks = global->getData("Networks").toMap(); + VarMap networks = Global::data("Networks").toMap(); QList sel = ui.networkTree->selectedItems(); foreach(QTreeWidgetItem *item, sel) { networks.remove(item->text(0)); } - global->putData("Networks", networks); + Global::putData("Networks", networks); updateNetworkTree(); } } @@ -183,14 +183,14 @@ NetworkEditDlg::NetworkEditDlg(QWidget *parent, VarMap _network) : QDialog(paren connect(ui.serverList, SIGNAL(itemSelectionChanged()), this, SLOT(updateServerButtons())); - VarMap identities = global->getData("Identities").toMap(); + VarMap identities = Global::data("Identities").toMap(); ui.identityList->addItem(tr("Default Identity")); foreach(QString id, identities.keys()) { if(id != "Default") ui.identityList->addItem(id); } QStringList groups; groups << ""; - VarMap nets = global->getData("Networks").toMap(); + VarMap nets = Global::data("Networks").toMap(); foreach(QString net, nets.keys()) { QString gr = nets[net].toMap()["Group"].toString(); if(!groups.contains(gr) && !gr.isEmpty()) { @@ -273,7 +273,7 @@ void NetworkEditDlg::accept() { QString NetworkEditDlg::checkValidity() { QString r; - VarMap nets = global->getData("Networks").toMap(); + VarMap nets = Global::data("Networks").toMap(); if(ui.networkName->text() != oldName && nets.keys().contains(ui.networkName->text())) { r += tr(" Network name already exists."); } @@ -338,7 +338,7 @@ void NetworkEditDlg::on_editIdentities_clicked() { else id = "Default"; IdentitiesDlg dlg(this, id); if(dlg.exec() == QDialog::Accepted) { - VarMap identities = global->getData("Identities").toMap(); + VarMap identities = Global::data("Identities").toMap(); ui.identityList->clear(); ui.identityList->addItem(tr("Default Identity")); foreach(QString i, identities.keys()) { diff --git a/main/global.cpp b/main/global.cpp index 3317cfda..3c82e815 100644 --- a/main/global.cpp +++ b/main/global.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel IRC Development Team * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -29,60 +29,89 @@ extern void messageHandler(QtMsgType type, const char *msg); +Global *Global::instanceptr = 0; + +Global * Global::instance() { + if(instanceptr) return instanceptr; + return instanceptr = new Global(); +} + +void Global::destroy() { + delete instanceptr; + instanceptr = 0; +} + Global::Global() { - if(global) qFatal("Trying to instantiate more than one Global object!"); qInstallMsgHandler(messageHandler); qRegisterMetaType("Message"); qRegisterMetaTypeStreamOperators("Message"); qRegisterMetaType("BufferId"); qRegisterMetaTypeStreamOperators("BufferId"); - //initIconMap(); + guiUser = 0; } -/* -void Global::setLogger(Logger *) { +Global::~Global() { -}; -*/ +} + +void Global::setGuiUser(UserId uid) { + guiUser = uid; +} + +QVariant Global::data(QString key, QVariant defval) { + return data(guiUser, key, defval); +} -QVariant Global::getData(QString key, QVariant defval) { +QVariant Global::data(UserId uid, QString key, QVariant defval) { QVariant d; mutex.lock(); - if(data.contains(key)) d = data[key]; + if(instance()->datastore[uid].contains(key)) d = instance()->datastore[uid][key]; else d = defval; mutex.unlock(); //qDebug() << "getData("<datastore[uid].keys(); mutex.unlock(); return k; } void Global::putData(QString key, QVariant d) { + putData(guiUser, key, d); +} + +void Global::putData(UserId uid, QString key, QVariant d) { mutex.lock(); - data[key] = d; + instance()->datastore[uid][key] = d; mutex.unlock(); - emit dataPutLocally(key); + emit instance()->dataPutLocally(uid, key); } void Global::updateData(QString key, QVariant d) { + updateData(guiUser, key, d); +} + +void Global::updateData(UserId uid, QString key, QVariant d) { mutex.lock(); - data[key] = d; + instance()->datastore[uid][key] = d; mutex.unlock(); - emit dataUpdatedRemotely(key); + emit instance()->dataUpdatedRemotely(uid, key); } /* not done yet */ +/* void Global::initIconMap() { // Do not depend on GUI in core! -/* QDomDocument doc("IconMap"); QFile file("images/iconmap.xml"); if(!file.open(QIODevice::ReadOnly)) { @@ -95,8 +124,8 @@ void Global::initIconMap() { file.close(); } -*/ } +*/ /**************************************************************************************/ @@ -141,6 +170,7 @@ uint qHash(const BufferId &bid) { // return 0; //} -Global *global = 0; +QMutex Global::mutex; Global::RunMode Global::runMode; +UserId Global::guiUser; QString Global::quasselDir; diff --git a/main/global.h b/main/global.h index a662fd77..fa961f2f 100644 --- a/main/global.h +++ b/main/global.h @@ -22,7 +22,7 @@ #define _GLOBAL_H_ /** The protocol version we use fo the communication between core and GUI */ -#define GUI_PROTOCOL 1 +#define GUI_PROTOCOL 2 #define BACKLOG_FORMAT 2 #define BACKLOG_STRING "QuasselIRC Backlog File" @@ -34,7 +34,6 @@ class Global; /* Some global stuff */ typedef QMap VarMap; -extern Global *global; typedef uint UserId; typedef uint MsgId; @@ -53,41 +52,52 @@ class Global : public QObject { Q_OBJECT public: - Global(); //static Logger *getLogger(); //static void setLogger(Logger *); // static QIcon *getIcon(QString symbol); - QVariant getData(QString key, QVariant defaultValue = QVariant()); - QStringList getKeys(); + static Global *instance(); + static void destroy(); + static void setGuiUser(UserId); + + static QVariant data(QString key, QVariant defaultValue = QVariant()); + static QVariant data(UserId, QString key, QVariant defaultValue = QVariant()); + static QStringList keys(); + static QStringList keys(UserId); + + static void putData(QString key, QVariant data); ///< Store data changed locally, will be propagated to all other clients and the core + static void putData(UserId, QString key, QVariant data); - public slots: - void putData(QString key, QVariant data); ///< Store data changed locally, will be propagated to all other clients and the core - void updateData(QString key, QVariant data); ///< Update stored data if requested by the core or other clients + static void updateData(QString key, QVariant data); ///< Update stored data if requested by the core or other clients + static void updateData(UserId, QString key, QVariant data); signals: - void dataPutLocally(QString key); - void dataUpdatedRemotely(QString key); // sent by remote update only! + void dataPutLocally(UserId, QString key); + void dataUpdatedRemotely(UserId, QString key); // sent by remote update only! public: - enum RunMode { Monolithic, GUIOnly, CoreOnly }; + enum RunMode { Monolithic, GuiOnly, CoreOnly }; static RunMode runMode; static QString quasselDir; private: - static void initIconMap(); + Global(); + ~Global(); + static Global *instanceptr; + + static UserId guiUser; + //static void initIconMap(); //static Logger *logger; // static QString iconPath; - QHash iconMap; - QMutex mutex; - QHash data; + //QHash iconMap; + static QMutex mutex; + QHash > datastore; }; -class Exception { - public: +struct Exception { Exception(QString msg = "Unknown Exception") : _msg(msg) {}; virtual inline QString msg() { return _msg; } diff --git a/main/main_mono.cpp b/main/main_mono.cpp index e12ad2e9..fdfb22f7 100644 --- a/main/main_mono.cpp +++ b/main/main_mono.cpp @@ -34,17 +34,19 @@ int main(int argc, char **argv) { QApplication app(argc, argv); - QApplication::setOrganizationDomain("quassel-irc.org"); - QApplication::setApplicationName("Quassel IRC"); - QApplication::setOrganizationName("The Quassel Team"); + QCoreApplication::setOrganizationDomain("quassel-irc.org"); + QCoreApplication::setApplicationName("Quassel IRC"); + QCoreApplication::setOrganizationName("Quassel IRC Development Team"); Global::runMode = Global::Monolithic; Global::quasselDir = QDir::homePath() + "/.quassel"; //settings = new Settings(); - global = new Global(); + //global = new Global(); guiProxy = new GUIProxy(); - coreProxy = new CoreProxy(); + //coreProxy = new CoreProxy(); + QObject::connect(Core::guiSession(), SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), guiProxy, SLOT(recv(CoreSignal, QVariant, QVariant, QVariant))); + QObject::connect(guiProxy, SIGNAL(send(GUISignal, QVariant, QVariant, QVariant)), Core::guiSession(), SLOT(processSignal(GUISignal, QVariant, QVariant, QVariant))); Settings::init(); Style::init(); @@ -53,33 +55,38 @@ int main(int argc, char **argv) { mainWin->show(); mainWin->init(); int exitCode = app.exec(); - delete core; + //delete core; + Core::destroy(); delete guiProxy; - delete coreProxy; - delete global; + //delete coreProxy; + //delete global; delete mainWin; //delete settings; return exitCode; } void MainWin::syncToCore() { - Q_ASSERT(global->getData("CoreReady").toBool()); - coreBuffers = core->getBuffers(); + //Q_ASSERT(Global::data("CoreReady").toBool()); + coreBuffers = Core::guiSession()->buffers(); // NOTE: We don't need to request server states, because in the monolithic version there can't be // any servers connected at this stage... } +/* void CoreProxy::sendToGUI(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { guiProxy->recv(sig, arg1, arg2, arg3); } +*/ GUIProxy::GUIProxy() { if(guiProxy) qFatal("Trying to instantiate more than one GUIProxy object!"); } +/* void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { coreProxy->recv(sig, arg1, arg2, arg3); } +*/ // Dummy function definitions // These are not needed, since we don't have a network connection to the core. -- 2.20.1 From b27b03c4239150189b7ae8963ca2e8c9b1a0ce4a Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 09:37:08 +0000 Subject: [PATCH 04/16] Setting status buffer active on connection (by creating a BufferId for it in Core before we try to access the corresponding Buffer in GUI), fixing BR #40. --- core/core.cpp | 20 +++++++++++++++----- core/core.h | 1 + gui/mainwin.cpp | 10 +++++----- main/main_mono.cpp | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/core/core.cpp b/core/core.cpp index b1815d9c..2a8d4cc2 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -56,8 +56,11 @@ void Core::init() { connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); //startListening(); // FIXME if(Global::runMode == Global::Monolithic) { // TODO Make GUI user configurable - guiUser = storage->validateUser("Default", "password"); - if(!guiUser) guiUser = storage->addUser("Default", "password"); + try { + guiUser = storage->validateUser("Default", "password"); + } catch(Storage::AuthError) { + guiUser = storage->addUser("Default", "password"); + } Q_ASSERT(guiUser); Global::setGuiUser(guiUser); createSession(guiUser); @@ -253,8 +256,8 @@ void Core::recvProxySignal(CoreSignal sig, QVariant arg1, QVariant arg2, QVarian CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_storage) { coreProxy = new CoreProxy(); - connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); + connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); connect(coreProxy, SIGNAL(gsUserInput(BufferId, QString)), this, SLOT(msgFromGui(BufferId, QString))); @@ -267,7 +270,6 @@ CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_st connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); connect(Global::instance(), SIGNAL(dataUpdatedRemotely(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(globalDataUpdated(UserId, QString))); - } CoreSession::~CoreSession() { @@ -299,6 +301,10 @@ void CoreSession::connectToIrc(QStringList networks) { connect(this, SIGNAL(connectToIrc(QString)), server, SLOT(connectToIrc(QString))); connect(this, SIGNAL(disconnectFromIrc(QString)), server, SLOT(disconnectFromIrc(QString))); connect(this, SIGNAL(msgFromGui(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString))); + + connect(server, SIGNAL(connected(QString)), this, SLOT(serverConnected(QString))); + connect(server, SIGNAL(disconnected(QString)), this, SLOT(serverDisconnected(QString))); + connect(server, SIGNAL(serverState(QString, VarMap)), coreProxy, SLOT(csServerState(QString, VarMap))); //connect(server, SIGNAL(displayMsg(Message)), this, SLOT(recvMessageFromServer(Message))); connect(server, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8)), this, SLOT(recvMessageFromServer(Message::Type, QString, QString, QString, quint8))); @@ -313,7 +319,7 @@ void CoreSession::connectToIrc(QStringList networks) { connect(server, SIGNAL(queryRequested(QString, QString)), coreProxy, SLOT(csQueryRequested(QString, QString))); // TODO add error handling connect(server, SIGNAL(connected(QString)), coreProxy, SLOT(csServerConnected(QString))); - connect(server, SIGNAL(disconnected(QString)), this, SLOT(serverDisconnected(QString))); + connect(server, SIGNAL(disconnected(QString)), coreProxy, SLOT(csServerDisconnected(QString))); server->start(); servers[net] = server; @@ -322,6 +328,10 @@ void CoreSession::connectToIrc(QStringList networks) { } } +void CoreSession::serverConnected(QString net) { + storage->getBufferId(userId(), net); // create status buffer +} + void CoreSession::serverDisconnected(QString net) { delete servers[net]; servers.remove(net); diff --git a/core/core.h b/core/core.h index 400c21eb..c4a66465 100644 --- a/core/core.h +++ b/core/core.h @@ -109,6 +109,7 @@ class CoreSession : public QObject { void globalDataUpdated(UserId, QString); void recvStatusMsgFromServer(QString msg); void recvMessageFromServer(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None); + void serverConnected(QString net); void serverDisconnected(QString net); private: diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 08792035..2b63b178 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -153,7 +153,7 @@ void MainWin::setupMenus() { } void MainWin::setupViews() { - BufferTreeModel *model = new BufferTreeModel(this); + BufferTreeModel *model = new BufferTreeModel(this); // FIXME Where is the delete for that? :p connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); connect(this, SIGNAL(bufferUpdated(Buffer *)), model, SLOT(bufferUpdated(Buffer *))); @@ -237,10 +237,10 @@ void MainWin::showBuffer(Buffer *b) { void MainWin::networkConnected(QString net) { connected[net] = true; - //BufferId id = getStatusBufferId(net); - //Buffer *b = getBuffer(id); - //b->setActive(true); - //b->displayMsg(Message(id, Message::Server, tr("Connected."))); FIXME + BufferId id = getStatusBufferId(net); + Buffer *b = getBuffer(id); + b->setActive(true); + //b->displayMsg(Message(id, Message::Server, tr("Connected."))); // TODO buffersUpdated(); } diff --git a/main/main_mono.cpp b/main/main_mono.cpp index fdfb22f7..d9c682f4 100644 --- a/main/main_mono.cpp +++ b/main/main_mono.cpp @@ -1,7 +1,7 @@ /*************************************************************************** - * Copyright (C) 2005 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel IRC Development Team * * devel@quassel-irc.org * - * * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * -- 2.20.1 From 9d4be7eefb855df7efe6d140bc498cc574140466 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 10:00:42 +0000 Subject: [PATCH 05/16] Make BufferView trees expanded by default. --- gui/bufferview.cpp | 4 ++++ gui/bufferview.h | 16 +++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index 4045f206..7e2cf217 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -106,3 +106,7 @@ void BufferView::dragEnterEvent(QDragEnterEvent *event) { // not yet needed... this will be usefull to keep track of the active view when customizing them with drag and drop QTreeView::dragEnterEvent(event); } + +void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) { + setExpanded(parent, true); +} diff --git a/gui/bufferview.h b/gui/bufferview.h index 307505e8..6fcadf86 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -70,14 +70,16 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(BufferViewFilter::Modes) class BufferView : public QTreeView { Q_OBJECT -public: - BufferView(QWidget *parent = 0); - void init(); - void setModel(QAbstractItemModel *model); - void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets); - - void dragEnterEvent(QDragEnterEvent *); + public: + BufferView(QWidget *parent = 0); + void init(); + void setModel(QAbstractItemModel *model); + void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets); + void dragEnterEvent(QDragEnterEvent *); + + protected: + void rowsInserted (const QModelIndex & parent, int start, int end); }; -- 2.20.1 From a19a2f6e05b831aac9e85d21fbfc424aabb7a04e Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 12:26:32 +0000 Subject: [PATCH 06/16] Only expand network items in bufferviews. --- gui/bufferview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index 7e2cf217..03ab7580 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -108,5 +108,5 @@ void BufferView::dragEnterEvent(QDragEnterEvent *event) { } void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) { - setExpanded(parent, true); + if(parent.parent() == QModelIndex()) setExpanded(parent, true); } -- 2.20.1 From 0d5499deed248902ce2341208cbc33acd8cace19 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Tue, 19 Jun 2007 19:27:05 +0000 Subject: [PATCH 07/16] Fixed a Bug where an issued /join did not trigger the creation of a Item in the BufferViews --- gui/bufferview.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index 03ab7580..68b7f318 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -75,6 +75,8 @@ bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &sourc /***************************************** * The TreeView showing the Buffers *****************************************/ +// Please be carefull when reimplementing methods which are used to inform the view about changes to the data +// to be on the safe side: call QTreeView's method aswell BufferView::BufferView(QWidget *parent) : QTreeView(parent) { } @@ -109,4 +111,5 @@ void BufferView::dragEnterEvent(QDragEnterEvent *event) { void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) { if(parent.parent() == QModelIndex()) setExpanded(parent, true); + QTreeView::rowsInserted(parent, start, end); } -- 2.20.1 From 26586e615ffe42bb2b1b307ed1324a6e3051f5da Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 22:09:28 +0000 Subject: [PATCH 08/16] Refactoring the GUI. Work in progress. --- core/core.cpp | 8 +- core/core.h | 4 +- core/coreproxy.cpp | 2 +- core/coreproxy.h | 8 +- core/server.cpp | 3 +- gui/CMakeLists.txt | 4 +- gui/bufferview.cpp | 2 +- gui/bufferview.h | 2 +- gui/bufferviewwidget.cpp | 11 +- gui/coreconnectdlg.cpp | 13 +- gui/gui.cpp | 353 +++++++++++++++++++++++++++++++++++++++ gui/gui.h | 124 ++++++++++++++ gui/guiproxy.cpp | 23 ++- gui/guiproxy.h | 42 ++--- gui/mainwin.cpp | 217 ++---------------------- gui/mainwin.h | 58 +++---- gui/serverlist.cpp | 2 +- main/main_gui.cpp | 22 ++- main/main_mono.cpp | 29 ++-- main/proxy_common.h | 2 +- 20 files changed, 621 insertions(+), 308 deletions(-) create mode 100644 gui/gui.cpp create mode 100644 gui/gui.h diff --git a/core/core.cpp b/core/core.cpp index 2a8d4cc2..a3dcd269 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -94,7 +94,7 @@ CoreSession *Core::session(UserId uid) { else return 0; } -CoreSession *Core::guiSession() { +CoreSession *Core::localSession() { Core *core = instance(); if(core->guiUser && core->sessions.contains(core->guiUser)) return core->sessions[core->guiUser]; else return 0; @@ -141,10 +141,10 @@ void Core::clientHasData() { while(readDataFromDevice(socket, bsize, item)) { if(validClients.contains(socket)) { QList sigdata = item.toList(); - if((GUISignal)sigdata[0].toInt() == GS_UPDATE_GLOBAL_DATA) { + if((ClientSignal)sigdata[0].toInt() == GS_UPDATE_GLOBAL_DATA) { processClientUpdate(socket, sigdata[1].toString(), sigdata[2]); } else { - sessions[validClients[socket]]->processSignal((GUISignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + sessions[validClients[socket]]->processSignal((ClientSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); } } else { // we need to auth the client @@ -280,7 +280,7 @@ UserId CoreSession::userId() { return user; } -void CoreSession::processSignal(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { +void CoreSession::processSignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { coreProxy->recv(sig, arg1, arg2, arg3); } diff --git a/core/core.h b/core/core.h index c4a66465..126e3a57 100644 --- a/core/core.h +++ b/core/core.h @@ -40,7 +40,7 @@ class Core : public QObject { static void destroy(); static CoreSession * session(UserId); - static CoreSession * guiSession(); + static CoreSession * localSession(); static CoreSession * createSession(UserId); private slots: @@ -84,7 +84,7 @@ class CoreSession : public QObject { public slots: void connectToIrc(QStringList); - void processSignal(GUISignal, QVariant, QVariant, QVariant); + void processSignal(ClientSignal, QVariant, QVariant, QVariant); void sendBacklog(BufferId, QVariant, QVariant); void msgFromGui(BufferId, QString message); void sendServerStates(); diff --git a/core/coreproxy.cpp b/core/coreproxy.cpp index c6325eef..ee9ea2d1 100644 --- a/core/coreproxy.cpp +++ b/core/coreproxy.cpp @@ -60,7 +60,7 @@ void CoreProxy::send(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3 } */ -void CoreProxy::recv(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { +void CoreProxy::recv(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { //qDebug() << "[CORE] Received signal" << sig << ":" << arg1< /** This class is the Core side of the proxy. The Core connects its signals and slots to it, - * and the calls are marshalled and sent to (or received and unmarshalled from) the GUIProxy. + * and the calls are marshalled and sent to (or received and unmarshalled from) the GuiProxy. * The connection functions are defined in main/main_core.cpp or main/main_mono.cpp. */ class CoreProxy : public QObject { @@ -66,7 +66,7 @@ class CoreProxy : public QObject { void gsImportBacklog(); void gsRequestBacklog(BufferId, QVariant, QVariant); - void gsGeneric(GUISignal, QVariant, QVariant, QVariant); + void gsGeneric(ClientSignal, QVariant, QVariant, QVariant); void requestServerStates(); @@ -74,7 +74,7 @@ class CoreProxy : public QObject { public: //void send(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); - void recv(GUISignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + void recv(ClientSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); private: void processClientUpdate(QTcpSocket *, QString key, QVariant data); @@ -82,7 +82,7 @@ class CoreProxy : public QObject { private: - friend class GUIProxy; + friend class GuiProxy; }; //extern CoreProxy *coreProxy; diff --git a/core/server.cpp b/core/server.cpp index ca878d12..e5ed4eb3 100644 --- a/core/server.cpp +++ b/core/server.cpp @@ -879,7 +879,8 @@ void Server::handleCtcpPing(CtcpType ctcptype, QString prefix, QString target, Q void Server::handleCtcpVersion(CtcpType ctcptype, QString prefix, QString target, QString param) { if(ctcptype == CtcpQuery) { // FIXME use real Info about quassel :) - ctcpReply(nickFromMask(prefix), "VERSION", QString("Quassel:pre Release:*nix")); + //ctcpReply(nickFromMask(prefix), "VERSION", QString("Quassel:pre Release:*nix")); + ctcpReply(nickFromMask(prefix), "VERSION", QString("Quassel IRC (Pre-Release) - http://www.quassel-irc.org")); emit displayMsg(Message::Server, "", tr("Received CTCP VERSION request by %1").arg(prefix)); } else { // TODO display Version answer diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index f118eae7..d651be0c 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,7 +1,7 @@ -SET(gui_SRCS chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp buffer.cpp bufferwidget.cpp +SET(gui_SRCS gui.cpp chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp buffer.cpp bufferwidget.cpp identities.cpp coreconnectdlg.cpp guiproxy.cpp bufferview.cpp bufferviewwidget.cpp style.cpp settingsdlg.cpp settingspages.cpp) SET(gui_HDRS style.h) -SET(gui_MOCS chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h +SET(gui_MOCS gui.h chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h guiproxy.h bufferview.h buffer.h bufferwidget.h bufferviewwidget.h settingsdlg.h settingspages.h) SET(gui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index 68b7f318..017ce259 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -110,6 +110,6 @@ void BufferView::dragEnterEvent(QDragEnterEvent *event) { } void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) { - if(parent.parent() == QModelIndex()) setExpanded(parent, true); + if(parent.parent() == QModelIndex()) setExpanded(parent, true); qDebug() << "expanded"; QTreeView::rowsInserted(parent, start, end); } diff --git a/gui/bufferview.h b/gui/bufferview.h index 6fcadf86..9daee9f1 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -78,7 +78,7 @@ class BufferView : public QTreeView { void dragEnterEvent(QDragEnterEvent *); - protected: + protected slots: void rowsInserted (const QModelIndex & parent, int start, int end); }; diff --git a/gui/bufferviewwidget.cpp b/gui/bufferviewwidget.cpp index e21b98ba..04331c38 100644 --- a/gui/bufferviewwidget.cpp +++ b/gui/bufferviewwidget.cpp @@ -155,7 +155,7 @@ BufferTreeModel::BufferTreeModel(QObject *parent) : QAbstractItemModel(parent) { rootData << "Buffer" << "Network"; rootItem = new TreeItem(rootData, 0); - connect(this, SIGNAL(fakeUserInput(BufferId, QString)), guiProxy, SLOT(gsUserInput(BufferId, QString))); + connect(this, SIGNAL(fakeUserInput(BufferId, QString)), ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); } BufferTreeModel::~BufferTreeModel() { @@ -291,11 +291,11 @@ QModelIndex BufferTreeModel::getOrCreateBufferItemIndex(Buffer *buffer) { TreeItem *networkItem = static_cast(networkItemIndex.internalPointer()); int nextRow = networkItem->childCount(); - + beginInsertRows(networkItemIndex, nextRow, nextRow); networkItem->appendChild(new BufferTreeItem(buffer, networkItem)); endInsertRows(); - + bufferItem[buffer] = static_cast(networkItem->child(nextRow)); return index(nextRow, 0, networkItemIndex); } @@ -334,13 +334,14 @@ bool BufferTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, if(sourceBuffer == targetBuffer) // we won't merge with ourself :) return false; - + /* if(QMessageBox::warning(static_cast(QObject::parent()), tr("Merge Buffers?"), tr("Do you really want to merge the following Buffers?
%1.%2
%3.%4").arg(sourceBuffer->networkName()).arg(sourceBuffer->bufferName()).arg(targetBuffer->networkName()).arg(targetBuffer->bufferName()), QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) return false; - + + */ qDebug() << "merging" << sourceBuffer->bufferName() << "with" << targetBuffer->bufferName(); bufferItem.remove(getBufferByIndex(parent)); removeRow(parent.row(), BufferTreeModel::parent(parent)); diff --git a/gui/coreconnectdlg.cpp b/gui/coreconnectdlg.cpp index b465ae18..c0ca4808 100644 --- a/gui/coreconnectdlg.cpp +++ b/gui/coreconnectdlg.cpp @@ -22,6 +22,7 @@ #include "coreconnectdlg.h" #include "guiproxy.h" #include "global.h" +#include "gui.h" CoreConnectDlg::CoreConnectDlg(QWidget *parent) : QDialog(parent) { ui.setupUi(this); @@ -56,9 +57,9 @@ void CoreConnectDlg::hostSelected() { ui.hostName->hide(); ui.hostPort->hide(); ui.hostLabel->hide(); ui.portLabel->hide(); ui.statusText->setText(tr("Connecting to %1:%2" ).arg(ui.hostName->text()).arg(ui.hostPort->value())); ui.buttonBox->button(QDialogButtonBox::Ok)->hide(); - connect(guiProxy, SIGNAL(coreConnected()), this, SLOT(coreConnected())); - connect(guiProxy, SIGNAL(coreConnectionError(QString)), this, SLOT(coreConnectionError(QString))); - guiProxy->connectToCore(ui.hostName->text(), ui.hostPort->value()); + connect(ClientProxy::instance(), SIGNAL(coreConnected()), this, SLOT(coreConnected())); + connect(ClientProxy::instance(), SIGNAL(coreConnectionError(QString)), this, SLOT(coreConnectionError(QString))); + Client::instance()->connectToCore(ui.hostName->text(), ui.hostPort->value()); } @@ -69,8 +70,8 @@ void CoreConnectDlg::coreConnected() { s.setValue("GUI/CoreHost", ui.hostName->text()); s.setValue("GUI/CorePort", ui.hostPort->value()); s.setValue("GUI/CoreAutoConnect", ui.autoConnect->isChecked()); - connect(guiProxy, SIGNAL(recvPartialItem(quint32, quint32)), this, SLOT(updateProgressBar(quint32, quint32))); - connect(guiProxy, SIGNAL(csCoreState(QVariant)), this, SLOT(recvCoreState(QVariant))); + connect(ClientProxy::instance(), SIGNAL(recvPartialItem(quint32, quint32)), this, SLOT(updateProgressBar(quint32, quint32))); + connect(ClientProxy::instance(), SIGNAL(csCoreState(QVariant)), this, SLOT(recvCoreState(QVariant))); ui.progressBar->show(); VarMap initmsg; initmsg["GUIProtocol"] = GUI_PROTOCOL; @@ -79,7 +80,7 @@ void CoreConnectDlg::coreConnected() { void CoreConnectDlg::coreConnectionError(QString err) { QMessageBox::warning(this, tr("Connection Error"), tr("Could not connect to Quassel Core!
\n") + err, QMessageBox::Retry); - disconnect(guiProxy, 0, this, 0); + disconnect(ClientProxy::instance(), 0, this, 0); ui.autoConnect->setChecked(false); setStartState(); } diff --git a/gui/gui.cpp b/gui/gui.cpp new file mode 100644 index 00000000..9f38d199 --- /dev/null +++ b/gui/gui.cpp @@ -0,0 +1,353 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "gui.h" +#include "guiproxy.h" +#include "mainwin.h" +#include "buffer.h" +#include "bufferview.h" +#include "bufferviewwidget.h" +#include "util.h" + +Client * Client::instanceptr = 0; + +Client::ClientMode Client::clientMode; +QHash Client::buffers; +QHash Client::bufferIds; +QHash > Client::nicks; +QHash Client::connected; +QHash Client::ownNick; +QList Client::coreBuffers; + + +Client *Client::instance() { + if(instanceptr) return instanceptr; + instanceptr = new Client(); + instanceptr->init(); +} + +void Client::destroy() { + delete instanceptr; + instanceptr = 0; +} + +Client::Client() { + clientProxy = ClientProxy::instance(); + + mainWin = new MainWin(); + _bufferModel = new BufferTreeModel(mainWin); // FIXME + + connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); + connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *))); + connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), _bufferModel, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); + + // TODO: make this configurable (allow monolithic client to connect to remote cores) + if(Global::runMode == Global::Monolithic) clientMode = LocalCore; + else clientMode = RemoteCore; +} + +void Client::init() { + blockSize = 0; + + connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData())); + connect(&socket, SIGNAL(connected()), this, SLOT(coreConnected())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(coreDisconnected())); + connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(serverError(QAbstractSocket::SocketError))); + + connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateCoreData(UserId, QString))); + connect(ClientProxy::instance(), SIGNAL(csUpdateGlobalData(QString, QVariant)), this, SLOT(updateLocalData(QString, QVariant))); + + connect(ClientProxy::instance(), SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant))); + + connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); + connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); + connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); + connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(Message))); + connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); + connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); + connect(clientProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap))); + connect(clientProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); + connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); + connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap))); + connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); + connect(clientProxy, SIGNAL(csBacklogData(BufferId, QList, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); + connect(clientProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId))); + connect(this, SIGNAL(sendInput(BufferId, QString)), clientProxy, SLOT(gsUserInput(BufferId, QString))); + connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), clientProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); + + syncToCore(); + + layoutTimer = new QTimer(this); + layoutTimer->setInterval(0); + layoutTimer->setSingleShot(false); + connect(layoutTimer, SIGNAL(timeout()), this, SLOT(layoutMsg())); + + /* make lookups by id faster */ + foreach(BufferId id, coreBuffers) { + bufferIds[id.uid()] = id; // make lookups by id faster + buffer(id); // create all buffers, so we see them in the network views + emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request + } + + //mainWin = new MainWin(); + mainWin->init(); + +} + +Client::~Client() { + delete mainWin; + foreach(Buffer *buf, buffers.values()) delete buf; + delete _bufferModel; + ClientProxy::destroy(); + +} + +BufferTreeModel *Client::bufferModel() { + return instance()->_bufferModel; +} + +void Client::coreConnected() { + +} + +void Client::coreDisconnected() { + +} + +void Client::updateCoreData(UserId, QString key) { + if(clientMode == LocalCore) return; + QVariant data = Global::data(key); + recvProxySignal(GS_UPDATE_GLOBAL_DATA, key, data, QVariant()); +} + +void Client::updateLocalData(QString key, QVariant data) { + Global::updateData(key, data); +} + +void Client::recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + if(clientMode == LocalCore) return; + QList sigdata; + sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3); + //qDebug() << "Sending signal: " << sigdata; + writeDataToDevice(&socket, QVariant(sigdata)); +} + +void Client::connectToCore(QString host, quint16 port) { + // TODO implement SSL + socket.connectToHost(host, port); +} + +void Client::disconnectFromCore() { + socket.close(); +} + +void Client::serverError(QAbstractSocket::SocketError) { + emit coreConnectionError(socket.errorString()); +} + +void Client::serverHasData() { + QVariant item; + while(readDataFromDevice(&socket, blockSize, item)) { + emit recvPartialItem(1,1); + QList sigdata = item.toList(); + Q_ASSERT(sigdata.size() == 4); + ClientProxy::instance()->recv((CoreSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + blockSize = 0; + } + if(blockSize > 0) { + emit recvPartialItem(socket.bytesAvailable(), blockSize); + } +} + +/*******************************************************************************************************************/ + +void Client::networkConnected(QString net) { + connected[net] = true; + BufferId id = statusBufferId(net); + Buffer *b = buffer(id); + b->setActive(true); + //b->displayMsg(Message(id, Message::Server, tr("Connected."))); + // TODO buffersUpdated(); +} + +void Client::networkDisconnected(QString net) { + foreach(BufferId id, buffers.keys()) { + if(id.network() != net) continue; + Buffer *b = buffer(id); + //b->displayMsg(Message(id, Message::Server, tr("Server disconnected."))); FIXME + b->setActive(false); + } + connected[net] = false; +} + +void Client::updateBufferId(BufferId id) { + bufferIds[id.uid()] = id; // make lookups by id faster + buffer(id); +} + +BufferId Client::bufferId(QString net, QString buf) { + foreach(BufferId id, buffers.keys()) { + if(id.network() == net && id.buffer() == buf) return id; + } + Q_ASSERT(false); // should never happen! + return BufferId(); +} + +BufferId Client::statusBufferId(QString net) { + return bufferId(net, ""); +} + + +Buffer * Client::buffer(BufferId id) { + Client *client = Client::instance(); + if(!buffers.contains(id)) { + Buffer *b = new Buffer(id); + b->setOwnNick(ownNick[id.network()]); + connect(b, SIGNAL(userInput(BufferId, QString)), client, SLOT(userInput(BufferId, QString))); + connect(b, SIGNAL(bufferUpdated(Buffer *)), client, SIGNAL(bufferUpdated(Buffer *))); + connect(b, SIGNAL(bufferDestroyed(Buffer *)), client, SIGNAL(bufferDestroyed(Buffer *))); + buffers[id] = b; + emit client->bufferUpdated(b); + } + return buffers[id]; +} + +void Client::recvNetworkState(QString net, QVariant state) { + connected[net] = true; + setOwnNick(net, state.toMap()["OwnNick"].toString()); + buffer(statusBufferId(net))->setActive(true); + VarMap t = state.toMap()["Topics"].toMap(); + VarMap n = state.toMap()["Nicks"].toMap(); + foreach(QVariant v, t.keys()) { + QString buf = v.toString(); + BufferId id = bufferId(net, buf); + buffer(id)->setActive(true); + setTopic(net, buf, t[buf].toString()); + } + foreach(QString nick, n.keys()) { + addNick(net, nick, n[nick].toMap()); + } +} + +void Client::recvMessage(Message msg) { + Buffer *b = buffer(msg.buffer); + + Buffer::ActivityLevel level = Buffer::OtherActivity; + if(msg.type == Message::Plain || msg.type == Message::Notice){ + level |= Buffer::NewMessage; + } + if(msg.flags & Message::Highlight){ + level |= Buffer::Highlight; + } + emit bufferActivity(level, b); + + //b->displayMsg(msg); + b->appendChatLine(new ChatLine(msg)); +} + +void Client::recvStatusMsg(QString net, QString msg) { + //recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg))); + +} + +void Client::recvBacklogData(BufferId id, QList msgs, bool done) { + foreach(QVariant v, msgs) { + layoutQueue.append(v.value()); + } + if(!layoutTimer->isActive()) layoutTimer->start(); +} + + +void Client::layoutMsg() { + if(layoutQueue.count()) { + ChatLine *line = new ChatLine(layoutQueue.takeFirst()); + buffer(line->bufferId())->prependChatLine(line); + } + if(!layoutQueue.count()) layoutTimer->stop(); +} + +void Client::userInput(BufferId id, QString msg) { + emit sendInput(id, msg); +} + +void Client::setTopic(QString net, QString buf, QString topic) { + BufferId id = bufferId(net, buf); + if(!connected[id.network()]) return; + Buffer *b = buffer(id); + b->setTopic(topic); + //if(!b->isActive()) { + // b->setActive(true); + // buffersUpdated(); + //} +} + +void Client::addNick(QString net, QString nick, VarMap props) { + if(!connected[net]) return; + nicks[net][nick] = props; + VarMap chans = props["Channels"].toMap(); + QStringList c = chans.keys(); + foreach(QString bufname, c) { + buffer(bufferId(net, bufname))->addNick(nick, props); + } +} + +void Client::renameNick(QString net, QString oldnick, QString newnick) { + if(!connected[net]) return; + QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys(); + foreach(QString c, chans) { + buffer(bufferId(net, c))->renameNick(oldnick, newnick); + } + nicks[net][newnick] = nicks[net].take(oldnick); +} + +void Client::updateNick(QString net, QString nick, VarMap props) { + if(!connected[net]) return; + QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys(); + QStringList newchans = props["Channels"].toMap().keys(); + foreach(QString c, newchans) { + if(oldchans.contains(c)) buffer(bufferId(net, c))->updateNick(nick, props); + else buffer(bufferId(net, c))->addNick(nick, props); + } + foreach(QString c, oldchans) { + if(!newchans.contains(c)) buffer(bufferId(net, c))->removeNick(nick); + } + nicks[net][nick] = props; +} + +void Client::removeNick(QString net, QString nick) { + if(!connected[net]) return; + VarMap chans = nicks[net][nick]["Channels"].toMap(); + foreach(QString bufname, chans.keys()) { + buffer(bufferId(net, bufname))->removeNick(nick); + } + nicks[net].remove(nick); +} + +void Client::setOwnNick(QString net, QString nick) { + if(!connected[net]) return; + ownNick[net] = nick; + foreach(BufferId id, buffers.keys()) { + if(id.network() == net) { + buffers[id]->setOwnNick(nick); + } + } +} + + diff --git a/gui/gui.h b/gui/gui.h new file mode 100644 index 00000000..6ec1dbad --- /dev/null +++ b/gui/gui.h @@ -0,0 +1,124 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel IRC Development Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _GUI_H_ +#define _GUI_H_ + +#include +#include +#include + +#include "global.h" +#include "buffer.h" +#include "message.h" +#include "guiproxy.h" + +class MainWin; +class ClientProxy; +class BufferTreeModel; + +class Client : public QObject { + Q_OBJECT + + public: + static Client *instance(); + static void destroy(); + + static Buffer *buffer(BufferId); + static BufferId statusBufferId(QString net); + static BufferId bufferId(QString net, QString buf); + + static BufferTreeModel *bufferModel(); + + signals: + void sendInput(BufferId, QString message); + void showBuffer(Buffer *); + void bufferSelected(Buffer *); + void bufferUpdated(Buffer *); + void bufferActivity(Buffer::ActivityLevel, Buffer *); + void bufferDestroyed(Buffer *); + void backlogReceived(Buffer *, QList); + void requestBacklog(BufferId, QVariant, QVariant); + + void recvPartialItem(quint32 avail, quint32 size); + void coreConnectionError(QString errorMsg); + + public slots: + //void selectBuffer(Buffer *); + void connectToCore(QString host, quint16 port); + void disconnectFromCore(); + + private slots: + void updateCoreData(UserId, QString); + void updateLocalData(QString, QVariant); + void recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3); + + void serverError(QAbstractSocket::SocketError); + void serverHasData(); + void coreConnected(); + void coreDisconnected(); + + void userInput(BufferId, QString); + void networkConnected(QString); + void networkDisconnected(QString); + void recvNetworkState(QString, QVariant); + void recvMessage(Message message); + void recvStatusMsg(QString network, QString message); + void setTopic(QString net, QString buf, QString); + void addNick(QString net, QString nick, VarMap props); + void removeNick(QString net, QString nick); + void renameNick(QString net, QString oldnick, QString newnick); + void updateNick(QString net, QString nick, VarMap props); + void setOwnNick(QString net, QString nick); + void recvBacklogData(BufferId, QList, bool); + void updateBufferId(BufferId); + + void layoutMsg(); + + private: + Client(); + ~Client(); + void init(); + static Client *instanceptr; + + void syncToCore(); + + enum ClientMode { LocalCore, RemoteCore }; + static ClientMode clientMode; + + MainWin *mainWin; + ClientProxy *clientProxy; + BufferTreeModel *_bufferModel; + + QTcpSocket socket; + quint32 blockSize; + + static QHash buffers; + static QHash bufferIds; + static QHash > nicks; + static QHash connected; + static QHash ownNick; + static QList coreBuffers; + + QTimer *layoutTimer; + QList layoutQueue; +}; + +#endif diff --git a/gui/guiproxy.cpp b/gui/guiproxy.cpp index 7211649a..5b6177fc 100644 --- a/gui/guiproxy.cpp +++ b/gui/guiproxy.cpp @@ -24,7 +24,24 @@ #include "util.h" #include "message.h" -void GUIProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { +ClientProxy *ClientProxy::instanceptr = 0; + +ClientProxy *ClientProxy::instance() { + if(instanceptr) return instanceptr; + else return instanceptr = new ClientProxy(); +} + +void ClientProxy::destroy() { + delete instanceptr; + instanceptr = 0; +} + +ClientProxy::ClientProxy() { + + +} + +void ClientProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { //qDebug() << "[GUI] Received signal:" << sig <(), arg2.toList(), arg3.toBool()); break; case CS_UPDATE_BUFFERID: emit csUpdateBufferId(arg1.value()); break; - //default: qWarning() << "Unknown signal in GUIProxy::recv: " << sig; + //default: qWarning() << "Unknown signal in ClientProxy::recv: " << sig; default: emit csGeneric(sig, arg1, arg2, arg3); } } -GUIProxy *guiProxy; +//ClientProxy *guiProxy; diff --git a/gui/guiproxy.h b/gui/guiproxy.h index aeb12f3f..28fbfff4 100644 --- a/gui/guiproxy.h +++ b/gui/guiproxy.h @@ -30,15 +30,12 @@ #include #include -/** This class is the GUI side of the proxy. The GUI connects its signals and slots to it, - * and the calls are marshalled and sent to (or received and unmarshalled from) the CoreProxy. - * The connection function is defined in main/main_gui.cpp or main/main_mono.cpp. - */ -class GUIProxy : public QObject { +class ClientProxy : public QObject { Q_OBJECT public: - GUIProxy(); + static ClientProxy *instance(); + static void destroy(); public slots: inline void gsUserInput(BufferId id, QString msg) { send(GS_USER_INPUT, QVariant::fromValue(id), msg); } @@ -46,10 +43,10 @@ class GUIProxy : public QObject { inline void gsImportBacklog() { send(GS_IMPORT_BACKLOG); } inline void gsRequestBacklog(BufferId id, QVariant v1, QVariant v2) { send(GS_REQUEST_BACKLOG, QVariant::fromValue(id), v1, v2); } - inline void gsGeneric(GUISignal sig, QVariant v1 = QVariant(), QVariant v2 = QVariant(), QVariant v3 = QVariant()) { send(sig, v1, v2, v3); } + inline void gsGeneric(ClientSignal sig, QVariant v1 = QVariant(), QVariant v2 = QVariant(), QVariant v3 = QVariant()) { send(sig, v1, v2, v3); } - void connectToCore(QString host, quint16 port); - void disconnectFromCore(); + //void connectToCore(QString host, quint16 port); + //void disconnectFromCore(); signals: void csCoreState(QVariant); @@ -73,32 +70,35 @@ class GUIProxy : public QObject { void csGeneric(CoreSignal, QVariant, QVariant, QVariant); - void coreConnected(); - void coreDisconnected(); - void coreConnectionError(QString errorMsg); + //void coreConnected(); + //void coreDisconnected(); + //void coreConnectionError(QString errorMsg); - void recvPartialItem(quint32 avail, quint32 size); + //void recvPartialItem(quint32 avail, quint32 size); - void send(GUISignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + void send(ClientSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); public slots: void recv(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); private slots: - void updateCoreData(QString); + //void updateCoreData(QString); - void serverError(QAbstractSocket::SocketError); - void serverHasData(); + //void serverError(QAbstractSocket::SocketError); + //void serverHasData(); private: - QTcpSocket socket; - quint32 blockSize; + ClientProxy(); + static ClientProxy *instanceptr; - friend class CoreProxy; + //QTcpSocket socket; + //quint32 blockSize; + + //friend class CoreProxy; }; -extern GUIProxy *guiProxy; +//extern ClientProxy *guiProxy; diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 2b63b178..3d2df39b 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -22,6 +22,7 @@ #include #include +#include "gui.h" #include "util.h" #include "global.h" #include "message.h" @@ -46,17 +47,13 @@ MainWin::MainWin() : QMainWindow() { setWindowIcon(QIcon(":/qirc-icon.png")); setWindowIconText("Quassel IRC"); - layoutTimer = new QTimer(this); - layoutTimer->setInterval(0); - layoutTimer->setSingleShot(false); - connect(layoutTimer, SIGNAL(timeout()), this, SLOT(layoutMsg())); //workspace = new QWorkspace(this); //setCentralWidget(workspace); statusBar()->showMessage(tr("Waiting for core...")); } void MainWin::init() { - +/* connect(guiProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); connect(guiProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); connect(guiProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); @@ -76,10 +73,11 @@ void MainWin::init() { //layoutThread = new LayoutThread(); //layoutThread->start(); //while(!layoutThread->isRunning()) {}; +*/ ui.bufferWidget->init(); show(); - syncToCore(); + //syncToCore(); statusBar()->showMessage(tr("Ready.")); systray = new QSystemTrayIcon(this); systray->setIcon(QIcon(":/qirc-icon.png")); @@ -100,13 +98,6 @@ void MainWin::init() { if(s.contains("MainWinState")) restoreState(s.value("MainWinState").toByteArray()); s.endGroup(); - /* make lookups by id faster */ - foreach(BufferId id, coreBuffers) { - bufferIds[id.uid()] = id; // make lookups by id faster - getBuffer(id); // create all buffers, so we see them in the network views - emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request - } - s.beginGroup("Buffers"); QString net = s.value("CurrentNetwork", "").toString(); QString buf = s.value("CurrentBuffer", "").toString(); @@ -131,7 +122,7 @@ MainWin::~MainWin() { // delete b; // } //} - foreach(Buffer *buf, buffers.values()) delete buf; + //foreach(Buffer *buf, buffers.values()) delete buf; } /* This is implemented in settingspages.cpp */ @@ -149,15 +140,15 @@ void MainWin::setupMenus() { connect(ui.actionAboutQt, SIGNAL(triggered()), QApplication::instance(), SLOT(aboutQt())); // for debugging connect(ui.actionImportBacklog, SIGNAL(triggered()), this, SLOT(importBacklog())); - connect(this, SIGNAL(importOldBacklog()), guiProxy, SLOT(gsImportBacklog())); + connect(this, SIGNAL(importOldBacklog()), ClientProxy::instance(), SLOT(gsImportBacklog())); } void MainWin::setupViews() { - BufferTreeModel *model = new BufferTreeModel(this); // FIXME Where is the delete for that? :p + BufferTreeModel *model = Client::bufferModel(); // FIXME Where is the delete for that? :p connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); - connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); - connect(this, SIGNAL(bufferUpdated(Buffer *)), model, SLOT(bufferUpdated(Buffer *))); - connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), model, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); + //connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); + //connect(this, SIGNAL(bufferUpdated(Buffer *)), model, SLOT(bufferUpdated(Buffer *))); + //connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), model, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); BufferViewDock *all = new BufferViewDock(model, tr("All Buffers"), BufferViewFilter::AllNets); registerBufferViewDock(all); @@ -224,7 +215,7 @@ void MainWin::closeEvent(QCloseEvent *event) } void MainWin::showBuffer(BufferId id) { - showBuffer(getBuffer(id)); + showBuffer(Client::buffer(id)); } void MainWin::showBuffer(Buffer *b) { @@ -232,191 +223,7 @@ void MainWin::showBuffer(Buffer *b) { //emit bufferSelected(b); //qApp->processEvents(); ui.bufferWidget->setBuffer(b); - emit bufferSelected(b); -} - -void MainWin::networkConnected(QString net) { - connected[net] = true; - BufferId id = getStatusBufferId(net); - Buffer *b = getBuffer(id); - b->setActive(true); - //b->displayMsg(Message(id, Message::Server, tr("Connected."))); - // TODO buffersUpdated(); -} - -void MainWin::networkDisconnected(QString net) { - //getBuffer(net, "")->setActive(false); - foreach(BufferId id, buffers.keys()) { - if(id.network() != net) continue; - Buffer *b = getBuffer(id); - //b->displayMsg(Message(id, Message::Server, tr("Server disconnected."))); FIXME - b->setActive(false); - } - connected[net] = false; -} - -void MainWin::updateBufferId(BufferId id) { - bufferIds[id.uid()] = id; // make lookups by id faster - getBuffer(id); -} - -BufferId MainWin::getBufferId(QString net, QString buf) { - foreach(BufferId id, buffers.keys()) { - if(id.network() == net && id.buffer() == buf) return id; - } - Q_ASSERT(false); - return BufferId(); -} - -BufferId MainWin::getStatusBufferId(QString net) { - return getBufferId(net, ""); -} - - -Buffer * MainWin::getBuffer(BufferId id) { - if(!buffers.contains(id)) { - Buffer *b = new Buffer(id); - b->setOwnNick(ownNick[id.network()]); - connect(b, SIGNAL(userInput(BufferId, QString)), this, SLOT(userInput(BufferId, QString))); - connect(b, SIGNAL(bufferUpdated(Buffer *)), this, SIGNAL(bufferUpdated(Buffer *))); - connect(b, SIGNAL(bufferDestroyed(Buffer *)), this, SIGNAL(bufferDestroyed(Buffer *))); - buffers[id] = b; - emit bufferUpdated(b); - } - return buffers[id]; -} - -void MainWin::recvNetworkState(QString net, QVariant state) { - connected[net] = true; - setOwnNick(net, state.toMap()["OwnNick"].toString()); - getBuffer(getStatusBufferId(net))->setActive(true); - VarMap t = state.toMap()["Topics"].toMap(); - VarMap n = state.toMap()["Nicks"].toMap(); - foreach(QVariant v, t.keys()) { - QString buf = v.toString(); - BufferId id = getBufferId(net, buf); - getBuffer(id)->setActive(true); - setTopic(net, buf, t[buf].toString()); - } - foreach(QString nick, n.keys()) { - addNick(net, nick, n[nick].toMap()); - } -} - -void MainWin::recvMessage(Message msg) { - /* - Buffer *b; - if(msg.flags & Message::PrivMsg) { - // query - if(msg.flags & Message::Self) b = getBuffer(net, msg.target); - else b = getBuffer(net, nickFromMask(msg.sender)); - } else { - b = getBuffer(net, msg.target); - } - */ - - - Buffer *b = getBuffer(msg.buffer); - - Buffer::ActivityLevel level = Buffer::OtherActivity; - if(msg.type == Message::Plain or msg.type == Message::Notice){ - level |= Buffer::NewMessage; - } - if(msg.flags & Message::Highlight){ - level |= Buffer::Highlight; - } - emit bufferActivity(level, b); - - //b->displayMsg(msg); - b->appendChatLine(new ChatLine(msg)); -} - -void MainWin::recvStatusMsg(QString net, QString msg) { - //recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg))); - -} - -void MainWin::recvBacklogData(BufferId id, QList msgs, bool done) { - foreach(QVariant v, msgs) { - layoutQueue.append(v.value()); - } - if(!layoutTimer->isActive()) layoutTimer->start(); -} - - -void MainWin::layoutMsg() { - if(layoutQueue.count()) { - ChatLine *line = new ChatLine(layoutQueue.takeFirst()); - getBuffer(line->bufferId())->prependChatLine(line); - } - if(!layoutQueue.count()) layoutTimer->stop(); -} - -void MainWin::userInput(BufferId id, QString msg) { - emit sendInput(id, msg); -} - -void MainWin::setTopic(QString net, QString buf, QString topic) { - BufferId id = getBufferId(net, buf); - if(!connected[id.network()]) return; - Buffer *b = getBuffer(id); - b->setTopic(topic); - //if(!b->isActive()) { - // b->setActive(true); - // buffersUpdated(); - //} -} - -void MainWin::addNick(QString net, QString nick, VarMap props) { - if(!connected[net]) return; - nicks[net][nick] = props; - VarMap chans = props["Channels"].toMap(); - QStringList c = chans.keys(); - foreach(QString bufname, c) { - getBuffer(getBufferId(net, bufname))->addNick(nick, props); - } -} - -void MainWin::renameNick(QString net, QString oldnick, QString newnick) { - if(!connected[net]) return; - QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys(); - foreach(QString c, chans) { - getBuffer(getBufferId(net, c))->renameNick(oldnick, newnick); - } - nicks[net][newnick] = nicks[net].take(oldnick); -} - -void MainWin::updateNick(QString net, QString nick, VarMap props) { - if(!connected[net]) return; - QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys(); - QStringList newchans = props["Channels"].toMap().keys(); - foreach(QString c, newchans) { - if(oldchans.contains(c)) getBuffer(getBufferId(net, c))->updateNick(nick, props); - else getBuffer(getBufferId(net, c))->addNick(nick, props); - } - foreach(QString c, oldchans) { - if(!newchans.contains(c)) getBuffer(getBufferId(net, c))->removeNick(nick); - } - nicks[net][nick] = props; -} - -void MainWin::removeNick(QString net, QString nick) { - if(!connected[net]) return; - VarMap chans = nicks[net][nick]["Channels"].toMap(); - foreach(QString bufname, chans.keys()) { - getBuffer(getBufferId(net, bufname))->removeNick(nick); - } - nicks[net].remove(nick); -} - -void MainWin::setOwnNick(QString net, QString nick) { - if(!connected[net]) return; - ownNick[net] = nick; - foreach(BufferId id, buffers.keys()) { - if(id.network() == net) { - buffers[id]->setOwnNick(nick); - } - } + //emit bufferSelected(b); // FIXME do we need this? } void MainWin::importBacklog() { diff --git a/gui/mainwin.h b/gui/mainwin.h index 8092395c..41d1a2f7 100644 --- a/gui/mainwin.h +++ b/gui/mainwin.h @@ -56,31 +56,32 @@ class MainWin : public QMainWindow { void closeEvent(QCloseEvent *event); signals: - void sendInput(BufferId, QString message); - void bufferSelected(Buffer *); - void bufferUpdated(Buffer *); - void bufferActivity(Buffer::ActivityLevel, Buffer *); - void bufferDestroyed(Buffer *); - void backlogReceived(Buffer *, QList); - void requestBacklog(BufferId, QVariant, QVariant); + //void sendInput(BufferId, QString message); + //void bufferSelected(Buffer *); + //void bufferUpdated(Buffer *); + //void bufferActivity(Buffer::ActivityLevel, Buffer *); + //void bufferDestroyed(Buffer *); + //void backlogReceived(Buffer *, QList); + //void requestBacklog(BufferId, QVariant, QVariant); void importOldBacklog(); private slots: - void userInput(BufferId, QString); - void networkConnected(QString); - void networkDisconnected(QString); - void recvNetworkState(QString, QVariant); - void recvMessage(Message message); - void recvStatusMsg(QString network, QString message); - void setTopic(QString net, QString buf, QString); - void addNick(QString net, QString nick, VarMap props); - void removeNick(QString net, QString nick); - void renameNick(QString net, QString oldnick, QString newnick); - void updateNick(QString net, QString nick, VarMap props); - void setOwnNick(QString net, QString nick); - void recvBacklogData(BufferId, QList, bool); - void updateBufferId(BufferId); + + //void userInput(BufferId, QString); + //void networkConnected(QString); + //void networkDisconnected(QString); + //void recvNetworkState(QString, QVariant); + //void recvMessage(Message message); + //void recvStatusMsg(QString network, QString message); + //void setTopic(QString net, QString buf, QString); + //void addNick(QString net, QString nick, VarMap props); + //void removeNick(QString net, QString nick); + //void renameNick(QString net, QString oldnick, QString newnick); + //void updateNick(QString net, QString nick, VarMap props); + //void setOwnNick(QString net, QString nick); + //void recvBacklogData(BufferId, QList, bool); + //void updateBufferId(BufferId); void showServerList(); void showSettingsDlg(); @@ -89,7 +90,6 @@ class MainWin : public QMainWindow { void showBuffer(Buffer *); void importBacklog(); - void layoutMsg(); private: Ui::MainWin ui; @@ -97,7 +97,7 @@ class MainWin : public QMainWindow { void setupMenus(); void setupViews(); void setupSettingsDlg(); - void syncToCore(); // implemented in main_mono.cpp or main_gui.cpp + //void syncToCore(); // implemented in main_mono.cpp or main_gui.cpp //Buffer * getBuffer(QString net, QString buf); Buffer *getBuffer(BufferId); BufferId getStatusBufferId(QString net); @@ -116,13 +116,13 @@ class MainWin : public QMainWindow { //QString currentNetwork, currentBuffer; //QHash > buffers; uint currentBuffer; - QHash buffers; - QHash bufferIds; - QHash > nicks; - QHash connected; - QHash ownNick; + //QHash buffers; + //QHash bufferIds; + //QHash > nicks; + //QHash connected; + //QHash ownNick; //QHash > coreBackLog; - QList coreBuffers; + //QList coreBuffers; QList netViews; diff --git a/gui/serverlist.cpp b/gui/serverlist.cpp index 855056c2..ab12919d 100644 --- a/gui/serverlist.cpp +++ b/gui/serverlist.cpp @@ -40,7 +40,7 @@ ServerListDlg::ServerListDlg(QWidget *parent) : QDialog(parent) { settings.endGroup(); // check if we already have a valid identity if(!Global::data("Identities", VarMap()).toMap().contains("Default")) editIdentities(true); - connect(this, SIGNAL(requestConnect(QStringList)), guiProxy, SLOT(gsRequestConnect(QStringList))); + connect(this, SIGNAL(requestConnect(QStringList)), ClientProxy::instance(), SLOT(gsRequestConnect(QStringList))); // Autoconnect QStringList list; diff --git a/main/main_gui.cpp b/main/main_gui.cpp index f48f615c..e9bd6c8e 100644 --- a/main/main_gui.cpp +++ b/main/main_gui.cpp @@ -42,7 +42,7 @@ int main(int argc, char **argv) { Global::quasselDir = QDir::homePath() + "/.quassel"; global = new Global(); - guiProxy = new GUIProxy(); + guiProxy = new GuiProxy(); Style::init(); @@ -89,7 +89,9 @@ void MainWin::syncToCore() { foreach(QVariant v, state["CoreBuffers"].toList()) { coreBuffers.append(v.value()); } } -GUIProxy::GUIProxy() { +/* + +GuiProxy::GuiProxy() { if(guiProxy) qFatal("Trying to instantiate more than one CoreProxy object!"); blockSize = 0; @@ -104,20 +106,20 @@ GUIProxy::GUIProxy() { } -void GUIProxy::connectToCore(QString host, quint16 port) { +void GuiProxy::connectToCore(QString host, quint16 port) { socket.connectToHost(host, port); } -void GUIProxy::disconnectFromCore() { +void GuiProxy::disconnectFromCore() { socket.close(); } -void GUIProxy::serverError(QAbstractSocket::SocketError) { +void GuiProxy::serverError(QAbstractSocket::SocketError) { emit coreConnectionError(socket.errorString()); //qFatal(QString("Connection error: %1").arg(socket.errorString()).toAscii()); } -void GUIProxy::serverHasData() { +void GuiProxy::serverHasData() { QVariant item; while(readDataFromDevice(&socket, blockSize, item)) { emit recvPartialItem(1,1); @@ -130,15 +132,17 @@ void GUIProxy::serverHasData() { emit recvPartialItem(socket.bytesAvailable(), blockSize); } } - -void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { +*/ +/* +void GuiProxy::send(GuiSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { QList sigdata; sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3); //qDebug() << "Sending signal: " << sigdata; writeDataToDevice(&socket, QVariant(sigdata)); } +*/ -void GUIProxy::updateCoreData(QString key) { +void GuiProxy::updateCoreData(QString key) { QVariant data = global->getData(key); send(GS_UPDATE_GLOBAL_DATA, key, data); } diff --git a/main/main_mono.cpp b/main/main_mono.cpp index d9c682f4..419b1505 100644 --- a/main/main_mono.cpp +++ b/main/main_mono.cpp @@ -22,6 +22,7 @@ #include +#include "gui.h" #include "core.h" #include "style.h" #include "global.h" @@ -43,31 +44,33 @@ int main(int argc, char **argv) { //settings = new Settings(); //global = new Global(); - guiProxy = new GUIProxy(); + //guiProxy = new GUIProxy(); //coreProxy = new CoreProxy(); - QObject::connect(Core::guiSession(), SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), guiProxy, SLOT(recv(CoreSignal, QVariant, QVariant, QVariant))); - QObject::connect(guiProxy, SIGNAL(send(GUISignal, QVariant, QVariant, QVariant)), Core::guiSession(), SLOT(processSignal(GUISignal, QVariant, QVariant, QVariant))); + QObject::connect(Core::localSession(), SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), ClientProxy::instance(), SLOT(recv(CoreSignal, QVariant, QVariant, QVariant))); + QObject::connect(ClientProxy::instance(), SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), Core::localSession(), SLOT(processSignal(ClientSignal, QVariant, QVariant, QVariant))); Settings::init(); Style::init(); - MainWin *mainWin = new MainWin(); - mainWin->show(); - mainWin->init(); + //MainWin *mainWin = new MainWin(); + //mainWin->show(); + //mainWin->init(); + Client::instance(); int exitCode = app.exec(); //delete core; + Client::destroy(); Core::destroy(); - delete guiProxy; + //delete guiProxy; //delete coreProxy; //delete global; - delete mainWin; + //delete mainWin; //delete settings; return exitCode; } -void MainWin::syncToCore() { +void Client::syncToCore() { //Q_ASSERT(Global::data("CoreReady").toBool()); - coreBuffers = Core::guiSession()->buffers(); + coreBuffers = Core::localSession()->buffers(); // NOTE: We don't need to request server states, because in the monolithic version there can't be // any servers connected at this stage... } @@ -78,10 +81,11 @@ void CoreProxy::sendToGUI(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant } */ +/* GUIProxy::GUIProxy() { if(guiProxy) qFatal("Trying to instantiate more than one GUIProxy object!"); } - +*/ /* void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { coreProxy->recv(sig, arg1, arg2, arg3); @@ -90,9 +94,10 @@ void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) // Dummy function definitions // These are not needed, since we don't have a network connection to the core. +/* void GUIProxy::serverHasData() {} void GUIProxy::connectToCore(QString, quint16) {} void GUIProxy::disconnectFromCore() {} void GUIProxy::updateCoreData(QString) {} void GUIProxy::serverError(QAbstractSocket::SocketError) {} - +*/ diff --git a/main/proxy_common.h b/main/proxy_common.h index 208bb88d..30421e71 100644 --- a/main/proxy_common.h +++ b/main/proxy_common.h @@ -21,7 +21,7 @@ #ifndef _PROXY_COMMON_H_ #define _PROXY_COMMON_H_ -enum GUISignal { GS_CLIENT_INIT, GS_USER_INPUT, GS_REQUEST_CONNECT, GS_UPDATE_GLOBAL_DATA, GS_IMPORT_BACKLOG, +enum ClientSignal { GS_CLIENT_INIT, GS_USER_INPUT, GS_REQUEST_CONNECT, GS_UPDATE_GLOBAL_DATA, GS_IMPORT_BACKLOG, GS_REQUEST_BACKLOG }; -- 2.20.1 From 4ccba157efd91e531a3106012f5d54ba372a0292 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 19 Jun 2007 23:42:47 +0000 Subject: [PATCH 09/16] Two hours of bughunting ending between keyboard and chair. Or something like that. Fixed. --- gui/bufferview.cpp | 4 +++- gui/bufferview.h | 2 +- gui/bufferviewwidget.h | 2 +- gui/gui.cpp | 17 +++++++++-------- gui/gui.h | 3 ++- gui/mainwin.cpp | 3 +-- gui/mainwin.h | 12 +++++------- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/gui/bufferview.cpp b/gui/bufferview.cpp index 017ce259..d30e4da1 100644 --- a/gui/bufferview.cpp +++ b/gui/bufferview.cpp @@ -92,6 +92,8 @@ void BufferView::init() { connect(selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), model(), SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model(), SLOT(doubleClickReceived(const QModelIndex &))); connect(model(), SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), selectionModel(), SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); + + expandAll(); } void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets) { @@ -110,6 +112,6 @@ void BufferView::dragEnterEvent(QDragEnterEvent *event) { } void BufferView::rowsInserted(const QModelIndex & parent, int start, int end) { - if(parent.parent() == QModelIndex()) setExpanded(parent, true); qDebug() << "expanded"; + if(parent.parent() == QModelIndex()) setExpanded(parent, true); QTreeView::rowsInserted(parent, start, end); } diff --git a/gui/bufferview.h b/gui/bufferview.h index 9daee9f1..6fcadf86 100644 --- a/gui/bufferview.h +++ b/gui/bufferview.h @@ -78,7 +78,7 @@ class BufferView : public QTreeView { void dragEnterEvent(QDragEnterEvent *); - protected slots: + protected: void rowsInserted (const QModelIndex & parent, int start, int end); }; diff --git a/gui/bufferviewwidget.h b/gui/bufferviewwidget.h index a14d173d..24523aed 100644 --- a/gui/bufferviewwidget.h +++ b/gui/bufferviewwidget.h @@ -26,7 +26,7 @@ #include "guiproxy.h" #include "buffer.h" -#include "ui_bufferviewwidget.h" +#include "gui/ui_bufferviewwidget.h" #include "bufferview.h" /***************************************** diff --git a/gui/gui.cpp b/gui/gui.cpp index 9f38d199..1924001b 100644 --- a/gui/gui.cpp +++ b/gui/gui.cpp @@ -22,7 +22,7 @@ #include "guiproxy.h" #include "mainwin.h" #include "buffer.h" -#include "bufferview.h" +//#include "bufferview.h" #include "bufferviewwidget.h" #include "util.h" @@ -41,6 +41,7 @@ Client *Client::instance() { if(instanceptr) return instanceptr; instanceptr = new Client(); instanceptr->init(); + return instanceptr; } void Client::destroy() { @@ -51,8 +52,9 @@ void Client::destroy() { Client::Client() { clientProxy = ClientProxy::instance(); - mainWin = new MainWin(); - _bufferModel = new BufferTreeModel(mainWin); // FIXME + //mainWin = new MainWin(); + + _bufferModel = new BufferTreeModel(0); // FIXME connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *))); @@ -72,10 +74,9 @@ void Client::init() { connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(serverError(QAbstractSocket::SocketError))); connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateCoreData(UserId, QString))); - connect(ClientProxy::instance(), SIGNAL(csUpdateGlobalData(QString, QVariant)), this, SLOT(updateLocalData(QString, QVariant))); - - connect(ClientProxy::instance(), SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant))); + connect(clientProxy, SIGNAL(csUpdateGlobalData(QString, QVariant)), this, SLOT(updateLocalData(QString, QVariant))); + connect(clientProxy, SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant))); connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); @@ -106,15 +107,15 @@ void Client::init() { emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request } - //mainWin = new MainWin(); + mainWin = new MainWin(); mainWin->init(); } Client::~Client() { delete mainWin; - foreach(Buffer *buf, buffers.values()) delete buf; delete _bufferModel; + foreach(Buffer *buf, buffers.values()) delete buf; ClientProxy::destroy(); } diff --git a/gui/gui.h b/gui/gui.h index 6ec1dbad..2bf9c02f 100644 --- a/gui/gui.h +++ b/gui/gui.h @@ -29,10 +29,11 @@ #include "buffer.h" #include "message.h" #include "guiproxy.h" +#include "bufferviewwidget.h" class MainWin; class ClientProxy; -class BufferTreeModel; +//class BufferTreeModel; class Client : public QObject { Q_OBJECT diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 3d2df39b..0adce3db 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -36,8 +36,6 @@ #include "settingsdlg.h" #include "settingspages.h" -LayoutThread *layoutThread; - MainWin::MainWin() : QMainWindow() { ui.setupUi(this); //widget = 0; @@ -144,6 +142,7 @@ void MainWin::setupMenus() { } void MainWin::setupViews() { + BufferTreeModel *model = Client::bufferModel(); // FIXME Where is the delete for that? :p connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); //connect(this, SIGNAL(bufferSelected(Buffer *)), model, SLOT(selectBuffer(Buffer *))); diff --git a/gui/mainwin.h b/gui/mainwin.h index 41d1a2f7..7876b50d 100644 --- a/gui/mainwin.h +++ b/gui/mainwin.h @@ -35,8 +35,6 @@ class Buffer; class BufferWidget; class SettingsDlg; -extern LayoutThread *layoutThread; - //!\brief The main window and central object of Quassel GUI. /** In addition to displaying the main window including standard stuff like a menubar, * dockwidgets and of course the chat window, this class also stores all data it @@ -99,9 +97,9 @@ class MainWin : public QMainWindow { void setupSettingsDlg(); //void syncToCore(); // implemented in main_mono.cpp or main_gui.cpp //Buffer * getBuffer(QString net, QString buf); - Buffer *getBuffer(BufferId); - BufferId getStatusBufferId(QString net); - BufferId getBufferId(QString net, QString buf); + //Buffer *getBuffer(BufferId); + //BufferId getStatusBufferId(QString net); + //BufferId getBufferId(QString net, QString buf); //void buffersUpdated(); QSystemTrayIcon *systray; @@ -126,8 +124,8 @@ class MainWin : public QMainWindow { QList netViews; - QTimer *layoutTimer; - QList layoutQueue; + //QTimer *layoutTimer; + //QList layoutQueue; }; #endif -- 2.20.1 From f0a6776fc5102ff6a7fe1469917fe231e4cd3a8a Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 20 Jun 2007 00:01:31 +0000 Subject: [PATCH 10/16] Make selections in bufferviews (mostly) synchronous again. --- gui/bufferviewwidget.cpp | 3 ++- gui/mainwin.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gui/bufferviewwidget.cpp b/gui/bufferviewwidget.cpp index 04331c38..a78754e7 100644 --- a/gui/bufferviewwidget.cpp +++ b/gui/bufferviewwidget.cpp @@ -154,7 +154,7 @@ BufferTreeModel::BufferTreeModel(QObject *parent) : QAbstractItemModel(parent) { QList rootData; rootData << "Buffer" << "Network"; rootItem = new TreeItem(rootData, 0); - + connect(this, SIGNAL(fakeUserInput(BufferId, QString)), ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); } @@ -361,6 +361,7 @@ void BufferTreeModel::changeCurrent(const QModelIndex ¤t, const QModelInde currentBuffer = getBufferByIndex(current); bufferActivity(Buffer::NoActivity, currentBuffer); emit bufferSelected(currentBuffer); + emit updateSelection(current, QItemSelectionModel::ClearAndSelect); } } diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 0adce3db..35441a1b 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -222,7 +222,7 @@ void MainWin::showBuffer(Buffer *b) { //emit bufferSelected(b); //qApp->processEvents(); ui.bufferWidget->setBuffer(b); - //emit bufferSelected(b); // FIXME do we need this? + //emit bufferSelected(b); } void MainWin::importBacklog() { -- 2.20.1 From 077d44f36d2f5c730283ef6be839aea7dd073d56 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 20 Jun 2007 01:21:00 +0000 Subject: [PATCH 11/16] Starting reorganization of files in preparation of separation of client and GUI. --- {main => src/common}/CMakeLists.txt | 0 {main => src/common}/global.cpp | 0 {main => src/common}/global.h | 0 {main => src/common}/logger.cpp | 0 {main => src/common}/logger.h | 0 {main => src/common}/main_core.cpp | 0 {main => src/common}/main_gui.cpp | 0 {main => src/common}/main_mono.cpp | 0 {main => src/common}/message.cpp | 0 {main => src/common}/message.h | 0 {main => src/common}/proxy_common.h | 0 {main => src/common}/settings.cpp | 0 {main => src/common}/settings.h | 0 {main => src/common}/util.cpp | 0 {main => src/common}/util.h | 0 {core => src/core}/CMakeLists.txt | 0 {core => src/core}/backlog.cpp | 0 {core => src/core}/backlog.h | 0 {core => src/core}/core.cpp | 0 {core => src/core}/core.h | 0 {core => src/core}/coreproxy.cpp | 0 {core => src/core}/coreproxy.h | 0 {core => src/core}/server.cpp | 0 {core => src/core}/server.h | 0 {core => src/core}/sqlitestorage.cpp | 0 {core => src/core}/sqlitestorage.h | 0 {core => src/core}/storage.cpp | 0 {core => src/core}/storage.h | 0 {plugins => src/plugins}/plugin.h | 0 {gui => src/qtgui}/CMakeLists.txt | 0 {gui => src/qtgui}/buffer.cpp | 0 {gui => src/qtgui}/buffer.h | 0 {gui => src/qtgui}/bufferview.cpp | 0 {gui => src/qtgui}/bufferview.h | 0 {gui => src/qtgui}/bufferviewwidget.cpp | 0 {gui => src/qtgui}/bufferviewwidget.h | 0 {gui => src/qtgui}/bufferwidget.cpp | 0 {gui => src/qtgui}/bufferwidget.h | 0 {gui => src/qtgui}/channelwidgetinput.cpp | 0 {gui => src/qtgui}/channelwidgetinput.h | 0 {gui => src/qtgui}/chatwidget.cpp | 0 {gui => src/qtgui}/chatwidget.h | 0 {gui => src/qtgui}/coreconnectdlg.cpp | 0 {gui => src/qtgui}/coreconnectdlg.h | 0 {gui => src/qtgui}/gui.cpp | 0 {gui => src/qtgui}/gui.h | 0 {gui => src/qtgui}/guiproxy.cpp | 0 {gui => src/qtgui}/guiproxy.h | 0 {gui => src/qtgui}/identities.cpp | 0 {gui => src/qtgui}/identities.h | 0 {gui => src/qtgui}/mainwin.cpp | 0 {gui => src/qtgui}/mainwin.h | 0 {gui => src/qtgui}/serverlist.cpp | 0 {gui => src/qtgui}/serverlist.h | 0 {gui => src/qtgui}/settingsdlg.cpp | 0 {gui => src/qtgui}/settingsdlg.h | 0 {gui => src/qtgui}/settingspages.cpp | 0 {gui => src/qtgui}/settingspages.h | 0 {gui => src/qtgui}/style.cpp | 0 {gui => src/qtgui}/style.h | 0 {gui => src/qtgui}/tabcompleter.cpp | 0 {gui => src/qtgui}/tabcompleter.h | 0 {gui => src/qtgui}/ui/aboutdlg.ui | 0 {gui => src/qtgui}/ui/buffermgmntsettingspage.ui | 0 {gui => src/qtgui}/ui/bufferviewwidget.ui | 0 {gui => src/qtgui}/ui/bufferwidget.ui | 0 {gui => src/qtgui}/ui/channelwidget.ui | 0 {gui => src/qtgui}/ui/connectionsettingspage.ui | 0 {gui => src/qtgui}/ui/coreconnectdlg.ui | 0 {gui => src/qtgui}/ui/coresettingspage.ui | 0 {gui => src/qtgui}/ui/identitiesdlg.ui | 0 {gui => src/qtgui}/ui/identitieseditdlg.ui | 0 {gui => src/qtgui}/ui/ircwidget.ui | 0 {gui => src/qtgui}/ui/mainwin.ui | 0 {gui => src/qtgui}/ui/networkeditdlg.ui | 0 {gui => src/qtgui}/ui/nickeditdlg.ui | 0 {gui => src/qtgui}/ui/servereditdlg.ui | 0 {gui => src/qtgui}/ui/serverlistdlg.ui | 0 {gui => src/qtgui}/ui/settingsdlg.ui | 0 79 files changed, 0 insertions(+), 0 deletions(-) rename {main => src/common}/CMakeLists.txt (100%) rename {main => src/common}/global.cpp (100%) rename {main => src/common}/global.h (100%) rename {main => src/common}/logger.cpp (100%) rename {main => src/common}/logger.h (100%) rename {main => src/common}/main_core.cpp (100%) rename {main => src/common}/main_gui.cpp (100%) rename {main => src/common}/main_mono.cpp (100%) rename {main => src/common}/message.cpp (100%) rename {main => src/common}/message.h (100%) rename {main => src/common}/proxy_common.h (100%) rename {main => src/common}/settings.cpp (100%) rename {main => src/common}/settings.h (100%) rename {main => src/common}/util.cpp (100%) rename {main => src/common}/util.h (100%) rename {core => src/core}/CMakeLists.txt (100%) rename {core => src/core}/backlog.cpp (100%) rename {core => src/core}/backlog.h (100%) rename {core => src/core}/core.cpp (100%) rename {core => src/core}/core.h (100%) rename {core => src/core}/coreproxy.cpp (100%) rename {core => src/core}/coreproxy.h (100%) rename {core => src/core}/server.cpp (100%) rename {core => src/core}/server.h (100%) rename {core => src/core}/sqlitestorage.cpp (100%) rename {core => src/core}/sqlitestorage.h (100%) rename {core => src/core}/storage.cpp (100%) rename {core => src/core}/storage.h (100%) rename {plugins => src/plugins}/plugin.h (100%) rename {gui => src/qtgui}/CMakeLists.txt (100%) rename {gui => src/qtgui}/buffer.cpp (100%) rename {gui => src/qtgui}/buffer.h (100%) rename {gui => src/qtgui}/bufferview.cpp (100%) rename {gui => src/qtgui}/bufferview.h (100%) rename {gui => src/qtgui}/bufferviewwidget.cpp (100%) rename {gui => src/qtgui}/bufferviewwidget.h (100%) rename {gui => src/qtgui}/bufferwidget.cpp (100%) rename {gui => src/qtgui}/bufferwidget.h (100%) rename {gui => src/qtgui}/channelwidgetinput.cpp (100%) rename {gui => src/qtgui}/channelwidgetinput.h (100%) rename {gui => src/qtgui}/chatwidget.cpp (100%) rename {gui => src/qtgui}/chatwidget.h (100%) rename {gui => src/qtgui}/coreconnectdlg.cpp (100%) rename {gui => src/qtgui}/coreconnectdlg.h (100%) rename {gui => src/qtgui}/gui.cpp (100%) rename {gui => src/qtgui}/gui.h (100%) rename {gui => src/qtgui}/guiproxy.cpp (100%) rename {gui => src/qtgui}/guiproxy.h (100%) rename {gui => src/qtgui}/identities.cpp (100%) rename {gui => src/qtgui}/identities.h (100%) rename {gui => src/qtgui}/mainwin.cpp (100%) rename {gui => src/qtgui}/mainwin.h (100%) rename {gui => src/qtgui}/serverlist.cpp (100%) rename {gui => src/qtgui}/serverlist.h (100%) rename {gui => src/qtgui}/settingsdlg.cpp (100%) rename {gui => src/qtgui}/settingsdlg.h (100%) rename {gui => src/qtgui}/settingspages.cpp (100%) rename {gui => src/qtgui}/settingspages.h (100%) rename {gui => src/qtgui}/style.cpp (100%) rename {gui => src/qtgui}/style.h (100%) rename {gui => src/qtgui}/tabcompleter.cpp (100%) rename {gui => src/qtgui}/tabcompleter.h (100%) rename {gui => src/qtgui}/ui/aboutdlg.ui (100%) rename {gui => src/qtgui}/ui/buffermgmntsettingspage.ui (100%) rename {gui => src/qtgui}/ui/bufferviewwidget.ui (100%) rename {gui => src/qtgui}/ui/bufferwidget.ui (100%) rename {gui => src/qtgui}/ui/channelwidget.ui (100%) rename {gui => src/qtgui}/ui/connectionsettingspage.ui (100%) rename {gui => src/qtgui}/ui/coreconnectdlg.ui (100%) rename {gui => src/qtgui}/ui/coresettingspage.ui (100%) rename {gui => src/qtgui}/ui/identitiesdlg.ui (100%) rename {gui => src/qtgui}/ui/identitieseditdlg.ui (100%) rename {gui => src/qtgui}/ui/ircwidget.ui (100%) rename {gui => src/qtgui}/ui/mainwin.ui (100%) rename {gui => src/qtgui}/ui/networkeditdlg.ui (100%) rename {gui => src/qtgui}/ui/nickeditdlg.ui (100%) rename {gui => src/qtgui}/ui/servereditdlg.ui (100%) rename {gui => src/qtgui}/ui/serverlistdlg.ui (100%) rename {gui => src/qtgui}/ui/settingsdlg.ui (100%) diff --git a/main/CMakeLists.txt b/src/common/CMakeLists.txt similarity index 100% rename from main/CMakeLists.txt rename to src/common/CMakeLists.txt diff --git a/main/global.cpp b/src/common/global.cpp similarity index 100% rename from main/global.cpp rename to src/common/global.cpp diff --git a/main/global.h b/src/common/global.h similarity index 100% rename from main/global.h rename to src/common/global.h diff --git a/main/logger.cpp b/src/common/logger.cpp similarity index 100% rename from main/logger.cpp rename to src/common/logger.cpp diff --git a/main/logger.h b/src/common/logger.h similarity index 100% rename from main/logger.h rename to src/common/logger.h diff --git a/main/main_core.cpp b/src/common/main_core.cpp similarity index 100% rename from main/main_core.cpp rename to src/common/main_core.cpp diff --git a/main/main_gui.cpp b/src/common/main_gui.cpp similarity index 100% rename from main/main_gui.cpp rename to src/common/main_gui.cpp diff --git a/main/main_mono.cpp b/src/common/main_mono.cpp similarity index 100% rename from main/main_mono.cpp rename to src/common/main_mono.cpp diff --git a/main/message.cpp b/src/common/message.cpp similarity index 100% rename from main/message.cpp rename to src/common/message.cpp diff --git a/main/message.h b/src/common/message.h similarity index 100% rename from main/message.h rename to src/common/message.h diff --git a/main/proxy_common.h b/src/common/proxy_common.h similarity index 100% rename from main/proxy_common.h rename to src/common/proxy_common.h diff --git a/main/settings.cpp b/src/common/settings.cpp similarity index 100% rename from main/settings.cpp rename to src/common/settings.cpp diff --git a/main/settings.h b/src/common/settings.h similarity index 100% rename from main/settings.h rename to src/common/settings.h diff --git a/main/util.cpp b/src/common/util.cpp similarity index 100% rename from main/util.cpp rename to src/common/util.cpp diff --git a/main/util.h b/src/common/util.h similarity index 100% rename from main/util.h rename to src/common/util.h diff --git a/core/CMakeLists.txt b/src/core/CMakeLists.txt similarity index 100% rename from core/CMakeLists.txt rename to src/core/CMakeLists.txt diff --git a/core/backlog.cpp b/src/core/backlog.cpp similarity index 100% rename from core/backlog.cpp rename to src/core/backlog.cpp diff --git a/core/backlog.h b/src/core/backlog.h similarity index 100% rename from core/backlog.h rename to src/core/backlog.h diff --git a/core/core.cpp b/src/core/core.cpp similarity index 100% rename from core/core.cpp rename to src/core/core.cpp diff --git a/core/core.h b/src/core/core.h similarity index 100% rename from core/core.h rename to src/core/core.h diff --git a/core/coreproxy.cpp b/src/core/coreproxy.cpp similarity index 100% rename from core/coreproxy.cpp rename to src/core/coreproxy.cpp diff --git a/core/coreproxy.h b/src/core/coreproxy.h similarity index 100% rename from core/coreproxy.h rename to src/core/coreproxy.h diff --git a/core/server.cpp b/src/core/server.cpp similarity index 100% rename from core/server.cpp rename to src/core/server.cpp diff --git a/core/server.h b/src/core/server.h similarity index 100% rename from core/server.h rename to src/core/server.h diff --git a/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp similarity index 100% rename from core/sqlitestorage.cpp rename to src/core/sqlitestorage.cpp diff --git a/core/sqlitestorage.h b/src/core/sqlitestorage.h similarity index 100% rename from core/sqlitestorage.h rename to src/core/sqlitestorage.h diff --git a/core/storage.cpp b/src/core/storage.cpp similarity index 100% rename from core/storage.cpp rename to src/core/storage.cpp diff --git a/core/storage.h b/src/core/storage.h similarity index 100% rename from core/storage.h rename to src/core/storage.h diff --git a/plugins/plugin.h b/src/plugins/plugin.h similarity index 100% rename from plugins/plugin.h rename to src/plugins/plugin.h diff --git a/gui/CMakeLists.txt b/src/qtgui/CMakeLists.txt similarity index 100% rename from gui/CMakeLists.txt rename to src/qtgui/CMakeLists.txt diff --git a/gui/buffer.cpp b/src/qtgui/buffer.cpp similarity index 100% rename from gui/buffer.cpp rename to src/qtgui/buffer.cpp diff --git a/gui/buffer.h b/src/qtgui/buffer.h similarity index 100% rename from gui/buffer.h rename to src/qtgui/buffer.h diff --git a/gui/bufferview.cpp b/src/qtgui/bufferview.cpp similarity index 100% rename from gui/bufferview.cpp rename to src/qtgui/bufferview.cpp diff --git a/gui/bufferview.h b/src/qtgui/bufferview.h similarity index 100% rename from gui/bufferview.h rename to src/qtgui/bufferview.h diff --git a/gui/bufferviewwidget.cpp b/src/qtgui/bufferviewwidget.cpp similarity index 100% rename from gui/bufferviewwidget.cpp rename to src/qtgui/bufferviewwidget.cpp diff --git a/gui/bufferviewwidget.h b/src/qtgui/bufferviewwidget.h similarity index 100% rename from gui/bufferviewwidget.h rename to src/qtgui/bufferviewwidget.h diff --git a/gui/bufferwidget.cpp b/src/qtgui/bufferwidget.cpp similarity index 100% rename from gui/bufferwidget.cpp rename to src/qtgui/bufferwidget.cpp diff --git a/gui/bufferwidget.h b/src/qtgui/bufferwidget.h similarity index 100% rename from gui/bufferwidget.h rename to src/qtgui/bufferwidget.h diff --git a/gui/channelwidgetinput.cpp b/src/qtgui/channelwidgetinput.cpp similarity index 100% rename from gui/channelwidgetinput.cpp rename to src/qtgui/channelwidgetinput.cpp diff --git a/gui/channelwidgetinput.h b/src/qtgui/channelwidgetinput.h similarity index 100% rename from gui/channelwidgetinput.h rename to src/qtgui/channelwidgetinput.h diff --git a/gui/chatwidget.cpp b/src/qtgui/chatwidget.cpp similarity index 100% rename from gui/chatwidget.cpp rename to src/qtgui/chatwidget.cpp diff --git a/gui/chatwidget.h b/src/qtgui/chatwidget.h similarity index 100% rename from gui/chatwidget.h rename to src/qtgui/chatwidget.h diff --git a/gui/coreconnectdlg.cpp b/src/qtgui/coreconnectdlg.cpp similarity index 100% rename from gui/coreconnectdlg.cpp rename to src/qtgui/coreconnectdlg.cpp diff --git a/gui/coreconnectdlg.h b/src/qtgui/coreconnectdlg.h similarity index 100% rename from gui/coreconnectdlg.h rename to src/qtgui/coreconnectdlg.h diff --git a/gui/gui.cpp b/src/qtgui/gui.cpp similarity index 100% rename from gui/gui.cpp rename to src/qtgui/gui.cpp diff --git a/gui/gui.h b/src/qtgui/gui.h similarity index 100% rename from gui/gui.h rename to src/qtgui/gui.h diff --git a/gui/guiproxy.cpp b/src/qtgui/guiproxy.cpp similarity index 100% rename from gui/guiproxy.cpp rename to src/qtgui/guiproxy.cpp diff --git a/gui/guiproxy.h b/src/qtgui/guiproxy.h similarity index 100% rename from gui/guiproxy.h rename to src/qtgui/guiproxy.h diff --git a/gui/identities.cpp b/src/qtgui/identities.cpp similarity index 100% rename from gui/identities.cpp rename to src/qtgui/identities.cpp diff --git a/gui/identities.h b/src/qtgui/identities.h similarity index 100% rename from gui/identities.h rename to src/qtgui/identities.h diff --git a/gui/mainwin.cpp b/src/qtgui/mainwin.cpp similarity index 100% rename from gui/mainwin.cpp rename to src/qtgui/mainwin.cpp diff --git a/gui/mainwin.h b/src/qtgui/mainwin.h similarity index 100% rename from gui/mainwin.h rename to src/qtgui/mainwin.h diff --git a/gui/serverlist.cpp b/src/qtgui/serverlist.cpp similarity index 100% rename from gui/serverlist.cpp rename to src/qtgui/serverlist.cpp diff --git a/gui/serverlist.h b/src/qtgui/serverlist.h similarity index 100% rename from gui/serverlist.h rename to src/qtgui/serverlist.h diff --git a/gui/settingsdlg.cpp b/src/qtgui/settingsdlg.cpp similarity index 100% rename from gui/settingsdlg.cpp rename to src/qtgui/settingsdlg.cpp diff --git a/gui/settingsdlg.h b/src/qtgui/settingsdlg.h similarity index 100% rename from gui/settingsdlg.h rename to src/qtgui/settingsdlg.h diff --git a/gui/settingspages.cpp b/src/qtgui/settingspages.cpp similarity index 100% rename from gui/settingspages.cpp rename to src/qtgui/settingspages.cpp diff --git a/gui/settingspages.h b/src/qtgui/settingspages.h similarity index 100% rename from gui/settingspages.h rename to src/qtgui/settingspages.h diff --git a/gui/style.cpp b/src/qtgui/style.cpp similarity index 100% rename from gui/style.cpp rename to src/qtgui/style.cpp diff --git a/gui/style.h b/src/qtgui/style.h similarity index 100% rename from gui/style.h rename to src/qtgui/style.h diff --git a/gui/tabcompleter.cpp b/src/qtgui/tabcompleter.cpp similarity index 100% rename from gui/tabcompleter.cpp rename to src/qtgui/tabcompleter.cpp diff --git a/gui/tabcompleter.h b/src/qtgui/tabcompleter.h similarity index 100% rename from gui/tabcompleter.h rename to src/qtgui/tabcompleter.h diff --git a/gui/ui/aboutdlg.ui b/src/qtgui/ui/aboutdlg.ui similarity index 100% rename from gui/ui/aboutdlg.ui rename to src/qtgui/ui/aboutdlg.ui diff --git a/gui/ui/buffermgmntsettingspage.ui b/src/qtgui/ui/buffermgmntsettingspage.ui similarity index 100% rename from gui/ui/buffermgmntsettingspage.ui rename to src/qtgui/ui/buffermgmntsettingspage.ui diff --git a/gui/ui/bufferviewwidget.ui b/src/qtgui/ui/bufferviewwidget.ui similarity index 100% rename from gui/ui/bufferviewwidget.ui rename to src/qtgui/ui/bufferviewwidget.ui diff --git a/gui/ui/bufferwidget.ui b/src/qtgui/ui/bufferwidget.ui similarity index 100% rename from gui/ui/bufferwidget.ui rename to src/qtgui/ui/bufferwidget.ui diff --git a/gui/ui/channelwidget.ui b/src/qtgui/ui/channelwidget.ui similarity index 100% rename from gui/ui/channelwidget.ui rename to src/qtgui/ui/channelwidget.ui diff --git a/gui/ui/connectionsettingspage.ui b/src/qtgui/ui/connectionsettingspage.ui similarity index 100% rename from gui/ui/connectionsettingspage.ui rename to src/qtgui/ui/connectionsettingspage.ui diff --git a/gui/ui/coreconnectdlg.ui b/src/qtgui/ui/coreconnectdlg.ui similarity index 100% rename from gui/ui/coreconnectdlg.ui rename to src/qtgui/ui/coreconnectdlg.ui diff --git a/gui/ui/coresettingspage.ui b/src/qtgui/ui/coresettingspage.ui similarity index 100% rename from gui/ui/coresettingspage.ui rename to src/qtgui/ui/coresettingspage.ui diff --git a/gui/ui/identitiesdlg.ui b/src/qtgui/ui/identitiesdlg.ui similarity index 100% rename from gui/ui/identitiesdlg.ui rename to src/qtgui/ui/identitiesdlg.ui diff --git a/gui/ui/identitieseditdlg.ui b/src/qtgui/ui/identitieseditdlg.ui similarity index 100% rename from gui/ui/identitieseditdlg.ui rename to src/qtgui/ui/identitieseditdlg.ui diff --git a/gui/ui/ircwidget.ui b/src/qtgui/ui/ircwidget.ui similarity index 100% rename from gui/ui/ircwidget.ui rename to src/qtgui/ui/ircwidget.ui diff --git a/gui/ui/mainwin.ui b/src/qtgui/ui/mainwin.ui similarity index 100% rename from gui/ui/mainwin.ui rename to src/qtgui/ui/mainwin.ui diff --git a/gui/ui/networkeditdlg.ui b/src/qtgui/ui/networkeditdlg.ui similarity index 100% rename from gui/ui/networkeditdlg.ui rename to src/qtgui/ui/networkeditdlg.ui diff --git a/gui/ui/nickeditdlg.ui b/src/qtgui/ui/nickeditdlg.ui similarity index 100% rename from gui/ui/nickeditdlg.ui rename to src/qtgui/ui/nickeditdlg.ui diff --git a/gui/ui/servereditdlg.ui b/src/qtgui/ui/servereditdlg.ui similarity index 100% rename from gui/ui/servereditdlg.ui rename to src/qtgui/ui/servereditdlg.ui diff --git a/gui/ui/serverlistdlg.ui b/src/qtgui/ui/serverlistdlg.ui similarity index 100% rename from gui/ui/serverlistdlg.ui rename to src/qtgui/ui/serverlistdlg.ui diff --git a/gui/ui/settingsdlg.ui b/src/qtgui/ui/settingsdlg.ui similarity index 100% rename from gui/ui/settingsdlg.ui rename to src/qtgui/ui/settingsdlg.ui -- 2.20.1 From 130ccf5033c21ca3ad0e0357a82953b5727bd0e9 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 20 Jun 2007 01:24:38 +0000 Subject: [PATCH 12/16] Continuing file reorganization... --- CMakeLists.txt => src/CMakeLists.txt | 0 src/{qtgui => client}/buffer.cpp | 0 src/{qtgui => client}/buffer.h | 0 src/{qtgui/gui.cpp => client/client.cpp} | 0 src/{qtgui/gui.h => client/client.h} | 0 src/{qtgui/guiproxy.cpp => client/clientproxy.cpp} | 0 src/{qtgui/guiproxy.h => client/clientproxy.h} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename CMakeLists.txt => src/CMakeLists.txt (100%) rename src/{qtgui => client}/buffer.cpp (100%) rename src/{qtgui => client}/buffer.h (100%) rename src/{qtgui/gui.cpp => client/client.cpp} (100%) rename src/{qtgui/gui.h => client/client.h} (100%) rename src/{qtgui/guiproxy.cpp => client/clientproxy.cpp} (100%) rename src/{qtgui/guiproxy.h => client/clientproxy.h} (100%) diff --git a/CMakeLists.txt b/src/CMakeLists.txt similarity index 100% rename from CMakeLists.txt rename to src/CMakeLists.txt diff --git a/src/qtgui/buffer.cpp b/src/client/buffer.cpp similarity index 100% rename from src/qtgui/buffer.cpp rename to src/client/buffer.cpp diff --git a/src/qtgui/buffer.h b/src/client/buffer.h similarity index 100% rename from src/qtgui/buffer.h rename to src/client/buffer.h diff --git a/src/qtgui/gui.cpp b/src/client/client.cpp similarity index 100% rename from src/qtgui/gui.cpp rename to src/client/client.cpp diff --git a/src/qtgui/gui.h b/src/client/client.h similarity index 100% rename from src/qtgui/gui.h rename to src/client/client.h diff --git a/src/qtgui/guiproxy.cpp b/src/client/clientproxy.cpp similarity index 100% rename from src/qtgui/guiproxy.cpp rename to src/client/clientproxy.cpp diff --git a/src/qtgui/guiproxy.h b/src/client/clientproxy.h similarity index 100% rename from src/qtgui/guiproxy.h rename to src/client/clientproxy.h -- 2.20.1 From 15ee1478137bc748e27b0b06537973d8df04b9d7 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 20 Jun 2007 01:44:11 +0000 Subject: [PATCH 13/16] Finished file reorganization (for now). Sources are now in src/, subdir names have changed, and files from the former gui/ dir have been split up between the new qtgui/ and client/. Most, if not all files should now be at their final location, while the real work (cleaning up the code from the first phase of GUI reorganization, as well as doing the actual separation) begins now. --- Quassel.kdevelop.filelist | 155 +++++++++--------- src/CMakeLists.txt | 22 +-- src/client/client.cpp | 5 +- src/client/client.h | 6 +- src/client/clientproxy.cpp | 2 +- src/common/CMakeLists.txt | 10 +- src/common/main_mono.cpp | 6 +- {images => src/images}/default/1downarrow.png | Bin {images => src/images}/default/1leftarrow.png | Bin .../images}/default/1rightarrow.png | Bin {images => src/images}/default/1uparrow.png | Bin {images => src/images}/default/2dowarrow.png | Bin {images => src/images}/default/2downarrow.png | Bin {images => src/images}/default/2leftarrow.png | Bin .../images}/default/2rightarrow.png | Bin {images => src/images}/default/2uparrow.png | Bin {images => src/images}/default/3downarrow.png | Bin {images => src/images}/default/3uparrow.png | Bin {images => src/images}/default/add_user.png | Bin {images => src/images}/default/apply.png | Bin {images => src/images}/default/back.png | Bin {images => src/images}/default/bell.png | Bin {images => src/images}/default/bookmark.png | Bin .../images}/default/bookmark_add.png | Bin .../images}/default/bookmark_folder.png | Bin .../images}/default/bookmark_toolbar.png | Bin .../images}/default/bookmarks_list_add.png | Bin {images => src/images}/default/bottom.png | Bin .../images}/default/button_cancel.png | Bin {images => src/images}/default/button_ok.png | Bin {images => src/images}/default/cancel.png | Bin {images => src/images}/default/configure.png | Bin .../images}/default/configure_shortcuts.png | Bin .../images}/default/configure_toolbars.png | Bin .../images}/default/connect_creating.png | Bin .../images}/default/connect_established.png | Bin {images => src/images}/default/connect_no.png | Bin {images => src/images}/default/edit.png | Bin {images => src/images}/default/edit_add.png | Bin .../images}/default/edit_remove.png | Bin {images => src/images}/default/edit_user.png | Bin {images => src/images}/default/editcopy.png | Bin {images => src/images}/default/edittrash.png | Bin {images => src/images}/default/exit.png | Bin {images => src/images}/default/fileclose.png | Bin {images => src/images}/default/filenew.png | Bin {images => src/images}/default/fileopen.png | Bin {images => src/images}/default/fileprint.png | Bin {images => src/images}/default/filesave.png | Bin {images => src/images}/default/filesaveas.png | Bin {images => src/images}/default/finish.png | Bin {images => src/images}/default/folder.png | Bin {images => src/images}/default/folder_new.png | Bin {images => src/images}/default/fonts.png | Bin .../images}/default/fontsizedown.png | Bin {images => src/images}/default/fontsizeup.png | Bin {images => src/images}/default/forward.png | Bin {images => src/images}/default/help.png | Bin {images => src/images}/default/identity.png | Bin {images => src/images}/default/next.png | Bin {images => src/images}/default/no.png | Bin {images => src/images}/default/ok.png | Bin {images => src/images}/default/remove.png | Bin {images => src/images}/default/server.png | Bin {images => src/images}/default/start.png | Bin .../images}/default/status_unknown.png | Bin {images => src/images}/default/stop.png | Bin {images => src/images}/default/tab.png | Bin .../images}/default/tab_breakoff.png | Bin .../images}/default/tab_duplicate.png | Bin {images => src/images}/default/tab_first.png | Bin {images => src/images}/default/tab_last.png | Bin {images => src/images}/default/tab_left.png | Bin {images => src/images}/default/tab_new.png | Bin {images => src/images}/default/tab_new_bg.png | Bin .../images}/default/tab_new_raised.png | Bin {images => src/images}/default/tab_remove.png | Bin {images => src/images}/default/tab_right.png | Bin {images => src/images}/default/top.png | Bin {images => src/images}/default/trash.png | Bin {images => src/images}/default/tux.png | Bin {images => src/images}/default/up.png | Bin .../images}/default/view_bottom.png | Bin .../images}/default/view_choose.png | Bin .../images}/default/view_detailed.png | Bin {images => src/images}/default/view_icon.png | Bin .../images}/default/view_left_right.png | Bin .../images}/default/view_multicolumn.png | Bin .../images}/default/view_orientation.png | Bin .../images}/default/view_remove 2.png | Bin .../images}/default/view_remove.png | Bin {images => src/images}/default/view_right.png | Bin .../images}/default/view_sidetree.png | Bin {images => src/images}/default/view_split.png | Bin .../images}/default/view_top_bottom.png | Bin {images => src/images}/default/wizard.png | Bin {images => src/images}/iconmap.xml | 0 {images => src/images}/icons.qrc | 0 {images => src/images}/qirc-icon.png | Bin src/qtgui/CMakeLists.txt | 27 +-- src/qtgui/bufferviewwidget.h | 4 +- src/qtgui/bufferwidget.h | 2 +- src/qtgui/coreconnectdlg.cpp | 4 +- src/qtgui/coreconnectdlg.h | 3 +- src/qtgui/mainwin.cpp | 4 +- src/qtgui/mainwin.h | 2 +- src/qtgui/serverlist.cpp | 2 +- 107 files changed, 127 insertions(+), 127 deletions(-) rename {images => src/images}/default/1downarrow.png (100%) rename {images => src/images}/default/1leftarrow.png (100%) rename {images => src/images}/default/1rightarrow.png (100%) rename {images => src/images}/default/1uparrow.png (100%) rename {images => src/images}/default/2dowarrow.png (100%) rename {images => src/images}/default/2downarrow.png (100%) rename {images => src/images}/default/2leftarrow.png (100%) rename {images => src/images}/default/2rightarrow.png (100%) rename {images => src/images}/default/2uparrow.png (100%) rename {images => src/images}/default/3downarrow.png (100%) rename {images => src/images}/default/3uparrow.png (100%) rename {images => src/images}/default/add_user.png (100%) rename {images => src/images}/default/apply.png (100%) rename {images => src/images}/default/back.png (100%) rename {images => src/images}/default/bell.png (100%) rename {images => src/images}/default/bookmark.png (100%) rename {images => src/images}/default/bookmark_add.png (100%) rename {images => src/images}/default/bookmark_folder.png (100%) rename {images => src/images}/default/bookmark_toolbar.png (100%) rename {images => src/images}/default/bookmarks_list_add.png (100%) rename {images => src/images}/default/bottom.png (100%) rename {images => src/images}/default/button_cancel.png (100%) rename {images => src/images}/default/button_ok.png (100%) rename {images => src/images}/default/cancel.png (100%) rename {images => src/images}/default/configure.png (100%) rename {images => src/images}/default/configure_shortcuts.png (100%) rename {images => src/images}/default/configure_toolbars.png (100%) rename {images => src/images}/default/connect_creating.png (100%) rename {images => src/images}/default/connect_established.png (100%) rename {images => src/images}/default/connect_no.png (100%) rename {images => src/images}/default/edit.png (100%) rename {images => src/images}/default/edit_add.png (100%) rename {images => src/images}/default/edit_remove.png (100%) rename {images => src/images}/default/edit_user.png (100%) rename {images => src/images}/default/editcopy.png (100%) rename {images => src/images}/default/edittrash.png (100%) rename {images => src/images}/default/exit.png (100%) rename {images => src/images}/default/fileclose.png (100%) rename {images => src/images}/default/filenew.png (100%) rename {images => src/images}/default/fileopen.png (100%) rename {images => src/images}/default/fileprint.png (100%) rename {images => src/images}/default/filesave.png (100%) rename {images => src/images}/default/filesaveas.png (100%) rename {images => src/images}/default/finish.png (100%) rename {images => src/images}/default/folder.png (100%) rename {images => src/images}/default/folder_new.png (100%) rename {images => src/images}/default/fonts.png (100%) rename {images => src/images}/default/fontsizedown.png (100%) rename {images => src/images}/default/fontsizeup.png (100%) rename {images => src/images}/default/forward.png (100%) rename {images => src/images}/default/help.png (100%) rename {images => src/images}/default/identity.png (100%) rename {images => src/images}/default/next.png (100%) rename {images => src/images}/default/no.png (100%) rename {images => src/images}/default/ok.png (100%) rename {images => src/images}/default/remove.png (100%) rename {images => src/images}/default/server.png (100%) rename {images => src/images}/default/start.png (100%) rename {images => src/images}/default/status_unknown.png (100%) rename {images => src/images}/default/stop.png (100%) rename {images => src/images}/default/tab.png (100%) rename {images => src/images}/default/tab_breakoff.png (100%) rename {images => src/images}/default/tab_duplicate.png (100%) rename {images => src/images}/default/tab_first.png (100%) rename {images => src/images}/default/tab_last.png (100%) rename {images => src/images}/default/tab_left.png (100%) rename {images => src/images}/default/tab_new.png (100%) rename {images => src/images}/default/tab_new_bg.png (100%) rename {images => src/images}/default/tab_new_raised.png (100%) rename {images => src/images}/default/tab_remove.png (100%) rename {images => src/images}/default/tab_right.png (100%) rename {images => src/images}/default/top.png (100%) rename {images => src/images}/default/trash.png (100%) rename {images => src/images}/default/tux.png (100%) rename {images => src/images}/default/up.png (100%) rename {images => src/images}/default/view_bottom.png (100%) rename {images => src/images}/default/view_choose.png (100%) rename {images => src/images}/default/view_detailed.png (100%) rename {images => src/images}/default/view_icon.png (100%) rename {images => src/images}/default/view_left_right.png (100%) rename {images => src/images}/default/view_multicolumn.png (100%) rename {images => src/images}/default/view_orientation.png (100%) rename {images => src/images}/default/view_remove 2.png (100%) rename {images => src/images}/default/view_remove.png (100%) rename {images => src/images}/default/view_right.png (100%) rename {images => src/images}/default/view_sidetree.png (100%) rename {images => src/images}/default/view_split.png (100%) rename {images => src/images}/default/view_top_bottom.png (100%) rename {images => src/images}/default/wizard.png (100%) rename {images => src/images}/iconmap.xml (100%) rename {images => src/images}/icons.qrc (100%) rename {images => src/images}/qirc-icon.png (100%) diff --git a/Quassel.kdevelop.filelist b/Quassel.kdevelop.filelist index 8fb3b40f..73fdb28c 100644 --- a/Quassel.kdevelop.filelist +++ b/Quassel.kdevelop.filelist @@ -1,86 +1,87 @@ # KDevelop Custom Project File List -core/core.cpp +client +client/buffer.cpp +client/buffer.h +client/client.cpp +client/client.h +client/clientproxy.cpp +client/clientproxy.h +CMakeLists.txt +common +common/CMakeLists.txt +common/global.cpp +common/global.h +common/logger.cpp +common/logger.h +common/main_core.cpp +common/main_gui.cpp +common/main_mono.cpp +common/message.cpp +common/message.h +common/proxy_common.h +common/settings.cpp +common/settings.h +common/util.cpp +common/util.h +core +core/backlog.cpp +core/backlog.h core/CMakeLists.txt +core/core.cpp core/core.h -gui/CMakeLists.txt -gui/mainwin.cpp -gui/mainwin.h -gui/serverlist.cpp -gui/serverlist.h -images/iconmap.xml -images/icons.qrc -main/main_core.cpp -main/main_mono.cpp -CMakeLists.txt -COPYING -Doxyfile -Makefile -gui/guiproxy.h -gui/guiproxy.cpp -main/main_gui.cpp core/coreproxy.cpp core/coreproxy.h -main/util.cpp -main/util.h -gui/coreconnectdlg.cpp -gui/coreconnectdlg.h -main/proxy_common.h -main/CMakeLists.txt -images/qirc-icon.png -main/global.cpp -main/global.h -gui/identities.cpp -gui/identities.h -gui/channelwidgetinput.h -gui/channelwidgetinput.cpp -plugins/plugin.h -gui/ui/channelwidget.ui -gui/ui/coreconnectdlg.ui -gui/ui/identitiesdlg.ui -gui/ui/identitieseditdlg.ui -gui/ui/ircwidget.ui -gui/ui/mainwin.ui -gui/ui/networkeditdlg.ui -gui/ui/nickeditdlg.ui -gui/ui/servereditdlg.ui -gui/ui/serverlistdlg.ui -gui/ui/settingsdlg.ui -gui/ui/bufferview.ui -gui/buffer.cpp -gui/buffer.h -main/message.cpp -main/message.h -gui/ui/bufferwidget.ui core/server.cpp core/server.h -gui/chatwidget.cpp -gui/chatwidget.h -gui/style.cpp -gui/style.h -main/logger.cpp -main/logger.h -templates/cpp -templates/h -gui/bufferwidget.h -gui/bufferwidget.cpp -main/settings.cpp -main/settings.h -gui/settingsdlg.h -gui/settingsdlg.cpp -gui/settingspages.cpp -gui/settingspages.h -gui/bufferview.cpp -gui/bufferview.h -core/backlog.cpp -core/backlog.h -ChangeLog -core/storage.cpp -core/storage.h core/sqlitestorage.cpp -dev-notes -dev-notes/builtin_cmds.obsolete.cpp -gui -gui/tabcompleter.cpp -gui/tabcompleter.h -core core/sqlitestorage.h +core/storage.cpp +core/storage.h +plugins +plugins/plugin.h +qtgui +qtgui/bufferview.cpp +qtgui/bufferview.h +qtgui/bufferviewwidget.cpp +qtgui/bufferviewwidget.h +qtgui/bufferwidget.cpp +qtgui/bufferwidget.h +qtgui/channelwidgetinput.cpp +qtgui/channelwidgetinput.h +qtgui/chatwidget.cpp +qtgui/chatwidget.h +qtgui/CMakeLists.txt +qtgui/coreconnectdlg.cpp +qtgui/coreconnectdlg.h +qtgui/identities.cpp +qtgui/identities.h +qtgui/mainwin.cpp +qtgui/mainwin.h +qtgui/serverlist.cpp +qtgui/serverlist.h +qtgui/settingsdlg.cpp +qtgui/settingsdlg.h +qtgui/settingspages.cpp +qtgui/settingspages.h +qtgui/style.cpp +qtgui/style.h +qtgui/tabcompleter.cpp +qtgui/tabcompleter.h +qtgui/ui +qtgui/ui/aboutdlg.ui +qtgui/ui/buffermgmntsettingspage.ui +qtgui/ui/bufferviewwidget.ui +qtgui/ui/bufferwidget.ui +qtgui/ui/channelwidget.ui +qtgui/ui/connectionsettingspage.ui +qtgui/ui/coreconnectdlg.ui +qtgui/ui/coresettingspage.ui +qtgui/ui/identitiesdlg.ui +qtgui/ui/identitieseditdlg.ui +qtgui/ui/ircwidget.ui +qtgui/ui/mainwin.ui +qtgui/ui/networkeditdlg.ui +qtgui/ui/nickeditdlg.ui +qtgui/ui/servereditdlg.ui +qtgui/ui/serverlistdlg.ui +qtgui/ui/settingsdlg.ui diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2a89fd5..31227039 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,19 +31,19 @@ ENDIF(BUILD_CORE OR BUILD_GUI) SET(CMAKE_BUILD_TYPE Debug) # Define files -SET(quassel_mono_SRCS main/main_mono.cpp) -SET(quassel_core_SRCS main/main_core.cpp) -SET(quassel_gui_SRCS main/main_gui.cpp ${common_SRCS}) +SET(quassel_mono_SRCS common/main_mono.cpp) +SET(quassel_core_SRCS common/main_core.cpp) +SET(quassel_gui_SRCS common/main_gui.cpp ${common_SRCS}) SET(quassel_RCCS images/icons.qrc) -SET(quassel_DIRS main gui core) +SET(quassel_DIRS common qtgui core) # Build correct absolute paths for subdirs to include SET(SDIRS "") FOREACH(dir ${quassel_DIRS}) SET(SDIRS ${SDIRS} "${CMAKE_CURRENT_SOURCE_DIR}/${dir}") ENDFOREACH(dir) -INCLUDE_DIRECTORIES(${SDIRS} plugins) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${SDIRS} client plugins) +#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # We need Qt4 support. SET(QT_MIN_VERSION "4.3.0") # 4.3 is required for SSL, crypto and some other stuff @@ -59,7 +59,7 @@ INCLUDE(${QT_USE_FILE}) # Define subdirs. CMake complains if a directory is added twice, so make sure this # does not happen in any combination of the requested targets. -ADD_SUBDIRECTORY(main) +ADD_SUBDIRECTORY(common) IF(BUILD_CORE) ADD_SUBDIRECTORY(core) ENDIF(BUILD_CORE) @@ -74,7 +74,7 @@ SET(TARGET_LIST ) IF(BUILD_CORE) ADD_DEFINITIONS(-DBUILD_CORE) ADD_EXECUTABLE(quasselcore ${quassel_core_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quasselcore core main ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quasselcore core common ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quasselcore) ENDIF(BUILD_CORE) @@ -84,19 +84,19 @@ IF(BUILD_GUI OR BUILD_MONO) # OK, now we need QtGui! SET(QT_INCLUDE_DIR "") SET(QT_LIBRARIES "") INCLUDE(${QT_USE_FILE}) - ADD_SUBDIRECTORY(gui) + ADD_SUBDIRECTORY(qtgui) IF(BUILD_MONO) ADD_DEFINITIONS(-DBUILD_MONO) ADD_EXECUTABLE(quassel ${quassel_mono_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quassel gui core main ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quassel qtgui core common ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quassel) ENDIF(BUILD_MONO) IF(BUILD_GUI) ADD_DEFINITIONS(-DBUILD_GUI) ADD_EXECUTABLE(quasselgui ${quassel_gui_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quasselgui gui main ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quasselgui qtgui common ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quasselgui) ENDIF(BUILD_GUI) diff --git a/src/client/client.cpp b/src/client/client.cpp index 1924001b..5211214c 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -18,11 +18,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "gui.h" -#include "guiproxy.h" +#include "client.h" +#include "clientproxy.h" #include "mainwin.h" #include "buffer.h" -//#include "bufferview.h" #include "bufferviewwidget.h" #include "util.h" diff --git a/src/client/client.h b/src/client/client.h index 2bf9c02f..3c6b56f9 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -28,12 +28,12 @@ #include "global.h" #include "buffer.h" #include "message.h" -#include "guiproxy.h" -#include "bufferviewwidget.h" +#include "clientproxy.h" +//#include "bufferviewwidget.h" class MainWin; class ClientProxy; -//class BufferTreeModel; +class BufferTreeModel; class Client : public QObject { Q_OBJECT diff --git a/src/client/clientproxy.cpp b/src/client/clientproxy.cpp index 5b6177fc..c991dba3 100644 --- a/src/client/clientproxy.cpp +++ b/src/client/clientproxy.cpp @@ -20,7 +20,7 @@ #include -#include "guiproxy.h" +#include "clientproxy.h" #include "util.h" #include "message.h" diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 32b82ba3..acfa640d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,6 +1,6 @@ -SET(main_SRCS global.cpp logger.cpp util.cpp message.cpp settings.cpp) -SET(main_HDRS util.h message.h settings.h) -SET(main_MOCS global.h logger.h) +SET(common_SRCS global.cpp logger.cpp util.cpp message.cpp settings.cpp) +SET(common_HDRS util.h message.h settings.h) +SET(common_MOCS global.h logger.h) -QT4_WRAP_CPP(_MOC ${main_MOCS}) -ADD_LIBRARY(main ${_MOC} ${main_SRCS} ${main_HDRS}) +QT4_WRAP_CPP(_MOC ${common_MOCS}) +ADD_LIBRARY(common ${_MOC} ${common_SRCS} ${common_HDRS}) diff --git a/src/common/main_mono.cpp b/src/common/main_mono.cpp index 419b1505..f0bafd9e 100644 --- a/src/common/main_mono.cpp +++ b/src/common/main_mono.cpp @@ -22,17 +22,15 @@ #include -#include "gui.h" +#include "client.h" #include "core.h" #include "style.h" #include "global.h" -#include "guiproxy.h" +#include "clientproxy.h" #include "coreproxy.h" #include "settings.h" #include "chatwidget.h" -#include "mainwin.h" - int main(int argc, char **argv) { QApplication app(argc, argv); QCoreApplication::setOrganizationDomain("quassel-irc.org"); diff --git a/images/default/1downarrow.png b/src/images/default/1downarrow.png similarity index 100% rename from images/default/1downarrow.png rename to src/images/default/1downarrow.png diff --git a/images/default/1leftarrow.png b/src/images/default/1leftarrow.png similarity index 100% rename from images/default/1leftarrow.png rename to src/images/default/1leftarrow.png diff --git a/images/default/1rightarrow.png b/src/images/default/1rightarrow.png similarity index 100% rename from images/default/1rightarrow.png rename to src/images/default/1rightarrow.png diff --git a/images/default/1uparrow.png b/src/images/default/1uparrow.png similarity index 100% rename from images/default/1uparrow.png rename to src/images/default/1uparrow.png diff --git a/images/default/2dowarrow.png b/src/images/default/2dowarrow.png similarity index 100% rename from images/default/2dowarrow.png rename to src/images/default/2dowarrow.png diff --git a/images/default/2downarrow.png b/src/images/default/2downarrow.png similarity index 100% rename from images/default/2downarrow.png rename to src/images/default/2downarrow.png diff --git a/images/default/2leftarrow.png b/src/images/default/2leftarrow.png similarity index 100% rename from images/default/2leftarrow.png rename to src/images/default/2leftarrow.png diff --git a/images/default/2rightarrow.png b/src/images/default/2rightarrow.png similarity index 100% rename from images/default/2rightarrow.png rename to src/images/default/2rightarrow.png diff --git a/images/default/2uparrow.png b/src/images/default/2uparrow.png similarity index 100% rename from images/default/2uparrow.png rename to src/images/default/2uparrow.png diff --git a/images/default/3downarrow.png b/src/images/default/3downarrow.png similarity index 100% rename from images/default/3downarrow.png rename to src/images/default/3downarrow.png diff --git a/images/default/3uparrow.png b/src/images/default/3uparrow.png similarity index 100% rename from images/default/3uparrow.png rename to src/images/default/3uparrow.png diff --git a/images/default/add_user.png b/src/images/default/add_user.png similarity index 100% rename from images/default/add_user.png rename to src/images/default/add_user.png diff --git a/images/default/apply.png b/src/images/default/apply.png similarity index 100% rename from images/default/apply.png rename to src/images/default/apply.png diff --git a/images/default/back.png b/src/images/default/back.png similarity index 100% rename from images/default/back.png rename to src/images/default/back.png diff --git a/images/default/bell.png b/src/images/default/bell.png similarity index 100% rename from images/default/bell.png rename to src/images/default/bell.png diff --git a/images/default/bookmark.png b/src/images/default/bookmark.png similarity index 100% rename from images/default/bookmark.png rename to src/images/default/bookmark.png diff --git a/images/default/bookmark_add.png b/src/images/default/bookmark_add.png similarity index 100% rename from images/default/bookmark_add.png rename to src/images/default/bookmark_add.png diff --git a/images/default/bookmark_folder.png b/src/images/default/bookmark_folder.png similarity index 100% rename from images/default/bookmark_folder.png rename to src/images/default/bookmark_folder.png diff --git a/images/default/bookmark_toolbar.png b/src/images/default/bookmark_toolbar.png similarity index 100% rename from images/default/bookmark_toolbar.png rename to src/images/default/bookmark_toolbar.png diff --git a/images/default/bookmarks_list_add.png b/src/images/default/bookmarks_list_add.png similarity index 100% rename from images/default/bookmarks_list_add.png rename to src/images/default/bookmarks_list_add.png diff --git a/images/default/bottom.png b/src/images/default/bottom.png similarity index 100% rename from images/default/bottom.png rename to src/images/default/bottom.png diff --git a/images/default/button_cancel.png b/src/images/default/button_cancel.png similarity index 100% rename from images/default/button_cancel.png rename to src/images/default/button_cancel.png diff --git a/images/default/button_ok.png b/src/images/default/button_ok.png similarity index 100% rename from images/default/button_ok.png rename to src/images/default/button_ok.png diff --git a/images/default/cancel.png b/src/images/default/cancel.png similarity index 100% rename from images/default/cancel.png rename to src/images/default/cancel.png diff --git a/images/default/configure.png b/src/images/default/configure.png similarity index 100% rename from images/default/configure.png rename to src/images/default/configure.png diff --git a/images/default/configure_shortcuts.png b/src/images/default/configure_shortcuts.png similarity index 100% rename from images/default/configure_shortcuts.png rename to src/images/default/configure_shortcuts.png diff --git a/images/default/configure_toolbars.png b/src/images/default/configure_toolbars.png similarity index 100% rename from images/default/configure_toolbars.png rename to src/images/default/configure_toolbars.png diff --git a/images/default/connect_creating.png b/src/images/default/connect_creating.png similarity index 100% rename from images/default/connect_creating.png rename to src/images/default/connect_creating.png diff --git a/images/default/connect_established.png b/src/images/default/connect_established.png similarity index 100% rename from images/default/connect_established.png rename to src/images/default/connect_established.png diff --git a/images/default/connect_no.png b/src/images/default/connect_no.png similarity index 100% rename from images/default/connect_no.png rename to src/images/default/connect_no.png diff --git a/images/default/edit.png b/src/images/default/edit.png similarity index 100% rename from images/default/edit.png rename to src/images/default/edit.png diff --git a/images/default/edit_add.png b/src/images/default/edit_add.png similarity index 100% rename from images/default/edit_add.png rename to src/images/default/edit_add.png diff --git a/images/default/edit_remove.png b/src/images/default/edit_remove.png similarity index 100% rename from images/default/edit_remove.png rename to src/images/default/edit_remove.png diff --git a/images/default/edit_user.png b/src/images/default/edit_user.png similarity index 100% rename from images/default/edit_user.png rename to src/images/default/edit_user.png diff --git a/images/default/editcopy.png b/src/images/default/editcopy.png similarity index 100% rename from images/default/editcopy.png rename to src/images/default/editcopy.png diff --git a/images/default/edittrash.png b/src/images/default/edittrash.png similarity index 100% rename from images/default/edittrash.png rename to src/images/default/edittrash.png diff --git a/images/default/exit.png b/src/images/default/exit.png similarity index 100% rename from images/default/exit.png rename to src/images/default/exit.png diff --git a/images/default/fileclose.png b/src/images/default/fileclose.png similarity index 100% rename from images/default/fileclose.png rename to src/images/default/fileclose.png diff --git a/images/default/filenew.png b/src/images/default/filenew.png similarity index 100% rename from images/default/filenew.png rename to src/images/default/filenew.png diff --git a/images/default/fileopen.png b/src/images/default/fileopen.png similarity index 100% rename from images/default/fileopen.png rename to src/images/default/fileopen.png diff --git a/images/default/fileprint.png b/src/images/default/fileprint.png similarity index 100% rename from images/default/fileprint.png rename to src/images/default/fileprint.png diff --git a/images/default/filesave.png b/src/images/default/filesave.png similarity index 100% rename from images/default/filesave.png rename to src/images/default/filesave.png diff --git a/images/default/filesaveas.png b/src/images/default/filesaveas.png similarity index 100% rename from images/default/filesaveas.png rename to src/images/default/filesaveas.png diff --git a/images/default/finish.png b/src/images/default/finish.png similarity index 100% rename from images/default/finish.png rename to src/images/default/finish.png diff --git a/images/default/folder.png b/src/images/default/folder.png similarity index 100% rename from images/default/folder.png rename to src/images/default/folder.png diff --git a/images/default/folder_new.png b/src/images/default/folder_new.png similarity index 100% rename from images/default/folder_new.png rename to src/images/default/folder_new.png diff --git a/images/default/fonts.png b/src/images/default/fonts.png similarity index 100% rename from images/default/fonts.png rename to src/images/default/fonts.png diff --git a/images/default/fontsizedown.png b/src/images/default/fontsizedown.png similarity index 100% rename from images/default/fontsizedown.png rename to src/images/default/fontsizedown.png diff --git a/images/default/fontsizeup.png b/src/images/default/fontsizeup.png similarity index 100% rename from images/default/fontsizeup.png rename to src/images/default/fontsizeup.png diff --git a/images/default/forward.png b/src/images/default/forward.png similarity index 100% rename from images/default/forward.png rename to src/images/default/forward.png diff --git a/images/default/help.png b/src/images/default/help.png similarity index 100% rename from images/default/help.png rename to src/images/default/help.png diff --git a/images/default/identity.png b/src/images/default/identity.png similarity index 100% rename from images/default/identity.png rename to src/images/default/identity.png diff --git a/images/default/next.png b/src/images/default/next.png similarity index 100% rename from images/default/next.png rename to src/images/default/next.png diff --git a/images/default/no.png b/src/images/default/no.png similarity index 100% rename from images/default/no.png rename to src/images/default/no.png diff --git a/images/default/ok.png b/src/images/default/ok.png similarity index 100% rename from images/default/ok.png rename to src/images/default/ok.png diff --git a/images/default/remove.png b/src/images/default/remove.png similarity index 100% rename from images/default/remove.png rename to src/images/default/remove.png diff --git a/images/default/server.png b/src/images/default/server.png similarity index 100% rename from images/default/server.png rename to src/images/default/server.png diff --git a/images/default/start.png b/src/images/default/start.png similarity index 100% rename from images/default/start.png rename to src/images/default/start.png diff --git a/images/default/status_unknown.png b/src/images/default/status_unknown.png similarity index 100% rename from images/default/status_unknown.png rename to src/images/default/status_unknown.png diff --git a/images/default/stop.png b/src/images/default/stop.png similarity index 100% rename from images/default/stop.png rename to src/images/default/stop.png diff --git a/images/default/tab.png b/src/images/default/tab.png similarity index 100% rename from images/default/tab.png rename to src/images/default/tab.png diff --git a/images/default/tab_breakoff.png b/src/images/default/tab_breakoff.png similarity index 100% rename from images/default/tab_breakoff.png rename to src/images/default/tab_breakoff.png diff --git a/images/default/tab_duplicate.png b/src/images/default/tab_duplicate.png similarity index 100% rename from images/default/tab_duplicate.png rename to src/images/default/tab_duplicate.png diff --git a/images/default/tab_first.png b/src/images/default/tab_first.png similarity index 100% rename from images/default/tab_first.png rename to src/images/default/tab_first.png diff --git a/images/default/tab_last.png b/src/images/default/tab_last.png similarity index 100% rename from images/default/tab_last.png rename to src/images/default/tab_last.png diff --git a/images/default/tab_left.png b/src/images/default/tab_left.png similarity index 100% rename from images/default/tab_left.png rename to src/images/default/tab_left.png diff --git a/images/default/tab_new.png b/src/images/default/tab_new.png similarity index 100% rename from images/default/tab_new.png rename to src/images/default/tab_new.png diff --git a/images/default/tab_new_bg.png b/src/images/default/tab_new_bg.png similarity index 100% rename from images/default/tab_new_bg.png rename to src/images/default/tab_new_bg.png diff --git a/images/default/tab_new_raised.png b/src/images/default/tab_new_raised.png similarity index 100% rename from images/default/tab_new_raised.png rename to src/images/default/tab_new_raised.png diff --git a/images/default/tab_remove.png b/src/images/default/tab_remove.png similarity index 100% rename from images/default/tab_remove.png rename to src/images/default/tab_remove.png diff --git a/images/default/tab_right.png b/src/images/default/tab_right.png similarity index 100% rename from images/default/tab_right.png rename to src/images/default/tab_right.png diff --git a/images/default/top.png b/src/images/default/top.png similarity index 100% rename from images/default/top.png rename to src/images/default/top.png diff --git a/images/default/trash.png b/src/images/default/trash.png similarity index 100% rename from images/default/trash.png rename to src/images/default/trash.png diff --git a/images/default/tux.png b/src/images/default/tux.png similarity index 100% rename from images/default/tux.png rename to src/images/default/tux.png diff --git a/images/default/up.png b/src/images/default/up.png similarity index 100% rename from images/default/up.png rename to src/images/default/up.png diff --git a/images/default/view_bottom.png b/src/images/default/view_bottom.png similarity index 100% rename from images/default/view_bottom.png rename to src/images/default/view_bottom.png diff --git a/images/default/view_choose.png b/src/images/default/view_choose.png similarity index 100% rename from images/default/view_choose.png rename to src/images/default/view_choose.png diff --git a/images/default/view_detailed.png b/src/images/default/view_detailed.png similarity index 100% rename from images/default/view_detailed.png rename to src/images/default/view_detailed.png diff --git a/images/default/view_icon.png b/src/images/default/view_icon.png similarity index 100% rename from images/default/view_icon.png rename to src/images/default/view_icon.png diff --git a/images/default/view_left_right.png b/src/images/default/view_left_right.png similarity index 100% rename from images/default/view_left_right.png rename to src/images/default/view_left_right.png diff --git a/images/default/view_multicolumn.png b/src/images/default/view_multicolumn.png similarity index 100% rename from images/default/view_multicolumn.png rename to src/images/default/view_multicolumn.png diff --git a/images/default/view_orientation.png b/src/images/default/view_orientation.png similarity index 100% rename from images/default/view_orientation.png rename to src/images/default/view_orientation.png diff --git a/images/default/view_remove 2.png b/src/images/default/view_remove 2.png similarity index 100% rename from images/default/view_remove 2.png rename to src/images/default/view_remove 2.png diff --git a/images/default/view_remove.png b/src/images/default/view_remove.png similarity index 100% rename from images/default/view_remove.png rename to src/images/default/view_remove.png diff --git a/images/default/view_right.png b/src/images/default/view_right.png similarity index 100% rename from images/default/view_right.png rename to src/images/default/view_right.png diff --git a/images/default/view_sidetree.png b/src/images/default/view_sidetree.png similarity index 100% rename from images/default/view_sidetree.png rename to src/images/default/view_sidetree.png diff --git a/images/default/view_split.png b/src/images/default/view_split.png similarity index 100% rename from images/default/view_split.png rename to src/images/default/view_split.png diff --git a/images/default/view_top_bottom.png b/src/images/default/view_top_bottom.png similarity index 100% rename from images/default/view_top_bottom.png rename to src/images/default/view_top_bottom.png diff --git a/images/default/wizard.png b/src/images/default/wizard.png similarity index 100% rename from images/default/wizard.png rename to src/images/default/wizard.png diff --git a/images/iconmap.xml b/src/images/iconmap.xml similarity index 100% rename from images/iconmap.xml rename to src/images/iconmap.xml diff --git a/images/icons.qrc b/src/images/icons.qrc similarity index 100% rename from images/icons.qrc rename to src/images/icons.qrc diff --git a/images/qirc-icon.png b/src/images/qirc-icon.png similarity index 100% rename from images/qirc-icon.png rename to src/images/qirc-icon.png diff --git a/src/qtgui/CMakeLists.txt b/src/qtgui/CMakeLists.txt index d651be0c..367efa45 100644 --- a/src/qtgui/CMakeLists.txt +++ b/src/qtgui/CMakeLists.txt @@ -1,24 +1,27 @@ -SET(gui_SRCS gui.cpp chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp buffer.cpp bufferwidget.cpp - identities.cpp coreconnectdlg.cpp guiproxy.cpp bufferview.cpp bufferviewwidget.cpp style.cpp settingsdlg.cpp settingspages.cpp) -SET(gui_HDRS style.h) -SET(gui_MOCS gui.h chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h - guiproxy.h bufferview.h buffer.h bufferwidget.h bufferviewwidget.h settingsdlg.h settingspages.h) -SET(gui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui +SET(qtgui_SRCS chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp bufferwidget.cpp + identities.cpp coreconnectdlg.cpp bufferview.cpp bufferviewwidget.cpp style.cpp settingsdlg.cpp settingspages.cpp) +SET(qtgui_HDRS style.h) +SET(qtgui_MOCS chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h + bufferview.h bufferwidget.h bufferviewwidget.h settingsdlg.h settingspages.h) +SET(qtgui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui bufferviewwidget.ui bufferwidget.ui settingsdlg.ui buffermgmntsettingspage.ui connectionsettingspage.ui) +SET(client_SRCS ../client/client.cpp ../client/clientproxy.cpp ../client/buffer.cpp) +SET(client_MOCS ../client/client.h ../client/clientproxy.h ../client/buffer.h) + # This prepends ui/ to the UIC names, so we don't have to do this ourselves. -FOREACH(ui ${gui_UICS}) - SET(gui_UICS_UI ${gui_UICS_UI} "ui/${ui}") +FOREACH(ui ${qtgui_UICS}) + SET(qtgui_UICS_UI ${qtgui_UICS_UI} "ui/${ui}") ENDFOREACH(ui) -QT4_WRAP_UI(_UIC ${gui_UICS_UI}) -QT4_WRAP_CPP(_MOC ${gui_MOCS}) +QT4_WRAP_UI(_UIC ${qtgui_UICS_UI}) +QT4_WRAP_CPP(_MOC ${qtgui_MOCS} ${client_MOCS}) # We need to work around a dependency bug with out-of-source builds... # Seems to be fixed! #SET_SOURCE_FILES_PROPERTIES(${gui_SRCS} PROPERTIES OBJECT_DEPENDS "${_UIC}") -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} client) -ADD_LIBRARY(gui ${gui_HDRS} ${gui_SRCS} ${_MOC} ${_UIC}) +ADD_LIBRARY(qtgui ${qtgui_HDRS} ${qtgui_SRCS} ${client_SRCS} ${_MOC} ${_UIC}) diff --git a/src/qtgui/bufferviewwidget.h b/src/qtgui/bufferviewwidget.h index 24523aed..81b6455a 100644 --- a/src/qtgui/bufferviewwidget.h +++ b/src/qtgui/bufferviewwidget.h @@ -24,9 +24,9 @@ #include #include -#include "guiproxy.h" +#include "clientproxy.h" #include "buffer.h" -#include "gui/ui_bufferviewwidget.h" +#include "ui_bufferviewwidget.h" #include "bufferview.h" /***************************************** diff --git a/src/qtgui/bufferwidget.h b/src/qtgui/bufferwidget.h index fb68a484..b6dd62b9 100644 --- a/src/qtgui/bufferwidget.h +++ b/src/qtgui/bufferwidget.h @@ -21,7 +21,7 @@ #ifndef _BUFFERWIDGET_H_ #define _BUFFERWIDGET_H_ -#include "gui/ui_bufferwidget.h" +#include "ui_bufferwidget.h" #include "global.h" #include "message.h" diff --git a/src/qtgui/coreconnectdlg.cpp b/src/qtgui/coreconnectdlg.cpp index c0ca4808..d51bb5d8 100644 --- a/src/qtgui/coreconnectdlg.cpp +++ b/src/qtgui/coreconnectdlg.cpp @@ -20,9 +20,9 @@ #include #include "coreconnectdlg.h" -#include "guiproxy.h" +#include "clientproxy.h" #include "global.h" -#include "gui.h" +#include "client.h" CoreConnectDlg::CoreConnectDlg(QWidget *parent) : QDialog(parent) { ui.setupUi(this); diff --git a/src/qtgui/coreconnectdlg.h b/src/qtgui/coreconnectdlg.h index b3a82f4c..53fc4256 100644 --- a/src/qtgui/coreconnectdlg.h +++ b/src/qtgui/coreconnectdlg.h @@ -21,8 +21,7 @@ #ifndef _CORECONNECTDLG_H #define _CORECONNECTDLG_H -#include "coreconnectdlg.h" -#include "gui/ui_coreconnectdlg.h" +#include "ui_coreconnectdlg.h" class CoreConnectDlg: public QDialog { Q_OBJECT diff --git a/src/qtgui/mainwin.cpp b/src/qtgui/mainwin.cpp index 35441a1b..ddb23cfe 100644 --- a/src/qtgui/mainwin.cpp +++ b/src/qtgui/mainwin.cpp @@ -22,11 +22,11 @@ #include #include -#include "gui.h" +#include "client.h" #include "util.h" #include "global.h" #include "message.h" -#include "guiproxy.h" +#include "clientproxy.h" #include "mainwin.h" #include "buffer.h" diff --git a/src/qtgui/mainwin.h b/src/qtgui/mainwin.h index 7876b50d..1b32cdd2 100644 --- a/src/qtgui/mainwin.h +++ b/src/qtgui/mainwin.h @@ -22,7 +22,7 @@ #define _MAINWIN_H_ #include -#include "gui/ui_mainwin.h" +#include "ui_mainwin.h" #include "global.h" #include "message.h" diff --git a/src/qtgui/serverlist.cpp b/src/qtgui/serverlist.cpp index ab12919d..e221c736 100644 --- a/src/qtgui/serverlist.cpp +++ b/src/qtgui/serverlist.cpp @@ -20,7 +20,7 @@ #include "serverlist.h" #include "identities.h" -#include "guiproxy.h" +#include "clientproxy.h" /* NOTE: This dialog holds not only the server list, but also the identities. * This makes perfect sense given the fact that connections are initiated from -- 2.20.1 From e7e564dcf469faa4c47383368a58cedbe3a204e6 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Wed, 20 Jun 2007 13:49:30 +0000 Subject: [PATCH 14/16] still continuing separation of gui and data and file reorganisation: bufferviewwidget got split into: - treemodel (a basic tree model for easy inheritance) - buffertreemodel (fancy version of treemodel) - bufferviewwidget (not much more left here then pure gui stuff) bufferview got split into: - bufferviewfilter - bufferview --- src/client/client.cpp | 2 - src/client/client.h | 2 +- src/qtgui/CMakeLists.txt | 8 +- src/qtgui/bufferview.cpp | 54 +---- src/qtgui/bufferview.h | 44 +--- src/qtgui/bufferviewwidget.cpp | 369 --------------------------------- src/qtgui/bufferviewwidget.h | 117 +---------- src/qtgui/mainwin.cpp | 1 - src/qtgui/mainwin.h | 4 +- 9 files changed, 16 insertions(+), 585 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 5211214c..a04361cc 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -22,7 +22,6 @@ #include "clientproxy.h" #include "mainwin.h" #include "buffer.h" -#include "bufferviewwidget.h" #include "util.h" Client * Client::instanceptr = 0; @@ -52,7 +51,6 @@ Client::Client() { clientProxy = ClientProxy::instance(); //mainWin = new MainWin(); - _bufferModel = new BufferTreeModel(0); // FIXME connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); diff --git a/src/client/client.h b/src/client/client.h index 3c6b56f9..82e3e844 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -29,11 +29,11 @@ #include "buffer.h" #include "message.h" #include "clientproxy.h" +#include "buffertreemodel.h" //#include "bufferviewwidget.h" class MainWin; class ClientProxy; -class BufferTreeModel; class Client : public QObject { Q_OBJECT diff --git a/src/qtgui/CMakeLists.txt b/src/qtgui/CMakeLists.txt index 367efa45..99c9de7c 100644 --- a/src/qtgui/CMakeLists.txt +++ b/src/qtgui/CMakeLists.txt @@ -1,15 +1,15 @@ SET(qtgui_SRCS chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp bufferwidget.cpp - identities.cpp coreconnectdlg.cpp bufferview.cpp bufferviewwidget.cpp style.cpp settingsdlg.cpp settingspages.cpp) + identities.cpp coreconnectdlg.cpp bufferview.cpp bufferviewwidget.cpp bufferviewfilter.cpp style.cpp settingsdlg.cpp settingspages.cpp) SET(qtgui_HDRS style.h) SET(qtgui_MOCS chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h - bufferview.h bufferwidget.h bufferviewwidget.h settingsdlg.h settingspages.h) + bufferview.h bufferwidget.h bufferviewwidget.h bufferviewfilter.h settingsdlg.h settingspages.h) SET(qtgui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui bufferviewwidget.ui bufferwidget.ui settingsdlg.ui buffermgmntsettingspage.ui connectionsettingspage.ui) -SET(client_SRCS ../client/client.cpp ../client/clientproxy.cpp ../client/buffer.cpp) -SET(client_MOCS ../client/client.h ../client/clientproxy.h ../client/buffer.h) +SET(client_SRCS ../client/client.cpp ../client/clientproxy.cpp ../client/buffer.cpp ../client/treemodel.cpp ../client/buffertreemodel.cpp) +SET(client_MOCS ../client/client.h ../client/clientproxy.h ../client/buffer.h ../client/treemodel.h ../client/buffertreemodel.h) # This prepends ui/ to the UIC names, so we don't have to do this ourselves. FOREACH(ui ${qtgui_UICS}) diff --git a/src/qtgui/bufferview.cpp b/src/qtgui/bufferview.cpp index d30e4da1..f8054189 100644 --- a/src/qtgui/bufferview.cpp +++ b/src/qtgui/bufferview.cpp @@ -19,58 +19,6 @@ ***************************************************************************/ #include "bufferview.h" -#include "bufferviewwidget.h" - -/***************************************** -* The TreeView showing the Buffers -*****************************************/ -BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, Modes filtermode, QStringList nets, QObject *parent) : QSortFilterProxyModel(parent) { - setSourceModel(model); - mode = filtermode; - networks = nets; - - connect(model, SIGNAL(invalidateFilter()), this, SLOT(invalidateMe())); - connect(model, SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), this, SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); - - connect(this, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), model, SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); - connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model, SLOT(doubleClickReceived(const QModelIndex &))); -} - -void BufferViewFilter::invalidateMe() { - invalidateFilter(); -} - -void BufferViewFilter::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { - emit updateSelection(mapFromSource(index), command); -} - -void BufferViewFilter::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { - emit currentChanged(mapToSource(current), mapToSource(previous)); -} - -void BufferViewFilter::doubleClickReceived(const QModelIndex &clicked) { - emit doubleClicked(mapToSource(clicked)); -} - -bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { - QModelIndex child = source_parent.child(source_row, 0); - if(!child.isValid()) - return true; // can't imagine this case but true sounds good :) - - Buffer::Type bufferType = (Buffer::Type) child.data(BufferTreeModel::BufferTypeRole).toInt(); - if((mode & NoChannels) && bufferType == Buffer::ChannelBuffer) return false; - if((mode & NoQueries) && bufferType == Buffer::QueryBuffer) return false; - if((mode & NoServers) && bufferType == Buffer::ServerBuffer) return false; - - bool isActive = child.data(BufferTreeModel::BufferActiveRole).toBool(); - if((mode & NoActive) && isActive) return false; - if((mode & NoInactive) && !isActive) return false; - - QString net = child.data(Qt::DisplayRole).toString(); - if((mode & SomeNets) && !networks.contains(net)) return false; - - return true; -} /***************************************** * The TreeView showing the Buffers @@ -84,6 +32,7 @@ void BufferView::init() { setIndentation(10); header()->hide(); header()->hideSection(1); + expandAll(); setDragEnabled(true); setAcceptDrops(true); @@ -93,7 +42,6 @@ void BufferView::init() { connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model(), SLOT(doubleClickReceived(const QModelIndex &))); connect(model(), SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), selectionModel(), SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); - expandAll(); } void BufferView::setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets) { diff --git a/src/qtgui/bufferview.h b/src/qtgui/bufferview.h index 6fcadf86..561cae72 100644 --- a/src/qtgui/bufferview.h +++ b/src/qtgui/bufferview.h @@ -18,51 +18,13 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _BUFFERVIEWWIDGET_H_ -#define _BUFFERVIEWWIDGET_H_ +#ifndef _BUFFERVIEW_H_ +#define _BUFFERVIEW_H_ #include #include -#include "buffer.h" -/***************************************** - * Buffer View Filter - *****************************************/ -class BufferViewFilter : public QSortFilterProxyModel { - Q_OBJECT - -public: - enum Mode { - NoActive = 0x01, - NoInactive = 0x02, - SomeNets = 0x04, - AllNets = 0x08, - NoChannels = 0x10, - NoQueries = 0x20, - NoServers = 0x40 - }; - Q_DECLARE_FLAGS(Modes, Mode) - - BufferViewFilter(QAbstractItemModel *model, Modes mode, QStringList nets, QObject *parent = 0); - -public slots: - void invalidateMe(); - void changeCurrent(const QModelIndex &, const QModelIndex &); - void doubleClickReceived(const QModelIndex &); - void select(const QModelIndex &, QItemSelectionModel::SelectionFlags); - -signals: - void currentChanged(const QModelIndex &, const QModelIndex &); - void doubleClicked(const QModelIndex &); - void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); - -private: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - - Modes mode; - QStringList networks; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(BufferViewFilter::Modes) +#include "bufferviewfilter.h" /***************************************** * The TreeView showing the Buffers diff --git a/src/qtgui/bufferviewwidget.cpp b/src/qtgui/bufferviewwidget.cpp index a78754e7..10b921e4 100644 --- a/src/qtgui/bufferviewwidget.cpp +++ b/src/qtgui/bufferviewwidget.cpp @@ -18,377 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include "global.h" #include "bufferviewwidget.h" -/***************************************** - * Buffer Items stored in the Tree Model - *****************************************/ -TreeItem::TreeItem(QList &data, TreeItem *parent) { - itemData = data; - parentItem = parent; - foreground = Qt::black; -} - -TreeItem::TreeItem(TreeItem *parent) { - itemData = QList(); - parentItem = parent; - foreground = Qt::black; -} - -TreeItem::~TreeItem() { - qDeleteAll(childItems); -} - -void TreeItem::appendChild(TreeItem *item) { - childItems.append(item); -} - -void TreeItem::removeChild(int row) { - childItems.removeAt(row); -} - -TreeItem *TreeItem::child(int row) { - return childItems.value(row); -} - -int TreeItem::childCount() const { - return childItems.count(); -} - -int TreeItem::row() const { - if(parentItem) - return parentItem->childItems.indexOf(const_cast(this)); - else - return 0; -} - -TreeItem *TreeItem::parent() { - return parentItem; -} - -int TreeItem::columnCount() const { - return itemData.count(); -} - -void TreeItem::setForeground(QColor newcolor) { - foreground = newcolor; -} - -QVariant TreeItem::data(int column, int role) const { - switch(role) { - case Qt::DisplayRole: - if(column < itemData.count()) - return itemData[column]; - else - return QVariant(); - - case Qt::ForegroundRole: - return foreground; - - default: - return QVariant(); - - } -} - -/***************************************** -* Fancy Buffer Items -*****************************************/ -BufferTreeItem::BufferTreeItem(Buffer *buffer, TreeItem *parent) : TreeItem(parent) { - buf = buffer; - activity = Buffer::NoActivity; -} - -void BufferTreeItem::setActivity(const Buffer::ActivityLevel &level) { - activity = level; -} - -QString BufferTreeItem::text(int column) const { - switch(column) { - case 0: - return buf->displayName(); - case 1: - return buf->networkName(); - default: - return QString(); - } -} - -QColor BufferTreeItem::foreground(int column) const { - // for the time beeing we ignore the column :) - if(activity & Buffer::Highlight) { - return QColor(Qt::red); - } else if(activity & Buffer::NewMessage) { - return QColor(Qt::darkYellow); - } else if(activity & Buffer::OtherActivity) { - return QColor(Qt::darkGreen); - } else { - if(buf->isActive()) - return QColor(Qt::black); - else - return QColor(Qt::gray); - } -} - - -QVariant BufferTreeItem::data(int column, int role) const { - switch(role) { - case Qt::DisplayRole: - return text(column); - case Qt::ForegroundRole: - return foreground(column); - case BufferTreeModel::BufferTypeRole: - return buf->bufferType(); - case BufferTreeModel::BufferActiveRole: - return buf->isActive(); - default: - return QVariant(); - } -} - -/***************************************** - * BufferTreeModel - *****************************************/ -BufferTreeModel::BufferTreeModel(QObject *parent) : QAbstractItemModel(parent) { - QList rootData; - rootData << "Buffer" << "Network"; - rootItem = new TreeItem(rootData, 0); - - connect(this, SIGNAL(fakeUserInput(BufferId, QString)), ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); -} - -BufferTreeModel::~BufferTreeModel() { - delete rootItem; -} - -QModelIndex BufferTreeModel::index(int row, int column, const QModelIndex &parent) const { - if(!hasIndex(row, column, parent)) - return QModelIndex(); - - TreeItem *parentItem; - - if(!parent.isValid()) - parentItem = rootItem; - else - parentItem = static_cast(parent.internalPointer()); - - TreeItem *childItem = parentItem->child(row); - if(childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); -} - -QModelIndex BufferTreeModel::parent(const QModelIndex &index) const { - if(!index.isValid()) - return QModelIndex(); - - TreeItem *childItem = static_cast(index.internalPointer()); - TreeItem *parentItem = childItem->parent(); - - if(parentItem == rootItem) - return QModelIndex(); - - return createIndex(parentItem->row(), 0, parentItem); -} - -int BufferTreeModel::rowCount(const QModelIndex &parent) const { - TreeItem *parentItem; - if(parent.column() > 0) - return 0; - - if(!parent.isValid()) - parentItem = rootItem; - else - parentItem = static_cast(parent.internalPointer()); - - return parentItem->childCount(); -} - -int BufferTreeModel::columnCount(const QModelIndex &parent) const { - if(parent.isValid()) - return static_cast(parent.internalPointer())->columnCount(); - else - return rootItem->columnCount(); -} - -QVariant BufferTreeModel::data(const QModelIndex &index, int role) const { - if(!index.isValid()) - return QVariant(); - - TreeItem *item = static_cast(index.internalPointer()); - return item->data(index.column(), role); -} - -Qt::ItemFlags BufferTreeModel::flags(const QModelIndex &index) const { - if(!index.isValid()) - return 0; - - // I think this is pretty ugly.. - if(isBufferIndex(index)) { - Buffer *buffer = getBufferByIndex(index); - if(buffer->bufferType() == Buffer::QueryBuffer) - return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - else - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } else { - return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; - } -} - -QVariant BufferTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - return rootItem->data(section, role); - else - return QVariant(); -} - -bool BufferTreeModel::removeRow(int row, const QModelIndex &parent) { - beginRemoveRows(parent, row, row); - TreeItem *item = static_cast(parent.internalPointer()); - item->removeChild(row); - endRemoveRows(); - return true; -} - -bool BufferTreeModel::isBufferIndex(const QModelIndex &index) const { - return parent(index) != QModelIndex(); -} - -Buffer *BufferTreeModel::getBufferByIndex(const QModelIndex &index) const { - BufferTreeItem *item = static_cast(index.internalPointer()); - return item->buffer(); -} - -QModelIndex BufferTreeModel::getOrCreateNetworkItemIndex(Buffer *buffer) { - QString net = buffer->networkName(); - - if(networkItem.contains(net)) { - return index(networkItem[net]->row(), 0); - } else { - QList data; - data << net << ""; - - int nextRow = rootItem->childCount(); - - beginInsertRows(QModelIndex(), nextRow, nextRow); - rootItem->appendChild(new TreeItem(data, rootItem)); - endInsertRows(); - - networkItem[net] = rootItem->child(nextRow); - return index(nextRow, 0); - } -} - -QModelIndex BufferTreeModel::getOrCreateBufferItemIndex(Buffer *buffer) { - QModelIndex networkItemIndex = getOrCreateNetworkItemIndex(buffer); - - if(bufferItem.contains(buffer)) { - return index(bufferItem[buffer]->row(), 0, networkItemIndex); - } else { - // first we determine the parent of the new Item - TreeItem *networkItem = static_cast(networkItemIndex.internalPointer()); - - int nextRow = networkItem->childCount(); - - beginInsertRows(networkItemIndex, nextRow, nextRow); - networkItem->appendChild(new BufferTreeItem(buffer, networkItem)); - endInsertRows(); - - bufferItem[buffer] = static_cast(networkItem->child(nextRow)); - return index(nextRow, 0, networkItemIndex); - } -} - -QStringList BufferTreeModel::mimeTypes() const { - QStringList types; - types << "application/Quassel/BufferItem/row" - << "application/Quassel/BufferItem/network"; - return types; -} - -QMimeData *BufferTreeModel::mimeData(const QModelIndexList &indexes) const { - QMimeData *mimeData = new QMimeData(); - - QModelIndex index = indexes.first(); - - mimeData->setData("application/Quassel/BufferItem/row", QByteArray::number(index.row())); - mimeData->setData("application/Quassel/BufferItem/network", getBufferByIndex(index)->networkName().toUtf8()); - return mimeData; -} - -bool BufferTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { - int sourcerow = data->data("application/Quassel/BufferItem/row").toInt(); - QString network = QString::fromUtf8(data->data("application/Quassel/BufferItem/network")); - - if(!networkItem.contains(network)) - return false; - - if(!isBufferIndex(parent)) // dropping at a network -> no merging needed - return false; - - Buffer *sourceBuffer = static_cast(networkItem[network]->child(sourcerow))->buffer(); - Buffer *targetBuffer = getBufferByIndex(parent); - - if(sourceBuffer == targetBuffer) // we won't merge with ourself :) - return false; - - /* - if(QMessageBox::warning(static_cast(QObject::parent()), - tr("Merge Buffers?"), - tr("Do you really want to merge the following Buffers?
%1.%2
%3.%4").arg(sourceBuffer->networkName()).arg(sourceBuffer->bufferName()).arg(targetBuffer->networkName()).arg(targetBuffer->bufferName()), - QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) - return false; - - */ - qDebug() << "merging" << sourceBuffer->bufferName() << "with" << targetBuffer->bufferName(); - bufferItem.remove(getBufferByIndex(parent)); - removeRow(parent.row(), BufferTreeModel::parent(parent)); - - return true; -} - -void BufferTreeModel::bufferUpdated(Buffer *buffer) { - QModelIndex itemindex = getOrCreateBufferItemIndex(buffer); - emit invalidateFilter(); - emit dataChanged(itemindex, itemindex); -} - -// This Slot indicates that the user has selected a different buffer in the gui -void BufferTreeModel::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { - if(isBufferIndex(current)) { - currentBuffer = getBufferByIndex(current); - bufferActivity(Buffer::NoActivity, currentBuffer); - emit bufferSelected(currentBuffer); - emit updateSelection(current, QItemSelectionModel::ClearAndSelect); - } -} - -// we received a double click on a buffer, so we're going to join it -void BufferTreeModel::doubleClickReceived(const QModelIndex &clicked) { - if(isBufferIndex(clicked)) { - Buffer *buffer = getBufferByIndex(clicked); - if(!buffer->isStatusBuffer()) - emit fakeUserInput(buffer->bufferId(), QString("/join " + buffer->bufferName())); - } - -} - -void BufferTreeModel::bufferActivity(Buffer::ActivityLevel level, Buffer *buffer) { - if(bufferItem.contains(buffer) and buffer != currentBuffer) - bufferItem[buffer]->setActivity(level); - else - bufferItem[buffer]->setActivity(Buffer::NoActivity); - bufferUpdated(buffer); -} - -void BufferTreeModel::selectBuffer(Buffer *buffer) { - QModelIndex index = getOrCreateBufferItemIndex(buffer); - emit updateSelection(index, QItemSelectionModel::ClearAndSelect); -} - - /***************************************** * This Widget Contains the BufferView *****************************************/ diff --git a/src/qtgui/bufferviewwidget.h b/src/qtgui/bufferviewwidget.h index 81b6455a..e6e21164 100644 --- a/src/qtgui/bufferviewwidget.h +++ b/src/qtgui/bufferviewwidget.h @@ -18,123 +18,15 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _BUFFERVIEW_H_ -#define _BUFFERVIEW_H_ +#ifndef _BUFFERVIEWWIDGET_H_ +#define _BUFFERVIEWWIDGET_H_ #include #include -#include "clientproxy.h" -#include "buffer.h" -#include "ui_bufferviewwidget.h" +#include "bufferviewfilter.h" #include "bufferview.h" - -/***************************************** - * general item used in the Tree Model - *****************************************/ -class TreeItem { -public: - TreeItem(QList &data, TreeItem *parent = 0); - TreeItem(TreeItem *parent = 0); - virtual ~TreeItem(); - - void appendChild(TreeItem *child); - void removeChild(int row); - - TreeItem *child(int row); - int childCount() const; - int columnCount() const; - virtual QVariant data(int column, int role) const; - int row() const; - TreeItem *parent(); - - void setForeground(QColor); - -private: - QList childItems; - TreeItem *parentItem; - QList itemData; - - QColor foreground; -}; - - -/***************************************** - * Fancy Buffer Items - *****************************************/ -class BufferTreeItem : public TreeItem{ -public: - BufferTreeItem(Buffer *, TreeItem *parent = 0); - QVariant data(int column, int role) const; - Buffer *buffer() const { return buf; } - void setActivity(const Buffer::ActivityLevel &); - -private: - QString text(int column) const; - QColor foreground(int column) const; - Buffer *buf; - Buffer::ActivityLevel activity; -}; - - -/***************************************** - * BufferTreeModel - *****************************************/ -class BufferTreeModel : public QAbstractItemModel { - Q_OBJECT - -public: - enum myRoles { - BufferTypeRole = Qt::UserRole, - BufferActiveRole - }; - - - BufferTreeModel(QObject *parent = 0); - ~BufferTreeModel(); - - QVariant data(const QModelIndex &index, int role) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - - void clearActivity(Buffer *buffer); - -public slots: - void bufferUpdated(Buffer *); - void changeCurrent(const QModelIndex &, const QModelIndex &); - void selectBuffer(Buffer *buffer); - void doubleClickReceived(const QModelIndex &); - void bufferActivity(Buffer::ActivityLevel, Buffer *buffer); - -signals: - void bufferSelected(Buffer *); - void invalidateFilter(); - void fakeUserInput(BufferId, QString); - void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); - -private: - bool isBufferIndex(const QModelIndex &) const; - Buffer *getBufferByIndex(const QModelIndex &) const; - QModelIndex getOrCreateNetworkItemIndex(Buffer *buffer); - QModelIndex getOrCreateBufferItemIndex(Buffer *buffer); - - bool removeRow(int row, const QModelIndex &parent = QModelIndex()); - - QStringList mimeTypes() const; - QMimeData *mimeData(const QModelIndexList &) const; - bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &); - TreeItem *rootItem; - - QHash networkItem; - QHash bufferItem; - Buffer *currentBuffer; -}; - - +#include "ui_bufferviewwidget.h" /***************************************** @@ -150,7 +42,6 @@ public: private: Ui::BufferViewWidget ui; - }; diff --git a/src/qtgui/mainwin.cpp b/src/qtgui/mainwin.cpp index ddb23cfe..05cd7d3d 100644 --- a/src/qtgui/mainwin.cpp +++ b/src/qtgui/mainwin.cpp @@ -30,7 +30,6 @@ #include "mainwin.h" #include "buffer.h" -#include "bufferviewwidget.h" #include "serverlist.h" #include "coreconnectdlg.h" #include "settingsdlg.h" diff --git a/src/qtgui/mainwin.h b/src/qtgui/mainwin.h index 1b32cdd2..d8936583 100644 --- a/src/qtgui/mainwin.h +++ b/src/qtgui/mainwin.h @@ -27,10 +27,12 @@ #include "global.h" #include "message.h" #include "chatwidget.h" +#include "bufferviewfilter.h" +#include "bufferviewwidget.h" class ServerListDlg; class CoreConnectDlg; -class BufferViewDock; +//class BufferViewDock; class Buffer; class BufferWidget; class SettingsDlg; -- 2.20.1 From 13b2affbdccd1d52479e49affdb81a77258392a6 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Wed, 20 Jun 2007 13:50:33 +0000 Subject: [PATCH 15/16] forgot to add 6 files... -.- --- src/client/buffertreemodel.cpp | 243 +++++++++++++++++++++++++++++++++ src/client/buffertreemodel.h | 99 ++++++++++++++ src/client/treemodel.cpp | 171 +++++++++++++++++++++++ src/client/treemodel.h | 78 +++++++++++ src/qtgui/bufferviewfilter.cpp | 72 ++++++++++ src/qtgui/bufferviewfilter.h | 68 +++++++++ 6 files changed, 731 insertions(+) create mode 100644 src/client/buffertreemodel.cpp create mode 100644 src/client/buffertreemodel.h create mode 100644 src/client/treemodel.cpp create mode 100644 src/client/treemodel.h create mode 100644 src/qtgui/bufferviewfilter.cpp create mode 100644 src/qtgui/bufferviewfilter.h diff --git a/src/client/buffertreemodel.cpp b/src/client/buffertreemodel.cpp new file mode 100644 index 00000000..7030547e --- /dev/null +++ b/src/client/buffertreemodel.cpp @@ -0,0 +1,243 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "global.h" +#include "buffertreemodel.h" + +/***************************************** +* Fancy Buffer Items +*****************************************/ +BufferTreeItem::BufferTreeItem(Buffer *buffer, TreeItem *parent) : TreeItem(parent) { + buf = buffer; + activity = Buffer::NoActivity; +} + +void BufferTreeItem::setActivity(const Buffer::ActivityLevel &level) { + activity = level; +} + +QString BufferTreeItem::text(int column) const { + switch(column) { + case 0: + return buf->displayName(); + case 1: + return buf->networkName(); + default: + return QString(); + } +} + +QColor BufferTreeItem::foreground(int column) const { + // for the time beeing we ignore the column :) + if(activity & Buffer::Highlight) { + return QColor(Qt::red); + } else if(activity & Buffer::NewMessage) { + return QColor(Qt::darkYellow); + } else if(activity & Buffer::OtherActivity) { + return QColor(Qt::darkGreen); + } else { + if(buf->isActive()) + return QColor(Qt::black); + else + return QColor(Qt::gray); + } +} + + +QVariant BufferTreeItem::data(int column, int role) const { + switch(role) { + case Qt::DisplayRole: + return text(column); + case Qt::ForegroundRole: + return foreground(column); + case BufferTreeModel::BufferTypeRole: + return buf->bufferType(); + case BufferTreeModel::BufferActiveRole: + return buf->isActive(); + default: + return QVariant(); + } +} + +/***************************************** + * BufferTreeModel + *****************************************/ +BufferTreeModel::BufferTreeModel(QObject *parent) : TreeModel(BufferTreeModel::defaultHeader(), parent) { + connect(this, SIGNAL(fakeUserInput(BufferId, QString)), ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); +} + +QListBufferTreeModel::defaultHeader() { + QList data; + data << tr("Buffer") << tr("Network"); + return data; +} + + +Qt::ItemFlags BufferTreeModel::flags(const QModelIndex &index) const { + if(!index.isValid()) + return 0; + + // I think this is pretty ugly.. + if(isBufferIndex(index)) { + Buffer *buffer = getBufferByIndex(index); + if(buffer->bufferType() == Buffer::QueryBuffer) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + else + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; + } +} + +bool BufferTreeModel::isBufferIndex(const QModelIndex &index) const { + return parent(index) != QModelIndex(); +} + +Buffer *BufferTreeModel::getBufferByIndex(const QModelIndex &index) const { + BufferTreeItem *item = static_cast(index.internalPointer()); + return item->buffer(); +} + +QModelIndex BufferTreeModel::getOrCreateNetworkItemIndex(Buffer *buffer) { + QString net = buffer->networkName(); + + if(networkItem.contains(net)) { + return index(networkItem[net]->row(), 0); + } else { + QList data; + data << net << ""; + + int nextRow = rootItem->childCount(); + + beginInsertRows(QModelIndex(), nextRow, nextRow); + rootItem->appendChild(new TreeItem(data, rootItem)); + endInsertRows(); + + networkItem[net] = rootItem->child(nextRow); + return index(nextRow, 0); + } +} + +QModelIndex BufferTreeModel::getOrCreateBufferItemIndex(Buffer *buffer) { + QModelIndex networkItemIndex = getOrCreateNetworkItemIndex(buffer); + + if(bufferItem.contains(buffer)) { + return index(bufferItem[buffer]->row(), 0, networkItemIndex); + } else { + // first we determine the parent of the new Item + TreeItem *networkItem = static_cast(networkItemIndex.internalPointer()); + + int nextRow = networkItem->childCount(); + + beginInsertRows(networkItemIndex, nextRow, nextRow); + networkItem->appendChild(new BufferTreeItem(buffer, networkItem)); + endInsertRows(); + + bufferItem[buffer] = static_cast(networkItem->child(nextRow)); + return index(nextRow, 0, networkItemIndex); + } +} + +QStringList BufferTreeModel::mimeTypes() const { + QStringList types; + types << "application/Quassel/BufferItem/row" + << "application/Quassel/BufferItem/network"; + return types; +} + +QMimeData *BufferTreeModel::mimeData(const QModelIndexList &indexes) const { + QMimeData *mimeData = new QMimeData(); + + QModelIndex index = indexes.first(); + + mimeData->setData("application/Quassel/BufferItem/row", QByteArray::number(index.row())); + mimeData->setData("application/Quassel/BufferItem/network", getBufferByIndex(index)->networkName().toUtf8()); + return mimeData; +} + +bool BufferTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { + int sourcerow = data->data("application/Quassel/BufferItem/row").toInt(); + QString network = QString::fromUtf8(data->data("application/Quassel/BufferItem/network")); + + if(!networkItem.contains(network)) + return false; + + if(!isBufferIndex(parent)) // dropping at a network -> no merging needed + return false; + + Buffer *sourceBuffer = static_cast(networkItem[network]->child(sourcerow))->buffer(); + Buffer *targetBuffer = getBufferByIndex(parent); + + if(sourceBuffer == targetBuffer) // we won't merge with ourself :) + return false; + + /* + if(QMessageBox::warning(static_cast(QObject::parent()), + tr("Merge Buffers?"), + tr("Do you really want to merge the following Buffers?
%1.%2
%3.%4").arg(sourceBuffer->networkName()).arg(sourceBuffer->bufferName()).arg(targetBuffer->networkName()).arg(targetBuffer->bufferName()), + QMessageBox::Yes|QMessageBox::No) == QMessageBox::No) + return false; + + */ + qDebug() << "merging" << sourceBuffer->bufferName() << "with" << targetBuffer->bufferName(); + bufferItem.remove(getBufferByIndex(parent)); + removeRow(parent.row(), BufferTreeModel::parent(parent)); + + return true; +} + +void BufferTreeModel::bufferUpdated(Buffer *buffer) { + QModelIndex itemindex = getOrCreateBufferItemIndex(buffer); + emit invalidateFilter(); + emit dataChanged(itemindex, itemindex); +} + +// This Slot indicates that the user has selected a different buffer in the gui +void BufferTreeModel::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { + if(isBufferIndex(current)) { + currentBuffer = getBufferByIndex(current); + bufferActivity(Buffer::NoActivity, currentBuffer); + emit bufferSelected(currentBuffer); + emit updateSelection(current, QItemSelectionModel::ClearAndSelect); + } +} + +// we received a double click on a buffer, so we're going to join it +void BufferTreeModel::doubleClickReceived(const QModelIndex &clicked) { + if(isBufferIndex(clicked)) { + Buffer *buffer = getBufferByIndex(clicked); + if(!buffer->isStatusBuffer()) + emit fakeUserInput(buffer->bufferId(), QString("/join " + buffer->bufferName())); + } + +} + +void BufferTreeModel::bufferActivity(Buffer::ActivityLevel level, Buffer *buffer) { + if(bufferItem.contains(buffer) and buffer != currentBuffer) + bufferItem[buffer]->setActivity(level); + else + bufferItem[buffer]->setActivity(Buffer::NoActivity); + bufferUpdated(buffer); +} + +void BufferTreeModel::selectBuffer(Buffer *buffer) { + QModelIndex index = getOrCreateBufferItemIndex(buffer); + emit updateSelection(index, QItemSelectionModel::ClearAndSelect); +} diff --git a/src/client/buffertreemodel.h b/src/client/buffertreemodel.h new file mode 100644 index 00000000..0848c8ff --- /dev/null +++ b/src/client/buffertreemodel.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BUFFERTREEMODEL_H_ +#define _BUFFERTREEMODEL_H_ + +#include + +#include "treemodel.h" +#include "buffer.h" +#include "clientproxy.h" + +/***************************************** + * Fancy Buffer Items + *****************************************/ +class BufferTreeItem : public TreeItem{ + Q_OBJECT + +public: + BufferTreeItem(Buffer *, TreeItem *parent = 0); + QVariant data(int column, int role) const; + Buffer *buffer() const { return buf; } + void setActivity(const Buffer::ActivityLevel &); + +protected: + QString text(int column) const; + QColor foreground(int column) const; + + Buffer *buf; + Buffer::ActivityLevel activity; +}; + + +/***************************************** + * BufferTreeModel + *****************************************/ +class BufferTreeModel : public TreeModel { + Q_OBJECT + +public: + enum myRoles { + BufferTypeRole = Qt::UserRole, + BufferActiveRole + }; + + //BufferTreeModel(const QList &, QObject *parent = 0); + BufferTreeModel(QObject *parent = 0); + static QList defaultHeader(); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + +// void clearActivity(Buffer *buffer); + +public slots: + void bufferUpdated(Buffer *); + void changeCurrent(const QModelIndex &, const QModelIndex &); + void selectBuffer(Buffer *buffer); + void doubleClickReceived(const QModelIndex &); + void bufferActivity(Buffer::ActivityLevel, Buffer *buffer); + +signals: + void bufferSelected(Buffer *); + void invalidateFilter(); + void fakeUserInput(BufferId, QString); + void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +private: + bool isBufferIndex(const QModelIndex &) const; + Buffer *getBufferByIndex(const QModelIndex &) const; + QModelIndex getOrCreateNetworkItemIndex(Buffer *buffer); + QModelIndex getOrCreateBufferItemIndex(Buffer *buffer); + + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &) const; + bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &); + + QHash networkItem; + QHash bufferItem; + Buffer *currentBuffer; +}; + +#endif diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp new file mode 100644 index 00000000..3f264498 --- /dev/null +++ b/src/client/treemodel.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "global.h" +#include "treemodel.h" + +/***************************************** + * Buffer Items stored in the Tree Model + *****************************************/ +TreeItem::TreeItem(const QList &data, TreeItem *parent) : QObject(parent) { + itemData = data; + parentItem = parent; +} + +TreeItem::TreeItem(TreeItem *parent) { + itemData = QList(); + parentItem = parent; +} + +TreeItem::~TreeItem() { + qDeleteAll(childItems); +} + +void TreeItem::appendChild(TreeItem *item) { + childItems.append(item); +} + +void TreeItem::removeChild(int row) { + childItems.removeAt(row); +} + +TreeItem *TreeItem::child(int row) { + return childItems.value(row); +} + +int TreeItem::childCount() const { + return childItems.count(); +} + +int TreeItem::row() const { + if(parentItem) + return parentItem->childItems.indexOf(const_cast(this)); + else + return 0; +} + +TreeItem *TreeItem::parent() { + return parentItem; +} + +int TreeItem::columnCount() const { + return itemData.count(); +} + +QVariant TreeItem::data(int column, int role) const { + if(role == Qt::DisplayRole and column < itemData.count()) + return itemData[column]; + else + return QVariant(); +} + + +/***************************************** + * TreeModel + *****************************************/ +TreeModel::TreeModel(const QList &data, QObject *parent) : QAbstractItemModel(parent) { + rootItem = new TreeItem(data, 0); +} + +TreeModel::~TreeModel() { + delete rootItem; +} + +QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const { + if(!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeItem *parentItem; + + if(!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + TreeItem *childItem = parentItem->child(row); + if(childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex TreeModel::parent(const QModelIndex &index) const { + if(!index.isValid()) + return QModelIndex(); + + TreeItem *childItem = static_cast(index.internalPointer()); + TreeItem *parentItem = childItem->parent(); + + if(parentItem == rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int TreeModel::rowCount(const QModelIndex &parent) const { + TreeItem *parentItem; + if(parent.column() > 0) + return 0; + + if(!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->childCount(); +} + +int TreeModel::columnCount(const QModelIndex &parent) const { + if(parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return rootItem->columnCount(); +} + +QVariant TreeModel::data(const QModelIndex &index, int role) const { + if(!index.isValid()) + return QVariant(); + + TreeItem *item = static_cast(index.internalPointer()); + return item->data(index.column(), role); +} + +Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const { + if(!index.isValid()) + return 0; + else + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return rootItem->data(section, role); + else + return QVariant(); +} + +bool TreeModel::removeRow(int row, const QModelIndex &parent) { + beginRemoveRows(parent, row, row); + TreeItem *item = static_cast(parent.internalPointer()); + item->removeChild(row); + endRemoveRows(); + return true; +} + diff --git a/src/client/treemodel.h b/src/client/treemodel.h new file mode 100644 index 00000000..a4039843 --- /dev/null +++ b/src/client/treemodel.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _TREEMODEL_H_ +#define _TREEMODEL_H_ + +#include + +/***************************************** + * general item used in the Tree Model + *****************************************/ +class TreeItem : public QObject { + Q_OBJECT + +public: + TreeItem(const QList &data, TreeItem *parent = 0); + TreeItem(TreeItem *parent = 0); + virtual ~TreeItem(); + + void appendChild(TreeItem *child); + void removeChild(int row); + + TreeItem *child(int row); + int childCount() const; + int columnCount() const; + virtual QVariant data(int column, int role) const; + int row() const; + TreeItem *parent(); + +protected: + QList childItems; + TreeItem *parentItem; + QList itemData; +}; + + +/***************************************** + * TreeModel + *****************************************/ +class TreeModel : public QAbstractItemModel { + Q_OBJECT + +public: + TreeModel(const QList &, QObject *parent = 0); + virtual ~TreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + +protected: + bool removeRow(int row, const QModelIndex &parent = QModelIndex()); + + TreeItem *rootItem; +}; + +#endif diff --git a/src/qtgui/bufferviewfilter.cpp b/src/qtgui/bufferviewfilter.cpp new file mode 100644 index 00000000..caa1fb38 --- /dev/null +++ b/src/qtgui/bufferviewfilter.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "bufferviewfilter.h" + +/***************************************** +* The Filter for the Tree View +*****************************************/ +BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, Modes filtermode, QStringList nets, QObject *parent) : QSortFilterProxyModel(parent) { + setSourceModel(model); + mode = filtermode; + networks = nets; + + connect(model, SIGNAL(invalidateFilter()), this, SLOT(invalidateMe())); + connect(model, SIGNAL(updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags)), this, SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags))); + + connect(this, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), model, SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); + connect(this, SIGNAL(doubleClicked(const QModelIndex &)), model, SLOT(doubleClickReceived(const QModelIndex &))); +} + +void BufferViewFilter::invalidateMe() { + invalidateFilter(); +} + +void BufferViewFilter::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { + emit updateSelection(mapFromSource(index), command); +} + +void BufferViewFilter::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) { + emit currentChanged(mapToSource(current), mapToSource(previous)); +} + +void BufferViewFilter::doubleClickReceived(const QModelIndex &clicked) { + emit doubleClicked(mapToSource(clicked)); +} + +bool BufferViewFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { + QModelIndex child = source_parent.child(source_row, 0); + if(!child.isValid()) + return true; // can't imagine this case but true sounds good :) + + Buffer::Type bufferType = (Buffer::Type) child.data(BufferTreeModel::BufferTypeRole).toInt(); + if((mode & NoChannels) && bufferType == Buffer::ChannelBuffer) return false; + if((mode & NoQueries) && bufferType == Buffer::QueryBuffer) return false; + if((mode & NoServers) && bufferType == Buffer::ServerBuffer) return false; + + bool isActive = child.data(BufferTreeModel::BufferActiveRole).toBool(); + if((mode & NoActive) && isActive) return false; + if((mode & NoInactive) && !isActive) return false; + + QString net = child.data(Qt::DisplayRole).toString(); + if((mode & SomeNets) && !networks.contains(net)) return false; + + return true; +} diff --git a/src/qtgui/bufferviewfilter.h b/src/qtgui/bufferviewfilter.h new file mode 100644 index 00000000..36c07078 --- /dev/null +++ b/src/qtgui/bufferviewfilter.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BUFFERVIEWFILTER_H_ +#define _BUFFERVIEWFILTER_H_ + +#include +#include "buffer.h" +#include "buffertreemodel.h" + +/***************************************** + * Buffer View Filter + *****************************************/ +class BufferViewFilter : public QSortFilterProxyModel { + Q_OBJECT + +public: + enum Mode { + NoActive = 0x01, + NoInactive = 0x02, + SomeNets = 0x04, + AllNets = 0x08, + NoChannels = 0x10, + NoQueries = 0x20, + NoServers = 0x40 + }; + Q_DECLARE_FLAGS(Modes, Mode) + + BufferViewFilter(QAbstractItemModel *model, Modes mode, QStringList nets, QObject *parent = 0); + +public slots: + void invalidateMe(); + void changeCurrent(const QModelIndex &, const QModelIndex &); + void doubleClickReceived(const QModelIndex &); + void select(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +signals: + void currentChanged(const QModelIndex &, const QModelIndex &); + void doubleClicked(const QModelIndex &); + void updateSelection(const QModelIndex &, QItemSelectionModel::SelectionFlags); + +private: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + + Modes mode; + QStringList networks; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(BufferViewFilter::Modes) + +#endif + -- 2.20.1 From 73edffb5f0f6ecae4118c36a7ca2c0d479b7f8c6 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 20 Jun 2007 19:26:32 +0000 Subject: [PATCH 16/16] Reorganizing of the Quassel architecture is almost done. Client and GUI have been split. I will now consolidate the main files and start enabling building of standalone core and client again. --- Doxyfile | 1049 +++++++++++++++++++++++++++++++- Quassel.kdevelop.filelist | 182 +++--- src/CMakeLists.txt | 40 +- src/client/CMakeLists.txt | 6 + src/client/buffer.cpp | 65 +- src/client/buffer.h | 57 +- src/client/buffertreemodel.cpp | 2 + src/client/buffertreemodel.h | 1 + src/client/client.cpp | 48 +- src/client/client.h | 24 +- src/common/CMakeLists.txt | 2 +- src/common/global.cpp | 2 +- src/common/global.h | 9 +- src/common/main_mono.cpp | 8 +- src/common/quasselui.h | 50 ++ src/qtgui/CMakeLists.txt | 13 +- src/qtgui/bufferviewfilter.h | 1 + src/qtgui/bufferwidget.cpp | 49 +- src/qtgui/chatline.cpp | 408 +++++++++++++ src/qtgui/chatline.h | 109 ++++ src/qtgui/chatwidget.cpp | 402 +----------- src/qtgui/chatwidget.h | 124 +--- src/qtgui/mainwin.cpp | 26 +- src/qtgui/mainwin.h | 56 +- templates/cpp | 2 +- templates/h | 2 +- 26 files changed, 1915 insertions(+), 822 deletions(-) create mode 100644 src/client/CMakeLists.txt create mode 100644 src/common/quasselui.h create mode 100644 src/qtgui/chatline.cpp create mode 100644 src/qtgui/chatline.h diff --git a/Doxyfile b/Doxyfile index f10fed8e..4def1635 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,16 +1,90 @@ -# Doxyfile 1.5.1-KDevelop +# Doxyfile 1.5.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + PROJECT_NAME = "Quassel IRC" -PROJECT_NUMBER = 0.1 + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = Pre-Release + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ @@ -22,70 +96,398 @@ ABBREVIATE_BRIEF = "The $name class" \ a \ an \ the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + STRIP_FROM_PATH = / + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + STRIP_FROM_INC_PATH = /home/sputnick/devel/local-quassel/ + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + SHORT_NAMES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + DISTRIBUTE_GROUP_DOC = YES + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + SUBGROUPING = YES + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + FILE_VERSION_FILTER = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + WARN_LOGFILE = + #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = gui \ - main \ - core \ - plugins + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + FILE_PATTERNS = *.c \ *.cc \ *.cxx \ @@ -132,152 +534,779 @@ FILE_PATTERNS = *.c \ *.moc \ *.xpm \ *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + FILTER_SOURCE_FILES = YES + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + VERBATIM_HEADERS = YES + #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + IGNORE_PREFIX = + #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + TREEVIEW_WIDTH = 250 + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + LATEX_HIDE_INDICES = NO + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + RTF_HYPERLINKS = YES + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + RTF_EXTENSIONS_FILE = + #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + MAN_LINKS = NO + #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + XML_PROGRAMLISTING = YES + #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + GENERATE_AUTOGEN_DEF = NO + #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + PERLMOD_MAKEVAR_PREFIX = + #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + INCLUDE_PATH = /usr/include/qt4 + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + SKIP_FUNCTION_MACROS = NO + #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + GENERATE_TAGFILE = quassel.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + ALLEXTERNALS = YES + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + PERL_PATH = /usr/bin/perl + #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 1000 + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen will always +# show the root nodes and its direct children regardless of this setting. + +DOT_GRAPH_MAX_NODES = 50 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + DOT_CLEANUP = YES + #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + SEARCHENGINE = NO diff --git a/Quassel.kdevelop.filelist b/Quassel.kdevelop.filelist index 73fdb28c..572f4e00 100644 --- a/Quassel.kdevelop.filelist +++ b/Quassel.kdevelop.filelist @@ -1,87 +1,97 @@ # KDevelop Custom Project File List -client -client/buffer.cpp -client/buffer.h -client/client.cpp -client/client.h -client/clientproxy.cpp -client/clientproxy.h -CMakeLists.txt -common -common/CMakeLists.txt -common/global.cpp -common/global.h -common/logger.cpp -common/logger.h -common/main_core.cpp -common/main_gui.cpp -common/main_mono.cpp -common/message.cpp -common/message.h -common/proxy_common.h -common/settings.cpp -common/settings.h -common/util.cpp -common/util.h -core -core/backlog.cpp -core/backlog.h -core/CMakeLists.txt -core/core.cpp -core/core.h -core/coreproxy.cpp -core/coreproxy.h -core/server.cpp -core/server.h -core/sqlitestorage.cpp -core/sqlitestorage.h -core/storage.cpp -core/storage.h -plugins -plugins/plugin.h -qtgui -qtgui/bufferview.cpp -qtgui/bufferview.h -qtgui/bufferviewwidget.cpp -qtgui/bufferviewwidget.h -qtgui/bufferwidget.cpp -qtgui/bufferwidget.h -qtgui/channelwidgetinput.cpp -qtgui/channelwidgetinput.h -qtgui/chatwidget.cpp -qtgui/chatwidget.h -qtgui/CMakeLists.txt -qtgui/coreconnectdlg.cpp -qtgui/coreconnectdlg.h -qtgui/identities.cpp -qtgui/identities.h -qtgui/mainwin.cpp -qtgui/mainwin.h -qtgui/serverlist.cpp -qtgui/serverlist.h -qtgui/settingsdlg.cpp -qtgui/settingsdlg.h -qtgui/settingspages.cpp -qtgui/settingspages.h -qtgui/style.cpp -qtgui/style.h -qtgui/tabcompleter.cpp -qtgui/tabcompleter.h -qtgui/ui -qtgui/ui/aboutdlg.ui -qtgui/ui/buffermgmntsettingspage.ui -qtgui/ui/bufferviewwidget.ui -qtgui/ui/bufferwidget.ui -qtgui/ui/channelwidget.ui -qtgui/ui/connectionsettingspage.ui -qtgui/ui/coreconnectdlg.ui -qtgui/ui/coresettingspage.ui -qtgui/ui/identitiesdlg.ui -qtgui/ui/identitieseditdlg.ui -qtgui/ui/ircwidget.ui -qtgui/ui/mainwin.ui -qtgui/ui/networkeditdlg.ui -qtgui/ui/nickeditdlg.ui -qtgui/ui/servereditdlg.ui -qtgui/ui/serverlistdlg.ui -qtgui/ui/settingsdlg.ui +Makefile +src +src/client +src/client/buffer.cpp +src/client/buffer.h +src/client/client.cpp +src/client/client.h +src/client/clientproxy.cpp +src/client/clientproxy.h +src/CMakeLists.txt +src/common +src/common/CMakeLists.txt +src/common/global.cpp +src/common/global.h +src/common/logger.cpp +src/common/logger.h +src/common/main_core.cpp +src/common/main_gui.cpp +src/common/main_mono.cpp +src/common/message.cpp +src/common/message.h +src/common/proxy_common.h +src/common/settings.cpp +src/common/settings.h +src/common/util.cpp +src/common/util.h +src/core +src/core/backlog.cpp +src/core/backlog.h +src/core/CMakeLists.txt +src/core/core.cpp +src/core/core.h +src/core/coreproxy.cpp +src/core/coreproxy.h +src/core/server.cpp +src/core/server.h +src/core/sqlitestorage.cpp +src/core/sqlitestorage.h +src/core/storage.cpp +src/core/storage.h +src/plugins +src/plugins/plugin.h +src/qtgui +src/qtgui/bufferview.cpp +src/qtgui/bufferview.h +src/qtgui/bufferviewwidget.cpp +src/qtgui/bufferviewwidget.h +src/qtgui/bufferwidget.cpp +src/qtgui/bufferwidget.h +src/qtgui/channelwidgetinput.cpp +src/qtgui/channelwidgetinput.h +src/qtgui/chatwidget.cpp +src/qtgui/chatwidget.h +src/qtgui/CMakeLists.txt +src/qtgui/coreconnectdlg.cpp +src/qtgui/coreconnectdlg.h +src/qtgui/identities.cpp +src/qtgui/identities.h +src/qtgui/mainwin.cpp +src/qtgui/mainwin.h +src/qtgui/serverlist.cpp +src/qtgui/serverlist.h +src/qtgui/settingsdlg.cpp +src/qtgui/settingsdlg.h +src/qtgui/settingspages.cpp +src/qtgui/settingspages.h +src/qtgui/style.cpp +src/qtgui/style.h +src/qtgui/tabcompleter.cpp +src/qtgui/tabcompleter.h +src/qtgui/ui +src/qtgui/ui/aboutdlg.ui +src/qtgui/ui/buffermgmntsettingspage.ui +src/qtgui/ui/bufferviewwidget.ui +src/qtgui/ui/bufferwidget.ui +src/qtgui/ui/channelwidget.ui +src/qtgui/ui/connectionsettingspage.ui +src/qtgui/ui/coreconnectdlg.ui +src/qtgui/ui/coresettingspage.ui +src/qtgui/ui/identitiesdlg.ui +src/qtgui/ui/identitieseditdlg.ui +src/qtgui/ui/ircwidget.ui +src/qtgui/ui/mainwin.ui +src/qtgui/ui/networkeditdlg.ui +src/qtgui/ui/nickeditdlg.ui +src/qtgui/ui/servereditdlg.ui +src/qtgui/ui/serverlistdlg.ui +src/qtgui/ui/settingsdlg.ui +src/common/quasselui.h +src/client/CMakeLists.txt +src/qtgui/chatline.cpp +src/qtgui/chatline.h +src/client/buffertreemodel.h +src/client/buffertreemodel.cpp +src/client/treemodel.cpp +src/client/treemodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31227039..24713921 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,16 +6,16 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.4.3 FATAL_ERROR) # Select if Quassel should be built in client, server or monolithic mode SET(BUILD "mono" CACHE STRING "Defines which Quassel parts are to be built. Can contain 'core', 'gui' and/or 'monolithic' (which is the default), or 'all' to build everything.") SET(BUILD_CORE ) -SET(BUILD_GUI ) +SET(BUILD_CLIENT ) SET(BUILD_MONO ) IF(BUILD MATCHES "core" OR BUILD MATCHES "all") SET(BUILD_CORE true) MESSAGE("Building Quassel core.") ENDIF(BUILD MATCHES "core" OR BUILD MATCHES "all") -IF(BUILD MATCHES "gui" OR BUILD MATCHES "all") - SET(BUILD_GUI true) +IF(BUILD MATCHES "client" OR BUILD MATCHES "all") + SET(BUILD_CLIENT true) MESSAGE("Building Quassel GUI.") -ENDIF(BUILD MATCHES "gui" OR BUILD MATCHES "all") +ENDIF(BUILD MATCHES "client" OR BUILD MATCHES "all") IF(BUILD MATCHES "mono" OR BUILD MATCHES "all") SET(BUILD_MONO true) MESSAGE("Building monolithic Quassel.") @@ -24,26 +24,26 @@ IF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) MESSAGE(FATAL_ERROR "\nYou have not selected which parts of Quassel I should build. Aborting.\nRun 'cmake -DBUILD=', where contains one or more of 'core', 'gui' or 'monolithic', or 'all' to build everything.\n") ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) -IF(BUILD_CORE OR BUILD_GUI) +IF(BUILD_CORE OR BUILD_CLIENT) MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n") -ENDIF(BUILD_CORE OR BUILD_GUI) +ENDIF(BUILD_CORE OR BUILD_CLIENT) SET(CMAKE_BUILD_TYPE Debug) # Define files SET(quassel_mono_SRCS common/main_mono.cpp) SET(quassel_core_SRCS common/main_core.cpp) -SET(quassel_gui_SRCS common/main_gui.cpp ${common_SRCS}) +SET(quassel_client_SRCS common/main_gui.cpp ${common_SRCS}) SET(quassel_RCCS images/icons.qrc) -SET(quassel_DIRS common qtgui core) +SET(quassel_DIRS common client core qtgui) # Build correct absolute paths for subdirs to include SET(SDIRS "") FOREACH(dir ${quassel_DIRS}) SET(SDIRS ${SDIRS} "${CMAKE_CURRENT_SOURCE_DIR}/${dir}") ENDFOREACH(dir) -INCLUDE_DIRECTORIES(${SDIRS} client plugins) -#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +INCLUDE_DIRECTORIES(${SDIRS} plugins) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/qtgui) # We need Qt4 support. SET(QT_MIN_VERSION "4.3.0") # 4.3 is required for SSL, crypto and some other stuff @@ -74,33 +74,37 @@ SET(TARGET_LIST ) IF(BUILD_CORE) ADD_DEFINITIONS(-DBUILD_CORE) ADD_EXECUTABLE(quasselcore ${quassel_core_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quasselcore core common ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quasselcore common core ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quasselcore) + REMOVE_DEFINITIONS(-DBUILD_CORE) ENDIF(BUILD_CORE) -IF(BUILD_GUI OR BUILD_MONO) # OK, now we need QtGui! +IF(BUILD_CLIENT OR BUILD_MONO) # OK, now we need QtGui! REMOVE_DEFINITIONS(-DQT_CORE_LIB -DQT_GUI_LIB ${QT_DEFINITIONS}) SET(QT_DONT_USE_QTGUI "") SET(QT_INCLUDE_DIR "") SET(QT_LIBRARIES "") INCLUDE(${QT_USE_FILE}) + ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(qtgui) IF(BUILD_MONO) ADD_DEFINITIONS(-DBUILD_MONO) ADD_EXECUTABLE(quassel ${quassel_mono_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quassel qtgui core common ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quassel common client core qtgui ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quassel) + REMOVE_DEFINITIONS(-DBUILD_MONO) ENDIF(BUILD_MONO) - IF(BUILD_GUI) - ADD_DEFINITIONS(-DBUILD_GUI) + IF(BUILD_CLIENT) + ADD_DEFINITIONS(-DBUILD_CLIENT) ADD_EXECUTABLE(quasselgui ${quassel_gui_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quasselgui qtgui common ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quasselclient common client qtgui ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quasselgui) - ENDIF(BUILD_GUI) + REMOVE_DEFINITIONS(-DBUILD_CLIENT) + ENDIF(BUILD_CLIENT) -ENDIF(BUILD_GUI OR BUILD_MONO) +ENDIF(BUILD_CLIENT OR BUILD_MONO) INSTALL(TARGETS ${TARGET_LIST} RUNTIME DESTINATION bin diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt new file mode 100644 index 00000000..40a7695f --- /dev/null +++ b/src/client/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(client_SRCS buffer.cpp buffertreemodel.cpp client.cpp clientproxy.cpp treemodel.cpp) +SET(client_HDRS ) +SET(client_MOCS buffer.h buffertreemodel.h client.h clientproxy.h treemodel.h) + +QT4_WRAP_CPP(_MOC ${client_MOCS}) +ADD_LIBRARY(client ${_MOC} ${client_SRCS} ${client_HDRS}) diff --git a/src/client/buffer.cpp b/src/client/buffer.cpp index cf764c1b..c8f375d0 100644 --- a/src/client/buffer.cpp +++ b/src/client/buffer.cpp @@ -18,10 +18,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include "client.h" #include "buffer.h" #include "util.h" -#include "chatwidget.h" -#include "bufferwidget.h" /* Buffer::Buffer(QString netname, QString bufname) { @@ -62,18 +61,53 @@ Buffer::~Buffer() { emit bufferDestroyed(this); } -void Buffer::init() { +Buffer::Type Buffer::bufferType() const { + return type; +} +bool Buffer::isActive() const { + return active; +} +QString Buffer::networkName() const { + return _networkName; } -QString Buffer::displayName() { +QString Buffer::bufferName() const { + return _bufferName; +} + +QString Buffer::displayName() const { if(bufferType() == ServerBuffer) - return tr("status"); + return tr("Status Buffer"); else return bufferName(); } +BufferId Buffer::bufferId() const { + return id; +} + +QList Buffer::contents() const { + return layoutedMsgs; +} + +VarMap Buffer::nickList() const { + return nicks; +} + +QString Buffer::topic() const { + return _topic; +} + +QString Buffer::ownNick() const { + return _ownNick; +} + +bool Buffer::isStatusBuffer() const { + return bufferType() == ServerBuffer; +} + void Buffer::setActive(bool a) { if(a != active) { active = a; @@ -81,14 +115,23 @@ void Buffer::setActive(bool a) { } } -void Buffer::appendChatLine(ChatLine *line) { - lines.append(line); - emit chatLineAppended(line); +void Buffer::appendMsg(const Message &msg) { + AbstractUiMsg *m = Client::layoutMsg(msg); + layoutedMsgs.append(m); + emit msgAppended(m); +} + +void Buffer::prependMsg(const Message &msg) { + layoutQueue.append(msg); } -void Buffer::prependChatLine(ChatLine *line) { - lines.prepend(line); - emit chatLinePrepended(line); +bool Buffer::layoutMsg() { + if(layoutQueue.count()) { + AbstractUiMsg *m = Client::layoutMsg(layoutQueue.takeFirst()); + layoutedMsgs.prepend(m); + emit msgPrepended(m); + } + return layoutQueue.count(); } void Buffer::processUserInput(QString msg) { diff --git a/src/client/buffer.h b/src/client/buffer.h index 944b07cc..2c361d3d 100644 --- a/src/client/buffer.h +++ b/src/client/buffer.h @@ -22,16 +22,11 @@ #define _BUFFER_H_ #include -#include -#include "chatwidget.h" #include "global.h" #include "message.h" +#include "quasselui.h" -class ChatWidget; -class ChatLine; -class ChatWidgetContents; -class BufferWidget; struct BufferState; //!\brief Encapsulates the contents of a single channel, query or server status context. @@ -43,10 +38,8 @@ class Buffer : public QObject { Q_OBJECT public: - //Buffer(QString network, QString buffer); Buffer(BufferId); ~Buffer(); - static void init(); enum Type { ServerBuffer, ChannelBuffer, QueryBuffer }; @@ -57,39 +50,37 @@ class Buffer : public QObject { Highlight = 0x40 }; Q_DECLARE_FLAGS(ActivityLevel, Activity) - - Type bufferType() { return type; } - bool isActive() { return active; } - - QString networkName() { return _networkName; } - QString bufferName() { return _bufferName; } - QString displayName(); - BufferId bufferId() { return id; } - QList contents() { return lines; } - VarMap nickList() { return nicks; } - QString topic() { return _topic; } - QString ownNick() { return _ownNick; } - bool isStatusBuffer() { return bufferType() == ServerBuffer; } + + Type bufferType() const; + bool isActive() const; + + QString networkName() const; + QString bufferName() const; + QString displayName() const; + BufferId bufferId() const; + QList contents() const; + VarMap nickList() const; + QString topic() const; + QString ownNick() const; + bool isStatusBuffer() const; signals: - void userInput(BufferId, QString); - //void msgDisplayed(Message); - void chatLineAppended(ChatLine *); - void chatLinePrepended(ChatLine *); + void userInput(const BufferId &, QString); void nickListChanged(VarMap nicks); void topicSet(QString topic); void ownNickSet(QString ownNick); void bufferUpdated(Buffer *); void bufferDestroyed(Buffer *); + void msgAppended(AbstractUiMsg *); + void msgPrepended(AbstractUiMsg *); + void layoutQueueEmpty(); + public slots: void setActive(bool active = true); - //void displayMsg(Message); - //void prependMessages(QList); // for backlog - void appendChatLine(ChatLine *); - void prependChatLine(ChatLine *); - //void prependChatLines(QList); - //void recvStatusMsg(QString msg); + void appendMsg(const Message &); + void prependMsg(const Message &); + bool layoutMsg(); void setTopic(QString); //void setNicks(QStringList); void addNick(QString nick, VarMap props); @@ -111,8 +102,8 @@ class Buffer : public QObject { QString _networkName, _bufferName; BufferState *state; - //QList _contents; - QList lines; + QList layoutQueue; + QList layoutedMsgs; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Buffer::ActivityLevel) diff --git a/src/client/buffertreemodel.cpp b/src/client/buffertreemodel.cpp index 7030547e..2d51d85c 100644 --- a/src/client/buffertreemodel.cpp +++ b/src/client/buffertreemodel.cpp @@ -18,6 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include // FIXME Dependency on QtGui! + #include "global.h" #include "buffertreemodel.h" diff --git a/src/client/buffertreemodel.h b/src/client/buffertreemodel.h index 0848c8ff..9d71dee7 100644 --- a/src/client/buffertreemodel.h +++ b/src/client/buffertreemodel.h @@ -22,6 +22,7 @@ #define _BUFFERTREEMODEL_H_ #include +#include // FIXME Dependency on QtGui #include "treemodel.h" #include "buffer.h" diff --git a/src/client/client.cpp b/src/client/client.cpp index a04361cc..419a8a2a 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -20,8 +20,8 @@ #include "client.h" #include "clientproxy.h" -#include "mainwin.h" #include "buffer.h" +#include "buffertreemodel.h" #include "util.h" Client * Client::instanceptr = 0; @@ -38,7 +38,6 @@ QList Client::coreBuffers; Client *Client::instance() { if(instanceptr) return instanceptr; instanceptr = new Client(); - instanceptr->init(); return instanceptr; } @@ -50,8 +49,7 @@ void Client::destroy() { Client::Client() { clientProxy = ClientProxy::instance(); - //mainWin = new MainWin(); - _bufferModel = new BufferTreeModel(0); // FIXME + _bufferModel = new BufferTreeModel(this); connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *))); @@ -62,6 +60,11 @@ Client::Client() { else clientMode = RemoteCore; } +void Client::init(AbstractUi *ui) { + instance()->mainUi = ui; + instance()->init(); +} + void Client::init() { blockSize = 0; @@ -77,7 +80,7 @@ void Client::init() { connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); - connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(Message))); + connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(const Message &))); connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); connect(clientProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap))); @@ -85,7 +88,7 @@ void Client::init() { connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap))); connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); - connect(clientProxy, SIGNAL(csBacklogData(BufferId, QList, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); + connect(clientProxy, SIGNAL(csBacklogData(BufferId, const QList &, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); connect(clientProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId))); connect(this, SIGNAL(sendInput(BufferId, QString)), clientProxy, SLOT(gsUserInput(BufferId, QString))); connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), clientProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); @@ -103,15 +106,11 @@ void Client::init() { buffer(id); // create all buffers, so we see them in the network views emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request } - - mainWin = new MainWin(); - mainWin->init(); - } Client::~Client() { - delete mainWin; - delete _bufferModel; + //delete mainUi; + //delete _bufferModel; foreach(Buffer *buf, buffers.values()) delete buf; ClientProxy::destroy(); @@ -174,8 +173,6 @@ void Client::serverHasData() { } } -/*******************************************************************************************************************/ - void Client::networkConnected(QString net) { connected[net] = true; BufferId id = statusBufferId(net); @@ -244,7 +241,7 @@ void Client::recvNetworkState(QString net, QVariant state) { } } -void Client::recvMessage(Message msg) { +void Client::recvMessage(const Message &msg) { Buffer *b = buffer(msg.buffer); Buffer::ActivityLevel level = Buffer::OtherActivity; @@ -256,8 +253,7 @@ void Client::recvMessage(Message msg) { } emit bufferActivity(level, b); - //b->displayMsg(msg); - b->appendChatLine(new ChatLine(msg)); + b->appendMsg(msg); } void Client::recvStatusMsg(QString net, QString msg) { @@ -265,22 +261,28 @@ void Client::recvStatusMsg(QString net, QString msg) { } -void Client::recvBacklogData(BufferId id, QList msgs, bool done) { +void Client::recvBacklogData(BufferId id, const QList &msgs, bool done) { + Buffer *b = buffer(id); foreach(QVariant v, msgs) { - layoutQueue.append(v.value()); + Message msg = v.value(); + b->prependMsg(msg); + if(!layoutQueue.contains(b)) layoutQueue.append(b); } - if(!layoutTimer->isActive()) layoutTimer->start(); + if(layoutQueue.count() && !layoutTimer->isActive()) layoutTimer->start(); } - void Client::layoutMsg() { if(layoutQueue.count()) { - ChatLine *line = new ChatLine(layoutQueue.takeFirst()); - buffer(line->bufferId())->prependChatLine(line); + Buffer *b = layoutQueue.takeFirst(); // TODO make this the current buffer + if(b->layoutMsg()) layoutQueue.append(b); // Buffer has more messages in its queue --> Round Robin } if(!layoutQueue.count()) layoutTimer->stop(); } +AbstractUiMsg *Client::layoutMsg(const Message &msg) { + return instance()->mainUi->layoutMsg(msg); +} + void Client::userInput(BufferId id, QString msg) { emit sendInput(id, msg); } diff --git a/src/client/client.h b/src/client/client.h index 82e3e844..eee57fd5 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -18,28 +18,26 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _GUI_H_ -#define _GUI_H_ +#ifndef _CLIENT_H_ +#define _CLIENT_H_ #include -#include #include -#include "global.h" +#include "quasselui.h" #include "buffer.h" #include "message.h" -#include "clientproxy.h" -#include "buffertreemodel.h" -//#include "bufferviewwidget.h" +#include "proxy_common.h" -class MainWin; class ClientProxy; +class BufferTreeModel; class Client : public QObject { Q_OBJECT public: static Client *instance(); + static void init(AbstractUi *); static void destroy(); static Buffer *buffer(BufferId); @@ -48,6 +46,8 @@ class Client : public QObject { static BufferTreeModel *bufferModel(); + static AbstractUiMsg *layoutMsg(const Message &); + signals: void sendInput(BufferId, QString message); void showBuffer(Buffer *); @@ -80,7 +80,7 @@ class Client : public QObject { void networkConnected(QString); void networkDisconnected(QString); void recvNetworkState(QString, QVariant); - void recvMessage(Message message); + void recvMessage(const Message &message); void recvStatusMsg(QString network, QString message); void setTopic(QString net, QString buf, QString); void addNick(QString net, QString nick, VarMap props); @@ -88,7 +88,7 @@ class Client : public QObject { void renameNick(QString net, QString oldnick, QString newnick); void updateNick(QString net, QString nick, VarMap props); void setOwnNick(QString net, QString nick); - void recvBacklogData(BufferId, QList, bool); + void recvBacklogData(BufferId, const QList &, bool); void updateBufferId(BufferId); void layoutMsg(); @@ -104,7 +104,7 @@ class Client : public QObject { enum ClientMode { LocalCore, RemoteCore }; static ClientMode clientMode; - MainWin *mainWin; + AbstractUi *mainUi; ClientProxy *clientProxy; BufferTreeModel *_bufferModel; @@ -119,7 +119,7 @@ class Client : public QObject { static QList coreBuffers; QTimer *layoutTimer; - QList layoutQueue; + QList layoutQueue; }; #endif diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index acfa640d..7f465520 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ SET(common_SRCS global.cpp logger.cpp util.cpp message.cpp settings.cpp) -SET(common_HDRS util.h message.h settings.h) +SET(common_HDRS util.h message.h settings.h quasselui.h) SET(common_MOCS global.h logger.h) QT4_WRAP_CPP(_MOC ${common_MOCS}) diff --git a/src/common/global.cpp b/src/common/global.cpp index 3c82e815..b92f7959 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -136,7 +136,7 @@ BufferId::BufferId(uint _id, QString _net, QString _buf, uint _gid) : id(_id), g } -QString BufferId::buffer() { +QString BufferId::buffer() const { if(isChannelName(buf)) return buf; else return nickFromMask(buf); } diff --git a/src/common/global.h b/src/common/global.h index fa961f2f..42856068 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -111,14 +111,15 @@ class BufferId { BufferId() { id = gid = 0; } // FIXME BufferId(uint uid, QString net, QString buf, uint gid = 0); - inline uint uid() { return id; } - inline uint groupId() { return gid; } - inline QString network() { return net; } - QString buffer(); // nickfrommask? + inline uint uid() const { return id; } + inline uint groupId() const { return gid; } + inline QString network() const { return net; } + QString buffer() const; // nickfrommask? void setGroupId(uint _gid) { gid = _gid; } inline bool operator==(const BufferId &other) const { return id == other.id; } + private: uint id; uint gid; diff --git a/src/common/main_mono.cpp b/src/common/main_mono.cpp index f0bafd9e..a7565c56 100644 --- a/src/common/main_mono.cpp +++ b/src/common/main_mono.cpp @@ -30,6 +30,7 @@ #include "coreproxy.h" #include "settings.h" #include "chatwidget.h" +#include "mainwin.h" int main(int argc, char **argv) { QApplication app(argc, argv); @@ -50,14 +51,15 @@ int main(int argc, char **argv) { Settings::init(); Style::init(); - //MainWin *mainWin = new MainWin(); + MainWin *mainWin = new MainWin(); //mainWin->show(); - //mainWin->init(); - Client::instance(); + Client::init(mainWin); + mainWin->init(); int exitCode = app.exec(); //delete core; Client::destroy(); Core::destroy(); + delete mainWin; //delete guiProxy; //delete coreProxy; //delete global; diff --git a/src/common/quasselui.h b/src/common/quasselui.h new file mode 100644 index 00000000..4209cdd9 --- /dev/null +++ b/src/common/quasselui.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel IRC Development Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _QUASSELUI_H_ +#define _QUASSELUI_H_ + +#include "message.h" + +class AbstractUiMsg { + + public: + + virtual QString sender() const = 0; + virtual QString text() const = 0; + virtual MsgId msgId() const = 0; + virtual BufferId bufferId() const = 0; + virtual QDateTime timeStamp() const = 0; + +}; + + +class AbstractUi { + + public: + virtual AbstractUiMsg *layoutMsg(const Message &) = 0; + + + +}; + + + +#endif diff --git a/src/qtgui/CMakeLists.txt b/src/qtgui/CMakeLists.txt index 99c9de7c..11985659 100644 --- a/src/qtgui/CMakeLists.txt +++ b/src/qtgui/CMakeLists.txt @@ -1,27 +1,24 @@ -SET(qtgui_SRCS chatwidget.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp bufferwidget.cpp +SET(qtgui_SRCS chatwidget.cpp chatline.cpp channelwidgetinput.cpp tabcompleter.cpp mainwin.cpp serverlist.cpp bufferwidget.cpp identities.cpp coreconnectdlg.cpp bufferview.cpp bufferviewwidget.cpp bufferviewfilter.cpp style.cpp settingsdlg.cpp settingspages.cpp) SET(qtgui_HDRS style.h) -SET(qtgui_MOCS chatwidget.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h +SET(qtgui_MOCS chatwidget.h chatline.h channelwidgetinput.h tabcompleter.h mainwin.h serverlist.h identities.h coreconnectdlg.h bufferview.h bufferwidget.h bufferviewwidget.h bufferviewfilter.h settingsdlg.h settingspages.h) SET(qtgui_UICS identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui mainwin.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui bufferviewwidget.ui bufferwidget.ui settingsdlg.ui buffermgmntsettingspage.ui connectionsettingspage.ui) -SET(client_SRCS ../client/client.cpp ../client/clientproxy.cpp ../client/buffer.cpp ../client/treemodel.cpp ../client/buffertreemodel.cpp) -SET(client_MOCS ../client/client.h ../client/clientproxy.h ../client/buffer.h ../client/treemodel.h ../client/buffertreemodel.h) - # This prepends ui/ to the UIC names, so we don't have to do this ourselves. FOREACH(ui ${qtgui_UICS}) SET(qtgui_UICS_UI ${qtgui_UICS_UI} "ui/${ui}") ENDFOREACH(ui) QT4_WRAP_UI(_UIC ${qtgui_UICS_UI}) -QT4_WRAP_CPP(_MOC ${qtgui_MOCS} ${client_MOCS}) +QT4_WRAP_CPP(_MOC ${qtgui_MOCS}) # We need to work around a dependency bug with out-of-source builds... # Seems to be fixed! #SET_SOURCE_FILES_PROPERTIES(${gui_SRCS} PROPERTIES OBJECT_DEPENDS "${_UIC}") -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} client) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) -ADD_LIBRARY(qtgui ${qtgui_HDRS} ${qtgui_SRCS} ${client_SRCS} ${_MOC} ${_UIC}) +ADD_LIBRARY(qtgui ${qtgui_HDRS} ${qtgui_SRCS} ${_MOC} ${_UIC}) diff --git a/src/qtgui/bufferviewfilter.h b/src/qtgui/bufferviewfilter.h index 36c07078..8bce1439 100644 --- a/src/qtgui/bufferviewfilter.h +++ b/src/qtgui/bufferviewfilter.h @@ -22,6 +22,7 @@ #define _BUFFERVIEWFILTER_H_ #include +#include #include "buffer.h" #include "buffertreemodel.h" diff --git a/src/qtgui/bufferwidget.cpp b/src/qtgui/bufferwidget.cpp index 807dacf1..f1a8946c 100644 --- a/src/qtgui/bufferwidget.cpp +++ b/src/qtgui/bufferwidget.cpp @@ -20,18 +20,13 @@ #include "bufferwidget.h" #include "buffer.h" +#include "chatline.h" #include "chatwidget.h" #include "settings.h" -#include "mainwin.h" BufferWidget::BufferWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); - //layoutThread->start(); - //connect(this, SIGNAL(aboutToClose()), layoutThread, SLOT(quit())); - //connect(this, SIGNAL(layoutMessages(LayoutTask)), layoutThread, SLOT(processTask(LayoutTask)), Qt::QueuedConnection); - //layoutThread->start(); - curBuf = 0; //setBaseSize(QSize(600,400)); //setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -41,17 +36,10 @@ BufferWidget::BufferWidget(QWidget *parent) : QWidget(parent) { } void BufferWidget::init() { - //layoutThread = new LayoutThread(); - //layoutThread = ::layoutThread; - //connect(layoutThread, SIGNAL(taskProcessed(LayoutTask)), this, SLOT(messagesLayouted(LayoutTask))); - //layoutThread->start(); - //while(!layoutThread->isRunning()) {}; + } BufferWidget::~BufferWidget() { - //emit aboutToClose(); - //layoutThread->wait(10000); - //delete layoutThread; foreach(BufferState *s, states.values()) { delete s; } @@ -93,9 +81,14 @@ void BufferWidget::setBuffer(Buffer *buf) { states[buf] = s; state = s; state->chatWidget->init(networkName, bufferName); - state->chatWidget->setContents(buf->contents()); - connect(buf, SIGNAL(chatLineAppended(ChatLine *)), state->chatWidget, SLOT(appendChatLine(ChatLine *))); - connect(buf, SIGNAL(chatLinePrepended(ChatLine *)), state->chatWidget, SLOT(prependChatLine(ChatLine *))); + QList lines; + QList msgs = buf->contents(); + foreach(AbstractUiMsg *msg, msgs) { + lines.append(dynamic_cast(msg)); + } + state->chatWidget->setContents(lines); + connect(buf, SIGNAL(msgAppended(AbstractUiMsg *)), state->chatWidget, SLOT(appendMsg(AbstractUiMsg *))); + connect(buf, SIGNAL(msgPrepended(AbstractUiMsg *)), state->chatWidget, SLOT(prependMsg(AbstractUiMsg *))); connect(buf, SIGNAL(topicSet(QString)), this, SLOT(setTopic(QString))); connect(buf, SIGNAL(ownNickSet(QString)), this, SLOT(setOwnNick(QString))); ui.stackedWidget->addWidget(s->page); @@ -116,28 +109,6 @@ void BufferWidget::setBuffer(Buffer *buf) { updateTitle(); } -/* -void BufferWidget::prependMessages(Buffer *buf, QList messages) { - LayoutTask task; - task.messages = messages; - task.buffer = buf; - task.net = buf->networkName(); - task.buf = buf->bufferName(); - //emit layoutMessages(task); - layoutThread->processTask(task); -} - -void BufferWidget::messagesLayouted(LayoutTask task) { - if(states.contains(task.buffer)) { - states[task.buffer]->chatWidget->prependChatLines(task.lines); - task.buffer->prependMessages(task.messages); - } else { - msgCache[task.buffer] = task.messages + msgCache[task.buffer]; - chatLineCache[task.buffer] = task.lines + chatLineCache[task.buffer]; - } -} -*/ - void BufferWidget::saveState() { foreach(Buffer *buf, states.keys()) { BufferState *s = states[buf]; diff --git a/src/qtgui/chatline.cpp b/src/qtgui/chatline.cpp new file mode 100644 index 00000000..5d828c1f --- /dev/null +++ b/src/qtgui/chatline.cpp @@ -0,0 +1,408 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel IRC Development Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "chatline.h" + +//!\brief Construct a ChatLine object from a message. +/** + * \param m The message to be layouted and rendered + * \param net The network name + * \param buf The buffer name + */ +ChatLine::ChatLine(Message m) { + hght = 0; + //networkName = m.buffer.network(); + //bufferName = m.buffer.buffer(); + msg = m; + selectionMode = None; + formatMsg(msg); +} + +ChatLine::~ChatLine() { + +} + +void ChatLine::formatMsg(Message msg) { + QString user = userFromMask(msg.sender); + QString host = hostFromMask(msg.sender); + QString nick = nickFromMask(msg.sender); + QString text = Style::mircToInternal(msg.text); + QString networkName = msg.buffer.network(); + QString bufferName = msg.buffer.buffer(); + + QString c = tr("%DT[%1]").arg(msg.timeStamp.toLocalTime().toString("hh:mm:ss")); + QString s, t; + switch(msg.type) { + case Message::Plain: + s = tr("%DS<%1>").arg(nick); t = tr("%D0%1").arg(text); break; + case Message::Server: + s = tr("%Ds*"); t = tr("%Ds%1").arg(text); break; + case Message::Error: + s = tr("%De*"); t = tr("%De%1").arg(text); break; + case Message::Join: + s = tr("%Dj-->"); t = tr("%Dj%DN%DU%1%DU%DN %DH(%2@%3)%DH has joined %DC%DU%4%DU%DC").arg(nick, user, host, bufferName); break; + case Message::Part: + s = tr("%Dp<--"); t = tr("%Dp%DN%DU%1%DU%DN %DH(%2@%3)%DH has left %DC%DU%4%DU%DC").arg(nick, user, host, bufferName); + if(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text); + break; + case Message::Quit: + s = tr("%Dq<--"); t = tr("%Dq%DN%DU%1%DU%DN %DH(%2@%3)%DH has quit").arg(nick, user, host); + if(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text); + break; + case Message::Kick: + { s = tr("%Dk<-*"); + QString victim = text.section(" ", 0, 0); + //if(victim == ui.ownNick->currentText()) victim = tr("you"); + QString kickmsg = text.section(" ", 1); + t = tr("%Dk%DN%DU%1%DU%DN has kicked %DN%DU%2%DU%DN from %DC%DU%3%DU%DC").arg(nick).arg(victim).arg(bufferName); + if(!kickmsg.isEmpty()) t = QString("%1 (%2)").arg(t).arg(kickmsg); + } + break; + case Message::Nick: + s = tr("%Dr<->"); + if(nick == msg.text) t = tr("%DrYou are now known as %DN%1%DN").arg(msg.text); + else t = tr("%Dr%DN%1%DN is now known as %DN%DU%2%DU%DN").arg(nick, msg.text); + break; + case Message::Mode: + s = tr("%Dm***"); + if(nick.isEmpty()) t = tr("%DmUser mode: %DM%1%DM").arg(msg.text); + else t = tr("%DmMode %DM%1%DM by %DN%DU%2%DU%DN").arg(msg.text, nick); + break; + case Message::Action: + s = tr("%Da-*-"); + t = tr("%Da%DN%DU%1%DU%DN %2").arg(nick).arg(msg.text); + break; + default: + s = tr("%De%1").arg(msg.sender); + t = tr("%De[%1]").arg(msg.text); + } + QTextOption tsOption, senderOption, textOption; + tsFormatted = Style::internalToFormatted(c); + senderFormatted = Style::internalToFormatted(s); + textFormatted = Style::internalToFormatted(t); + precomputeLine(); +} + +QList ChatLine::calcFormatRanges(const Style::FormattedString &fs, QTextLayout::FormatRange additional) { + QList ranges; + QList formats = fs.formats; + formats.append(additional); + int cur = -1; + FormatRange range, lastrange; + for(int i = 0; i < fs.text.length(); i++) { + QTextCharFormat format; + foreach(QTextLayout::FormatRange f, formats) { + if(i >= f.start && i < f.start + f.length) format.merge(f.format); + } + if(cur < 0) { + range.start = 0; range.length = 1; range.format= format; + cur = 0; + } else { + if(format == range.format) range.length++; + else { + QFontMetrics metrics(range.format.font()); + range.height = metrics.lineSpacing(); + ranges.append(range); + range.start = i; range.length = 1; range.format = format; + cur++; + } + } + } + if(cur >= 0) { + QFontMetrics metrics(range.format.font()); + range.height = metrics.lineSpacing(); + ranges.append(range); + } + return ranges; +} + +void ChatLine::setSelection(SelectionMode mode, int start, int end) { + selectionMode = mode; + //tsFormat.clear(); senderFormat.clear(); textFormat.clear(); + QPalette pal = QApplication::palette(); + QTextLayout::FormatRange tsSel, senderSel, textSel; + switch (mode) { + case None: + tsFormat = calcFormatRanges(tsFormatted); + senderFormat = calcFormatRanges(senderFormatted); + textFormat = calcFormatRanges(textFormatted); + break; + case Partial: + selectionStart = qMin(start, end); selectionEnd = qMax(start, end); + textSel.format.setForeground(pal.brush(QPalette::HighlightedText)); + textSel.format.setBackground(pal.brush(QPalette::Highlight)); + textSel.start = selectionStart; + textSel.length = selectionEnd - selectionStart; + //textFormat.append(textSel); + textFormat = calcFormatRanges(textFormatted, textSel); + foreach(FormatRange fr, textFormat); + break; + case Full: + tsSel.format.setForeground(pal.brush(QPalette::HighlightedText)); + tsSel.format.setBackground(pal.brush(QPalette::Highlight)); + tsSel.start = 0; tsSel.length = tsFormatted.text.length(); + tsFormat = calcFormatRanges(tsFormatted, tsSel); + senderSel.format.setForeground(pal.brush(QPalette::HighlightedText)); + senderSel.format.setBackground(pal.brush(QPalette::Highlight)); + senderSel.start = 0; senderSel.length = senderFormatted.text.length(); + senderFormat = calcFormatRanges(senderFormatted, senderSel); + textSel.format.setForeground(pal.brush(QPalette::HighlightedText)); + textSel.format.setBackground(pal.brush(QPalette::Highlight)); + textSel.start = 0; textSel.length = textFormatted.text.length(); + textFormat = calcFormatRanges(textFormatted, textSel); + break; + } +} + +uint ChatLine::msgId() const { + return msg.buffer.uid(); +} + +BufferId ChatLine::bufferId() const { + return msg.buffer; +} + +QDateTime ChatLine::timeStamp() const { + return msg.timeStamp; +} + +QString ChatLine::sender() const { + return senderFormatted.text; +} + +QString ChatLine::text() const { + return textFormatted.text; +} + +bool ChatLine::isUrl(int c) const { + if(c < 0 || c >= charUrlIdx.count()) return false;; + return charUrlIdx[c] >= 0; +} + +QUrl ChatLine::getUrl(int c) const { + if(c < 0 || c >= charUrlIdx.count()) return QUrl(); + int i = charUrlIdx[c]; + if(i >= 0) return textFormatted.urls[i].url; + else return QUrl(); +} + +//!\brief Return the cursor position for the given coordinate pos. +/** + * \param pos The position relative to the ChatLine + * \return The cursor position, [or -3 for invalid,] or -2 for timestamp, or -1 for sender + */ +int ChatLine::posToCursor(QPointF pos) { + if(pos.x() < tsWidth + (int)Style::sepTsSender()/2) return -2; + qreal textStart = tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(); + if(pos.x() < textStart) return -1; + int x = (int)(pos.x() - textStart); + for(int l = lineLayouts.count() - 1; l >=0; l--) { + LineLayout line = lineLayouts[l]; + if(pos.y() >= line.y) { + int offset = charPos[line.start]; x += offset; + for(int i = line.start + line.length - 1; i >= line.start; i--) { + if((charPos[i] + charPos[i+1])/2 <= x) return i+1; // FIXME: Optimize this! + } + return line.start; + } + } +} + +void ChatLine::precomputeLine() { + tsFormat = calcFormatRanges(tsFormatted); + senderFormat = calcFormatRanges(senderFormatted); + textFormat = calcFormatRanges(textFormatted); + + minHeight = 0; + foreach(FormatRange fr, tsFormat) minHeight = qMax(minHeight, fr.height); + foreach(FormatRange fr, senderFormat) minHeight = qMax(minHeight, fr.height); + + words.clear(); + charPos.resize(textFormatted.text.length() + 1); + charHeights.resize(textFormatted.text.length()); + charUrlIdx.fill(-1, textFormatted.text.length()); + for(int i = 0; i < textFormatted.urls.count(); i++) { + Style::UrlInfo url = textFormatted.urls[i]; + for(int j = url.start; j < url.end; j++) charUrlIdx[j] = i; + } + if(!textFormat.count()) return; + int idx = 0; int cnt = 0; int w = 0; int h = 0; + QFontMetrics metrics(textFormat[0].format.font()); + Word wr; + wr.start = -1; wr.trailing = -1; + for(int i = 0; i < textFormatted.text.length(); ) { + charPos[i] = w; charHeights[i] = textFormat[idx].height; + w += metrics.charWidth(textFormatted.text, i); + if(!textFormatted.text[i].isSpace()) { + if(wr.trailing >= 0) { + // new word after space + words.append(wr); + wr.start = -1; + } + if(wr.start < 0) { + wr.start = i; wr.length = 1; wr.trailing = -1; wr.height = textFormat[idx].height; + } else { + wr.length++; wr.height = qMax(wr.height, textFormat[idx].height); + } + } else { + if(wr.start < 0) { + wr.start = i; wr.length = 0; wr.trailing = 1; wr.height = 0; + } else { + wr.trailing++; + } + } + if(++i < textFormatted.text.length() && ++cnt >= textFormat[idx].length) { + cnt = 0; idx++; + Q_ASSERT(idx < textFormat.count()); + metrics = QFontMetrics(textFormat[idx].format.font()); + } + } + charPos[textFormatted.text.length()] = w; + if(wr.start >= 0) words.append(wr); +} + +qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) { + tsWidth = tsw; senderWidth = senderw; textWidth = textw; + if(textw <= 0) return minHeight; + lineLayouts.clear(); LineLayout line; + int h = 0; + int offset = 0; int numWords = 0; + line.y = 0; + line.start = 0; + line.height = minHeight; // first line needs room for ts and sender + for(int i = 0; i < words.count(); i++) { + int lastpos = charPos[words[i].start + words[i].length]; // We use charPos[lastchar + 1], 'coz last char needs to fit + if(lastpos - offset <= textw) { + line.height = qMax(line.height, words[i].height); + line.length = words[i].start + words[i].length - line.start; + numWords++; + } else { + // we need to wrap! + if(numWords > 0) { + // ok, we had some words before, so store the layout and start a new line + h += line.height; + line.length = words[i-1].start + words[i-1].length - line.start; + lineLayouts.append(line); + line.y += line.height; + line.start = words[i].start; + line.height = words[i].height; + offset = charPos[words[i].start]; + } + numWords = 1; + // check if the word fits into the current line + if(lastpos - offset <= textw) { + line.length = words[i].length; + } else { + // we need to break a word in the middle + int border = (int)textw + offset; // save some additions + line.start = words[i].start; + line.length = 1; + line.height = charHeights[line.start]; + int j = line.start + 1; + for(int l = 1; l < words[i].length; j++, l++) { + if(charPos[j+1] < border) { + line.length++; + line.height = qMax(line.height, charHeights[j]); + continue; + } else { + h += line.height; + lineLayouts.append(line); + line.y += line.height; + line.start = j; + line.height = charHeights[j]; + line.length = 1; + offset = charPos[j]; + border = (int)textw + offset; + } + } + } + } + } + h += line.height; + if(numWords > 0) { + lineLayouts.append(line); + } + hght = h; + return hght; +} + +//!\brief Draw ChatLine on the given QPainter at the given position. +void ChatLine::draw(QPainter *p, const QPointF &pos) { + QPalette pal = QApplication::palette(); + + if(selectionMode == Full) { + p->setPen(Qt::NoPen); + p->setBrush(pal.brush(QPalette::Highlight)); + p->drawRect(QRectF(pos, QSizeF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText() + textWidth, height()))); + } else if(selectionMode == Partial) { + + } /* + p->setClipRect(QRectF(pos, QSizeF(tsWidth, height()))); + tsLayout.draw(p, pos, tsFormat); + p->setClipRect(QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, height()))); + senderLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender(), 0), senderFormat); + p->setClipping(false); + textLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0), textFormat); + */ + //p->setClipRect(QRectF(pos, QSizeF(tsWidth, 15))); + //p->drawRect(QRectF(pos, QSizeF(tsWidth, minHeight))); + p->setBackgroundMode(Qt::OpaqueMode); + QPointF tp = pos; + QRectF rect(pos, QSizeF(tsWidth, minHeight)); + QRectF brect; + foreach(FormatRange fr, tsFormat) { + p->setFont(fr.format.font()); + p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); + p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, tsFormatted.text.mid(fr.start, fr.length), &brect); + rect.setLeft(brect.right()); + } + rect = QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, minHeight)); + for(int i = senderFormat.count() - 1; i >= 0; i--) { + FormatRange fr = senderFormat[i]; + p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); + p->drawText(rect, Qt::AlignRight|Qt::TextSingleLine, senderFormatted.text.mid(fr.start, fr.length), &brect); + rect.setRight(brect.left()); + } + QPointF tpos = pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0); + qreal h = 0; int l = 0; + rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height)); + int offset = 0; + foreach(FormatRange fr, textFormat) { + if(l >= lineLayouts.count()) break; + p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); + int start, end, frend, llend; + do { + frend = fr.start + fr.length; + if(frend <= lineLayouts[l].start) break; + llend = lineLayouts[l].start + lineLayouts[l].length; + start = qMax(fr.start, lineLayouts[l].start); end = qMin(frend, llend); + rect.setLeft(tpos.x() + charPos[start] - offset); + p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, textFormatted.text.mid(start, end - start), &brect); + if(llend <= end) { + h += lineLayouts[l].height; + l++; + if(l < lineLayouts.count()) { + rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height)); + offset = charPos[lineLayouts[l].start]; + } + } + } while(end < frend && l < lineLayouts.count()); + } +} diff --git a/src/qtgui/chatline.h b/src/qtgui/chatline.h new file mode 100644 index 00000000..b42982c8 --- /dev/null +++ b/src/qtgui/chatline.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2005-07 by The Quassel IRC Development Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _CHATLINE_H_ +#define _CHATLINE_H_ + +#include + +#include "util.h" +#include "style.h" +#include "quasselui.h" + +//FIXME: chatline doku +//!\brief Containing the layout and providing the rendering of a single message. +/** A ChatLine takes a Message object, + * formats it (by turning the various message types into a human-readable form and afterwards pumping it through + * our Style engine), and stores it as a number of QTextLayouts representing the three fields of a chat line + * (timestamp, sender and text). These layouts already include any rendering information such as font, + * color, or selected characters. By calling layout(), they can be quickly layouted to fit a given set of field widths. + * Afterwards, they can quickly be painted whenever necessary. + * + * By separating the complex and slow task of interpreting and formatting Message objects (which happens exactly once + * per message) from the actual layouting and painting, we gain a lot of speed compared to the standard Qt rendering + * functions. + */ +class ChatLine : public QObject, public AbstractUiMsg { + Q_OBJECT + + public: + ChatLine(Message message); + virtual ~ChatLine(); + + qreal layout(qreal tsWidth, qreal nickWidth, qreal textWidth); + qreal height() const { return hght; } + int posToCursor(QPointF pos); + void draw(QPainter *p, const QPointF &pos); + + enum SelectionMode { None, Partial, Full }; + void setSelection(SelectionMode, int start = 0, int end = 0); + + QDateTime timeStamp() const; + QString sender() const; + QString text() const; + MsgId msgId() const; + BufferId bufferId() const; + + bool isUrl(int pos) const; + QUrl getUrl(int pos) const; + + public slots: + + private: + qreal hght; + Message msg; + qreal tsWidth, senderWidth, textWidth; + Style::FormattedString tsFormatted, senderFormatted, textFormatted; + + struct FormatRange { + int start; + int length; + int height; + QTextCharFormat format; + }; + struct Word { + int start; + int length; + int trailing; + int height; + }; + struct LineLayout { + int y; + int height; + int start; + int length; + }; + QVector charPos; + QVector charWidths; + QVector charHeights; + QVector charUrlIdx; + QList tsFormat, senderFormat, textFormat; + QList words; + QList lineLayouts; + int minHeight; + + SelectionMode selectionMode; + int selectionStart, selectionEnd; + void formatMsg(Message); + void precomputeLine(); + QList calcFormatRanges(const Style::FormattedString &, QTextLayout::FormatRange additional = QTextLayout::FormatRange()); +}; + +#endif diff --git a/src/qtgui/chatwidget.cpp b/src/qtgui/chatwidget.cpp index 51ab625c..d67eb9ef 100644 --- a/src/qtgui/chatwidget.cpp +++ b/src/qtgui/chatwidget.cpp @@ -21,8 +21,8 @@ #include "util.h" #include "style.h" #include "chatwidget.h" -#include -#include +#include "chatline.h" + ChatWidget::ChatWidget(QWidget *parent) : QAbstractScrollArea(parent) { scrollTimer = new QTimer(this); @@ -140,6 +140,12 @@ void ChatWidget::clear() { //contents->clear(); } +void ChatWidget::prependMsg(AbstractUiMsg *msg) { + ChatLine *line = dynamic_cast(msg); + Q_ASSERT(line); + prependChatLine(line); +} + void ChatWidget::prependChatLine(ChatLine *line) { qreal h = line->layout(tsWidth, senderWidth, textWidth); for(int i = 1; i < ycoords.count(); i++) ycoords[i] += h; @@ -181,6 +187,11 @@ void ChatWidget::prependChatLines(QList clist) { viewport()->update(); } +void ChatWidget::appendMsg(AbstractUiMsg *msg) { + ChatLine *line = dynamic_cast(msg); + Q_ASSERT(line); + appendChatLine(line); +} void ChatWidget::appendChatLine(ChatLine *line) { qreal h = line->layout(tsWidth, senderWidth, textWidth); @@ -193,6 +204,7 @@ void ChatWidget::appendChatLine(ChatLine *line) { viewport()->update(); } + void ChatWidget::appendChatLines(QList list) { foreach(ChatLine *line, list) { qreal h = line->layout(tsWidth, senderWidth, textWidth); @@ -525,392 +537,6 @@ QString ChatWidget::selectionToString() { /************************************************************************************/ -//!\brief Construct a ChatLine object from a message. -/** - * \param m The message to be layouted and rendered - * \param net The network name - * \param buf The buffer name - */ -ChatLine::ChatLine(Message m) : QObject() { - hght = 0; - //networkName = m.buffer.network(); - //bufferName = m.buffer.buffer(); - msg = m; - selectionMode = None; - formatMsg(msg); -} - -ChatLine::~ChatLine() { - -} - -void ChatLine::formatMsg(Message msg) { - QString user = userFromMask(msg.sender); - QString host = hostFromMask(msg.sender); - QString nick = nickFromMask(msg.sender); - QString text = Style::mircToInternal(msg.text); - QString networkName = msg.buffer.network(); - QString bufferName = msg.buffer.buffer(); - - QString c = tr("%DT[%1]").arg(msg.timeStamp.toLocalTime().toString("hh:mm:ss")); - QString s, t; - switch(msg.type) { - case Message::Plain: - s = tr("%DS<%1>").arg(nick); t = tr("%D0%1").arg(text); break; - case Message::Server: - s = tr("%Ds*"); t = tr("%Ds%1").arg(text); break; - case Message::Error: - s = tr("%De*"); t = tr("%De%1").arg(text); break; - case Message::Join: - s = tr("%Dj-->"); t = tr("%Dj%DN%DU%1%DU%DN %DH(%2@%3)%DH has joined %DC%DU%4%DU%DC").arg(nick, user, host, bufferName); break; - case Message::Part: - s = tr("%Dp<--"); t = tr("%Dp%DN%DU%1%DU%DN %DH(%2@%3)%DH has left %DC%DU%4%DU%DC").arg(nick, user, host, bufferName); - if(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text); - break; - case Message::Quit: - s = tr("%Dq<--"); t = tr("%Dq%DN%DU%1%DU%DN %DH(%2@%3)%DH has quit").arg(nick, user, host); - if(!text.isEmpty()) t = QString("%1 (%2)").arg(t).arg(text); - break; - case Message::Kick: - { s = tr("%Dk<-*"); - QString victim = text.section(" ", 0, 0); - //if(victim == ui.ownNick->currentText()) victim = tr("you"); - QString kickmsg = text.section(" ", 1); - t = tr("%Dk%DN%DU%1%DU%DN has kicked %DN%DU%2%DU%DN from %DC%DU%3%DU%DC").arg(nick).arg(victim).arg(bufferName); - if(!kickmsg.isEmpty()) t = QString("%1 (%2)").arg(t).arg(kickmsg); - } - break; - case Message::Nick: - s = tr("%Dr<->"); - if(nick == msg.text) t = tr("%DrYou are now known as %DN%1%DN").arg(msg.text); - else t = tr("%Dr%DN%1%DN is now known as %DN%DU%2%DU%DN").arg(nick, msg.text); - break; - case Message::Mode: - s = tr("%Dm***"); - if(nick.isEmpty()) t = tr("%DmUser mode: %DM%1%DM").arg(msg.text); - else t = tr("%DmMode %DM%1%DM by %DN%DU%2%DU%DN").arg(msg.text, nick); - break; - case Message::Action: - s = tr("%Da-*-"); - t = tr("%Da%DN%DU%1%DU%DN %2").arg(nick).arg(msg.text); - break; - default: - s = tr("%De%1").arg(msg.sender); - t = tr("%De[%1]").arg(msg.text); - } - QTextOption tsOption, senderOption, textOption; - tsFormatted = Style::internalToFormatted(c); - senderFormatted = Style::internalToFormatted(s); - textFormatted = Style::internalToFormatted(t); - precomputeLine(); -} - -QList ChatLine::calcFormatRanges(const Style::FormattedString &fs, QTextLayout::FormatRange additional) { - QList ranges; - QList formats = fs.formats; - formats.append(additional); - int cur = -1; - FormatRange range, lastrange; - for(int i = 0; i < fs.text.length(); i++) { - QTextCharFormat format; - foreach(QTextLayout::FormatRange f, formats) { - if(i >= f.start && i < f.start + f.length) format.merge(f.format); - } - if(cur < 0) { - range.start = 0; range.length = 1; range.format= format; - cur = 0; - } else { - if(format == range.format) range.length++; - else { - QFontMetrics metrics(range.format.font()); - range.height = metrics.lineSpacing(); - ranges.append(range); - range.start = i; range.length = 1; range.format = format; - cur++; - } - } - } - if(cur >= 0) { - QFontMetrics metrics(range.format.font()); - range.height = metrics.lineSpacing(); - ranges.append(range); - } - return ranges; -} - -void ChatLine::setSelection(SelectionMode mode, int start, int end) { - selectionMode = mode; - //tsFormat.clear(); senderFormat.clear(); textFormat.clear(); - QPalette pal = QApplication::palette(); - QTextLayout::FormatRange tsSel, senderSel, textSel; - switch (mode) { - case None: - tsFormat = calcFormatRanges(tsFormatted); - senderFormat = calcFormatRanges(senderFormatted); - textFormat = calcFormatRanges(textFormatted); - break; - case Partial: - selectionStart = qMin(start, end); selectionEnd = qMax(start, end); - textSel.format.setForeground(pal.brush(QPalette::HighlightedText)); - textSel.format.setBackground(pal.brush(QPalette::Highlight)); - textSel.start = selectionStart; - textSel.length = selectionEnd - selectionStart; - //textFormat.append(textSel); - textFormat = calcFormatRanges(textFormatted, textSel); - foreach(FormatRange fr, textFormat); - break; - case Full: - tsSel.format.setForeground(pal.brush(QPalette::HighlightedText)); - tsSel.format.setBackground(pal.brush(QPalette::Highlight)); - tsSel.start = 0; tsSel.length = tsFormatted.text.length(); - tsFormat = calcFormatRanges(tsFormatted, tsSel); - senderSel.format.setForeground(pal.brush(QPalette::HighlightedText)); - senderSel.format.setBackground(pal.brush(QPalette::Highlight)); - senderSel.start = 0; senderSel.length = senderFormatted.text.length(); - senderFormat = calcFormatRanges(senderFormatted, senderSel); - textSel.format.setForeground(pal.brush(QPalette::HighlightedText)); - textSel.format.setBackground(pal.brush(QPalette::Highlight)); - textSel.start = 0; textSel.length = textFormatted.text.length(); - textFormat = calcFormatRanges(textFormatted, textSel); - break; - } -} - -uint ChatLine::msgId() { - return msg.buffer.uid(); -} - -BufferId ChatLine::bufferId() { - return msg.buffer; -} - -QDateTime ChatLine::timeStamp() { - return msg.timeStamp; -} - -QString ChatLine::sender() { - return senderFormatted.text; -} - -QString ChatLine::text() { - return textFormatted.text; -} - -bool ChatLine::isUrl(int c) { - if(c < 0 || c >= charUrlIdx.count()) return false;; - return charUrlIdx[c] >= 0; -} - -QUrl ChatLine::getUrl(int c) { - if(c < 0 || c >= charUrlIdx.count()) return QUrl(); - int i = charUrlIdx[c]; - if(i >= 0) return textFormatted.urls[i].url; - else return QUrl(); -} - -//!\brief Return the cursor position for the given coordinate pos. -/** - * \param pos The position relative to the ChatLine - * \return The cursor position, [or -3 for invalid,] or -2 for timestamp, or -1 for sender - */ -int ChatLine::posToCursor(QPointF pos) { - if(pos.x() < tsWidth + (int)Style::sepTsSender()/2) return -2; - qreal textStart = tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(); - if(pos.x() < textStart) return -1; - int x = (int)(pos.x() - textStart); - for(int l = lineLayouts.count() - 1; l >=0; l--) { - LineLayout line = lineLayouts[l]; - if(pos.y() >= line.y) { - int offset = charPos[line.start]; x += offset; - for(int i = line.start + line.length - 1; i >= line.start; i--) { - if((charPos[i] + charPos[i+1])/2 <= x) return i+1; // FIXME: Optimize this! - } - return line.start; - } - } -} - -void ChatLine::precomputeLine() { - tsFormat = calcFormatRanges(tsFormatted); - senderFormat = calcFormatRanges(senderFormatted); - textFormat = calcFormatRanges(textFormatted); - - minHeight = 0; - foreach(FormatRange fr, tsFormat) minHeight = qMax(minHeight, fr.height); - foreach(FormatRange fr, senderFormat) minHeight = qMax(minHeight, fr.height); - - words.clear(); - charPos.resize(textFormatted.text.length() + 1); - charHeights.resize(textFormatted.text.length()); - charUrlIdx.fill(-1, textFormatted.text.length()); - for(int i = 0; i < textFormatted.urls.count(); i++) { - Style::UrlInfo url = textFormatted.urls[i]; - for(int j = url.start; j < url.end; j++) charUrlIdx[j] = i; - } - if(!textFormat.count()) return; - int idx = 0; int cnt = 0; int w = 0; int h = 0; - QFontMetrics metrics(textFormat[0].format.font()); - Word wr; - wr.start = -1; wr.trailing = -1; - for(int i = 0; i < textFormatted.text.length(); ) { - charPos[i] = w; charHeights[i] = textFormat[idx].height; - w += metrics.charWidth(textFormatted.text, i); - if(!textFormatted.text[i].isSpace()) { - if(wr.trailing >= 0) { - // new word after space - words.append(wr); - wr.start = -1; - } - if(wr.start < 0) { - wr.start = i; wr.length = 1; wr.trailing = -1; wr.height = textFormat[idx].height; - } else { - wr.length++; wr.height = qMax(wr.height, textFormat[idx].height); - } - } else { - if(wr.start < 0) { - wr.start = i; wr.length = 0; wr.trailing = 1; wr.height = 0; - } else { - wr.trailing++; - } - } - if(++i < textFormatted.text.length() && ++cnt >= textFormat[idx].length) { - cnt = 0; idx++; - Q_ASSERT(idx < textFormat.count()); - metrics = QFontMetrics(textFormat[idx].format.font()); - } - } - charPos[textFormatted.text.length()] = w; - if(wr.start >= 0) words.append(wr); -} - -qreal ChatLine::layout(qreal tsw, qreal senderw, qreal textw) { - tsWidth = tsw; senderWidth = senderw; textWidth = textw; - if(textw <= 0) return minHeight; - lineLayouts.clear(); LineLayout line; - int h = 0; - int offset = 0; int numWords = 0; - line.y = 0; - line.start = 0; - line.height = minHeight; // first line needs room for ts and sender - for(int i = 0; i < words.count(); i++) { - int lastpos = charPos[words[i].start + words[i].length]; // We use charPos[lastchar + 1], 'coz last char needs to fit - if(lastpos - offset <= textw) { - line.height = qMax(line.height, words[i].height); - line.length = words[i].start + words[i].length - line.start; - numWords++; - } else { - // we need to wrap! - if(numWords > 0) { - // ok, we had some words before, so store the layout and start a new line - h += line.height; - line.length = words[i-1].start + words[i-1].length - line.start; - lineLayouts.append(line); - line.y += line.height; - line.start = words[i].start; - line.height = words[i].height; - offset = charPos[words[i].start]; - } - numWords = 1; - // check if the word fits into the current line - if(lastpos - offset <= textw) { - line.length = words[i].length; - } else { - // we need to break a word in the middle - int border = (int)textw + offset; // save some additions - line.start = words[i].start; - line.length = 1; - line.height = charHeights[line.start]; - int j = line.start + 1; - for(int l = 1; l < words[i].length; j++, l++) { - if(charPos[j+1] < border) { - line.length++; - line.height = qMax(line.height, charHeights[j]); - continue; - } else { - h += line.height; - lineLayouts.append(line); - line.y += line.height; - line.start = j; - line.height = charHeights[j]; - line.length = 1; - offset = charPos[j]; - border = (int)textw + offset; - } - } - } - } - } - h += line.height; - if(numWords > 0) { - lineLayouts.append(line); - } - hght = h; - return hght; -} - -//!\brief Draw ChatLine on the given QPainter at the given position. -void ChatLine::draw(QPainter *p, const QPointF &pos) { - QPalette pal = QApplication::palette(); - - if(selectionMode == Full) { - p->setPen(Qt::NoPen); - p->setBrush(pal.brush(QPalette::Highlight)); - p->drawRect(QRectF(pos, QSizeF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText() + textWidth, height()))); - } else if(selectionMode == Partial) { - - } /* - p->setClipRect(QRectF(pos, QSizeF(tsWidth, height()))); - tsLayout.draw(p, pos, tsFormat); - p->setClipRect(QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, height()))); - senderLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender(), 0), senderFormat); - p->setClipping(false); - textLayout.draw(p, pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0), textFormat); - */ - //p->setClipRect(QRectF(pos, QSizeF(tsWidth, 15))); - //p->drawRect(QRectF(pos, QSizeF(tsWidth, minHeight))); - p->setBackgroundMode(Qt::OpaqueMode); - QPointF tp = pos; - QRectF rect(pos, QSizeF(tsWidth, minHeight)); - QRectF brect; - foreach(FormatRange fr, tsFormat) { - p->setFont(fr.format.font()); - p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); - p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, tsFormatted.text.mid(fr.start, fr.length), &brect); - rect.setLeft(brect.right()); - } - rect = QRectF(pos + QPointF(tsWidth + Style::sepTsSender(), 0), QSizeF(senderWidth, minHeight)); - for(int i = senderFormat.count() - 1; i >= 0; i--) { - FormatRange fr = senderFormat[i]; - p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); - p->drawText(rect, Qt::AlignRight|Qt::TextSingleLine, senderFormatted.text.mid(fr.start, fr.length), &brect); - rect.setRight(brect.left()); - } - QPointF tpos = pos + QPointF(tsWidth + Style::sepTsSender() + senderWidth + Style::sepSenderText(), 0); - qreal h = 0; int l = 0; - rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height)); - int offset = 0; - foreach(FormatRange fr, textFormat) { - if(l >= lineLayouts.count()) break; - p->setFont(fr.format.font()); p->setPen(QPen(fr.format.foreground(), 0)); p->setBackground(fr.format.background()); - int start, end, frend, llend; - do { - frend = fr.start + fr.length; - if(frend <= lineLayouts[l].start) break; - llend = lineLayouts[l].start + lineLayouts[l].length; - start = qMax(fr.start, lineLayouts[l].start); end = qMin(frend, llend); - rect.setLeft(tpos.x() + charPos[start] - offset); - p->drawText(rect, Qt::AlignLeft|Qt::TextSingleLine, textFormatted.text.mid(start, end - start), &brect); - if(llend <= end) { - h += lineLayouts[l].height; - l++; - if(l < lineLayouts.count()) { - rect = QRectF(tpos + QPointF(0, h), QSizeF(textWidth, lineLayouts[l].height)); - offset = charPos[lineLayouts[l].start]; - } - } - } while(end < frend && l < lineLayouts.count()); - } -} /******************************************************************************************************************/ diff --git a/src/qtgui/chatwidget.h b/src/qtgui/chatwidget.h index 2fdd8957..f15be23f 100644 --- a/src/qtgui/chatwidget.h +++ b/src/qtgui/chatwidget.h @@ -21,13 +21,14 @@ #ifndef _CHATWIDGET_H_ #define _CHATWIDGET_H_ -#include "style.h" -#include "message.h" -#include "buffer.h" -#include +//#include "style.h" +//#include "message.h" +//#include "buffer.h" +//#include #include class ChatLine; +class AbstractUiMsg; //!\brief Scroll area showing part of the chat messages for a given buffer. /** The contents of the scroll area, i.e. a widget of type ChatWidgetContents, @@ -52,6 +53,10 @@ class ChatWidget : public QAbstractScrollArea { public slots: void clear(); + + void prependMsg(AbstractUiMsg *); + void appendMsg(AbstractUiMsg *); + void prependChatLine(ChatLine *); void appendChatLine(ChatLine *); void prependChatLines(QList); @@ -118,115 +123,4 @@ class ChatWidget : public QAbstractScrollArea { }; -//FIXME: chatline doku -//!\brief Containing the layout and providing the rendering of a single message. -/** A ChatLine takes a Message object, - * formats it (by turning the various message types into a human-readable form and afterwards pumping it through - * our Style engine), and stores it as a number of QTextLayouts representing the three fields of a chat line - * (timestamp, sender and text). These layouts already include any rendering information such as font, - * color, or selected characters. By calling layout(), they can be quickly layouted to fit a given set of field widths. - * Afterwards, they can quickly be painted whenever necessary. - * - * By separating the complex and slow task of interpreting and formatting Message objects (which happens exactly once - * per message) from the actual layouting and painting, we gain a lot of speed compared to the standard Qt rendering - * functions. - */ -class ChatLine : public QObject { - Q_OBJECT - - public: - ChatLine(Message message); - ~ChatLine(); - - qreal layout(qreal tsWidth, qreal nickWidth, qreal textWidth); - qreal height() { return hght; } - int posToCursor(QPointF pos); - void draw(QPainter *p, const QPointF &pos); - - enum SelectionMode { None, Partial, Full }; - void setSelection(SelectionMode, int start = 0, int end = 0); - QDateTime timeStamp(); - QString sender(); - QString text(); - uint msgId(); - BufferId bufferId(); - - bool isUrl(int pos); - QUrl getUrl(int pos); - - public slots: - - private: - qreal hght; - Message msg; - qreal tsWidth, senderWidth, textWidth; - Style::FormattedString tsFormatted, senderFormatted, textFormatted; - - struct FormatRange { - int start; - int length; - int height; - QTextCharFormat format; - }; - struct Word { - int start; - int length; - int trailing; - int height; - }; - struct LineLayout { - int y; - int height; - int start; - int length; - }; - QVector charPos; - QVector charWidths; - QVector charHeights; - QVector charUrlIdx; - QList tsFormat, senderFormat, textFormat; - QList words; - QList lineLayouts; - int minHeight; - - SelectionMode selectionMode; - int selectionStart, selectionEnd; - void formatMsg(Message); - void precomputeLine(); - QList calcFormatRanges(const Style::FormattedString &, QTextLayout::FormatRange additional = QTextLayout::FormatRange()); -}; - -/* -struct LayoutTask { - QList messages; - Buffer *buffer; - QString net, buf; - QList lines; -}; - -Q_DECLARE_METATYPE(LayoutTask); - -class LayoutThread : public QThread { - Q_OBJECT - - public: - LayoutThread(); - virtual ~LayoutThread(); - virtual void run(); - - public: - void processTask(LayoutTask task); - - signals: - void taskProcessed(LayoutTask task); - - private: - QList queue; - QMutex mutex; - QWaitCondition condition; - bool abort; - -}; -*/ - #endif diff --git a/src/qtgui/mainwin.cpp b/src/qtgui/mainwin.cpp index 05cd7d3d..0ef57c18 100644 --- a/src/qtgui/mainwin.cpp +++ b/src/qtgui/mainwin.cpp @@ -30,6 +30,7 @@ #include "mainwin.h" #include "buffer.h" +#include "chatline.h" #include "serverlist.h" #include "coreconnectdlg.h" #include "settingsdlg.h" @@ -50,27 +51,6 @@ MainWin::MainWin() : QMainWindow() { } void MainWin::init() { -/* - connect(guiProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); - connect(guiProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); - connect(guiProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); - connect(guiProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(Message))); - connect(guiProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); - connect(guiProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); - connect(guiProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap))); - connect(guiProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); - connect(guiProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); - connect(guiProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap))); - connect(guiProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); - connect(guiProxy, SIGNAL(csBacklogData(BufferId, QList, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); - connect(guiProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId))); - connect(this, SIGNAL(sendInput(BufferId, QString)), guiProxy, SLOT(gsUserInput(BufferId, QString))); - connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), guiProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); - - //layoutThread = new LayoutThread(); - //layoutThread->start(); - //while(!layoutThread->isRunning()) {}; -*/ ui.bufferWidget->init(); show(); @@ -179,6 +159,10 @@ void MainWin::registerBufferViewDock(BufferViewDock *dock) { */ } +AbstractUiMsg *MainWin::layoutMsg(const Message &msg) { + return new ChatLine(msg); +} + void MainWin::showServerList() { // if(!serverListDlg) { // serverListDlg = new ServerListDlg(this); diff --git a/src/qtgui/mainwin.h b/src/qtgui/mainwin.h index d8936583..15852a82 100644 --- a/src/qtgui/mainwin.h +++ b/src/qtgui/mainwin.h @@ -24,7 +24,8 @@ #include #include "ui_mainwin.h" -#include "global.h" +#include "quasselui.h" +//#include "global.h" #include "message.h" #include "chatwidget.h" #include "bufferviewfilter.h" @@ -42,7 +43,7 @@ class SettingsDlg; * dockwidgets and of course the chat window, this class also stores all data it * receives from the core, and it maintains a list of all known nicks. */ -class MainWin : public QMainWindow { +class MainWin : public QMainWindow, public AbstractUi { Q_OBJECT public: @@ -52,36 +53,14 @@ class MainWin : public QMainWindow { void init(); void registerBufferViewDock(BufferViewDock *); + AbstractUiMsg *layoutMsg(const Message &); + protected: void closeEvent(QCloseEvent *event); - signals: - //void sendInput(BufferId, QString message); - //void bufferSelected(Buffer *); - //void bufferUpdated(Buffer *); - //void bufferActivity(Buffer::ActivityLevel, Buffer *); - //void bufferDestroyed(Buffer *); - //void backlogReceived(Buffer *, QList); - //void requestBacklog(BufferId, QVariant, QVariant); - - void importOldBacklog(); + //void importOldBacklog(); private slots: - - //void userInput(BufferId, QString); - //void networkConnected(QString); - //void networkDisconnected(QString); - //void recvNetworkState(QString, QVariant); - //void recvMessage(Message message); - //void recvStatusMsg(QString network, QString message); - //void setTopic(QString net, QString buf, QString); - //void addNick(QString net, QString nick, VarMap props); - //void removeNick(QString net, QString nick); - //void renameNick(QString net, QString oldnick, QString newnick); - //void updateNick(QString net, QString nick, VarMap props); - //void setOwnNick(QString net, QString nick); - //void recvBacklogData(BufferId, QList, bool); - //void updateBufferId(BufferId); void showServerList(); void showSettingsDlg(); @@ -91,43 +70,26 @@ class MainWin : public QMainWindow { void importBacklog(); + signals: + void importOldBacklog(); + private: Ui::MainWin ui; void setupMenus(); void setupViews(); void setupSettingsDlg(); - //void syncToCore(); // implemented in main_mono.cpp or main_gui.cpp - //Buffer * getBuffer(QString net, QString buf); - //Buffer *getBuffer(BufferId); - //BufferId getStatusBufferId(QString net); - //BufferId getBufferId(QString net, QString buf); - //void buffersUpdated(); QSystemTrayIcon *systray; - //QWorkspace *workspace; - //QWidget *widget; - //BufferWidget *bufferWidget; ServerListDlg *serverListDlg; CoreConnectDlg *coreConnectDlg; SettingsDlg *settingsDlg; - //QString currentNetwork, currentBuffer; - //QHash > buffers; uint currentBuffer; - //QHash buffers; - //QHash bufferIds; - //QHash > nicks; - //QHash connected; - //QHash ownNick; - //QHash > coreBackLog; - //QList coreBuffers; QList netViews; - //QTimer *layoutTimer; - //QList layoutQueue; }; #endif diff --git a/templates/cpp b/templates/cpp index 53f70707..9151cb79 100644 --- a/templates/cpp +++ b/templates/cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-07 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel IRC Development Team * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * diff --git a/templates/h b/templates/h index 21a1438d..2a25675a 100644 --- a/templates/h +++ b/templates/h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-07 by The Quassel Team * + * Copyright (C) 2005-07 by The Quassel IRC Development Team * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * -- 2.20.1