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