1 /*************************************************************************** 2 * Copyright (C) 2005-2020 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 #pragma once 22 23 #include "client-export.h" 24 25 #include <memory> 26 27 #include <QList> 28 #include <QPointer> 29 30 #include "bufferinfo.h" 31 #include "coreaccount.h" 32 #include "coreconnection.h" 33 #include "coreinfo.h" 34 #include "highlightrulemanager.h" 35 #include "quassel.h" 36 #include "singleton.h" 37 #include "types.h" 38 39 class Message; 40 class MessageModel; 41 class AbstractMessageProcessor; 42 43 class Identity; 44 class CertIdentity; 45 class Network; 46 47 class AbstractUi; 48 class AbstractUiMsg; 49 class NetworkModel; 50 class BufferModel; 51 class BufferSyncer; 52 class BufferViewOverlay; 53 class ClientAliasManager; 54 class ClientBacklogManager; 55 class ClientBufferViewManager; 56 class ClientIgnoreListManager; 57 class ClientIrcListHelper; 58 class ClientTransferManager; 59 class ClientUserInputHandler; 60 class CoreAccountModel; 61 class CoreConnection; 62 class DccConfig; 63 class IrcUser; 64 class IrcChannel; 65 class NetworkConfig; 66 class SignalProxy; 67 class TransferModel; 68 69 struct NetworkInfo; 70 71 class CLIENT_EXPORT Client : public QObject, public Singleton<Client> 72 { 73 Q_OBJECT 74 75 public: 76 enum ClientMode 77 { 78 LocalCore, 79 RemoteCore 80 }; 81 82 Client(std::unique_ptr<AbstractUi>, QObject* parent = nullptr); 83 ~Client() override; 84 85 static AbstractUi* mainUi(); 86 87 static QList<NetworkId> networkIds(); 88 static const Network* network(NetworkId); 89 90 static QList<IdentityId> identityIds(); 91 static const Identity* identity(IdentityId); 92 93 //! Request creation of an identity with the given data. 94 /** The request will be sent to the core, and will be propagated back to all the clients 95 * with a new valid IdentityId. 96 * \param identity The identity template for the new identity. It does not need to have a valid ID. 97 */ 98 static void createIdentity(const CertIdentity& identity); 99 100 //! Request update of an identity with the given data. 101 /** The request will be sent to the core, and will be propagated back to all the clients. 102 * \param id The identity to be updated. 103 * \param serializedData The identity's content (cf. SyncableObject::toVariantMap()) 104 */ 105 static void updateIdentity(IdentityId id, const QVariantMap& serializedData); 106 107 //! Request removal of the identity with the given ID from the core (and all the clients, of course). 108 /** \param id The ID of the identity to be removed. 109 */ 110 static void removeIdentity(IdentityId id); 111 112 static void createNetwork(const NetworkInfo& info, const QStringList& persistentChannels = QStringList()); 113 static void updateNetwork(const NetworkInfo& info); 114 static void removeNetwork(NetworkId id); 115 networkModel()116 static inline NetworkModel* networkModel() { return instance()->_networkModel; } bufferModel()117 static inline BufferModel* bufferModel() { return instance()->_bufferModel; } messageModel()118 static inline MessageModel* messageModel() { return instance()->_messageModel; } messageProcessor()119 static inline AbstractMessageProcessor* messageProcessor() { return instance()->_messageProcessor; } signalProxy()120 static inline SignalProxy* signalProxy() { return instance()->_signalProxy; } 121 aliasManager()122 static inline ClientAliasManager* aliasManager() { return instance()->_aliasManager; } backlogManager()123 static inline ClientBacklogManager* backlogManager() { return instance()->_backlogManager; } coreInfo()124 static inline CoreInfo* coreInfo() { return instance()->_coreInfo; } dccConfig()125 static inline DccConfig* dccConfig() { return instance()->_dccConfig; } ircListHelper()126 static inline ClientIrcListHelper* ircListHelper() { return instance()->_ircListHelper; } bufferViewManager()127 static inline ClientBufferViewManager* bufferViewManager() { return instance()->_bufferViewManager; } bufferViewOverlay()128 static inline BufferViewOverlay* bufferViewOverlay() { return instance()->_bufferViewOverlay; } inputHandler()129 static inline ClientUserInputHandler* inputHandler() { return instance()->_inputHandler; } networkConfig()130 static inline NetworkConfig* networkConfig() { return instance()->_networkConfig; } ignoreListManager()131 static inline ClientIgnoreListManager* ignoreListManager() { return instance()->_ignoreListManager; } highlightRuleManager()132 static inline HighlightRuleManager* highlightRuleManager() { return instance()->_highlightRuleManager; } transferManager()133 static inline ClientTransferManager* transferManager() { return instance()->_transferManager; } transferModel()134 static inline TransferModel* transferModel() { return instance()->_transferModel; } 135 bufferSyncer()136 static inline BufferSyncer* bufferSyncer() { return instance()->_bufferSyncer; } 137 coreAccountModel()138 static inline CoreAccountModel* coreAccountModel() { return instance()->_coreAccountModel; } coreConnection()139 static inline CoreConnection* coreConnection() { return instance()->_coreConnection; } currentCoreAccount()140 static inline CoreAccount currentCoreAccount() { return coreConnection()->currentAccount(); } 141 static bool isCoreFeatureEnabled(Quassel::Feature feature); 142 143 static bool isConnected(); 144 static bool internalCore(); 145 146 static void userInput(const BufferInfo& bufferInfo, const QString& message); 147 148 static void setBufferLastSeenMsg(BufferId id, const MsgId& msgId); // this is synced to core and other clients 149 static void setMarkerLine(BufferId id, const MsgId& msgId); // this is synced to core and other clients 150 static MsgId markerLine(BufferId id); 151 152 static void removeBuffer(BufferId id); 153 static void renameBuffer(BufferId bufferId, const QString& newName); 154 static void mergeBuffersPermanently(BufferId bufferId1, BufferId bufferId2); 155 static void purgeKnownBufferIds(); 156 157 /** 158 * Requests client to resynchronize the CoreInfo object for legacy (pre-0.13) cores 159 * 160 * This provides compatibility with updating core information for legacy cores, and can be 161 * removed after protocol break. 162 * 163 * NOTE: On legacy (pre-0.13) cores, any existing connected signals will be destroyed and must 164 * be re-added after calling this, in addition to checking for existing data in coreInfo(). 165 */ 166 static void refreshLegacyCoreInfo(); 167 168 static void changePassword(const QString& oldPassword, const QString& newPassword); 169 static void kickClient(int peerId); 170 displayIgnoreList(QString ignoreRule)171 void displayIgnoreList(QString ignoreRule) { emit showIgnoreList(ignoreRule); } 172 173 /** 174 * Request to show the channel list dialog for the network, optionally searching by channel name 175 * 176 * @see Client::showChannelList() 177 * 178 * @param networkId Network ID for associated network 179 * @param channelFilters Partial channel name to search for, or empty to show all 180 * @param listImmediately If true, immediately list channels, otherwise just show dialog 181 */ 182 void displayChannelList(NetworkId networkId, const QString& channelFilters = {}, bool listImmediately = false) 183 { 184 emit showChannelList(networkId, channelFilters, listImmediately); 185 } 186 187 signals: 188 void requestNetworkStates(); 189 190 void showConfigWizard(const QVariantMap& coredata); 191 192 /** 193 * Request to show the channel list dialog for the network, optionally searching by channel name 194 * 195 * @see MainWin::showChannelList() 196 * 197 * @param networkId Network ID for associated network 198 * @param channelFilters Partial channel name to search for, or empty to show all 199 * @param listImmediately If true, immediately list channels, otherwise just show dialog 200 */ 201 void showChannelList(NetworkId networkId, const QString& channelFilters = {}, bool listImmediately = false); 202 203 void showIgnoreList(QString ignoreRule); 204 205 void connected(); 206 void disconnected(); 207 void coreConnectionStateChanged(bool); 208 209 /** 210 * Signals that core information has been resynchronized, removing existing signal handlers 211 * 212 * Whenever this is emitted, one should re-add any handlers for CoreInfo::coreDataChanged() and 213 * apply any existing information in the coreInfo() object. 214 * 215 * Only emitted on legacy (pre-0.13) cores. Generally, one should use the 216 * CoreInfo::coreDataChanged() signal too. 217 */ 218 void coreInfoResynchronized(); 219 220 //! The identity with the given ID has been newly created in core and client. 221 /** \param id The ID of the newly created identity. 222 */ 223 void identityCreated(IdentityId id); 224 225 //! The identity with the given ID has been removed. 226 /** Upon emitting this signal, the identity is already gone from the core, and it will 227 * be deleted from the client immediately afterwards, so connected slots need to clean 228 * up their stuff. 229 * \param id The ID of the identity about to be removed. 230 */ 231 void identityRemoved(IdentityId id); 232 233 //! Sent to the core when an identity shall be created. Should not be used elsewhere. 234 void requestCreateIdentity(const Identity&, const QVariantMap&); 235 //! Sent to the core when an identity shall be removed. Should not be used elsewhere. 236 void requestRemoveIdentity(IdentityId); 237 238 void networkCreated(NetworkId id); 239 void networkRemoved(NetworkId id); 240 241 void requestCreateNetwork(const NetworkInfo& info, const QStringList& persistentChannels = QStringList()); 242 void requestRemoveNetwork(NetworkId); 243 244 //! Emitted when a buffer has been marked as read 245 /** This is currently triggered by setting lastSeenMsg, either local or remote, 246 * or by bringing the window to front. 247 * \param id The buffer that has been marked as read 248 */ 249 void bufferMarkedAsRead(BufferId id); 250 251 //! Requests a password change (user name must match the currently logged in user) 252 void requestPasswordChange(PeerPtr peer, const QString& userName, const QString& oldPassword, const QString& newPassword); 253 254 void requestKickClient(int peerId); 255 void passwordChanged(bool success); 256 257 //! Emitted when database schema upgrade starts or ends (only mono client) 258 void dbUpgradeInProgress(bool inProgress); 259 260 //! Emitted before an exit request is handled 261 void exitRequested(const QString& reason); 262 263 public slots: 264 void disconnectFromCore(); 265 266 void bufferRemoved(BufferId bufferId); 267 void bufferRenamed(BufferId bufferId, const QString& newName); 268 void buffersPermanentlyMerged(BufferId bufferId1, BufferId bufferId2); 269 270 void markBufferAsRead(BufferId id); 271 272 void onDbUpgradeInProgress(bool inProgress); 273 void onExitRequested(int exitCode, const QString& reason); 274 275 private slots: 276 void setSyncedToCore(); 277 void setDisconnectedFromCore(); 278 void connectionStateChanged(CoreConnection::ConnectionState); 279 280 void recvMessage(const Message& message); 281 void recvStatusMsg(QString network, QString message); 282 283 void networkDestroyed(); 284 void coreIdentityCreated(const Identity&); 285 void coreIdentityRemoved(IdentityId); 286 void coreNetworkCreated(NetworkId); 287 void coreNetworkRemoved(NetworkId); 288 289 void corePasswordChanged(PeerPtr, bool success); 290 291 void finishConnectionInitialization(); 292 293 void sendBufferedUserInput(); 294 295 private: 296 void requestInitialBacklog(); 297 298 /** 299 * Deletes and resynchronizes the CoreInfo object for legacy (pre-0.13) cores 300 * 301 * This provides compatibility with updating core information for legacy cores, and can be 302 * removed after protocol break. 303 * 304 * NOTE: On legacy (pre-0.13) cores, any existing connected signals will be destroyed and must 305 * be re-added after calling this, in addition to checking for existing data in coreInfo(). 306 */ 307 void requestLegacyCoreInfo(); 308 309 static void addNetwork(Network*); 310 311 SignalProxy* _signalProxy{nullptr}; 312 std::unique_ptr<AbstractUi> _mainUi; 313 NetworkModel* _networkModel{nullptr}; 314 BufferModel* _bufferModel{nullptr}; 315 BufferSyncer* _bufferSyncer{nullptr}; 316 ClientAliasManager* _aliasManager{nullptr}; 317 ClientBacklogManager* _backlogManager{nullptr}; 318 ClientBufferViewManager* _bufferViewManager{nullptr}; 319 BufferViewOverlay* _bufferViewOverlay{nullptr}; 320 CoreInfo* _coreInfo{nullptr}; 321 DccConfig* _dccConfig{nullptr}; 322 ClientIrcListHelper* _ircListHelper{nullptr}; 323 ClientUserInputHandler* _inputHandler{nullptr}; 324 NetworkConfig* _networkConfig{nullptr}; 325 ClientIgnoreListManager* _ignoreListManager{nullptr}; 326 HighlightRuleManager* _highlightRuleManager{nullptr}; 327 ClientTransferManager* _transferManager{nullptr}; 328 TransferModel* _transferModel{nullptr}; 329 330 MessageModel* _messageModel{nullptr}; 331 AbstractMessageProcessor* _messageProcessor{nullptr}; 332 333 CoreAccountModel* _coreAccountModel{nullptr}; 334 CoreConnection* _coreConnection{nullptr}; 335 336 ClientMode clientMode{}; 337 338 QHash<NetworkId, Network*> _networks; 339 QHash<IdentityId, Identity*> _identities; 340 341 bool _connected{false}; 342 343 QList<QPair<BufferInfo, QString>> _userInputBuffer; 344 345 friend class CoreConnection; 346 }; 347