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