File indexing completed on 2024-05-19 04:29:15
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org> 0003 SPDX-FileCopyrightText: 2000-2004 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KIS_MAIN_WINDOW_H 0009 #define KIS_MAIN_WINDOW_H 0010 0011 #include "kritaui_export.h" 0012 0013 #include <QPointer> 0014 #include <QPrinter> 0015 #include <QUuid> 0016 #include <QUrl> 0017 0018 #include <xmlgui/kxmlguiwindow.h> 0019 #include <KoCanvasObserverBase.h> 0020 #include <KoCanvasSupervisor.h> 0021 #include "KisView.h" 0022 #include <kis_workspace_resource.h> 0023 #include <KoResource.h> 0024 0025 class QCloseEvent; 0026 class QMoveEvent; 0027 0028 class KoCanvasResourceProvider; 0029 0030 class KisDocument; 0031 class KoDockFactoryBase; 0032 class QDockWidget; 0033 class KisView; 0034 class KisViewManager; 0035 class KoCanvasController; 0036 0037 0038 /** 0039 * @brief Main window for Krita 0040 * 0041 * This class is used to represent a main window within a Krita session. Each 0042 * main window contains a menubar and some toolbars, and potentially several 0043 * views of several canvases. 0044 * 0045 */ 0046 class KRITAUI_EXPORT KisMainWindow : public KXmlGuiWindow, public KoCanvasSupervisor 0047 { 0048 Q_OBJECT 0049 0050 public: 0051 enum OpenFlag { 0052 None = 0, 0053 Import = 0x1, 0054 BatchMode = 0x2, 0055 RecoveryFile = 0x4 0056 }; 0057 Q_DECLARE_FLAGS(OpenFlags, OpenFlag) 0058 0059 public: 0060 0061 /** 0062 * Initializes a Krita main window (with its basic GUI etc.). 0063 */ 0064 explicit KisMainWindow(QUuid id = QUuid()); 0065 0066 /** 0067 * Destructor. 0068 */ 0069 ~KisMainWindow() override; 0070 0071 QMenu *createPopupMenu() override; 0072 0073 0074 QUuid id() const; 0075 0076 /** 0077 * @brief showView shows the given view, in @p subWindow if not 0078 * null, in a new tab otherwise. 0079 */ 0080 virtual void showView(KisView *view, QMdiSubWindow *subWindow = 0); 0081 0082 /** 0083 * @returns the currently active view 0084 */ 0085 KisView *activeView() const; 0086 0087 /** 0088 * Load the desired document and show it. 0089 * @param url the URL to open 0090 * 0091 * @return TRUE on success. 0092 */ 0093 bool openDocument(const QString &path, OpenFlags flags); 0094 0095 /** 0096 * Activate a view containing the document in this window, creating one if needed. 0097 */ 0098 void showDocument(KisDocument *document); 0099 0100 0101 /** 0102 * Toggles between showing the welcome screen and the MDI area 0103 * 0104 * hack: There seems to be a bug that prevents events happening to the MDI area if it 0105 * isn't actively displayed (set in the widgetStack). This can cause things like the title bar 0106 * not to update correctly Before doing any actions related to opening or creating documents, 0107 * make sure to switch this first to make sure everything can communicate to the MDI area correctly 0108 */ 0109 void showWelcomeScreen(bool show); 0110 0111 /** 0112 * Saves the document, asking for a filename if necessary. 0113 * 0114 * @param saveas if set to TRUE the user is always prompted for a filename 0115 * @param silent if set to TRUE rootDocument()->setTitleModified will not be called. 0116 * 0117 * @return TRUE on success, false on error or cancel 0118 * (don't display anything in this case, the error dialog box is also implemented here 0119 * but restore the original URL in slotFileSaveAs) 0120 */ 0121 bool saveDocument(KisDocument *document, bool saveas, bool isExporting, bool isAdvancedExporting = false); 0122 0123 void setReadWrite(bool readwrite); 0124 0125 /// Return the list of dock widgets belonging to this main window. 0126 QList<QDockWidget*> dockWidgets() const; 0127 0128 QDockWidget* dockWidget(const QString &id); 0129 0130 QList<KoCanvasObserverBase*> canvasObservers() const override; 0131 0132 KoCanvasResourceProvider *resourceManager() const; 0133 0134 int viewCount() const; 0135 0136 void saveWindowState(bool restoreNormalState =false); 0137 0138 const KConfigGroup &windowStateConfig() const; 0139 0140 /** 0141 * A wrapper around restoreState 0142 * @param state the saved state 0143 * @return TRUE on success 0144 */ 0145 bool restoreWorkspace(KoResourceSP res); 0146 bool restoreWorkspaceState(const QByteArray &state); 0147 0148 static void swapWorkspaces(KisMainWindow *a, KisMainWindow *b); 0149 0150 KisViewManager *viewManager() const; 0151 0152 KisView *addViewAndNotifyLoadingCompleted(KisDocument *document, 0153 QMdiSubWindow *subWindow = 0); 0154 0155 QStringList showOpenFileDialog(bool isImporting); 0156 0157 /** 0158 * The top-level window used for a detached canvas. 0159 */ 0160 QWidget *canvasWindow() const; 0161 bool canvasDetached() const; 0162 0163 /** 0164 * Shows if the main window is saving anything right now. If the 0165 * user presses Ctrl+W too fast, then the document can be close 0166 * before the saving is completed. I'm not sure if it is fixable 0167 * in any way without avoiding using processEvents() 0168 * everywhere (DK) 0169 * 0170 * Don't use it unless you have no option. 0171 */ 0172 bool hackIsSaving() const; 0173 0174 /// Copy the given file into the bundle directory. 0175 bool installBundle(const QString &fileName) const; 0176 0177 /** 0178 * @brief layoutThumbnail 0179 * @return image for the workspaces. 0180 */ 0181 QImage layoutThumbnail(); 0182 0183 Q_SIGNALS: 0184 0185 /** 0186 * This signal is emitted if the document has been saved successfully. 0187 */ 0188 void documentSaved(); 0189 0190 /// This signal is emitted when this windows has finished loading of a 0191 /// document. The document may be opened in another window in the end. 0192 /// In this case, the signal means there is no link between the window 0193 /// and the document anymore. 0194 void loadCompleted(); 0195 0196 /// This signal is emitted right after the docker states have been successfully restored from config 0197 void restoringDone(); 0198 0199 /// This signal is emitted when the color theme changes 0200 void themeChanged(); 0201 0202 /// This signal is emitted when the shortcut key configuration has changed 0203 void keyBindingsChanged(); 0204 0205 void guiLoadingFinished(); 0206 0207 /// emitted when the current view has changed 0208 void activeViewChanged(); 0209 0210 0211 public Q_SLOTS: 0212 0213 0214 /** 0215 * clears the list of the recent files 0216 */ 0217 void clearRecentFiles(); 0218 0219 /** 0220 * remove one file from the list of the recent files 0221 */ 0222 void removeRecentFile(QString url); 0223 0224 0225 /** 0226 * Slot for opening a new document. 0227 * 0228 * If the current document is empty, the new document replaces it. 0229 * If not, a new mainwindow will be opened for showing the document. 0230 */ 0231 void slotFileNew(); 0232 0233 /** 0234 * Slot for opening a saved file. 0235 * 0236 * If the current document is empty, the opened document replaces it. 0237 * If not a new mainwindow will be opened for showing the opened file. 0238 */ 0239 void slotFileOpen(bool isImporting = false); 0240 0241 /** 0242 * Slot for opening a file among the recently opened files. 0243 * 0244 * If the current document is empty, the opened document replaces it. 0245 * If not a new mainwindow will be opened for showing the opened file. 0246 */ 0247 void slotFileOpenRecent(const QUrl &); 0248 0249 /** 0250 * @brief slotPreferences open the preferences dialog 0251 */ 0252 void slotPreferences(); 0253 0254 /** 0255 * Saves the current document with the current name. 0256 */ 0257 void slotFileSave(); 0258 0259 0260 void slotShowSessionManager(); 0261 0262 /** 0263 * Update the option widgets to the argument ones, removing the currently set widgets. 0264 */ 0265 void newOptionWidgets(KoCanvasController *controller, const QList<QPointer<QWidget> > & optionWidgetList); 0266 0267 KisView *newView(QObject *document, QMdiSubWindow *subWindow = 0); 0268 0269 void notifyChildViewDestroyed(KisView *view); 0270 0271 /// Set the active view, this will update the undo/redo actions 0272 void setActiveView(KisView *view); 0273 void unsetActiveView(); 0274 0275 void subWindowActivated(); 0276 0277 void windowFocused(); 0278 0279 /** 0280 * Detach canvas onto a separate window, or restore it back to to main window. 0281 */ 0282 void setCanvasDetached(bool detached); 0283 0284 /** 0285 * Toggle full screen on/off. 0286 */ 0287 void viewFullscreen(bool fullScreen); 0288 0289 /** 0290 * @brief checkActiveStorages checks whether there is at least one bundle available and 0291 * at least one paintop preset. 0292 */ 0293 bool checkActiveBundlesAvailable(); 0294 bool checkPaintOpAvailable(); 0295 0296 0297 private Q_SLOTS: 0298 void slotLoadCompleted(); 0299 void slotLoadCanceled(const QString &); 0300 void slotSaveCompleted(); 0301 void slotSaveCanceled(const QString &); 0302 void forceDockTabFonts(); 0303 0304 void slotUpdateWidgetStyle(); 0305 0306 void slotUpdateSaveActionTitle(const QString &documentPath); 0307 0308 /** 0309 * Saves the current document with a new name. 0310 */ 0311 void slotFileSaveAs(); 0312 0313 void importAnimation(); 0314 0315 void importVideoAnimation(); 0316 0317 void renderAnimation(); 0318 0319 void renderAnimationAgain(); 0320 0321 /** 0322 * Show a dialog with author and document information. 0323 */ 0324 void slotDocumentInfo(); 0325 0326 /** 0327 * Closes all open documents. 0328 */ 0329 bool slotFileCloseAll(); 0330 0331 /** 0332 * @brief showAboutApplication show the about box 0333 */ 0334 virtual void showAboutApplication(); 0335 0336 /** 0337 * Closes the mainwindow. 0338 */ 0339 void slotFileQuit(); 0340 0341 /** 0342 * Configure toolbars. 0343 */ 0344 void slotConfigureToolbars(); 0345 0346 /** 0347 * Post toolbar config. 0348 * (Plug action lists back in, etc.) 0349 */ 0350 void slotNewToolbarConfig(); 0351 0352 /** 0353 * Reset User Configurations. 0354 */ 0355 void slotResetConfigurations(); 0356 0357 /** 0358 * Shows or hides a toolbar 0359 */ 0360 void slotToolbarToggled(bool toggle); 0361 0362 /** 0363 * Toggle docker titlebars on/off. 0364 */ 0365 void showDockerTitleBars(bool show); 0366 0367 /** 0368 * File --> Import 0369 * 0370 * This will call slotFileOpen(). 0371 */ 0372 void slotImportFile(); 0373 0374 /** 0375 * File --> Export 0376 * 0377 * This will call slotFileSaveAs(). 0378 */ 0379 void slotExportFile(); 0380 0381 void slotExportAdvance(); 0382 0383 /** 0384 * Hide the dockers 0385 */ 0386 void toggleDockersVisibility(bool visible, bool onWelcomePage = false); 0387 0388 /** 0389 * Handle theme changes from theme manager 0390 */ 0391 void updateTheme(); 0392 void slotThemeChanged(); 0393 0394 void undo(); 0395 void redo(); 0396 void updateWindowMenu(); 0397 void updateSubwindowFlags(); 0398 void setActiveSubWindow(QWidget *window); 0399 void configChanged(); 0400 0401 void newWindow(); 0402 void closeCurrentWindow(); 0403 void checkSanity(); 0404 0405 /// Quits Krita with error message from m_errorMessage. 0406 void showErrorAndDie(); 0407 0408 void initializeGeometry(); 0409 void showManual(); 0410 void switchTab(int index); 0411 0412 void slotXmlGuiMakingChanges(bool finished); 0413 0414 void orientationChanged(); 0415 0416 void restoreWorkspace(); 0417 0418 void openCommandBar(); 0419 0420 void slotStoragesWarning(const QString &location = QString()); 0421 0422 protected: 0423 0424 void closeEvent(QCloseEvent * e) override; 0425 void resizeEvent(QResizeEvent * e) override; 0426 void showEvent(QShowEvent *event) override; 0427 0428 // QWidget overrides 0429 void dragMoveEvent(QDragMoveEvent *event) override; 0430 void dragLeaveEvent(QDragLeaveEvent *event) override; 0431 0432 bool windowsLayoutSavingAllowed() const override; 0433 0434 private: 0435 0436 friend class KisWelcomePageWidget; 0437 void dragMove(QDragMoveEvent *event); 0438 void dragLeave(); 0439 0440 private: 0441 0442 /** 0443 * Add a the given view to the list of views of this mainwindow. 0444 * This is a private implementation. For public usage please use 0445 * newView() and addViewAndNotifyLoadingCompleted(). 0446 */ 0447 void addView(KisView *view, QMdiSubWindow *subWindow = 0); 0448 0449 friend class KisPart; 0450 0451 0452 /** 0453 * Returns the dockwidget specified by the @p factory. If the dock widget doesn't exist yet it's created. 0454 * Add a "view_palette_action_menu" action to your view menu if you want to use closable dock widgets. 0455 * @param factory the factory used to create the dock widget if needed 0456 * @return the dock widget specified by @p factory (may be 0) 0457 */ 0458 QDockWidget* createDockWidget(KoDockFactoryBase* factory); 0459 0460 bool openDocumentInternal(const QString &path, KisMainWindow::OpenFlags f = KisMainWindow::OpenFlags()); 0461 0462 void saveWindowSettings(); 0463 0464 QPointer<KisView> activeKisView(); 0465 0466 void createActions(); 0467 0468 void applyToolBarLayout(); 0469 0470 QByteArray borrowWorkspace(KisMainWindow *borrower); 0471 0472 void customizeTabBar(); 0473 0474 void setMainWindowLayoutForCurrentMainWidget(int widgetIndex, bool widgetIndexChanged); 0475 void adjustLayoutForWelcomePage(); 0476 0477 private: 0478 0479 /** 0480 * Struct used in the list created by createCustomDocumentWidgets() 0481 */ 0482 struct CustomDocumentWidgetItem { 0483 /// Pointer to the custom document widget 0484 QWidget *widget; 0485 /// title used in the sidebar. If left empty it will be displayed as "Custom Document" 0486 QString title; 0487 /// icon used in the sidebar. If left empty it will use the unknown icon 0488 QString icon; 0489 }; 0490 0491 class Private; 0492 Private * const d; 0493 0494 QString m_errorMessage; 0495 bool m_dieOnError; 0496 }; 0497 0498 Q_DECLARE_OPERATORS_FOR_FLAGS(KisMainWindow::OpenFlags) 0499 0500 #endif