~ubuntu-branches/ubuntu/raring/mumble/raring

« back to all changes in this revision

Viewing changes to src/mumble/MainWindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thorvald Natvig
  • Date: 2010-01-09 19:28:50 UTC
  • mfrom: (9.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100109192850-zs4g5vwrrpd71kob
Tags: 1.2.1-2
Fix upgrade failure when upgrading mumble-server directly from 1.1.x
to 1.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
 
1
/* Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
2
2
   Copyright (C) 2009, Stefan Hacker <dd0t@users.sourceforge.net>
3
3
 
4
4
   All rights reserved.
57
57
#include "NetworkConfig.h"
58
58
#include "ACL.h"
59
59
 
 
60
#ifdef Q_OS_WIN
 
61
#include "TaskList.h"
 
62
#endif
 
63
 
60
64
/*!
61
65
  \fn void MainWindow::findDesiredChannel()
62
66
  This function tries to join a desired channel on connect. It gets called
110
114
        url = u;
111
115
}
112
116
 
 
117
const QString MainWindow::defaultStyleSheet = QLatin1String(".log-channel{text-decoration:none;}.log-user{text-decoration:none;}");
 
118
 
113
119
MainWindow::MainWindow(QWidget *p) : QMainWindow(p) {
114
120
        qiIconMuteSelf.addFile(QLatin1String("skin:muted_self.svg"));
115
121
        qiIconMuteServer.addFile(QLatin1String("skin:muted_server.svg"));
116
122
        qiIconMuteSuppressed.addFile(QLatin1String("skin:muted_suppressed.svg"));
117
123
        qiIconDeafSelf.addFile(QLatin1String("skin:deafened_self.svg"));
118
124
        qiIconDeafServer.addFile(QLatin1String("skin:deafened_server.svg"));
 
125
        qiTalkingOff.addFile(QLatin1String("skin:talking_off.svg"));
 
126
        qiTalkingOn.addFile(QLatin1String("skin:talking_on.svg"));
 
127
        qiTalkingWhisperChannel.addFile(QLatin1String("skin:talking_alt.svg"));
 
128
        qiTalkingWhisper.addFile(QLatin1String("skin:talking_whisper.svg"));
119
129
 
120
130
        qiIcon.addFile(QLatin1String("skin:mumble.svg"));
121
131
#ifdef Q_OS_MAC
142
152
        tokenEdit = NULL;
143
153
        bNoHide = false;
144
154
 
 
155
        cmUid = -1;
 
156
        cmCid = -1;
 
157
 
145
158
        qtReconnect = new QTimer(this);
146
159
        qtReconnect->setInterval(10000);
147
160
        qtReconnect->setSingleShot(true);
164
177
        on_qmUser_aboutToShow();
165
178
        on_qmConfig_aboutToShow();
166
179
 
167
 
        setOnTop(g.s.bAlwaysOnTop);
 
180
        setOnTop(g.s.aotbAlwaysOnTop == Settings::OnTopAlways ||
 
181
                 (g.s.bMinimalView && g.s.aotbAlwaysOnTop == Settings::OnTopInMinimal) ||
 
182
                 (!g.s.bMinimalView && g.s.aotbAlwaysOnTop == Settings::OnTopInNormal));
 
183
 
168
184
#ifdef NO_UPDATE_CHECK
169
185
        delete qaHelpVersionCheck;
170
186
#endif
250
266
        pmModel = new UserModel(qtvUsers);
251
267
        qtvUsers->setModel(pmModel);
252
268
        qtvUsers->setRowHidden(0, QModelIndex(), true);
 
269
        qtvUsers->ensurePolished();
253
270
 
254
271
        qaServerConnect->setShortcuts(QKeySequence::Open);
255
272
        qaServerDisconnect->setShortcuts(QKeySequence::Close);
276
293
        dtbChatDockTitle = new DockTitleBar();
277
294
        qdwChat->setTitleBarWidget(dtbChatDockTitle);
278
295
        qdwChat->installEventFilter(dtbChatDockTitle);
279
 
        qleChat->setDefaultText(tr("Not connected"));
 
296
        qleChat->setDefaultText(tr("Not connected"), true);
280
297
        qleChat->setEnabled(false);
281
298
 
282
299
        connect(qtvUsers->selectionModel(),
290
307
        else if (! g.s.bMinimalView && ! g.s.qbaMainWindowGeometry.isNull())
291
308
                restoreGeometry(g.s.qbaMainWindowGeometry);
292
309
 
 
310
        Settings::WindowLayout wlTmp = g.s.wlWindowLayout;
293
311
        restoreState(g.s.qbaMainWindowState);
294
 
        qtvUsers->header()->restoreState(g.s.qbaHeaderState);
 
312
        g.s.wlWindowLayout = wlTmp;
295
313
 
296
314
        setupView(false);
297
315
 
375
393
                qstiIcon->setIcon(qiIconMuteServer);
376
394
        } else if (p && p->bSuppress) {
377
395
                qstiIcon->setIcon(qiIconMuteSuppressed);
 
396
        } else if (p && g.s.bStateInTray) {
 
397
                switch (p->tsState) {
 
398
                        case ClientUser::Talking:
 
399
                                qstiIcon->setIcon(qiTalkingOn);
 
400
                                break;
 
401
                        case ClientUser::TalkingWhisper:
 
402
                                qstiIcon->setIcon(qiTalkingWhisper);
 
403
                                break;
 
404
                        case ClientUser::TalkingWhisperChannel:
 
405
                                qstiIcon->setIcon(qiTalkingWhisperChannel);
 
406
                                break;
 
407
                        case ClientUser::TalkingOff:
 
408
                        default:
 
409
                                qstiIcon->setIcon(qiTalkingOff);
 
410
                                break;
 
411
                }
378
412
        } else {
379
413
                qstiIcon->setIcon(qiIcon);
380
414
        }
381
415
}
382
416
 
 
417
Channel *MainWindow::getContextMenuChannel() {
 
418
        if (cmCid >= 0)
 
419
                return Channel::get(cmCid);
 
420
 
 
421
        return pmModel->getChannel(qtvUsers->currentIndex());
 
422
}
 
423
 
 
424
ClientUser *MainWindow::getContextMenuUser() {
 
425
        if (cmUid >= 0)
 
426
                return ClientUser::get(cmUid);
 
427
 
 
428
        return pmModel->getUser(qtvUsers->currentIndex());
 
429
}
 
430
 
 
431
bool MainWindow::handleSpecialContextMenu(const QUrl &url, const QPoint &_pos, bool focus) {
 
432
        if (url.scheme() == QString::fromLatin1("clientid")) {
 
433
                bool ok = false;
 
434
                QString x(url.host());
 
435
                if (x.length() == 40) {
 
436
                        ClientUser *cu = ClientUser::getByHash(x);
 
437
                        if (cu) {
 
438
                                cmUid = ClientUser::getUiSession(cu);
 
439
                                ok = true;
 
440
                        }
 
441
                } else {
 
442
                        QByteArray qbaServerDigest = QByteArray::fromBase64(url.path().remove(0, 1).toLatin1());
 
443
                        cmUid = url.host().toInt(&ok, 10);
 
444
                        ok = ok && (qbaServerDigest == g.sh->qbaDigest);
 
445
                }
 
446
                if (ok && ClientUser::isValid(cmUid)) {
 
447
                        if (focus)
 
448
                                qtvUsers->setCurrentIndex(pmModel->index(ClientUser::get(cmUid)));
 
449
                        else
 
450
                                qmUser->exec(_pos, NULL);
 
451
                }
 
452
                cmUid = -1;
 
453
        } else if (url.scheme() == QString::fromLatin1("channelid")) {
 
454
                bool ok;
 
455
                QByteArray qbaServerDigest = QByteArray::fromBase64(url.path().remove(0, 1).toLatin1());
 
456
                cmCid = url.host().toInt(&ok, 10);
 
457
                ok = ok && (qbaServerDigest == g.sh->qbaDigest);
 
458
                if (ok) {
 
459
                        if (focus)
 
460
                                qtvUsers->setCurrentIndex(pmModel->index(Channel::get(cmCid)));
 
461
                        else
 
462
                                qmChannel->exec(_pos, NULL);
 
463
                }
 
464
                cmCid = -1;
 
465
        } else {
 
466
                return false;
 
467
        }
 
468
        return true;
 
469
}
 
470
 
383
471
void MainWindow::on_qteLog_customContextMenuRequested(const QPoint &mpos) {
 
472
        QString link = qteLog->anchorAt(mpos);
 
473
        if (! link.isEmpty()) {
 
474
                QUrl l(link);
 
475
 
 
476
                if (handleSpecialContextMenu(l, qteLog->mapToGlobal(mpos)))
 
477
                        return;
 
478
        }
 
479
 
384
480
#if QT_VERSION >= 0x040400
385
481
        QMenu *menu = qteLog->createStandardContextMenu(mpos);
386
482
#else
443
539
                return;
444
540
        } else
445
541
#endif
446
 
                if ((major != 1) || (minor != 2) || (patch > 0)) {
 
542
                if ((major != 1) || (minor != 2) || (patch > 1)) {
447
543
                        g.l->log(Log::Warning, tr("This version of Mumble can't handle URLs for Mumble version %1.%2.%3").arg(major).arg(minor).arg(patch));
448
544
                        return;
449
545
                }
479
575
        if (g.sh && g.sh->isRunning()) {
480
576
                on_qaServerDisconnect_triggered();
481
577
                g.sh->wait();
 
578
                QCoreApplication::instance()->processEvents();
482
579
        }
483
580
 
484
581
        rtLast = MumbleProto::Reject_RejectType_None;
485
582
        qaServerDisconnect->setEnabled(true);
486
 
        g.l->log(Log::Information, tr("Connecting to server %1.").arg(host));
 
583
        g.l->log(Log::Information, tr("Connecting to server %1.").arg(Log::msgColor(host, Log::Server)));
487
584
        g.sh->setConnectionInfo(host, port, user, pw);
488
585
        g.sh->start(QThread::TimeCriticalPriority);
489
586
}
544
641
        bNoHide = true;
545
642
 
546
643
        // Update window layout
547
 
        int iTmp = g.s.iWindowLayout;
548
 
        switch (iTmp) {
 
644
        Settings::WindowLayout wlTmp = g.s.wlWindowLayout;
 
645
        switch (wlTmp) {
549
646
                case Settings::LayoutClassic:
550
647
                        removeDockWidget(qdwLog);
551
648
                        addDockWidget(Qt::LeftDockWidgetArea, qdwLog);
567
664
                        if (g.s.bShowChatbar) qdwChat->show();
568
665
                        break;
569
666
                default:
570
 
                        iTmp = Settings::LayoutCustom;
 
667
                        wlTmp = Settings::LayoutCustom;
571
668
                        break;
572
669
        }
573
 
        g.s.iWindowLayout = iTmp;
 
670
        g.s.wlWindowLayout = wlTmp;
574
671
 
575
672
        QRect geom = frameGeometry();
576
673
 
591
688
                f = Qt::Tool;
592
689
#endif
593
690
 
594
 
        if (g.s.bAlwaysOnTop)
 
691
        if (g.s.aotbAlwaysOnTop == Settings::OnTopAlways ||
 
692
                (g.s.bMinimalView && g.s.aotbAlwaysOnTop == Settings::OnTopInMinimal) ||
 
693
                (!g.s.bMinimalView && g.s.aotbAlwaysOnTop == Settings::OnTopInNormal))
595
694
                f |= Qt::WindowStaysOnTopHint;
596
695
 
597
696
        setWindowFlags(f);
598
697
 
599
698
        qdwLog->setVisible(showit);
600
699
        qdwChat->setVisible(showit && g.s.bShowChatbar);
601
 
        qtvUsers->header()->setVisible(showit);
602
700
        menuBar()->setVisible(showit);
603
701
 
604
702
        if (toggle_minimize) {
629
727
        if (g.sh && g.sh->isRunning() && res == QDialog::Accepted) {
630
728
                on_qaServerDisconnect_triggered();
631
729
                g.sh->wait();
 
730
                QCoreApplication::instance()->processEvents();
632
731
        }
633
732
 
634
733
        if (res == QDialog::Accepted) {
635
734
                qsDesiredChannel = QString();
636
735
                rtLast = MumbleProto::Reject_RejectType_None;
637
736
                qaServerDisconnect->setEnabled(true);
638
 
                g.l->log(Log::Information, tr("Connecting to server %1.").arg(cd->qsServer));
 
737
                g.l->log(Log::Information, tr("Connecting to server %1.").arg(Log::msgColor(cd->qsServer, Log::Server)));
639
738
                g.sh->setConnectionInfo(cd->qsServer, cd->usPort, cd->qsUsername, cd->qsPassword);
640
739
                g.sh->start(QThread::TimeCriticalPriority);
641
740
        }
808
907
}
809
908
 
810
909
void MainWindow::on_qmUser_aboutToShow() {
811
 
        ClientUser *p = pmModel->getUser(qtvUsers->currentIndex());
 
910
        ClientUser *p = getContextMenuUser();
 
911
 
812
912
        bool self = p && (p->uiSession == g.uiSession);
813
913
 
814
914
        qmUser->clear();
820
920
        qmUser->addAction(qaUserMute);
821
921
        qmUser->addAction(qaUserDeaf);
822
922
        qmUser->addAction(qaUserLocalMute);
823
 
        qmUser->addAction(qaUserComment);
 
923
 
 
924
        if (self)
 
925
                qmUser->addAction(qaUserComment);
 
926
        else {
 
927
                qmUser->addAction(qaUserCommentView);
 
928
                qmUser->addAction(qaUserCommentReset);
 
929
        }
 
930
 
824
931
        qmUser->addAction(qaUserTextMessage);
825
932
 
826
933
        if (p && (p->iId < 0) && (g.pPermissions & ((self ? ChanACL::SelfRegister : ChanACL::Register) | ChanACL::Write))) {
863
970
                qaUserKick->setEnabled(false);
864
971
                qaUserBan->setEnabled(false);
865
972
                qaUserMute->setEnabled(false);
866
 
                qaUserLocalMute->setEnabled(false);
867
973
                qaUserDeaf->setEnabled(false);
868
974
                qaUserTextMessage->setEnabled(false);
 
975
                qaUserLocalMute->setEnabled(false);
 
976
                qaUserComment->setEnabled(false);
 
977
                qaUserCommentReset->setEnabled(false);
 
978
                qaUserCommentView->setEnabled(false);
869
979
        } else {
870
980
                qaUserKick->setEnabled(! self);
871
981
                qaUserBan->setEnabled(! self);
873
983
                qaUserDeaf->setEnabled(! self || p->bDeaf);
874
984
                qaUserTextMessage->setEnabled(true);
875
985
                qaUserLocalMute->setEnabled(! self);
876
 
                qaUserComment->setEnabled(self || (g.pPermissions & (ChanACL::Move | ChanACL::Write)));
 
986
                qaUserComment->setEnabled(self);
 
987
                qaUserCommentReset->setEnabled(!p->qsComment.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write)));
 
988
                qaUserCommentView->setEnabled(! p->qsComment.isEmpty());
877
989
 
878
990
                qaUserMute->setChecked(p->bMute || p->bSuppress);
879
991
                qaUserDeaf->setChecked(p->bDeaf);
883
995
}
884
996
 
885
997
void MainWindow::on_qaUserMute_triggered() {
886
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
998
        ClientUser *p = getContextMenuUser();
887
999
        if (!p)
888
1000
                return;
889
1001
 
901
1013
}
902
1014
 
903
1015
void MainWindow::on_qaUserLocalMute_triggered() {
904
 
        ClientUser *p = pmModel->getUser(qtvUsers->currentIndex());
 
1016
        ClientUser *p = getContextMenuUser();
905
1017
        if (!p)
906
1018
                return;
907
1019
 
913
1025
}
914
1026
 
915
1027
void MainWindow::on_qaUserDeaf_triggered() {
916
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1028
        ClientUser *p = getContextMenuUser();
917
1029
        if (!p)
918
1030
                return;
919
1031
 
924
1036
}
925
1037
 
926
1038
void MainWindow::on_qaUserRegister_triggered() {
927
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1039
        ClientUser *p = getContextMenuUser();
928
1040
        if (!p)
929
1041
                return;
930
1042
 
949
1061
}
950
1062
 
951
1063
void MainWindow::on_qaUserFriendAdd_triggered() {
952
 
        ClientUser *p = pmModel->getUser(qtvUsers->currentIndex());
 
1064
        ClientUser *p = getContextMenuUser();
953
1065
        if (!p)
954
1066
                return;
955
1067
 
962
1074
}
963
1075
 
964
1076
void MainWindow::on_qaUserFriendRemove_triggered() {
965
 
        ClientUser *p = pmModel->getUser(qtvUsers->currentIndex());
 
1077
        ClientUser *p = getContextMenuUser();
966
1078
        if (!p)
967
1079
                return;
968
1080
 
971
1083
}
972
1084
 
973
1085
void MainWindow::on_qaUserKick_triggered() {
974
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1086
        ClientUser *p = getContextMenuUser();
975
1087
        if (!p)
976
1088
                return;
977
1089
 
993
1105
}
994
1106
 
995
1107
void MainWindow::on_qaUserBan_triggered() {
996
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1108
        ClientUser *p = getContextMenuUser();
997
1109
        if (!p)
998
1110
                return;
999
1111
 
1015
1127
}
1016
1128
 
1017
1129
void MainWindow::on_qaUserTextMessage_triggered() {
1018
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1130
        ClientUser *p = getContextMenuUser();
1019
1131
 
1020
1132
        if (!p)
1021
1133
                return;
1035
1147
                        mptm.add_session(p->uiSession);
1036
1148
                        mptm.set_message(u8(msg));
1037
1149
                        g.sh->sendMessage(mptm);
1038
 
                        g.l->log(Log::TextMessage, tr("To %1: %2").arg(p->qsName).arg(texm->message()), tr("Message to %1").arg(p->qsName));
 
1150
                        g.l->log(Log::TextMessage, tr("To %1: %2").arg(Log::msgColor(p->qsName, Log::Target)).arg(texm->message()), tr("Message to %1").arg(p->qsName));
1039
1151
                }
1040
1152
        }
1041
1153
        delete texm;
1042
1154
}
1043
1155
 
1044
1156
void MainWindow::on_qaUserComment_triggered() {
1045
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1157
        ClientUser *p = getContextMenuUser();
1046
1158
 
1047
1159
        if (!p)
1048
1160
                return;
1065
1177
        delete texm;
1066
1178
}
1067
1179
 
 
1180
void MainWindow::on_qaUserCommentView_triggered() {
 
1181
        ClientUser *p = getContextMenuUser();
 
1182
 
 
1183
        if (!p)
 
1184
                return;
 
1185
 
 
1186
        ::TextMessage *texm = new ::TextMessage(this, tr("View comment on user %1").arg(p->qsName));
 
1187
 
 
1188
        texm->rteMessage->setText(p->qsComment, true);
 
1189
        texm->setAttribute(Qt::WA_DeleteOnClose, true);
 
1190
        texm->show();
 
1191
}
 
1192
 
 
1193
void MainWindow::on_qaUserCommentReset_triggered() {
 
1194
        ClientUser *p = getContextMenuUser();
 
1195
 
 
1196
        if (!p)
 
1197
                return;
 
1198
 
 
1199
        unsigned int session = p->uiSession;
 
1200
 
 
1201
        int ret = QMessageBox::question(this, tr("Mumble"),
 
1202
                                        tr("Are you sure you want to reset the comment of user %1?").arg(p->qsName),
 
1203
                                        QMessageBox::Yes, QMessageBox::No);
 
1204
        if (ret == QMessageBox::Yes) {
 
1205
                MumbleProto::UserState mpus;
 
1206
                mpus.set_session(session);
 
1207
                mpus.set_comment(std::string());
 
1208
                g.sh->sendMessage(mpus);
 
1209
        }
 
1210
}
 
1211
 
1068
1212
void MainWindow::on_qaQuit_triggered() {
1069
1213
        bSuppressAskOnQuit = true;
1070
1214
        this->close();
1073
1217
void MainWindow::on_qleChat_returnPressed() {
1074
1218
        if (qleChat->text().isEmpty() || g.uiSession == 0) return; // Check if text & connection is available
1075
1219
 
1076
 
        User *p = pmModel->getUser(qtvUsers->currentIndex());
 
1220
        ClientUser *p = pmModel->getUser(qtvUsers->currentIndex());
1077
1221
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
1078
1222
 
1079
1223
        MumbleProto::TextMessage mptm;
1092
1236
                        c = ClientUser::get(g.uiSession)->cChannel;
1093
1237
 
1094
1238
                mptm.add_channel_id(c->iId);
1095
 
                g.l->log(Log::TextMessage, tr("To channel %1: %2").arg(c->qsName).arg(qsText), tr("Message to channel %1").arg(c->qsName));
 
1239
                g.l->log(Log::TextMessage, tr("To %1: %2").arg(Log::formatChannel(c)).arg(qsText), tr("Message to channel %1").arg(c->qsName));
1096
1240
        } else {
1097
1241
                // User message
1098
1242
                mptm.add_session(p->uiSession);
1099
 
                g.l->log(Log::TextMessage, tr("To %1: %2").arg(p->qsName).arg(qsText), tr("Message to %1").arg(p->qsName));
 
1243
                g.l->log(Log::TextMessage, tr("To %1: %2").arg(Log::formatClientUser(p, Log::Target)).arg(qsText), tr("Message to %1").arg(p->qsName));
1100
1244
        }
1101
1245
 
1102
1246
        g.sh->sendMessage(mptm);
1127
1271
}
1128
1272
 
1129
1273
void MainWindow::on_qmChannel_aboutToShow() {
1130
 
        QModelIndex idx = qtvUsers->currentIndex();
1131
 
 
1132
1274
        qmChannel->clear();
 
1275
 
 
1276
        if (cmCid >= 0 && g.uiSession != 0 && cmCid != ClientUser::get(g.uiSession)->cChannel->iId) {
 
1277
                qmChannel->addAction(qaChannelJoin);
 
1278
                qmChannel->addSeparator();
 
1279
        }
1133
1280
        qmChannel->addAction(qaChannelAdd);
1134
1281
        qmChannel->addAction(qaChannelACL);
1135
1282
        qmChannel->addAction(qaChannelRemove);
1164
1311
                msg = true;
1165
1312
                descUpdate = true;
1166
1313
 
1167
 
                Channel *c = pmModel->getChannel(idx);
 
1314
                Channel *c = getContextMenuChannel();
1168
1315
                Channel *home = ClientUser::get(g.uiSession)->cChannel;
1169
1316
 
1170
1317
                if (c && c->bTemporary)
1195
1342
        updateMenuPermissions();
1196
1343
}
1197
1344
 
 
1345
void MainWindow::on_qaChannelJoin_triggered() {
 
1346
        Channel *c = getContextMenuChannel();
 
1347
 
 
1348
        if (c) {
 
1349
                MumbleProto::UserState mpus;
 
1350
                mpus.set_session(g.uiSession);
 
1351
                mpus.set_channel_id(c->iId);
 
1352
                g.sh->sendMessage(mpus);
 
1353
        }
 
1354
}
 
1355
 
1198
1356
void MainWindow::on_qaChannelAdd_triggered() {
1199
 
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
 
1357
        Channel *c = getContextMenuChannel();
1200
1358
        if (aclEdit) {
1201
1359
                aclEdit->reject();
1202
1360
                delete aclEdit;
1214
1372
 
1215
1373
void MainWindow::on_qaChannelRemove_triggered() {
1216
1374
        int ret;
1217
 
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
 
1375
        Channel *c = getContextMenuChannel();
1218
1376
        if (! c)
1219
1377
                return;
1220
1378
 
1234
1392
}
1235
1393
 
1236
1394
void MainWindow::on_qaChannelACL_triggered() {
1237
 
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
 
1395
        Channel *c = getContextMenuChannel();
1238
1396
        int id = c ? c->iId : 0;
1239
1397
 
1240
1398
        MumbleProto::ACL mpacl;
1252
1410
 
1253
1411
void MainWindow::on_qaChannelLink_triggered() {
1254
1412
        Channel *c = ClientUser::get(g.uiSession)->cChannel;
1255
 
        Channel *l = pmModel->getChannel(qtvUsers->currentIndex());
 
1413
        Channel *l = getContextMenuChannel();
1256
1414
        if (! l)
1257
1415
                l = Channel::get(0);
1258
1416
 
1264
1422
 
1265
1423
void MainWindow::on_qaChannelUnlink_triggered() {
1266
1424
        Channel *c = ClientUser::get(g.uiSession)->cChannel;
1267
 
        Channel *l = pmModel->getChannel(qtvUsers->currentIndex());
 
1425
        Channel *l = getContextMenuChannel();
1268
1426
        if (! l)
1269
1427
                l = Channel::get(0);
1270
1428
 
1285
1443
}
1286
1444
 
1287
1445
void MainWindow::on_qaChannelSendMessage_triggered() {
1288
 
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
 
1446
        Channel *c = getContextMenuChannel();
1289
1447
 
1290
1448
        if (!c)
1291
1449
                return;
1307
1465
                g.sh->sendMessage(mptm);
1308
1466
 
1309
1467
                if (texm->bTreeMessage)
1310
 
                        g.l->log(Log::TextMessage, tr("To tree %1: %2").arg(c->qsName).arg(texm->message()), tr("Message to tree %1").arg(c->qsName));
 
1468
                        g.l->log(Log::TextMessage, tr("(Tree) %1: %2").arg(Log::formatChannel(c)).arg(texm->message()), tr("Message to tree %1").arg(c->qsName));
1311
1469
                else
1312
 
                        g.l->log(Log::TextMessage, tr("To channel %1: %2").arg(c->qsName).arg(texm->message()), tr("Message to channel %1").arg(c->qsName));
 
1470
                        g.l->log(Log::TextMessage, tr("%1: %2").arg(Log::formatChannel(c)).arg(texm->message()), tr("Message to channel %1").arg(c->qsName));
1313
1471
        }
1314
1472
        delete texm;
1315
1473
}
1316
1474
 
1317
1475
void MainWindow::updateMenuPermissions() {
1318
 
        Channel *c = g.uiSession ? pmModel->getChannel(qtvUsers->currentIndex()) : NULL;
 
1476
        ClientUser *cu = getContextMenuUser();
 
1477
        Channel *c = g.uiSession ? (cu ? cu->cChannel : getContextMenuChannel()) : NULL;
1319
1478
        ChanACL::Permissions p = static_cast<ChanACL::Permissions>(c ? c->uiPermissions : ChanACL::None);
1320
1479
 
1321
1480
        if (c && ! p) {
1377
1536
        qleChat->setEnabled(p & (ChanACL::Write | ChanACL::TextMessage));
1378
1537
}
1379
1538
 
 
1539
void MainWindow::talkingChanged() {
 
1540
        if (g.s.bAttenuateOthersOnTalk) {
 
1541
                ClientUser *p=ClientUser::get(g.uiSession);
 
1542
                switch (p->tsState) {
 
1543
                        case ClientUser::Talking:
 
1544
                        case ClientUser::TalkingWhisper:
 
1545
                        case ClientUser::TalkingWhisperChannel:
 
1546
                                g.bAttenuateOthers = true;
 
1547
                                break;
 
1548
                        case ClientUser::TalkingOff:
 
1549
                        default:
 
1550
                                g.bAttenuateOthers = false;
 
1551
                                break;
 
1552
                }
 
1553
        }
 
1554
 
 
1555
        if (g.s.bStateInTray)
 
1556
                updateTrayIcon();
 
1557
}
 
1558
 
1380
1559
void MainWindow::on_qaAudioReset_triggered() {
1381
1560
        AudioInputPtr ai = g.ai;
1382
1561
        if (ai)
1454
1633
 
1455
1634
void MainWindow::on_qaConfigDialog_triggered() {
1456
1635
        ConfigDialog *dlg= new ConfigDialog(this);
1457
 
        if (dlg->exec() == QDialog::Accepted)
 
1636
        if (dlg->exec() == QDialog::Accepted) {
1458
1637
                setupView(false);
 
1638
                updateTrayIcon();
 
1639
        }
1459
1640
        delete dlg;
1460
1641
}
1461
1642
 
1528
1709
}
1529
1710
 
1530
1711
void MainWindow::on_PushToTalk_triggered(bool down, QVariant) {
 
1712
        g.iPrevTarget = 0;
1531
1713
        if (down) {
1532
1714
                g.uiDoublePush = g.tDoublePush.restart();
1533
1715
                g.iPushToTalk++;
1574
1756
                                        c = c->cParent;
1575
1757
                                break;
1576
1758
                        default:
1577
 
                                c = pmModel->getSubChannel(c, -4 - idx);
 
1759
                                c = pmModel->getSubChannel(ClientUser::get(g.uiSession)->cChannel, -4 - idx);
1578
1760
                                break;
1579
1761
                }
1580
1762
        } else {
1584
1766
}
1585
1767
 
1586
1768
void MainWindow::updateTarget() {
 
1769
        g.iPrevTarget = g.iTarget;
1587
1770
        if (qsCurrentTargets.isEmpty()) {
1588
1771
                g.bCenterPosition = false;
1589
1772
                g.iTarget = 0;
1700
1883
 
1701
1884
                g.iPushToTalk++;
1702
1885
        } else if (g.iPushToTalk) {
 
1886
                g.iPushToTalk--;
 
1887
 
1703
1888
                qsCurrentTargets.remove(st);
1704
1889
                updateTarget();
1705
 
 
1706
 
                g.iPushToTalk--;
1707
1890
        }
1708
1891
}
1709
1892
 
1743
1926
                mpus.set_self_deaf(g.s.bDeaf);
1744
1927
                g.sh->sendMessage(mpus);
1745
1928
        }
 
1929
 
 
1930
#ifdef Q_OS_WIN
 
1931
        TaskList::addToRecentList(g.s.qsLastServer, host, port);
 
1932
#endif
 
1933
}
 
1934
 
 
1935
static QString getPathToChannel(Channel *c) {
 
1936
        QString out;
 
1937
 
 
1938
        if (!c)
 
1939
                return out;
 
1940
 
 
1941
        Channel *tmp = c;
 
1942
        while (tmp->cParent) {
 
1943
                // skip root channel
 
1944
                if (tmp->iId == 0)
 
1945
                        break;
 
1946
 
 
1947
                out.prepend(QString::fromLatin1("/"));
 
1948
                out.prepend(tmp->qsName);
 
1949
 
 
1950
                tmp = tmp->cParent;
 
1951
        }
 
1952
 
 
1953
        return out;
1746
1954
}
1747
1955
 
1748
1956
void MainWindow::serverDisconnected(QAbstractSocket::SocketError err, QString reason) {
 
1957
        if (g.uiSession)
 
1958
                qsDesiredChannel = getPathToChannel(ClientUser::get(g.uiSession)->cChannel);
 
1959
 
1749
1960
        g.uiSession = 0;
1750
1961
        g.pPermissions = ChanACL::None;
1751
1962
        qaServerDisconnect->setEnabled(false);
1978
2189
        Channel *c = pmModel->getChannel(qtvUsers->currentIndex());
1979
2190
 
1980
2191
        if (g.uiSession == 0) {
1981
 
                qleChat->setDefaultText(tr("Not connected"));
 
2192
                qleChat->setDefaultText(tr("Not connected"), true);
1982
2193
        } else if (p == NULL || p->uiSession == g.uiSession) {
1983
2194
                // Channel tree target
1984
2195
                if (c == NULL) // If no channel selected fallback to current one
2029
2240
#undef MUMBLE_MH_MSG
2030
2241
}
2031
2242
 
 
2243
 
2032
2244
void MainWindow::on_qteLog_anchorClicked(const QUrl &url) {
2033
 
        QDesktopServices::openUrl(url);
 
2245
        if (!handleSpecialContextMenu(url, QCursor::pos(), true)) {
 
2246
                if (url.scheme() != QLatin1String("file")
 
2247
                        && url.scheme() != QLatin1String("qrc")
 
2248
                        && !url.isRelative())
 
2249
                        QDesktopServices::openUrl(url);
 
2250
        }
2034
2251
}
2035
2252
 
2036
2253
void MainWindow::on_qteLog_highlighted(const QUrl &url) {
 
2254
        if (url.scheme() == QString::fromLatin1("clientid") || url.scheme() == QString::fromLatin1("channelid"))
 
2255
                return;
 
2256
 
2037
2257
        if (! url.isValid())
2038
2258
                QToolTip::hideText();
2039
2259
        else
2041
2261
}
2042
2262
 
2043
2263
void MainWindow::on_qdwChat_dockLocationChanged(Qt::DockWidgetArea) {
2044
 
        g.s.iWindowLayout = Settings::LayoutCustom;
 
2264
        g.s.wlWindowLayout = Settings::LayoutCustom;
2045
2265
}
2046
2266
 
2047
2267
void MainWindow::on_qdwLog_dockLocationChanged(Qt::DockWidgetArea) {
2048
 
        g.s.iWindowLayout = Settings::LayoutCustom;
 
2268
        g.s.wlWindowLayout = Settings::LayoutCustom;
2049
2269
}
2050
2270
 
2051
2271
void MainWindow::context_triggered() {