File indexing completed on 2024-04-28 05:49:27
0001 /* 0002 SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org> 0003 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include <ktexteditor/application.h> 0011 0012 #ifdef WITH_KUSERFEEDBACK 0013 #include <KUserFeedback/Provider> 0014 #endif 0015 0016 #include "kateappadaptor.h" 0017 #include "katedocmanager.h" 0018 #include "katepluginmanager.h" 0019 #include "kateprivate_export.h" 0020 #include "katesessionmanager.h" 0021 #include "katestashmanager.h" 0022 0023 #include <KConfig> 0024 #include <QList> 0025 0026 class KAboutData; 0027 class KateSessionManager; 0028 class KateMainWindow; 0029 class KatePluginManager; 0030 class KateDocManager; 0031 class KateAppCommands; 0032 class KateAppAdaptor; 0033 class QCommandLineParser; 0034 0035 /** 0036 * Kate Application 0037 * This class represents the core kate application object 0038 */ 0039 class KATE_PRIVATE_EXPORT KateApp : public QObject 0040 { 0041 Q_OBJECT 0042 0043 /** 0044 * constructors & accessor to app object + plugin interface for it 0045 */ 0046 public: 0047 /** 0048 * Do the needed setup steps before we create our QApplication. 0049 * @param detach shall we detach from the terminal? 0050 */ 0051 static void initPreApplicationCreation(bool detach); 0052 0053 /** 0054 * Was the application started inside a terminal? 0055 */ 0056 static bool isInsideTerminal(); 0057 0058 /** 0059 * Are we full featured Kate or the simplified KWrite? 0060 */ 0061 enum ApplicationMode { ApplicationKate, ApplicationKWrite }; 0062 0063 /** 0064 * application constructor 0065 * @param arg command line parser, reference will be stored, needs to survive as long as application object is alive 0066 * @param mode application mode, either Kate or KWrite 0067 * @param sessionDir directory used to store the session config files 0068 */ 0069 KateApp(const QCommandLineParser &arg, const ApplicationMode mode, const QString &sessionsDir); 0070 0071 /** 0072 * return current application mode 0073 */ 0074 static ApplicationMode mode() 0075 { 0076 return KateApp::self()->m_mode; 0077 } 0078 0079 /** 0080 * return current application mode 0081 */ 0082 static bool isKate() 0083 { 0084 return mode() == KateApp::ApplicationKate; 0085 } 0086 0087 /** 0088 * return current application mode 0089 */ 0090 static bool isKWrite() 0091 { 0092 return mode() == KateApp::ApplicationKWrite; 0093 } 0094 0095 /** 0096 * Fill in the authors and credits for the application. 0097 * Use by Kate & KWrite 0098 */ 0099 static void fillAuthorsAndCredits(KAboutData &aboutData); 0100 0101 /** 0102 * get kate inited 0103 * @return false, if application should exit 0104 */ 0105 bool init(); 0106 0107 /** 0108 * application destructor 0109 */ 0110 ~KateApp() override; 0111 0112 /** 0113 * static accessor to avoid casting ;) 0114 * @return app instance 0115 */ 0116 static KateApp *self(); 0117 0118 /** 0119 * KTextEditor::Application wrapper 0120 * @return KTextEditor::Application wrapper. 0121 */ 0122 KTextEditor::Application *wrapper() 0123 { 0124 return &m_wrapper; 0125 } 0126 0127 #ifdef WITH_KUSERFEEDBACK 0128 /** 0129 * Get our global user feedback provider 0130 * @return user feedback provider 0131 */ 0132 KUserFeedback::Provider &userFeedbackProvider() 0133 { 0134 return m_userFeedbackProvider; 0135 } 0136 #endif 0137 0138 /** 0139 * kate init 0140 */ 0141 private: 0142 /** 0143 * restore a old kate session 0144 */ 0145 void restoreKate(); 0146 0147 /** 0148 * try to start kate 0149 * @return success, if false, kate should exit 0150 */ 0151 bool startupKate(); 0152 0153 /** 0154 * kate shutdown 0155 */ 0156 public: 0157 /** 0158 * shutdown kate application 0159 * @param win mainwindow which is used for dialogs 0160 */ 0161 void shutdownKate(KateMainWindow *win); 0162 0163 /** 0164 * other accessors for global unique instances 0165 */ 0166 public: 0167 /** 0168 * accessor to plugin manager 0169 * @return plugin manager instance 0170 */ 0171 KatePluginManager *pluginManager(); 0172 0173 /** 0174 * accessor to document manager 0175 * @return document manager instance 0176 */ 0177 KateDocManager *documentManager(); 0178 0179 /** 0180 * accessor to session manager 0181 * @return session manager instance 0182 */ 0183 KateSessionManager *sessionManager(); 0184 0185 /** 0186 * 0187 */ 0188 KateStashManager *stashManager(); 0189 0190 /** 0191 * window management 0192 */ 0193 public: 0194 /** 0195 * create a new main window, use given config if any for restore 0196 * @param sconfig session config object 0197 * @param sgroup session group for this window 0198 * @param userTriggered did the user trigger creation of this new window 0199 * @return new constructed main window 0200 */ 0201 static KateMainWindow *newMainWindow(KConfig *sconfig = nullptr, const QString &sgroup = QString(), bool userTriggered = false); 0202 0203 /** 0204 * add the mainwindow given 0205 * should be called in mainwindow constructor 0206 * @param mainWindow window to remove 0207 */ 0208 void addMainWindow(KateMainWindow *mainWindow); 0209 0210 /** 0211 * removes the mainwindow given, DOES NOT DELETE IT 0212 * should be called in mainwindow destructor 0213 * @param mainWindow window to remove 0214 */ 0215 void removeMainWindow(KateMainWindow *mainWindow); 0216 0217 /** 0218 * give back current active main window 0219 * can only be 0 at app start or exit 0220 * @return current active main window 0221 */ 0222 KateMainWindow *activeKateMainWindow(); 0223 0224 /** 0225 * give back number of existing main windows 0226 * @return number of main windows 0227 */ 0228 int mainWindowsCount() const; 0229 0230 /** 0231 * give back the window you want 0232 * @param n window index 0233 * @return requested main window 0234 */ 0235 KateMainWindow *mainWindow(int n); 0236 0237 int mainWindowID(KateMainWindow *window); 0238 0239 /** 0240 * Has the given document tabs/views inside main windows 0241 * other then the given one? 0242 * 0243 * @param doc document to check 0244 * @param window window to check 0245 * @return is this document visible as tab/view/... in any other window? 0246 */ 0247 bool documentVisibleInOtherWindows(KTextEditor::Document *doc, KateMainWindow *window) const; 0248 0249 /** 0250 * some stuff for the DBus API 0251 */ 0252 public: 0253 /** 0254 * open url with given encoding 0255 * used by kate if --use given 0256 * @param url filename 0257 * @param encoding encoding name 0258 * @param isTempFile whether the file is temporary 0259 * @param activateView activate the view of the opened document? 0260 * @param c cursor position to set if not invalid 0261 * @return opened document or nullptr 0262 */ 0263 KTextEditor::Document * 0264 openDocUrl(const QUrl &url, const QString &encoding, bool isTempFile, bool activateView = true, KTextEditor::Cursor c = KTextEditor::Cursor::invalid()); 0265 0266 /** 0267 * position cursor in current active view 0268 * will clear selection 0269 * @param line line to set 0270 * @param column column to set 0271 * @return success 0272 */ 0273 bool setCursor(int line, int column); 0274 0275 /** 0276 * Checks if --line and/or --column args were provided and 0277 * returns the cursor for it 0278 */ 0279 KTextEditor::Cursor cursorFromArgs(); 0280 0281 /** 0282 * Checks if line or column were provided in query string 0283 * (e.g. file:///file1?line=3&column=4) and returns the cursor 0284 * If cursor was not set it will return invalid cursor 0285 * 0286 * @param url the url to check 0287 */ 0288 KTextEditor::Cursor cursorFromQueryString(const QUrl &url); 0289 0290 /** 0291 * @return true if --line or --column command line args were provided 0292 */ 0293 bool hasCursorInArgs(); 0294 0295 /** 0296 * helper to handle stdin input 0297 * open a new document/view, fill it with the text given 0298 * @param text text to fill in the new doc/view 0299 * @param encoding encoding to set for the document, if any 0300 * @return success 0301 */ 0302 bool openInput(const QString &text, const QString &encoding); 0303 0304 // 0305 // KTextEditor::Application interface, called by wrappers via invokeMethod 0306 // 0307 public Q_SLOTS: 0308 /** 0309 * Get a list of all main windows. 0310 * @return all main windows 0311 */ 0312 QList<KTextEditor::MainWindow *> mainWindows(); 0313 0314 /** 0315 * Accessor to the active main window. 0316 * \return a pointer to the active mainwindow 0317 */ 0318 KTextEditor::MainWindow *activeMainWindow(); 0319 0320 /** 0321 * Get a list of all documents that are managed by the application. 0322 * This might contain less documents than the editor has in his documents () list. 0323 * @return all documents the application manages 0324 */ 0325 QList<KTextEditor::Document *> documents() 0326 { 0327 return m_docManager.documentList(); 0328 } 0329 0330 /** 0331 * Get the document with the URL \p url. 0332 * if multiple documents match the searched url, return the first found one... 0333 * \param url the document's URL 0334 * \return the document with the given \p url or NULL, if none found 0335 */ 0336 KTextEditor::Document *findUrl(const QUrl &url) 0337 { 0338 return m_docManager.findDocument(url); 0339 } 0340 0341 /** 0342 * Open the document \p url with the given \p encoding. 0343 * if the url is empty, a new empty document will be created 0344 * \param url the document's url 0345 * \param encoding the preferred encoding. If encoding is QString() the 0346 * encoding will be guessed or the default encoding will be used. 0347 * \return a pointer to the created document 0348 */ 0349 KTextEditor::Document *openUrl(const QUrl &url, const QString &encoding = QString()) 0350 { 0351 return m_docManager.openUrl(url, encoding); 0352 } 0353 0354 /** 0355 * Close the given \p document. If the document is modified, user will be asked if he wants that. 0356 * \param document the document to be closed 0357 * \return \e true on success, otherwise \e false 0358 */ 0359 bool closeDocument(KTextEditor::Document *document) 0360 { 0361 return closeDocuments({document}); 0362 } 0363 0364 /** 0365 * Close a list of documents. If any of them are modified, user will be asked if he wants that. 0366 * Use this, if you want to close multiple documents at once, as the application might 0367 * be able to group the "do you really want that" dialogs into one. 0368 * \param documents list of documents to be closed 0369 * \return \e true on success, otherwise \e false 0370 */ 0371 bool closeDocuments(const QList<KTextEditor::Document *> &documents); 0372 0373 /** 0374 * Get a plugin for the plugin with with identifier \p name. 0375 * \param name the plugin's name 0376 * \return pointer to the plugin if a plugin with \p name is loaded, otherwise nullptr 0377 */ 0378 KTextEditor::Plugin *plugin(const QString &name); 0379 0380 /** 0381 * Ask app to quit. The app might interact with the user and decide that 0382 * quitting is not possible and return false. 0383 * 0384 * \return true if the app could quit 0385 */ 0386 bool quit() 0387 { 0388 shutdownKate(activeKateMainWindow()); 0389 return true; 0390 } 0391 0392 /** 0393 * last time some QEvent::ActivationChange occured 0394 * used to determine which instance to reuse, if we have multiple 0395 */ 0396 qint64 lastActivationChange() const 0397 { 0398 return m_lastActivationChange; 0399 } 0400 0401 /** 0402 * A message is received from an external instance, if we use QtSingleApplication 0403 * 0404 * \p instanceId the instance id we got the message from 0405 * \p message is a serialized message (at the moment just the file list separated by ';') 0406 */ 0407 void remoteMessageReceived(quint32 instanceId, QByteArray message); 0408 0409 Q_SIGNALS: 0410 /** 0411 * Emitted when the configuration got changed via the global config dialog. 0412 * Allows widgets to listen on this and adapt, the KSharedConfig::openConfig() 0413 * is already updated. 0414 */ 0415 void configurationChanged(); 0416 0417 protected: 0418 /** 0419 * Event filter for QApplication to handle mac os like file open 0420 */ 0421 bool eventFilter(QObject *obj, QEvent *event) override; 0422 0423 private Q_SLOTS: 0424 /** 0425 * Handle destroy of documents created via openDocUrl. 0426 * Needed to e.g. emit token signal and cleanup temporary files. 0427 */ 0428 void openDocUrlDocumentDestroyed(QObject *document); 0429 0430 private: 0431 /** 0432 * kate's command line args 0433 */ 0434 const QCommandLineParser &m_args; 0435 0436 /** 0437 * application mode, kate or kwrite 0438 */ 0439 const ApplicationMode m_mode; 0440 0441 /** 0442 * files opened via --tempfile, must be deleted on program exit 0443 * need to be constructed before document manager as the destructor of that might 0444 * access it via the destroyed signal of the document 0445 */ 0446 QHash<QObject *, QStringList> m_tempFilesToDelete; 0447 0448 /** 0449 * known main windows 0450 */ 0451 QList<KateMainWindow *> m_mainWindows; 0452 0453 /** 0454 * Wrapper of application for KTextEditor 0455 */ 0456 KTextEditor::Application m_wrapper; 0457 0458 /** 0459 * dbus interface, must survive longer than m_docManager 0460 * e.g. the destroyed signal of the document might access this 0461 */ 0462 KateAppAdaptor m_adaptor; 0463 0464 /** 0465 * document manager 0466 */ 0467 KateDocManager m_docManager; 0468 0469 /** 0470 * plugin manager 0471 */ 0472 KatePluginManager m_pluginManager; 0473 0474 /** 0475 * session manager 0476 */ 0477 KateSessionManager m_sessionManager; 0478 0479 KateStashManager m_stashManager; 0480 0481 #ifdef WITH_KUSERFEEDBACK 0482 /** 0483 * user feedback provider 0484 */ 0485 KUserFeedback::Provider m_userFeedbackProvider; 0486 #endif 0487 0488 /** 0489 * last time some QEvent::ActivationChange occured 0490 * used to determine which instance to reuse, if we have multiple 0491 */ 0492 qint64 m_lastActivationChange; 0493 };