1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 by the Quassel Project * |
3 | * devel@quassel-irc.org * |
4 | * * |
5 | * This program is free software; you can redistribute it and/or modify * |
6 | * it under the terms of the GNU General Public License as published by * |
7 | * the Free Software Foundation; either version 2 of the License, or * |
8 | * (at your option) version 3. * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU General Public License * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
19 | ***************************************************************************/ |
20 | |
21 | #include "buffermodel.h" |
22 | |
23 | #include <QAbstractItemView> |
24 | |
25 | #include "client.h" |
26 | #include "networkmodel.h" |
27 | #include "quassel.h" |
28 | |
29 | BufferModel::BufferModel(NetworkModel *parent) |
30 | : QSortFilterProxyModel(parent), |
31 | _selectionModelSynchronizer(this) |
32 | { |
33 | setSourceModel(parent); |
34 | if (Quassel::isOptionSet("debugbufferswitches" )) { |
35 | connect(_selectionModelSynchronizer.selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), |
36 | this, SLOT(debug_currentChanged(const QModelIndex &, const QModelIndex &))); |
37 | } |
38 | connect(Client::instance(), SIGNAL(networkCreated(NetworkId)), this, SLOT(newNetwork(NetworkId))); |
39 | connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(newBuffers(const QModelIndex &, int, int))); |
40 | } |
41 | |
42 | |
43 | bool BufferModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const |
44 | { |
45 | Q_UNUSED(sourceRow); |
46 | // only networks and buffers are allowed |
47 | if (!parent.isValid()) |
48 | return true; |
49 | if (parent.data(NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType) |
50 | return true; |
51 | |
52 | return false; |
53 | } |
54 | |
55 | |
56 | void BufferModel::newNetwork(NetworkId id) |
57 | { |
58 | const Network *net = Client::network(id); |
59 | Q_ASSERT(net); |
60 | connect(net, SIGNAL(connectionStateSet(Network::ConnectionState)), |
61 | this, SLOT(networkConnectionChanged(Network::ConnectionState))); |
62 | } |
63 | |
64 | |
65 | void BufferModel::networkConnectionChanged(Network::ConnectionState state) |
66 | { |
67 | switch (state) { |
68 | case Network::Connecting: |
69 | case Network::Initializing: |
70 | if (currentIndex().isValid()) |
71 | return; |
72 | { |
73 | Network *net = qobject_cast<Network *>(sender()); |
74 | Q_ASSERT(net); |
75 | setCurrentIndex(mapFromSource(Client::networkModel()->networkIndex(net->networkId()))); |
76 | } |
77 | break; |
78 | default: |
79 | return; |
80 | } |
81 | } |
82 | |
83 | |
84 | void BufferModel::synchronizeView(QAbstractItemView *view) |
85 | { |
86 | _selectionModelSynchronizer.synchronizeSelectionModel(view->selectionModel()); |
87 | } |
88 | |
89 | |
90 | void BufferModel::setCurrentIndex(const QModelIndex &newCurrent) |
91 | { |
92 | _selectionModelSynchronizer.selectionModel()->setCurrentIndex(newCurrent, QItemSelectionModel::Current); |
93 | _selectionModelSynchronizer.selectionModel()->select(newCurrent, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); |
94 | } |
95 | |
96 | |
97 | void BufferModel::switchToBuffer(const BufferId &bufferId) |
98 | { |
99 | QModelIndex source_index = Client::networkModel()->bufferIndex(bufferId); |
100 | setCurrentIndex(mapFromSource(source_index)); |
101 | } |
102 | |
103 | |
104 | void BufferModel::switchToBufferIndex(const QModelIndex &bufferIdx) |
105 | { |
106 | // we accept indexes that directly belong to us or our parent - nothing else |
107 | if (bufferIdx.model() == this) { |
108 | setCurrentIndex(bufferIdx); |
109 | return; |
110 | } |
111 | |
112 | if (bufferIdx.model() == sourceModel()) { |
113 | setCurrentIndex(mapFromSource(bufferIdx)); |
114 | return; |
115 | } |
116 | |
117 | qWarning() << "BufferModel::switchToBufferIndex(const QModelIndex &):" << bufferIdx << "does not belong to BufferModel or NetworkModel" ; |
118 | } |
119 | |
120 | |
121 | void BufferModel::switchToOrJoinBuffer(NetworkId networkId, const QString &name, bool isQuery) |
122 | { |
123 | BufferId bufId = Client::networkModel()->bufferId(networkId, name); |
124 | if (bufId.isValid()) { |
125 | QModelIndex targetIdx = Client::networkModel()->bufferIndex(bufId); |
126 | switchToBuffer(bufId); |
127 | if (!targetIdx.data(NetworkModel::ItemActiveRole).toBool()) { |
128 | qDebug() << "switchToOrJoinBuffer failed to switch even though bufId:" << bufId << "is valid." ; |
129 | Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString(isQuery ? "/QUERY %1" : "/JOIN %1" ).arg(name)); |
130 | } |
131 | } |
132 | else { |
133 | _bufferToSwitchTo = qMakePair(networkId, name); |
134 | Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString(isQuery ? "/QUERY %1" : "/JOIN %1" ).arg(name)); |
135 | } |
136 | } |
137 | |
138 | |
139 | void BufferModel::debug_currentChanged(QModelIndex current, QModelIndex previous) |
140 | { |
141 | Q_UNUSED(previous); |
142 | qDebug() << "Switched current Buffer: " << current << current.data().toString() << "Buffer:" << current.data(NetworkModel::BufferIdRole).value<BufferId>(); |
143 | } |
144 | |
145 | |
146 | void BufferModel::newBuffers(const QModelIndex &parent, int start, int end) |
147 | { |
148 | if (parent.data(NetworkModel::ItemTypeRole) != NetworkModel::NetworkItemType) |
149 | return; |
150 | |
151 | for (int row = start; row <= end; row++) { |
152 | QModelIndex child = parent.child(row, 0); |
153 | newBuffer(child.data(NetworkModel::BufferIdRole).value<BufferId>()); |
154 | } |
155 | } |
156 | |
157 | |
158 | void BufferModel::newBuffer(BufferId bufferId) |
159 | { |
160 | BufferInfo bufferInfo = Client::networkModel()->bufferInfo(bufferId); |
161 | if (_bufferToSwitchTo.first == bufferInfo.networkId() |
162 | && _bufferToSwitchTo.second == bufferInfo.bufferName()) { |
163 | _bufferToSwitchTo.first = 0; |
164 | _bufferToSwitchTo.second.clear(); |
165 | switchToBuffer(bufferId); |
166 | } |
167 | } |
168 | |
169 | |
170 | void BufferModel::switchToBufferAfterCreation(NetworkId network, const QString &name) |
171 | { |
172 | _bufferToSwitchTo = qMakePair(network, name); |
173 | } |
174 | |