File indexing completed on 2024-04-28 04:20:20
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #ifndef KP_MAIN_WINDOW_H 0030 #define KP_MAIN_WINDOW_H 0031 0032 0033 #include <QUrl> 0034 0035 #include <kxmlguiwindow.h> 0036 0037 #include "kpDefs.h" 0038 #include "pixmapfx/kpPixmapFX.h" 0039 #include "imagelib/kpImage.h" 0040 0041 0042 class QAction; 0043 class QActionGroup; 0044 class QDragEnterEvent; 0045 class QDropEvent; 0046 class QMenu; 0047 class QMoveEvent; 0048 class QPoint; 0049 class QRect; 0050 class QSize; 0051 0052 class KConfigGroup; 0053 class KToolBar; 0054 class QPrinter; 0055 0056 class kpColor; 0057 class kpColorCells; 0058 class kpColorToolBar; 0059 class kpCommand; 0060 class kpCommandEnvironment; 0061 class kpCommandHistory; 0062 class kpDocument; 0063 class kpDocumentEnvironment; 0064 class kpDocumentMetaInfo; 0065 class kpDocumentSaveOptions; 0066 class kpViewManager; 0067 class kpImageSelectionTransparency; 0068 class kpTextStyle; 0069 class kpThumbnail; 0070 class kpTool; 0071 class kpToolEnvironment; 0072 class kpToolSelectionEnvironment; 0073 class kpToolToolBar; 0074 class kpTransformDialogEnvironment; 0075 class kpAbstractSelection; 0076 0077 class kpMainWindow : public KXmlGuiWindow 0078 { 0079 Q_OBJECT 0080 0081 public: 0082 // Opens a new window with a blank document. 0083 kpMainWindow (); 0084 0085 // Opens a new window with the document specified by <url> 0086 // or creates a blank document if <url> could not be opened. 0087 explicit kpMainWindow (const QUrl &url); 0088 0089 // Opens a new window with the document <newDoc> 0090 // (<newDoc> can be 0 although this would result in a new 0091 // window without a document at all). 0092 explicit kpMainWindow (kpDocument *newDoc); 0093 0094 void finalizeGUI(KXMLGUIClient *client) override; 0095 0096 private: 0097 void readGeneralSettings (); 0098 void readThumbnailSettings (); 0099 0100 void init (); 0101 0102 // (only called for restoring a previous session e.g. starting KDE with 0103 // a previously saved session; it's not called on normal KolourPaint 0104 // startup) 0105 void readProperties (const KConfigGroup &configGroup) override; 0106 // (only called for saving the current session e.g. logging out of KDE 0107 // with the KolourPaint window open; it's not called on normal KolourPaint 0108 // exit) 0109 void saveProperties (KConfigGroup &configGroup) override; 0110 0111 public: 0112 ~kpMainWindow () override; 0113 0114 public: 0115 kpDocument *document () const; 0116 kpDocumentEnvironment *documentEnvironment (); 0117 kpViewManager *viewManager () const; 0118 kpColorToolBar *colorToolBar () const; 0119 kpColorCells *colorCells () const; 0120 kpToolToolBar *toolToolBar () const; 0121 kpCommandHistory *commandHistory () const; 0122 kpCommandEnvironment *commandEnvironment (); 0123 0124 private: 0125 void setupActions (); 0126 void enableDocumentActions (bool enable = true); 0127 0128 void setDocument (kpDocument *newDoc); 0129 0130 void dragEnterEvent (QDragEnterEvent *e) override; 0131 void dropEvent (QDropEvent *e) override; 0132 void moveEvent (QMoveEvent *e) override; 0133 0134 private Q_SLOTS: 0135 void slotScrollViewAfterScroll (); 0136 void slotUpdateCaption (); 0137 void slotDocumentRestored (); 0138 0139 0140 // 0141 // Tools 0142 // 0143 0144 private: 0145 kpToolSelectionEnvironment *toolSelectionEnvironment (); 0146 kpToolEnvironment *toolEnvironment (); 0147 0148 void setupToolActions (); 0149 void createToolBox (); 0150 void enableToolsDocumentActions (bool enable = true); 0151 0152 private Q_SLOTS: 0153 void updateToolOptionPrevNextActionsEnabled (); 0154 void updateActionDrawOpaqueChecked (); 0155 private: 0156 void updateActionDrawOpaqueEnabled (); 0157 0158 public: 0159 QActionGroup *toolsActionGroup (); 0160 0161 kpTool *tool () const; 0162 0163 bool toolHasBegunShape () const; 0164 bool toolIsASelectionTool (bool includingTextTool = true) const; 0165 bool toolIsTextTool () const; 0166 0167 private: 0168 // Ends the current shape. If there is no shape currently being drawn, 0169 // it does nothing. 0170 // 0171 // In general, call this at the start of every kpMainWindow slot, 0172 // directly invoked by the _user_ (by activating an action or via another 0173 // way), so that: 0174 // 0175 // 1. The document contains the pixels of that shape: 0176 // 0177 // Most tools have the shape, currently being drawn, layered above the 0178 // document as a kpTempImage. In other words, the document does not 0179 // yet contain the pixels of that shape. By ending the shape, the layer 0180 // is pushed down onto the document so that it now contains those 0181 // pixels. Your slot can now safely read the document as it's now 0182 // consistent with what's on the screen. 0183 // 0184 // For example, consider the case where a line is being dragged out and 0185 // CTRL+I is pressed to invert the image, while the mouse is still held 0186 // down. The CTRL+I invert code (kpMainWindow::slotInvertColors()) must 0187 // push the line kpTempImage onto the document before the invert can 0188 // meaningfully proceed (else the invert will see the state of the document 0189 // before the line was dragged out). 0190 // 0191 // Note that selection layers are not pushed down by this method. 0192 // This is a feature, not a bug. The user would be annoyed if e.g. 0193 // slotSave() happened to push down the selection. Use 0194 // kpDocument::imageWithSelection() to get around this problem. You 0195 // should still call toolEndShape() even if a selection is active 0196 // -- this ends selection "shapes", which are actually things like 0197 // selection moves or smearing operations, rather than the selections 0198 // themselves. 0199 // 0200 // AND/OR: 0201 // 0202 // 2. The current tool is no longer in a drawing state: 0203 // 0204 // If your slot is going to bring up a new main window or modal dialog 0205 // or at least some widget that acquires mouse or keyboard focus, this 0206 // could confuse the tool if the tool is in the middle of a drawing 0207 // operation. 0208 // 0209 // Do not call this in slots not invoked by the user. For instance, 0210 // calling this method in response to an internal timer tick would be 0211 // wrong. The user's drawing operation would unexpectedly finish and 0212 // this would bewilder and irritate the user. 0213 // 0214 // TODO: Help / KolourPaint Handbook does not call this. I'm sure there 0215 // are a few other actions that don't call this but should. 0216 void toolEndShape (); 0217 0218 public: 0219 kpImageSelectionTransparency imageSelectionTransparency () const; 0220 // The drawing background color is set to <transparency>.transparentColor() 0221 // if the <transparency> is in Transparent mode or if <forceColorChange> 0222 // is true (not the default). [x] 0223 // 0224 // If <transparency> is in Opaque mode and <forceColorChange> is false, 0225 // the background color is not changed because: 0226 // 0227 // 1. It is ignored by the selection in Opaque mode anyway. 0228 // 2. This avoids irritating the user with an unnecessary background 0229 // color change. 0230 // 0231 // The only case where you should set <forceColorChange> to true is in 0232 // kpToolImageSelectionTransparencyCommand to ensure that the state 0233 // is identical to when the command was constructed. 0234 // Later: I don't think setting it to true is ever necessary since: 0235 // 0236 // 1. The background color only counts in Transparent mode. 0237 // 0238 // 2. Any kpToolImageSelectionTransparencyCommand that switches to 0239 // Transparent mode will automatically set the background 0240 // color due to the first part of [x] anyway. 0241 // 0242 // The other fields of <transparency> are copied into the main window 0243 // as expected. 0244 void setImageSelectionTransparency (const kpImageSelectionTransparency &transparency, 0245 bool forceColorChange = false); 0246 int settingImageSelectionTransparency () const; 0247 0248 private Q_SLOTS: 0249 void slotToolSelected (kpTool *tool); 0250 0251 private: 0252 void readLastTool (); 0253 int toolNumber () const; 0254 void saveLastTool (); 0255 0256 private: 0257 bool maybeDragScrollingMainView () const; 0258 private Q_SLOTS: 0259 bool slotDragScroll (const QPoint &docPoint, 0260 const QPoint &docLastPoint, 0261 int zoomLevel, 0262 bool *didSomething); 0263 bool slotEndDragScroll (); 0264 0265 private Q_SLOTS: 0266 void slotBeganDocResize (); 0267 void slotContinuedDocResize (const QSize &size); 0268 void slotCancelledDocResize (); 0269 void slotEndedDocResize (const QSize &size); 0270 0271 void slotDocResizeMessageChanged (const QString &string); 0272 0273 private Q_SLOTS: 0274 void slotActionPrevToolOptionGroup1 (); 0275 void slotActionNextToolOptionGroup1 (); 0276 void slotActionPrevToolOptionGroup2 (); 0277 void slotActionNextToolOptionGroup2 (); 0278 0279 void slotActionDrawOpaqueToggled (); 0280 void slotActionDrawColorSimilarity (); 0281 0282 public Q_SLOTS: 0283 void slotToolRectSelection(); 0284 void slotToolEllipticalSelection(); 0285 void slotToolFreeFormSelection(); 0286 void slotToolText(); 0287 0288 // 0289 // File Menu 0290 // 0291 0292 private: 0293 void setupFileMenuActions (); 0294 void enableFileMenuDocumentActions (bool enable = true); 0295 0296 void addRecentURL (const QUrl &url); 0297 0298 private Q_SLOTS: 0299 void slotNew (); 0300 0301 private: 0302 QSize defaultDocSize () const; 0303 void saveDefaultDocSize (const QSize &size); 0304 0305 private: 0306 bool shouldOpen (); 0307 void setDocumentChoosingWindow (kpDocument *doc); 0308 0309 private: 0310 kpDocument *openInternal (const QUrl &url, 0311 const QSize &fallbackDocSize, 0312 bool newDocSameNameIfNotExist); 0313 // Same as above except that it: 0314 // 0315 // 1. Assumes a default fallback document size. 0316 // 2. If the URL is successfully opened (with the special exception of 0317 // the "kolourpaint doesnotexist.png" case), it is bubbled up to the 0318 // top in the Recent Files Action. 0319 // 0320 // As a result of this behavior, this should only be called in response 0321 // to a user open request e.g. File / Open or "kolourpaint doesexist.png". 0322 // It should not be used for session restore - in that case, it does not 0323 // make sense to bubble the Recent Files list. 0324 bool open (const QUrl &url, bool newDocSameNameIfNotExist = false); 0325 0326 QList<QUrl> askForOpenURLs(const QString &caption, 0327 bool allowMultipleURLs = true); 0328 0329 private Q_SLOTS: 0330 void slotOpen (); 0331 void slotOpenRecent (const QUrl &url); 0332 void slotRecentListCleared(); 0333 0334 #if HAVE_KSANE 0335 void slotScan (); 0336 void slotScanned (const QImage &image, int); 0337 #endif // HAVE_KSANE 0338 0339 void slotScreenshot(); 0340 void slotMakeScreenshot(); 0341 0342 void slotProperties (); 0343 0344 bool save (bool localOnly = false); 0345 bool slotSave (); 0346 0347 private: 0348 QUrl askForSaveURL (const QString &caption, 0349 const QString &startURL, 0350 const kpImage &imageToBeSaved, 0351 const kpDocumentSaveOptions &startSaveOptions, 0352 const kpDocumentMetaInfo &docMetaInfo, 0353 const QString &forcedSaveOptionsGroup, 0354 bool localOnly, 0355 kpDocumentSaveOptions *chosenSaveOptions, 0356 bool isSavingForFirstTime, 0357 bool *allowLossyPrompt); 0358 0359 private Q_SLOTS: 0360 bool saveAs (bool localOnly = false); 0361 bool slotSaveAs (); 0362 0363 bool slotExport (); 0364 0365 void slotEnableReload (); 0366 bool slotReload (); 0367 void sendPreviewToPrinter(QPrinter *printer); 0368 0369 private: 0370 void sendDocumentNameToPrinter (QPrinter *printer); 0371 void setPrinterPageOrientation(QPrinter *printer); 0372 void sendImageToPrinter(QPrinter *printer, bool showPrinterSetupDialog); 0373 0374 private Q_SLOTS: 0375 void slotPrint (); 0376 void slotPrintPreview (); 0377 0378 void slotMail (); 0379 0380 bool queryCloseDocument (); 0381 bool queryClose () override; 0382 0383 void slotClose (); 0384 void slotQuit (); 0385 0386 0387 // 0388 // Edit Menu 0389 // 0390 0391 private: 0392 void setupEditMenuActions (); 0393 void enableEditMenuDocumentActions (bool enable = true); 0394 0395 public: 0396 QMenu *selectionToolRMBMenu (); 0397 0398 private Q_SLOTS: 0399 void slotCut (); 0400 void slotCopy (); 0401 void slotEnablePaste (); 0402 private: 0403 QRect calcUsefulPasteRect (int imageWidth, int imageHeight); 0404 // (it is possible to paste a selection border i.e. a selection with no content) 0405 void paste (const kpAbstractSelection &sel, 0406 bool forceTopLeft = false); 0407 public: 0408 // (<forceNewTextSelection> is ignored if <text> is empty) 0409 void pasteText (const QString &text, 0410 bool forceNewTextSelection = false, 0411 const QPoint &newTextSelectionTopLeft = KP_INVALID_POINT); 0412 void pasteTextAt (const QString &text, const QPoint &point, 0413 // Allow tiny adjustment of <point> so that mouse 0414 // pointer is not exactly on top of the topLeft of 0415 // any new text selection (so that it doesn't look 0416 // weird by being on top of a resize handle just after 0417 // a paste). 0418 bool allowNewTextSelectionPointShift = false); 0419 public Q_SLOTS: 0420 void slotPaste (); 0421 private Q_SLOTS: 0422 void slotPasteInNewWindow (); 0423 public Q_SLOTS: 0424 void slotDelete (); 0425 0426 void slotSelectAll (); 0427 private: 0428 void addDeselectFirstCommand (kpCommand *cmd); 0429 public Q_SLOTS: 0430 void slotDeselect (); 0431 private Q_SLOTS: 0432 void slotCopyToFile (); 0433 void slotPasteFromFile (); 0434 0435 0436 // 0437 // View Menu 0438 // 0439 0440 private: 0441 void setupViewMenuActions (); 0442 0443 bool viewMenuDocumentActionsEnabled () const; 0444 void enableViewMenuDocumentActions (bool enable = true); 0445 void actionShowGridUpdate (); 0446 void updateMainViewGrid (); 0447 QRect mapToGlobal (const QRect &rect) const; 0448 QRect mapFromGlobal (const QRect &rect) const; 0449 0450 private Q_SLOTS: 0451 void slotShowGridToggled (); 0452 0453 0454 // 0455 // View Menu - Zoom 0456 // 0457 0458 private: 0459 void setupViewMenuZoomActions (); 0460 void enableViewMenuZoomDocumentActions (bool enable); 0461 0462 void sendZoomListToActionZoom (); 0463 0464 void zoomToPre (int zoomLevel); 0465 void zoomToPost (); 0466 0467 public: 0468 void zoomTo (int zoomLevel, bool centerUnderCursor = false); 0469 void zoomToRect (const QRect &normalizedDocRect, 0470 bool accountForGrips, 0471 bool careAboutWidth, bool careAboutHeight); 0472 0473 public Q_SLOTS: 0474 void slotActualSize (); 0475 void slotFitToPage (); 0476 void slotFitToWidth (); 0477 void slotFitToHeight (); 0478 0479 public: 0480 void zoomIn (bool centerUnderCursor = false); 0481 void zoomOut (bool centerUnderCursor = false); 0482 0483 public Q_SLOTS: 0484 void slotZoomIn (); 0485 void slotZoomOut (); 0486 0487 private: 0488 void zoomAccordingToZoomAction (bool centerUnderCursor = false); 0489 0490 private Q_SLOTS: 0491 void slotZoom (); 0492 0493 0494 // 0495 // View Menu - Thumbnail 0496 // 0497 0498 private: 0499 void setupViewMenuThumbnailActions (); 0500 void enableViewMenuThumbnailDocumentActions (bool enable); 0501 0502 private Q_SLOTS: 0503 void slotDestroyThumbnail (); 0504 void slotDestroyThumbnailInitatedByUser (); 0505 void slotCreateThumbnail (); 0506 0507 public: 0508 void notifyThumbnailGeometryChanged (); 0509 0510 private Q_SLOTS: 0511 void slotSaveThumbnailGeometry (); 0512 void slotShowThumbnailToggled (); 0513 void updateThumbnailZoomed (); 0514 void slotZoomedThumbnailToggled (); 0515 void slotThumbnailShowRectangleToggled (); 0516 0517 private: 0518 void enableViewZoomedThumbnail (bool enable = true); 0519 void enableViewShowThumbnailRectangle (bool enable = true); 0520 void enableThumbnailOptionActions (bool enable = true); 0521 void createThumbnailView (); 0522 void destroyThumbnailView (); 0523 void updateThumbnail (); 0524 0525 0526 // 0527 // Image Menu 0528 // 0529 0530 private: 0531 kpTransformDialogEnvironment *transformDialogEnvironment (); 0532 0533 bool isSelectionActive () const; 0534 bool isTextSelection () const; 0535 0536 QString autoCropText () const; 0537 0538 void setupImageMenuActions (); 0539 void enableImageMenuDocumentActions (bool enable = true); 0540 0541 private Q_SLOTS: 0542 void slotImageMenuUpdateDueToSelection (); 0543 0544 public: 0545 kpColor backgroundColor (bool ofSelection = false) const; 0546 void addImageOrSelectionCommand (kpCommand *cmd, 0547 bool addSelCreateCmdIfSelAvail = true, 0548 bool addSelContentCmdIfSelAvail = true); 0549 0550 public Q_SLOTS: 0551 void slotCrop (); 0552 0553 private Q_SLOTS: 0554 void slotResizeScale (); 0555 void slotAutoCrop (); 0556 void slotFlip (); 0557 void slotMirror (); 0558 0559 void slotRotate (); 0560 void slotRotate270 (); 0561 void slotRotate90 (); 0562 0563 void slotSkew (); 0564 void slotConvertToBlackAndWhite (); 0565 void slotConvertToGrayscale (); 0566 void slotInvertColors (); 0567 void slotClear (); 0568 void slotMakeConfidential(); 0569 void slotMoreEffects (); 0570 0571 0572 // 0573 // Colors Menu 0574 // 0575 0576 private: 0577 void setupColorsMenuActions (); 0578 void createColorBox (); 0579 void enableColorsMenuDocumentActions (bool enable); 0580 private Q_SLOTS: 0581 void slotUpdateColorsDeleteRowActionEnabled (); 0582 0583 private: 0584 void deselectActionColorsKDE (); 0585 0586 bool queryCloseColors (); 0587 0588 private: 0589 void openDefaultColors (); 0590 private Q_SLOTS: 0591 void slotColorsDefault (); 0592 0593 private: 0594 bool openKDEColors (const QString &name); 0595 private Q_SLOTS: 0596 void slotColorsKDE (); 0597 0598 private: 0599 bool openColors (const QUrl &url); 0600 private Q_SLOTS: 0601 void slotColorsOpen (); 0602 0603 void slotColorsReload (); 0604 0605 bool slotColorsSave (); 0606 bool slotColorsSaveAs (); 0607 0608 void slotColorsAppendRow (); 0609 void slotColorsDeleteRow (); 0610 0611 0612 // 0613 // Settings Menu 0614 // 0615 0616 private: 0617 void setupSettingsMenuActions (); 0618 void enableSettingsMenuDocumentActions (bool enable = true); 0619 0620 private Q_SLOTS: 0621 void slotFullScreen (); 0622 0623 void slotEnableSettingsShowPath (); 0624 void slotShowPathToggled (); 0625 void slotDrawAntiAliasedToggled(bool on); 0626 0627 void slotKeyBindings (); 0628 0629 // 0630 // Status Bar 0631 // 0632 0633 private: 0634 enum 0635 { 0636 StatusBarItemShapePoints, 0637 StatusBarItemShapeSize, 0638 StatusBarItemDocSize, 0639 StatusBarItemDocDepth, 0640 StatusBarItemZoom 0641 }; 0642 0643 void addPermanentStatusBarItem (int id, int maxTextLen); 0644 void createStatusBar (); 0645 0646 void setStatusBarDocDepth (int depth = 0); 0647 0648 private Q_SLOTS: 0649 void setStatusBarMessage (const QString &message = QString()); 0650 void setStatusBarShapePoints (const QPoint &startPoint = KP_INVALID_POINT, 0651 const QPoint &endPoint = KP_INVALID_POINT); 0652 void setStatusBarShapeSize (const QSize &size = KP_INVALID_SIZE); 0653 void setStatusBarDocSize (const QSize &size = KP_INVALID_SIZE); 0654 void setStatusBarZoom (int zoom = 0); 0655 0656 void recalculateStatusBarMessage (); 0657 void recalculateStatusBarShape (); 0658 0659 void recalculateStatusBar (); 0660 0661 0662 // 0663 // Text ToolBar 0664 // 0665 0666 private: 0667 void setupTextToolBarActions (); 0668 void readAndApplyTextSettings (); 0669 0670 public: 0671 void enableTextToolBarActions (bool enable = true); 0672 0673 private Q_SLOTS: 0674 void slotTextFontFamilyChanged (); 0675 void slotTextFontSizeChanged (); 0676 void slotTextBoldChanged (); 0677 void slotTextItalicChanged (); 0678 void slotTextUnderlineChanged (); 0679 void slotTextStrikeThruChanged (); 0680 0681 public: 0682 KToolBar *textToolBar (); 0683 bool isTextStyleBackgroundOpaque () const; 0684 kpTextStyle textStyle () const; 0685 void setTextStyle (const kpTextStyle &textStyle_); 0686 int settingTextStyle () const; 0687 0688 private: 0689 struct kpMainWindowPrivate *d; 0690 }; 0691 0692 #endif // KP_MAIN_WINDOW_H