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