3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <kpMainWindow.h>
30 #include <kpMainWindowPrivate.h>
36 #include <kactioncollection.h>
37 #include <kapplication.h>
39 #include <kconfiggroup.h>
44 #include <KToggleAction>
46 #include <kpAbstractImageSelection.h>
49 #include <kpColorToolBar.h>
50 #include <kpCommandHistory.h>
51 #include <kpDocument.h>
52 #include <kpEffectInvertCommand.h>
53 #include <kpEffectReduceColorsCommand.h>
54 #include <kpEffectsDialog.h>
55 #include <kpEffectClearCommand.h>
56 #include <kpEffectGrayscaleCommand.h>
57 #include <kpMacroCommand.h>
58 #include <kpTextSelection.h>
59 #include <kpToolSelectionCreateCommand.h>
60 #include <kpToolSelectionPullFromDocumentCommand.h>
61 #include <kpToolTextGiveContentCommand.h>
62 #include <kpTransformAutoCrop.h>
63 #include <kpTransformCrop.h>
64 #include <kpTransformDialogEnvironment.h>
65 #include <kpTransformFlipCommand.h>
66 #include <kpTransformFlipDialog.h>
67 #include <kpTransformResizeScaleCommand.h>
68 #include <kpTransformResizeScaleDialog.h>
69 #include <kpTransformRotateCommand.h>
70 #include <kpTransformRotateDialog.h>
71 #include <kpTransformSkewCommand.h>
72 #include <kpTransformSkewDialog.h>
73 #include <kpViewManager.h>
77 kpTransformDialogEnvironment
*kpMainWindow::transformDialogEnvironment ()
79 if (!d
->transformDialogEnvironment
)
80 d
->transformDialogEnvironment
= new kpTransformDialogEnvironment (this);
82 return d
->transformDialogEnvironment
;
87 bool kpMainWindow::isSelectionActive () const
89 return (d
->document
? bool (d
->document
->selection ()) : false);
93 bool kpMainWindow::isTextSelection () const
95 return (d
->document
&& d
->document
->textSelection ());
100 QString
kpMainWindow::autoCropText () const
102 return kpTransformAutoCropCommand::name (isSelectionActive (),
103 kpTransformAutoCropCommand::ShowAccel
);
108 void kpMainWindow::setupImageMenuActions ()
110 KActionCollection
*ac
= actionCollection ();
112 d
->actionResizeScale
= ac
->addAction ("image_resize_scale");
113 d
->actionResizeScale
->setText (i18n ("R&esize / Scale..."));
114 connect (d
->actionResizeScale
, SIGNAL (triggered (bool)), SLOT (slotResizeScale ()));
115 d
->actionResizeScale
->setShortcut(Qt::CTRL
+ Qt::Key_E
);
117 d
->actionCrop
= ac
->addAction ("image_crop");
118 d
->actionCrop
->setText (i18n ("Se&t as Image (Crop)"));
119 connect (d
->actionCrop
, SIGNAL (triggered (bool)), SLOT (slotCrop ()));
120 d
->actionCrop
->setShortcut(Qt::CTRL
+ Qt::Key_T
);
122 d
->actionAutoCrop
= ac
->addAction ("image_auto_crop");
123 d
->actionAutoCrop
->setText (autoCropText ());
124 connect (d
->actionAutoCrop
, SIGNAL (triggered (bool)), SLOT (slotAutoCrop ()));
125 d
->actionAutoCrop
->setShortcut(Qt::CTRL
+ Qt::Key_U
);
127 d
->actionFlip
= ac
->addAction ("image_flip");
128 d
->actionFlip
->setText (i18n ("&Flip..."));
129 connect (d
->actionFlip
, SIGNAL (triggered (bool)), SLOT (slotFlip ()));
130 d
->actionFlip
->setShortcut(Qt::CTRL
+ Qt::Key_F
);
132 d
->actionRotate
= ac
->addAction ("image_rotate");
133 d
->actionRotate
->setText (i18n ("&Rotate..."));
134 d
->actionRotate
->setIcon (KIcon ("transform-rotate"));
135 connect (d
->actionRotate
, SIGNAL (triggered (bool)), SLOT (slotRotate ()));
136 d
->actionRotate
->setShortcut(Qt::CTRL
+ Qt::Key_R
);
138 d
->actionRotateLeft
= ac
->addAction ("image_rotate_270deg");
139 d
->actionRotateLeft
->setText (i18n ("Rotate &Left"));
140 d
->actionRotateLeft
->setIcon (KIcon ("object-rotate-left"));
141 connect (d
->actionRotateLeft
, SIGNAL (triggered (bool)), SLOT (slotRotate270 ()));
142 d
->actionRotateLeft
->setShortcut(Qt::CTRL
+ Qt::SHIFT
+ Qt::Key_Left
);
144 d
->actionRotateRight
= ac
->addAction ("image_rotate_90deg");
145 d
->actionRotateRight
->setText (i18n ("Rotate Righ&t"));
146 d
->actionRotateRight
->setIcon (KIcon ("object-rotate-right"));
147 connect (d
->actionRotateRight
, SIGNAL (triggered (bool)), SLOT (slotRotate90 ()));
148 d
->actionRotateRight
->setShortcut(Qt::CTRL
+ Qt::SHIFT
+ Qt::Key_Right
);
150 d
->actionSkew
= ac
->addAction ("image_skew");
151 d
->actionSkew
->setText (i18n ("S&kew..."));
152 connect (d
->actionSkew
, SIGNAL (triggered (bool)), SLOT (slotSkew ()));
153 d
->actionSkew
->setShortcut(Qt::CTRL
+ Qt::Key_K
);
155 d
->actionConvertToBlackAndWhite
= ac
->addAction ("image_convert_to_black_and_white");
156 d
->actionConvertToBlackAndWhite
->setText (i18n ("Reduce to Mo&nochrome (Dithered)"));
157 connect (d
->actionConvertToBlackAndWhite
, SIGNAL (triggered (bool)), SLOT (slotConvertToBlackAndWhite ()));
159 d
->actionConvertToGrayscale
= ac
->addAction ("image_convert_to_grayscale");
160 d
->actionConvertToGrayscale
->setText (i18n ("Reduce to &Grayscale"));
161 connect (d
->actionConvertToGrayscale
, SIGNAL (triggered (bool)), SLOT (slotConvertToGrayscale ()));
163 d
->actionInvertColors
= ac
->addAction ("image_invert_colors");
164 d
->actionInvertColors
->setText (i18n ("&Invert Colors"));
165 connect (d
->actionInvertColors
, SIGNAL (triggered (bool)), SLOT (slotInvertColors ()));
166 d
->actionInvertColors
->setShortcut(Qt::CTRL
+ Qt::Key_I
);
168 d
->actionClear
= ac
->addAction ("image_clear");
169 d
->actionClear
->setText (i18n ("C&lear"));
170 connect (d
->actionClear
, SIGNAL (triggered (bool)), SLOT (slotClear ()));
171 d
->actionClear
->setShortcut(Qt::CTRL
+ Qt::SHIFT
+ Qt::Key_N
);
173 d
->actionMoreEffects
= ac
->addAction ("image_more_effects");
174 d
->actionMoreEffects
->setText (i18n ("&More Effects..."));
175 connect (d
->actionMoreEffects
, SIGNAL (triggered (bool)), SLOT (slotMoreEffects ()));
176 d
->actionMoreEffects
->setShortcut(Qt::CTRL
+ Qt::Key_M
);
179 enableImageMenuDocumentActions (false);
183 void kpMainWindow::enableImageMenuDocumentActions (bool enable
)
185 d
->actionResizeScale
->setEnabled (enable
);
186 d
->actionCrop
->setEnabled (enable
);
187 d
->actionAutoCrop
->setEnabled (enable
);
188 d
->actionFlip
->setEnabled (enable
);
189 d
->actionRotate
->setEnabled (enable
);
190 d
->actionRotateLeft
->setEnabled (enable
);
191 d
->actionRotateRight
->setEnabled (enable
);
192 d
->actionSkew
->setEnabled (enable
);
193 d
->actionConvertToBlackAndWhite
->setEnabled (enable
);
194 d
->actionConvertToGrayscale
->setEnabled (enable
);
195 d
->actionInvertColors
->setEnabled (enable
);
196 d
->actionClear
->setEnabled (enable
);
197 d
->actionMoreEffects
->setEnabled (enable
);
199 d
->imageMenuDocumentActionsEnabled
= enable
;
204 void kpMainWindow::slotImageMenuUpdateDueToSelection ()
206 // SYNC: kolourpaintui.rc
207 const QString MenuBarItemTextImage
= i18nc (
208 "Image/Selection Menu caption - make sure the translation has"
209 " the same accel as the Select&ion translation",
211 const QString MenuBarItemTextSelection
= i18nc (
212 "Image/Selection Menu caption - make sure that translation has"
213 " the same accel as the &Image translation",
216 Q_ASSERT (menuBar ());
217 foreach (QAction
*action
, menuBar ()->actions ())
219 if (action
->text () == MenuBarItemTextImage
||
220 action
->text () == MenuBarItemTextSelection
)
222 if (isSelectionActive ())
223 action
->setText (MenuBarItemTextSelection
);
225 action
->setText (MenuBarItemTextImage
);
232 d
->actionResizeScale
->setEnabled (d
->imageMenuDocumentActionsEnabled
);
233 d
->actionCrop
->setEnabled (d
->imageMenuDocumentActionsEnabled
&&
234 isSelectionActive ());
236 const bool enable
= (d
->imageMenuDocumentActionsEnabled
&& !isTextSelection ());
237 d
->actionAutoCrop
->setText (autoCropText ());
238 d
->actionAutoCrop
->setEnabled (enable
);
239 d
->actionFlip
->setEnabled (enable
);
240 d
->actionRotate
->setEnabled (enable
);
241 d
->actionRotateLeft
->setEnabled (enable
);
242 d
->actionRotateRight
->setEnabled (enable
);
243 d
->actionSkew
->setEnabled (enable
);
244 d
->actionConvertToBlackAndWhite
->setEnabled (enable
);
245 d
->actionConvertToGrayscale
->setEnabled (enable
);
246 d
->actionInvertColors
->setEnabled (enable
);
247 d
->actionClear
->setEnabled (enable
);
248 d
->actionMoreEffects
->setEnabled (enable
);
253 kpColor
kpMainWindow::backgroundColor (bool ofSelection
) const
256 return kpColor::Transparent
;
259 Q_ASSERT (d
->colorToolBar
);
260 return d
->colorToolBar
->backgroundColor ();
266 // REFACTOR: sync: Code dup with kpAbstractSelectionTool::addNeedingContentCommand().
267 void kpMainWindow::addImageOrSelectionCommand (kpCommand
*cmd
,
268 bool addSelCreateCmdIfSelAvail
,
269 bool addSelContentCmdIfSelAvail
)
271 #if DEBUG_KP_MAIN_WINDOW && 1
272 kDebug () << "kpMainWindow::addImageOrSelectionCommand()"
273 << " addSelCreateCmdIfSelAvail=" << addSelCreateCmdIfSelAvail
274 << " addSelContentCmdIfSelAvail=" << addSelContentCmdIfSelAvail
278 Q_ASSERT (d
->document
);
282 d
->viewManager
->setQueueUpdates ();
285 kpAbstractSelection
*sel
= d
->document
->selection ();
286 #if DEBUG_KP_MAIN_WINDOW && 1
287 kDebug () << "\timage sel=" << sel
288 << " sel->hasContent=" << (sel
? sel
->hasContent () : 0)
291 if (addSelCreateCmdIfSelAvail
&& sel
&& !sel
->hasContent ())
293 QString createCmdName
;
295 if (dynamic_cast <kpAbstractImageSelection
*> (sel
))
296 createCmdName
= i18n ("Selection: Create");
297 else if (dynamic_cast <kpTextSelection
*> (sel
))
298 createCmdName
= i18n ("Text: Create Box");
300 Q_ASSERT (!"Unknown selection type");
302 // create selection region
303 commandHistory ()->addCreateSelectionCommand (
304 new kpToolSelectionCreateCommand (
307 commandEnvironment ()),
308 false/*no exec - user already dragged out sel*/);
312 if (addSelContentCmdIfSelAvail
&& sel
&& !sel
->hasContent ())
314 kpAbstractImageSelection
*imageSel
=
315 dynamic_cast <kpAbstractImageSelection
*> (sel
);
316 kpTextSelection
*textSel
=
317 dynamic_cast <kpTextSelection
*> (sel
);
319 if (imageSel
&& imageSel
->transparency ().isTransparent ())
320 d
->colorToolBar
->flashColorSimilarityToolBarItem ();
322 kpMacroCommand
*macroCmd
= new kpMacroCommand (cmd
->name (),
323 commandEnvironment ());
327 macroCmd
->addCommand (
328 new kpToolSelectionPullFromDocumentCommand (
331 QString::null
/*uninteresting child of macro cmd*/, //krazy:exclude=nullstrassign for old broken gcc
332 commandEnvironment ()));
336 macroCmd
->addCommand (
337 new kpToolTextGiveContentCommand (
339 QString::null
/*uninteresting child of macro cmd*/, //krazy:exclude=nullstrassign for old broken gcc
340 commandEnvironment ()));
343 Q_ASSERT (!"Unknown selection type");
345 macroCmd
->addCommand (cmd
);
347 d
->commandHistory
->addCommand (macroCmd
);
351 d
->commandHistory
->addCommand (cmd
);
356 d
->viewManager
->restoreQueueUpdates ();
360 void kpMainWindow::slotResizeScale ()
365 kpTransformResizeScaleDialog
dialog (transformDialogEnvironment (), this);
366 dialog
.setKeepAspectRatio (d
->resizeScaleDialogLastKeepAspect
);
368 if (dialog
.exec () && !dialog
.isNoOp ())
370 kpTransformResizeScaleCommand
*cmd
= new kpTransformResizeScaleCommand (
371 dialog
.actOnSelection (),
372 dialog
.imageWidth (), dialog
.imageHeight (),
374 commandEnvironment ());
376 bool addSelCreateCommand
= (dialog
.actOnSelection () ||
377 cmd
->scaleSelectionWithImage ());
378 bool addSelContentCommand
= dialog
.actOnSelection ();
380 addImageOrSelectionCommand (
383 addSelContentCommand
);
386 if (!dialog
.actOnSelection () &&
387 dialog
.type () == kpTransformResizeScaleCommand::Resize
)
389 // TODO: this should be the responsibility of kpDocument
390 saveDefaultDocSize (QSize (dialog
.imageWidth (), dialog
.imageHeight ()));
395 if (d
->resizeScaleDialogLastKeepAspect
!= dialog
.keepAspectRatio ())
397 d
->resizeScaleDialogLastKeepAspect
= dialog
.keepAspectRatio ();
399 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupGeneral
);
401 cfg
.writeEntry (kpSettingResizeScaleLastKeepAspect
,
402 d
->resizeScaleDialogLastKeepAspect
);
408 void kpMainWindow::slotCrop ()
412 Q_ASSERT (d
->document
&& d
->document
->selection ());
415 ::kpTransformCrop (this);
419 void kpMainWindow::slotAutoCrop ()
423 ::kpTransformAutoCrop (this);
427 void kpMainWindow::slotFlip ()
431 kpTransformFlipDialog
dialog ((bool) d
->document
->selection (), this);
433 if (dialog
.exec () && !dialog
.isNoOp ())
435 addImageOrSelectionCommand (
436 new kpTransformFlipCommand (d
->document
->selection (),
437 dialog
.getHorizontalFlip (), dialog
.getVerticalFlip (),
438 commandEnvironment ()));
444 void kpMainWindow::slotRotate ()
448 kpTransformRotateDialog
dialog ((bool) d
->document
->selection (),
449 transformDialogEnvironment (), this);
451 if (dialog
.exec () && !dialog
.isNoOp ())
453 addImageOrSelectionCommand (
454 new kpTransformRotateCommand (d
->document
->selection (),
456 commandEnvironment ()));
461 void kpMainWindow::slotRotate270 ()
465 // TODO: Special command name instead of just "Rotate"?
466 addImageOrSelectionCommand (
467 new kpTransformRotateCommand (
468 d
->document
->selection (),
470 commandEnvironment ()));
474 void kpMainWindow::slotRotate90 ()
478 // TODO: Special command name instead of just "Rotate"?
479 addImageOrSelectionCommand (
480 new kpTransformRotateCommand (
481 d
->document
->selection (),
483 commandEnvironment ()));
488 void kpMainWindow::slotSkew ()
492 kpTransformSkewDialog
dialog ((bool) d
->document
->selection (),
493 transformDialogEnvironment (), this);
495 if (dialog
.exec () && !dialog
.isNoOp ())
497 addImageOrSelectionCommand (
498 new kpTransformSkewCommand (d
->document
->selection (),
499 dialog
.horizontalAngle (), dialog
.verticalAngle (),
500 commandEnvironment ()));
505 void kpMainWindow::slotConvertToBlackAndWhite ()
509 addImageOrSelectionCommand (
510 new kpEffectReduceColorsCommand (1/*depth*/, true/*dither*/,
511 d
->document
->selection (),
512 commandEnvironment ()));
516 void kpMainWindow::slotConvertToGrayscale ()
520 addImageOrSelectionCommand (
521 new kpEffectGrayscaleCommand (d
->document
->selection (),
522 commandEnvironment ()));
526 void kpMainWindow::slotInvertColors ()
530 addImageOrSelectionCommand (
531 new kpEffectInvertCommand (d
->document
->selection (),
532 commandEnvironment ()));
536 void kpMainWindow::slotClear ()
540 addImageOrSelectionCommand (
541 new kpEffectClearCommand (
542 d
->document
->selection (),
544 commandEnvironment ()));
548 void kpMainWindow::slotMoreEffects ()
552 kpEffectsDialog
dialog ((bool) d
->document
->selection (),
553 transformDialogEnvironment (), this,
554 d
->moreEffectsDialogLastEffect
);
556 if (dialog
.exec () && !dialog
.isNoOp ())
558 addImageOrSelectionCommand (dialog
.createCommand ());
562 if (d
->moreEffectsDialogLastEffect
!= dialog
.selectedEffect ())
564 d
->moreEffectsDialogLastEffect
= dialog
.selectedEffect ();
566 KConfigGroup
cfg (KGlobal::config (), kpSettingsGroupGeneral
);
568 cfg
.writeEntry (kpSettingMoreEffectsLastEffect
,
569 d
->moreEffectsDialogLastEffect
);