Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Message.h3
-rw-r--r--src/Mumble.proto8
-rw-r--r--src/mumble/AudioInput.cpp10
-rw-r--r--src/mumble/AudioOutput.cpp2
-rw-r--r--src/mumble/ConfigDialog.cpp1
-rw-r--r--src/mumble/Global.cpp2
-rw-r--r--src/mumble/Global.h2
-rw-r--r--src/mumble/GlobalShortcut.h1
-rw-r--r--src/mumble/GlobalShortcutTarget.ui2
-rw-r--r--src/mumble/MainWindow.cpp202
-rw-r--r--src/mumble/MainWindow.h15
-rw-r--r--src/mumble/Messages.cpp12
-rw-r--r--src/mumble/Settings.cpp35
-rw-r--r--src/mumble/Settings.h6
-rw-r--r--src/mumble/UserModel.cpp14
-rw-r--r--src/mumble/UserModel.h3
16 files changed, 232 insertions, 86 deletions
diff --git a/src/Message.h b/src/Message.h
index d45e9b890..2f4291c34 100644
--- a/src/Message.h
+++ b/src/Message.h
@@ -53,7 +53,8 @@
MUMBLE_MH_MSG(CryptSetup) \
MUMBLE_MH_MSG(ContextActionAdd) \
MUMBLE_MH_MSG(ContextAction) \
- MUMBLE_MH_MSG(UserList)
+ MUMBLE_MH_MSG(UserList) \
+ MUMBLE_MH_MSG(VoiceTarget)
class MessageHandler {
public:
diff --git a/src/Mumble.proto b/src/Mumble.proto
index ad8087790..c64417ff1 100644
--- a/src/Mumble.proto
+++ b/src/Mumble.proto
@@ -193,11 +193,11 @@ message UserList {
message VoiceTarget {
message Target {
- optional uint32 player_id = 1;
- optional uint32 channel = 2;
+ repeated uint32 session = 1;
+ optional uint32 channel_id = 2;
optional string group = 3;
- optional bool links = 4;
- optional bool children = 5;
+ optional bool links = 4 [default = false];
+ optional bool children = 5 [default = false];
}
optional uint32 id = 1;
repeated Target targets = 2;
diff --git a/src/mumble/AudioInput.cpp b/src/mumble/AudioInput.cpp
index 7f5e9ef9b..29f17cddc 100644
--- a/src/mumble/AudioInput.cpp
+++ b/src/mumble/AudioInput.cpp
@@ -631,9 +631,9 @@ void AudioInput::encodeAudioFrame() {
else if (g.s.atTransmit == Settings::PushToTalk)
iIsSpeech = g.s.uiDoublePush && ((g.uiDoublePush < g.s.uiDoublePush) || (g.tDoublePush.elapsed() < g.s.uiDoublePush));
- iIsSpeech = iIsSpeech || (g.iPushToTalk > 0) || (g.iAltSpeak > 0);
+ iIsSpeech = iIsSpeech || (g.iPushToTalk > 0);
- if (g.s.bMute || ((g.s.lmLoopMode != Settings::Local) && p && p->bMute) || g.bPushToMute) {
+ if (g.s.bMute || ((g.s.lmLoopMode != Settings::Local) && p && p->bMute) || g.bPushToMute || (g.iTarget < 0)) {
iIsSpeech = 0;
}
@@ -646,7 +646,7 @@ void AudioInput::encodeAudioFrame() {
}
if (p)
- p->setTalking(iIsSpeech, (g.iAltSpeak > 0));
+ p->setTalking(iIsSpeech, (g.iTarget != 0));
if (g.s.bPushClick && (g.s.atTransmit == Settings::PushToTalk)) {
AudioOutputPtr ao = g.ao;
@@ -685,11 +685,9 @@ void AudioInput::flushCheck(const QByteArray &qba) {
if (! qba.isEmpty() && qlFrames.count() < g.s.iFramesPerPacket)
return;
- int flags = 0;
+ int flags = g.iTarget;
if (g.s.lmLoopMode == Settings::Server)
flags = 0x1f;
- else if (g.iAltSpeak > 0)
- flags = 1;
char data[1024];
data[0] = static_cast<unsigned char>(flags);
diff --git a/src/mumble/AudioOutput.cpp b/src/mumble/AudioOutput.cpp
index 53c4cc01d..b7e8f8ccb 100644
--- a/src/mumble/AudioOutput.cpp
+++ b/src/mumble/AudioOutput.cpp
@@ -382,7 +382,7 @@ bool AudioOutputSpeech::needSamples(unsigned int snum) {
}
if (p)
- p->setTalking(bLastAlive, ((ucFlags == 1) ? true : false));
+ p->setTalking(bLastAlive, ((ucFlags != 0) ? true : false));
return bLastAlive;
}
diff --git a/src/mumble/ConfigDialog.cpp b/src/mumble/ConfigDialog.cpp
index e6781bf44..66bbfb1c2 100644
--- a/src/mumble/ConfigDialog.cpp
+++ b/src/mumble/ConfigDialog.cpp
@@ -244,7 +244,6 @@ void ConfigDialog::apply() {
// They might have changed their keys.
g.iPushToTalk = 0;
- g.iAltSpeak = 0;
}
void ConfigDialog::accept() {
diff --git a/src/mumble/Global.cpp b/src/mumble/Global.cpp
index 7a7b01585..2136b04a9 100644
--- a/src/mumble/Global.cpp
+++ b/src/mumble/Global.cpp
@@ -41,7 +41,7 @@ Global::Global() {
uiSession = 0;
uiDoublePush = 1000000;
iPushToTalk = 0;
- iAltSpeak = 0;
+ iTarget = 0;
bPushToMute = false;
bCenterPosition = false;
bEchoTest = false;
diff --git a/src/mumble/Global.h b/src/mumble/Global.h
index 64382ff96..594c2cea8 100644
--- a/src/mumble/Global.h
+++ b/src/mumble/Global.h
@@ -69,7 +69,7 @@ public:
int iPushToTalk;
Timer tDoublePush;
quint64 uiDoublePush;
- int iAltSpeak;
+ int iTarget;
bool bPushToMute;
bool bCenterPosition;
bool bEchoTest;
diff --git a/src/mumble/GlobalShortcut.h b/src/mumble/GlobalShortcut.h
index 8ba19a207..42c406cce 100644
--- a/src/mumble/GlobalShortcut.h
+++ b/src/mumble/GlobalShortcut.h
@@ -53,7 +53,6 @@ class GlobalShortcut : public QObject {
QString qsToolTip;
QString qsWhatsThis;
QString name;
- QVariant data;
QVariant qvDefault;
bool bExpert;
int idx;
diff --git a/src/mumble/GlobalShortcutTarget.ui b/src/mumble/GlobalShortcutTarget.ui
index 7aaa680a0..4225e26cd 100644
--- a/src/mumble/GlobalShortcutTarget.ui
+++ b/src/mumble/GlobalShortcutTarget.ui
@@ -24,7 +24,7 @@
<item row="2" column="0" colspan="2">
<widget class="QStackedWidget" name="qswStack">
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="qwChannelPage">
<layout class="QVBoxLayout" name="verticalLayout_2">
diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp
index e3afbbf1a..b15b572b3 100644
--- a/src/mumble/MainWindow.cpp
+++ b/src/mumble/MainWindow.cpp
@@ -187,22 +187,6 @@ void MainWindow::createActions() {
gsCenterPos=new GlobalShortcut(this, idx++, tr("Force Center Position", "Global Shortcut"));
gsCenterPos->setObjectName(QLatin1String("CenterPos"));
- GlobalShortcut *gs;
-
- gs = new GlobalShortcut(this, idx++, tr("Chan Parent", "Global Shortcut"));
- gs->data = 0;
- connect(gs, SIGNAL(triggered(bool, QVariant)), this, SLOT(pushLink(bool)));
-
- for (int i = 1; i< 10;i++) {
- gs = new GlobalShortcut(this, idx++, tr("Chan Sub#%1", "Global Shortcut").arg(i));
- gs->data = i;
- connect(gs, SIGNAL(triggered(bool, QVariant)), this, SLOT(pushLink(bool)));
- }
-
- gs = new GlobalShortcut(this, idx++, tr("Chan All Subs", "Global Shortcut"));
- gs->data = 10;
- connect(gs, SIGNAL(triggered(bool, QVariant)), this, SLOT(pushLink(bool)));
-
gsPushMute=new GlobalShortcut(this, idx++, tr("Push-to-Mute", "Global Shortcut"));
gsPushMute->setObjectName(QLatin1String("PushToMute"));
@@ -215,9 +199,6 @@ void MainWindow::createActions() {
gsToggleOverlay->qsWhatsThis = tr("This will switch the states of the in-game overlay between showing everybody, just the users who are talking, and nobody.", "Global Shortcut");
connect(gsToggleOverlay, SIGNAL(down(QVariant)), g.o, SLOT(toggleShow()));
- gsAltTalk=new GlobalShortcut(this, idx++, tr("Alt Push-to-Talk", "Global Shortcut"));
- gsAltTalk->setObjectName(QLatin1String("AltPushToTalk"));
-
gsMinimal=new GlobalShortcut(this, idx++, tr("Toggle Minimal", "Global Shortcut"));
gsMinimal->setObjectName(QLatin1String("ToggleMinimal"));
@@ -231,7 +212,8 @@ void MainWindow::createActions() {
qstiIcon->setToolTip(tr("Mumble"));
qstiIcon->setObjectName(QLatin1String("Icon"));
- gs = new GlobalShortcut(this, idx++, tr("Fudge it"), false, QVariant::fromValue(ShortcutTarget()));
+ gsWhisper = new GlobalShortcut(this, idx++, tr("Whisper"), false, QVariant::fromValue(ShortcutTarget()));
+ gsWhisper->setObjectName(QLatin1String("gsWhisper"));
#ifndef Q_OS_MAC
qstiIcon->show();
@@ -1373,24 +1355,13 @@ void MainWindow::on_PushToMute_triggered(bool down, QVariant) {
g.bPushToMute = down;
}
-void MainWindow::on_AltPushToTalk_triggered(bool down, QVariant) {
- if (down) {
- g.iAltSpeak++;
- g.iPushToTalk++;
- } else if (g.iPushToTalk) {
- g.iAltSpeak--;
- g.iPushToTalk--;
- }
-}
-
void MainWindow::on_CenterPos_triggered(bool down, QVariant) {
+ // TODO: Make this be a targetshortcut option
g.bCenterPosition = down;
if (down) {
- g.iAltSpeak++;
g.iPushToTalk++;
} else if (g.iPushToTalk) {
- g.iAltSpeak--;
g.iPushToTalk--;
}
}
@@ -1411,48 +1382,151 @@ void MainWindow::on_VolumeDown_triggered(bool down, QVariant) {
}
}
-void MainWindow::pushLink(bool down) {
- if (down) {
- g.iAltSpeak++;
- g.iPushToTalk++;
- } else if (g.iPushToTalk) {
- g.iAltSpeak--;
- g.iPushToTalk--;
- }
+Channel *MainWindow::mapChannel(int idx) const {
+ if (! g.uiSession)
+ return NULL;
- if (g.uiSession == 0)
- return;
+ Channel *c = NULL;
- GlobalShortcut *gs = qobject_cast<GlobalShortcut *>(sender());
- if (! gs)
- return;
- int idx = gs->data.toInt();
- Channel *home = ClientUser::get(g.uiSession)->cChannel;
+ if (idx < 0) {
+ switch (idx) {
+ case -1:
+ c = Channel::get(0);
+ break;
+ case -2:
+ case -3:
+ c = ClientUser::get(g.uiSession)->cChannel;
+ if (idx == -2)
+ c = c->cParent;
+ break;
+ default:
+ c = pmModel->getSubChannel(c, -4 - idx);
+ break;
+ }
+ } else {
+ c = Channel::get(idx);
+ }
+ return c;
+}
+
+void MainWindow::updateTarget() {
+ if (qsCurrentTargets.isEmpty())
+ g.iTarget = 0;
+ else {
+ QList<ShortcutTarget> ql;
+ foreach(const ShortcutTarget &st, qsCurrentTargets) {
+ ShortcutTarget nt;
+ nt.bUsers = st.bUsers;
+ if (st.bUsers) {
+ foreach(const QString &hash, st.qlUsers) {
+ ClientUser *p = pmModel->getUser(hash);
+ if (p)
+ nt.qlSessions.append(p->uiSession);
+ }
+ if (! nt.qlSessions.isEmpty())
+ ql << nt;
+ } else {
+ Channel *c = mapChannel(st.iChannel);
+ if (c) {
+ nt.bLinks = st.bLinks;
+ nt.bChildren = st.bChildren;
+ nt.iChannel = c->iId;
+ nt.qsGroup = st.qsGroup;
+ ql << nt;
+ }
+ }
+ }
+ if (ql.isEmpty()) {
+ g.iTarget = -1;
+ } else {
+ ++iTargetCounter;
+
+ int idx = qmTargets.value(ql);
+ if (idx == 0) {
+ QMap<int, int> qm;
+ QMap<int, int>::const_iterator i;
+ for(i=qmTargetUse.constBegin(); i != qmTargetUse.constEnd(); ++i) {
+ qm.insert(i.value(), i.key());
+ }
- Channel *target = NULL;
- switch (idx) {
- case 0:
- target = home->cParent;
- break;
- case 10:
- break;
- default:
- target = pmModel->getSubChannel(home, idx-1);
- break;
+ i = qm.constBegin();
+ idx = i.value();
+
+
+
+ MumbleProto::VoiceTarget mpvt;
+ mpvt.set_id(idx);
+
+ foreach(const ShortcutTarget &st, ql) {
+ MumbleProto::VoiceTarget_Target *t = mpvt.add_targets();
+ if (st.bUsers) {
+ foreach(unsigned int uisession, st.qlSessions)
+ t->add_session(uisession);
+ } else {
+ t->set_channel_id(st.iChannel);
+ if (st.bChildren)
+ t->set_children(true);
+ if (st.bLinks)
+ t->set_links(true);
+ if (! st.qsGroup.isEmpty())
+ t->set_group(u8(st.qsGroup));
+ }
+ }
+ g.sh->sendMessage(mpvt);
+
+ qmTargets.insert(ql, idx);
+
+ ++i;
+ ++i;
+ int oldidx = i.value();
+ if (oldidx) {
+ QHash<QList<ShortcutTarget>, int>::iterator mi;
+ for(mi = qmTargets.begin(); mi != qmTargets.end(); ++mi) {
+ if (mi.value() == oldidx) {
+ qmTargets.erase(mi);
+
+ mpvt.Clear();
+ mpvt.set_id(oldidx);
+ g.sh->sendMessage(mpvt);
+
+ break;
+ }
+ }
+ }
+ }
+ qmTargetUse.insert(idx, iTargetCounter);
+ g.iTarget = idx;
+ }
}
+}
+void MainWindow::on_gsWhisper_triggered(bool down, QVariant data) {
+ ShortcutTarget st = data.value<ShortcutTarget>();
- if (gsMetaChannel->active()) {
- if (! target || ! down)
- return;
- // FIXME: This was shortcut to move to a channel.
+ if (down) {
+ if (gsMetaChannel->active()) {
+ if (! st.bUsers) {
+ Channel *c = mapChannel(st.iChannel);
+ if (c) {
+ MumbleProto::UserState mpus;
+ mpus.set_session(g.uiSession);
+ mpus.set_channel_id(c->iId);
+ g.sh->sendMessage(mpus);
+ }
+ return;
+ }
+ }
- g.l->log(Log::Information, tr("Joining %1.").arg(target->qsName));
- } else {
+ qsCurrentTargets.insert(st);
+ updateTarget();
- // FIXME: This was shortcut to temp-link a channel. Replace with target.
+ g.iPushToTalk++;
+ } else if (g.iPushToTalk) {
+ qsCurrentTargets.remove(st);
+ updateTarget();
+ g.iPushToTalk--;
}
}
diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h
index 64a3ea917..28a58c2d4 100644
--- a/src/mumble/MainWindow.h
+++ b/src/mumble/MainWindow.h
@@ -43,6 +43,9 @@ class ServerHandler;
class GlobalShortcut;
class TextToSpeech;
class UserModel;
+class Channel;
+
+struct ShortcutTarget;
#include "Message.h"
#include "Usage.h"
@@ -85,7 +88,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
GlobalShortcut *gsPushTalk, *gsResetAudio, *gsMuteSelf, *gsDeafSelf;
GlobalShortcut *gsUnlink, *gsCenterPos, *gsPushMute, *gsMetaChannel, *gsToggleOverlay;
- GlobalShortcut *gsAltTalk, *gsMinimal, *gsVolumeUp, *gsVolumeDown;
+ GlobalShortcut *gsMinimal, *gsVolumeUp, *gsVolumeDown, *gsWhisper;
DockTitleBar *dtbLogDockTitle, *dtbChatDockTitle;
ACLEditor *aclEdit;
@@ -107,6 +110,12 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
QList<QAction *> qlChannelActions;
QList<QAction *> qlUserActions;
+ QSet<ShortcutTarget> qsCurrentTargets;
+ QHash<QList<ShortcutTarget>, int> qmTargets;
+ QMap<int, int> qmTargetUse;
+ Channel *mapChannel(int idx) const;
+ int iTargetCounter;
+
void createActions();
void setupGui();
void customEvent(QEvent *evt);
@@ -171,20 +180,20 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
void on_qteLog_highlighted(const QUrl & link);
void on_PushToTalk_triggered(bool, QVariant);
void on_PushToMute_triggered(bool, QVariant);
- void on_AltPushToTalk_triggered(bool, QVariant);
void on_CenterPos_triggered(bool, QVariant);
void on_VolumeUp_triggered(bool, QVariant);
void on_VolumeDown_triggered(bool, QVariant);
void on_gsMuteSelf_down(QVariant);
void on_gsDeafSelf_down(QVariant);
+ void on_gsWhisper_triggered(bool, QVariant);
void on_Reconnect_timeout();
void on_Icon_activated(QSystemTrayIcon::ActivationReason);
void serverConnected();
void serverDisconnected(QString reason);
- void pushLink(bool down);
void viewCertificate(bool);
void openUrl(const QUrl &url);
void context_triggered();
+ void updateTarget();
public:
MainWindow(QWidget *parent);
~MainWindow();
diff --git a/src/mumble/Messages.cpp b/src/mumble/Messages.cpp
index 77f53e33d..c47128e0b 100644
--- a/src/mumble/Messages.cpp
+++ b/src/mumble/Messages.cpp
@@ -96,6 +96,13 @@ void MainWindow::msgServerSync(const MumbleProto::ServerSync &msg) {
pmModel->ensureSelfVisible();
pmModel->recheckLinks();
+ qmTargetUse.clear();
+ qmTargets.clear();
+ for(int i=1;i<6;++i) {
+ qmTargetUse.insert(i, i);
+ }
+ iTargetCounter = 100;
+
AudioInputPtr ai = g.ai;
if (ai) {
int bw = ai->getMaxBandwidth();
@@ -163,7 +170,7 @@ void MainWindow::msgUserState(const MumbleProto::UserState &msg) {
pmModel->setUserId(pDst, msg.user_id());
if (msg.has_hash()) {
- pDst->qsHash = u8(msg.hash());
+ pmModel->setHash(pDst, u8(msg.hash()));
const QString &name = Database::getFriend(pDst->qsHash);
if (! name.isEmpty())
pmModel->setFriendName(pDst, name);
@@ -446,3 +453,6 @@ void MainWindow::msgUserList(const MumbleProto::UserList &msg) {
userEdit = new UserEdit(msg, this);
userEdit->show();
}
+
+void MainWindow::msgVoiceTarget(const MumbleProto::VoiceTarget &) {
+}
diff --git a/src/mumble/Settings.cpp b/src/mumble/Settings.cpp
index 0cb5cbbdb..c89d1c34b 100644
--- a/src/mumble/Settings.cpp
+++ b/src/mumble/Settings.cpp
@@ -45,7 +45,40 @@ ShortcutTarget::ShortcutTarget() {
}
bool ShortcutTarget::isServerSpecific() const {
- return (! bUsers && (iChannel > 0));
+ return (! bUsers && (iChannel >= 0));
+}
+
+bool ShortcutTarget::operator ==(const ShortcutTarget &o) const {
+ if (bUsers != o.bUsers)
+ return false;
+ if (bUsers)
+ return (qlUsers == o.qlUsers) && (qlSessions == o.qlSessions);
+ else
+ return (iChannel == o.iChannel) && (bLinks == o.bLinks) && (bChildren == o.bChildren) && (qsGroup == o.qsGroup);
+}
+
+quint32 qHash(const ShortcutTarget &t) {
+ quint32 h = 0;
+ if (t.bUsers) {
+ foreach(unsigned int u, t.qlSessions)
+ h ^= u;
+ } else {
+ h ^= t.iChannel;
+ if (t.bLinks)
+ h ^= 0x80000000;
+ if (t.bChildren)
+ h ^= 0x40000000;
+ h ^= qHash(t.qsGroup);
+ h = ~h;
+ }
+ return h;
+}
+
+quint32 qHash(const QList<ShortcutTarget> &l) {
+ quint32 h = l.count();
+ foreach(const ShortcutTarget &st, l)
+ h ^= qHash(st);
+ return h;
}
QDataStream &operator<<(QDataStream &qds, const ShortcutTarget &st) {
diff --git a/src/mumble/Settings.h b/src/mumble/Settings.h
index c94824f02..a3407cff2 100644
--- a/src/mumble/Settings.h
+++ b/src/mumble/Settings.h
@@ -51,14 +51,20 @@ struct Shortcut {
struct ShortcutTarget {
bool bUsers;
QStringList qlUsers;
+ QList<unsigned int> qlSessions;
int iChannel;
QString qsGroup;
bool bLinks;
bool bChildren;
ShortcutTarget();
bool isServerSpecific() const;
+ bool operator <(const ShortcutTarget &) const;
+ bool operator ==(const ShortcutTarget &) const;
};
+quint32 qHash(const ShortcutTarget &);
+quint32 qHash(const QList<ShortcutTarget> &);
+
QDataStream &operator<<(QDataStream &, const ShortcutTarget &);
QDataStream &operator>>(QDataStream &, ShortcutTarget &);
Q_DECLARE_METATYPE(ShortcutTarget);
diff --git a/src/mumble/UserModel.cpp b/src/mumble/UserModel.cpp
index c56dc2b07..c5ebe428d 100644
--- a/src/mumble/UserModel.cpp
+++ b/src/mumble/UserModel.cpp
@@ -695,6 +695,8 @@ void UserModel::removeUser(ClientUser *p) {
p->cChannel = NULL;
ClientUser::remove(p);
+ qmHashes.remove(p->qsHash);
+
delete p;
delete item;
@@ -762,6 +764,14 @@ void UserModel::setUserId(ClientUser *p, int id) {
emit dataChanged(idx, idx);
}
+void UserModel::setHash(ClientUser *p, const QString &hash) {
+ if (! p->qsHash.isEmpty())
+ qmHashes.remove(p->qsHash);
+
+ p->qsHash = hash;
+ qmHashes.insert(p->qsHash, p);
+}
+
void UserModel::setFriendName(ClientUser *p, const QString &name) {
p->qsFriendName = name;
QModelIndex idx_a = index(p, 0);
@@ -908,6 +918,10 @@ ClientUser *UserModel::getUser(const QModelIndex &idx) const {
return item->pUser;
}
+ClientUser *UserModel::getUser(const QString &hash) const {
+ return qmHashes.value(hash);
+}
+
Channel *UserModel::getChannel(const QModelIndex &idx) const {
if (! idx.isValid())
return NULL;
diff --git a/src/mumble/UserModel.h b/src/mumble/UserModel.h
index 1d400b034..fd0978c9e 100644
--- a/src/mumble/UserModel.h
+++ b/src/mumble/UserModel.h
@@ -96,6 +96,7 @@ class UserModel : public QAbstractItemModel {
QIcon qiFriend;
ModelItem *miRoot;
QSet<Channel *> qsLinked;
+ QMap<QString, ClientUser *> qmHashes;
QModelIndex index(ClientUser *, int column = 0) const;
QModelIndex index(Channel *) const;
@@ -123,6 +124,7 @@ class UserModel : public QAbstractItemModel {
ClientUser *addUser(unsigned int id, const QString &name);
ClientUser *getUser(const QModelIndex &idx) const;
+ ClientUser *getUser(const QString &hash) const;
Channel *addChannel(int id, Channel *p, const QString &name);
Channel *getChannel(const QModelIndex &idx) const;
@@ -132,6 +134,7 @@ class UserModel : public QAbstractItemModel {
void renameUser(ClientUser *p, const QString &name);
void renameChannel(Channel *c, const QString &name);
void setUserId(ClientUser *p, int id);
+ void setHash(ClientUser *p, const QString &hash);
void setFriendName(ClientUser *p, const QString &name);
void moveUser(ClientUser *p, Channel *c);