mumble-voip_mumble/src/mumble/MainWindow.h

440 lines
15 KiB
C++

// Copyright 2007-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_MAINWINDOW_H_
#define MUMBLE_MUMBLE_MAINWINDOW_H_
#include <QtCore/QPointer>
#include <QtCore/QtGlobal>
#include <QtNetwork/QAbstractSocket>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QSystemTrayIcon>
#include "CustomElements.h"
#include "MUComboBox.h"
#include "Mumble.pb.h"
#include "MumbleProtocol.h"
#include "QtUtils.h"
#include "Usage.h"
#include "UserLocalNicknameDialog.h"
#include "ui_MainWindow.h"
#define MB_QEVENT (QEvent::User + 939)
#define OU_QEVENT (QEvent::User + 940)
class ACLEditor;
class BanEditor;
class UserEdit;
class ServerHandler;
class GlobalShortcut;
class TextToSpeech;
class UserModel;
class Tokens;
class Channel;
class UserInformation;
class VoiceRecorderDialog;
class PositionalAudioViewer;
class PTTButtonWidget;
namespace Search {
class SearchDialog;
}
class MenuLabel;
class ListenerVolumeSlider;
class UserLocalVolumeSlider;
struct ShortcutTarget;
struct ContextMenuTarget {
ClientUser *user = nullptr;
Channel *channel = nullptr;
};
class MessageBoxEvent : public QEvent {
public:
QString msg;
MessageBoxEvent(QString msg);
};
class OpenURLEvent : public QEvent {
public:
QUrl url;
OpenURLEvent(QUrl url);
};
class MainWindow : public QMainWindow, public Ui::MainWindow {
friend class UserModel;
private:
Q_OBJECT
Q_DISABLE_COPY(MainWindow)
public:
UserModel *pmModel;
QSystemTrayIcon *qstiIcon;
QMenu *qmUser;
QMenu *qmChannel;
QMenu *qmListener;
QMenu *qmDeveloper;
QMenu *qmTray;
QIcon qiIcon, qiIconMutePushToMute, qiIconMuteSelf, qiIconMuteServer, qiIconDeafSelf, qiIconDeafServer,
qiIconMuteSuppressed;
QIcon qiTalkingOn, qiTalkingWhisper, qiTalkingShout, qiTalkingOff;
std::unordered_map< unsigned int, qt_unique_ptr< UserLocalNicknameDialog > > qmUserNicknameTracker;
/// "Action" for when there are no actions available
QAction *qaEmpty;
GlobalShortcut *gsPushTalk, *gsResetAudio, *gsMuteSelf, *gsDeafSelf;
GlobalShortcut *gsUnlink, *gsPushMute, *gsJoinChannel;
#ifdef USE_OVERLAY
GlobalShortcut *gsToggleOverlay;
#endif
GlobalShortcut *gsMinimal, *gsVolumeUp, *gsVolumeDown, *gsWhisper, *gsLinkChannel, *gsListenChannel;
GlobalShortcut *gsCycleTransmitMode, *gsToggleMainWindowVisibility, *gsTransmitModePushToTalk,
*gsTransmitModeContinuous, *gsTransmitModeVAD;
GlobalShortcut *gsSendTextMessage, *gsSendClipboardTextMessage;
GlobalShortcut *gsToggleTalkingUI;
GlobalShortcut *gsToggleSearch;
GlobalShortcut *gsServerConnect, *gsServerDisconnect, *gsServerInformation, *gsServerTokens;
GlobalShortcut *gsServerUserList, *gsServerBanList;
GlobalShortcut *gsSelfPrioritySpeaker;
GlobalShortcut *gsRecording;
GlobalShortcut *gsSelfComment, *gsServerTexture, *gsServerTextureRemove;
GlobalShortcut *gsSelfRegister, *gsAudioStats;
GlobalShortcut *gsConfigDialog, *gsAudioWizard, *gsConfigCert;
GlobalShortcut *gsAudioTTS;
GlobalShortcut *gsHelpAbout, *gsHelpAboutQt, *gsHelpVersionCheck;
DockTitleBar *dtbLogDockTitle, *dtbChatDockTitle;
ACLEditor *aclEdit;
BanEditor *banEdit;
UserEdit *userEdit;
Tokens *tokenEdit;
VoiceRecorderDialog *voiceRecorderDialog;
MumbleProto::Reject_RejectType rtLast;
bool bRetryServer;
QString qsDesiredChannel;
bool forceQuit;
/// Restart the client after shutdown
bool restartOnQuit;
bool bAutoUnmute;
/// Contains the cursor whose position is immediately before the image to
/// save when activating the "Save Image As..." context menu item.
QTextCursor qtcSaveImageCursor;
QPointer< Channel > cContextChannel;
QPointer< ClientUser > cuContextUser;
QPoint qpContextPosition;
void recheckTTS();
void msgBox(QString msg);
void setOnTop(bool top);
void setShowDockTitleBars(bool doShow);
void updateAudioToolTips();
void updateTrayIcon();
void updateUserModel();
void focusNextMainWidget();
QPair< QByteArray, QImage > openImageFile();
void updateChatBar();
void openTextMessageDialog(ClientUser *p);
void openUserLocalNicknameDialog(const ClientUser &p);
#ifdef Q_OS_WIN
bool nativeEvent(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
unsigned int uiNewHardware;
#endif
protected:
Usage uUsage;
QTimer *qtReconnect;
QList< QAction * > qlServerActions;
QList< QAction * > qlChannelActions;
QList< QAction * > qlUserActions;
QHash< ShortcutTarget, int > qmCurrentTargets;
/// A map that contains information about the currently active
/// shout/whisper targets. The mapping is between a List of
/// ShortcutTargets that are all triggered together and the
/// target ID for this specific combination of ShortcutTargets.
/// The target ID is what the server uses to identify this specific
/// set of ShortcutTargets.
QHash< QList< ShortcutTarget >, int > qmTargets;
/// This is a map between all target IDs the client will ever use
/// and a helper-number (see iTargetCounter).
QMap< int, int > qmTargetUse;
Channel *mapChannel(int idx) const;
/// This is a pure helper number whose job is to always be increased
/// if a new VoiceTarget is needed. It will be used as the helper
/// number in qmTargetUse.
int iTargetCounter;
QMap< unsigned int, UserInformation * > qmUserInformations;
std::unique_ptr< PositionalAudioViewer > m_paViewer;
PTTButtonWidget *qwPTTButtonWidget;
MUComboBox *qcbTransmitMode;
QAction *qaTransmitMode;
QAction *qaTransmitModeSeparator;
Search::SearchDialog *m_searchDialog = nullptr;
qt_unique_ptr< MenuLabel > m_localVolumeLabel;
qt_unique_ptr< UserLocalVolumeSlider > m_userLocalVolumeSlider;
qt_unique_ptr< ListenerVolumeSlider > m_listenerVolumeSlider;
void createActions();
void setupGui();
void updateWindowTitle();
/// updateToolbar updates the state of the toolbar depending on the current
/// window layout setting.
/// If the window layout setting is 'custom', the toolbar is made movable. If the
/// window layout is not 'custom', the toolbar is locked in place at the top of
/// the MainWindow.
void updateToolbar();
void customEvent(QEvent *evt) Q_DECL_OVERRIDE;
void findDesiredChannel();
void setupView(bool toggle_minimize = true);
void closeEvent(QCloseEvent *e) Q_DECL_OVERRIDE;
void hideEvent(QHideEvent *e) Q_DECL_OVERRIDE;
void showEvent(QShowEvent *e) Q_DECL_OVERRIDE;
void changeEvent(QEvent *e) Q_DECL_OVERRIDE;
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
QMenu *createPopupMenu() Q_DECL_OVERRIDE;
bool handleSpecialContextMenu(const QUrl &url, const QPoint &pos_, bool focus = false);
Channel *getContextMenuChannel();
ClientUser *getContextMenuUser();
ContextMenuTarget getContextMenuTargets();
void autocompleteUsername();
public slots:
void on_qmServer_aboutToShow();
void on_qaServerConnect_triggered(bool autoconnect = false);
void on_qaServerDisconnect_triggered();
void on_qaServerBanList_triggered();
void on_qaServerUserList_triggered();
void on_qaServerInformation_triggered();
void on_qaServerTexture_triggered();
void on_qaServerTextureRemove_triggered();
void on_qaServerTokens_triggered();
void on_qmSelf_aboutToShow();
void on_qaSelfComment_triggered();
void on_qaSelfRegister_triggered();
void qcbTransmitMode_activated(int index);
void updateTransmitModeComboBox(Settings::AudioTransmit newMode);
void qmUser_aboutToShow();
void qmListener_aboutToShow();
void on_qaUserCommentReset_triggered();
void on_qaUserTextureReset_triggered();
void on_qaUserCommentView_triggered();
void on_qaUserKick_triggered();
void on_qaUserBan_triggered();
void on_qaUserMute_triggered();
void on_qaUserDeaf_triggered();
void on_qaSelfPrioritySpeaker_triggered();
void on_qaUserPrioritySpeaker_triggered();
void on_qaUserLocalIgnore_triggered();
void on_qaUserLocalIgnoreTTS_triggered();
void on_qaUserLocalMute_triggered();
void on_qaUserLocalNickname_triggered();
void on_qaUserTextMessage_triggered();
void on_qaUserRegister_triggered();
void on_qaUserInformation_triggered();
void on_qaUserFriendAdd_triggered();
void on_qaUserFriendRemove_triggered();
void on_qaUserFriendUpdate_triggered();
void qmChannel_aboutToShow();
void on_qaChannelJoin_triggered();
void on_qaUserJoin_triggered();
void on_qaUserMove_triggered();
void on_qaChannelListen_triggered();
void on_qaChannelAdd_triggered();
void on_qaChannelRemove_triggered();
void on_qaChannelACL_triggered();
void on_qaChannelLink_triggered();
void on_qaChannelUnlink_triggered();
void on_qaChannelUnlinkAll_triggered();
void on_qaChannelSendMessage_triggered();
void on_qaChannelHide_triggered();
void on_qaChannelPin_triggered();
void on_qaChannelCopyURL_triggered();
void on_qaAudioReset_triggered();
void on_qaAudioMute_triggered();
void on_qaAudioDeaf_triggered();
void on_qaRecording_triggered();
void on_qaAudioTTS_triggered();
void on_qaAudioUnlink_triggered();
void on_qaAudioStats_triggered();
void on_qaConfigDialog_triggered();
void on_qaConfigHideFrame_triggered();
void on_qmConfig_aboutToShow();
void on_qaConfigMinimal_triggered();
void on_qaConfigCert_triggered();
void on_qaAudioWizard_triggered();
void on_qaDeveloperConsole_triggered();
void on_qaPositionalAudioViewer_triggered();
void on_qaHelpWhatsThis_triggered();
void on_qaHelpAbout_triggered();
void on_qaHelpAboutQt_triggered();
void on_qaHelpVersionCheck_triggered();
void on_qaQuit_triggered();
void on_qaHide_triggered();
void on_qteChat_tabPressed();
void on_qteChat_backtabPressed();
void on_qteChat_ctrlSpacePressed();
void on_qtvUsers_customContextMenuRequested(const QPoint &mpos, bool usePositionForGettingContext = true);
void on_qteLog_customContextMenuRequested(const QPoint &pos);
void on_qteLog_anchorClicked(const QUrl &);
void on_qteLog_highlighted(const QUrl &link);
void on_PushToTalk_triggered(bool, QVariant);
void on_PushToMute_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 addTarget(ShortcutTarget *);
void removeTarget(ShortcutTarget *);
void on_gsListenChannel_triggered(bool, QVariant);
void on_gsCycleTransmitMode_triggered(bool, QVariant);
void on_gsToggleMainWindowVisibility_triggered(bool, QVariant);
void on_gsTransmitModePushToTalk_triggered(bool, QVariant);
void on_gsTransmitModeContinuous_triggered(bool, QVariant);
void on_gsTransmitModeVAD_triggered(bool, QVariant);
void on_gsSendTextMessage_triggered(bool, QVariant);
void on_gsSendClipboardTextMessage_triggered(bool, QVariant);
void on_gsToggleTalkingUI_triggered(bool, QVariant);
void on_gsToggleSearch_triggered(bool, QVariant);
void on_gsServerConnect_triggered(bool, QVariant);
void on_gsServerDisconnect_triggered(bool, QVariant);
void on_gsServerInformation_triggered(bool, QVariant);
void on_gsServerTokens_triggered(bool, QVariant);
void on_gsServerUserList_triggered(bool, QVariant);
void on_gsServerBanList_triggered(bool, QVariant);
void on_gsSelfPrioritySpeaker_triggered(bool, QVariant);
void on_gsRecording_triggered(bool, QVariant);
void on_gsSelfComment_triggered(bool, QVariant);
void on_gsServerTexture_triggered(bool, QVariant);
void on_gsServerTextureRemove_triggered(bool, QVariant);
void on_gsSelfRegister_triggered(bool, QVariant);
void on_gsAudioStats_triggered(bool, QVariant);
void on_gsConfigDialog_triggered(bool, QVariant);
void on_gsAudioWizard_triggered(bool, QVariant);
void on_gsConfigCert_triggered(bool, QVariant);
void on_gsAudioTTS_triggered(bool, QVariant);
void on_gsHelpAbout_triggered(bool, QVariant);
void on_gsHelpAboutQt_triggered(bool, QVariant);
void on_gsHelpVersionCheck_triggered(bool, QVariant);
void on_Reconnect_timeout();
void on_Icon_activated(QSystemTrayIcon::ActivationReason);
void on_qaTalkingUIToggle_triggered();
void voiceRecorderDialog_finished(int);
void qtvUserCurrentChanged(const QModelIndex &, const QModelIndex &);
void serverConnected();
void serverDisconnected(QAbstractSocket::SocketError, QString reason);
void resolverError(QAbstractSocket::SocketError, QString reason);
void viewCertificate(bool);
void openUrl(const QUrl &url);
void context_triggered();
void updateTarget();
void updateMenuPermissions();
void on_muteCuePopup_triggered();
/// Handles state changes like talking mode changes and mute/unmute
/// or priority speaker flag changes for the gui user
void userStateChanged();
void destroyUserInformation();
void trayAboutToShow();
void sendChatbarMessage(QString msg);
void sendChatbarText(QString msg, bool plainText = false);
void pttReleased();
void whisperReleased(QVariant scdata);
void onResetAudio();
void showRaiseWindow();
void on_qaFilterToggle_triggered();
/// Opens a save dialog for the image referenced by qtcSaveImageCursor.
void saveImageAs();
/// Returns the path to the user's image directory, optionally with a
/// filename included.
QString getImagePath(QString filename = QString()) const;
/// Updates the user's image directory to the given path (any included
/// filename is discarded).
void updateImagePath(QString filepath) const;
void setTransmissionMode(Settings::AudioTransmit mode);
/// Sets the local user's mute state
///
/// @param mute Whether to mute the user
void setAudioMute(bool mute);
/// Sets the local user's deaf state
///
/// @param deaf Whether to deafen the user
void setAudioDeaf(bool deaf);
// Callback the search action being triggered
void on_qaSearch_triggered();
void toggleSearchDialogVisibility();
/// Enables or disables the recording feature
void enableRecording(bool recordingAllowed);
signals:
/// Signal emitted when the server and the client have finished
/// synchronizing (after a new connection).
void serverSynchronized();
/// Signal emitted whenever a user adds a new ChannelListener
void userAddedChannelListener(ClientUser *user, Channel *channel);
/// Signal emitted whenever a user removes a ChannelListener
void userRemovedChannelListener(ClientUser *user, Channel *channel);
void transmissionModeChanged(Settings::AudioTransmit newMode);
public:
MainWindow(QWidget *parent);
~MainWindow() Q_DECL_OVERRIDE;
// Implementation in Messages.cpp
#define PROCESS_MUMBLE_TCP_MESSAGE(name, value) void msg##name(const MumbleProto::name &);
MUMBLE_ALL_TCP_MESSAGES
#undef PROCESS_MUMBLE_TCP_MESSAGE
void removeContextAction(const MumbleProto::ContextActionModify &msg);
/// Logs a message that an action could not be saved permanently because
/// the user has no certificate and can't be reliably identified.
///
/// @param actionName The name of the action that has been executed.
/// @param p The user on which the action was performed.
void logChangeNotPermanent(const QString &actionName, ClientUser *const p) const;
void openServerConnectDialog(bool autoconnect = false);
void disconnectFromServer();
void openServerInformationDialog();
void openServerTokensDialog();
void openServerUserListDialog();
void openServerBanListDialog();
void toggleSelfPrioritySpeaker();
void recording();
void openSelfCommentDialog();
void changeServerTexture();
void removeServerTexture();
void selfRegister();
void openAudioStatsDialog();
void openConfigDialog();
void openAudioWizardDialog();
void openCertWizardDialog();
void enableAudioTTS(bool enable);
void openAboutDialog();
void openAboutQtDialog();
void versionCheck();
};
#endif