compile
[kdegraphics.git] / kolourpaint / mainWindow / kpMainWindow_Image.cpp
bloba53fad5b86467df6dc40f746bb13fa316a1bec17
2 /*
3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
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>
32 #include <qcolor.h>
33 #include <qsize.h>
35 #include <kaction.h>
36 #include <kactioncollection.h>
37 #include <kapplication.h>
38 #include <kconfig.h>
39 #include <kconfiggroup.h>
40 #include <kdebug.h>
41 #include <kglobal.h>
42 #include <klocale.h>
43 #include <kmenubar.h>
44 #include <KToggleAction>
46 #include <kpAbstractImageSelection.h>
47 #include <kpColor.h>
48 #include <kpDefs.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>
76 // private
77 kpTransformDialogEnvironment *kpMainWindow::transformDialogEnvironment ()
79 if (!d->transformDialogEnvironment)
80 d->transformDialogEnvironment = new kpTransformDialogEnvironment (this);
82 return d->transformDialogEnvironment;
86 // private
87 bool kpMainWindow::isSelectionActive () const
89 return (d->document ? bool (d->document->selection ()) : false);
92 // private
93 bool kpMainWindow::isTextSelection () const
95 return (d->document && d->document->textSelection ());
99 // private
100 QString kpMainWindow::autoCropText () const
102 return kpTransformAutoCropCommand::name (isSelectionActive (),
103 kpTransformAutoCropCommand::ShowAccel);
107 // private
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);
182 // private
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;
203 // private slot
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",
210 "&Image");
211 const QString MenuBarItemTextSelection = i18nc (
212 "Image/Selection Menu caption - make sure that translation has"
213 " the same accel as the &Image translation",
214 "Select&ion");
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);
224 else
225 action->setText (MenuBarItemTextImage);
227 break;
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);
252 // public
253 kpColor kpMainWindow::backgroundColor (bool ofSelection) const
255 if (ofSelection)
256 return kpColor::Transparent;
257 else
259 Q_ASSERT (d->colorToolBar);
260 return d->colorToolBar->backgroundColor ();
265 // public
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
275 << endl;
276 #endif
278 Q_ASSERT (d->document);
281 if (d->viewManager)
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)
289 << endl;
290 #endif
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");
299 else
300 Q_ASSERT (!"Unknown selection type");
302 // create selection region
303 commandHistory ()->addCreateSelectionCommand (
304 new kpToolSelectionCreateCommand (
305 createCmdName,
306 *sel,
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 ());
325 if (imageSel)
327 macroCmd->addCommand (
328 new kpToolSelectionPullFromDocumentCommand (
329 *imageSel,
330 backgroundColor (),
331 QString::null/*uninteresting child of macro cmd*/, //krazy:exclude=nullstrassign for old broken gcc
332 commandEnvironment ()));
334 else if (textSel)
336 macroCmd->addCommand (
337 new kpToolTextGiveContentCommand (
338 *textSel,
339 QString::null/*uninteresting child of macro cmd*/, //krazy:exclude=nullstrassign for old broken gcc
340 commandEnvironment ()));
342 else
343 Q_ASSERT (!"Unknown selection type");
345 macroCmd->addCommand (cmd);
347 d->commandHistory->addCommand (macroCmd);
349 else
351 d->commandHistory->addCommand (cmd);
355 if (d->viewManager)
356 d->viewManager->restoreQueueUpdates ();
359 // private slot
360 void kpMainWindow::slotResizeScale ()
362 toolEndShape ();
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 (),
373 dialog.type (),
374 commandEnvironment ());
376 bool addSelCreateCommand = (dialog.actOnSelection () ||
377 cmd->scaleSelectionWithImage ());
378 bool addSelContentCommand = dialog.actOnSelection ();
380 addImageOrSelectionCommand (
381 cmd,
382 addSelCreateCommand,
383 addSelContentCommand);
385 // Resized document?
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);
403 cfg.sync ();
407 // public slot
408 void kpMainWindow::slotCrop ()
410 toolEndShape ();
412 Q_ASSERT (d->document && d->document->selection ());
415 ::kpTransformCrop (this);
418 // private slot
419 void kpMainWindow::slotAutoCrop ()
421 toolEndShape ();
423 ::kpTransformAutoCrop (this);
426 // private slot
427 void kpMainWindow::slotFlip ()
429 toolEndShape ();
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 ()));
443 // private slot
444 void kpMainWindow::slotRotate ()
446 toolEndShape ();
448 kpTransformRotateDialog dialog ((bool) d->document->selection (),
449 transformDialogEnvironment (), this);
451 if (dialog.exec () && !dialog.isNoOp ())
453 addImageOrSelectionCommand (
454 new kpTransformRotateCommand (d->document->selection (),
455 dialog.angle (),
456 commandEnvironment ()));
460 // private slot
461 void kpMainWindow::slotRotate270 ()
463 toolEndShape ();
465 // TODO: Special command name instead of just "Rotate"?
466 addImageOrSelectionCommand (
467 new kpTransformRotateCommand (
468 d->document->selection (),
469 270,
470 commandEnvironment ()));
473 // private slot
474 void kpMainWindow::slotRotate90 ()
476 toolEndShape ();
478 // TODO: Special command name instead of just "Rotate"?
479 addImageOrSelectionCommand (
480 new kpTransformRotateCommand (
481 d->document->selection (),
483 commandEnvironment ()));
487 // private slot
488 void kpMainWindow::slotSkew ()
490 toolEndShape ();
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 ()));
504 // private slot
505 void kpMainWindow::slotConvertToBlackAndWhite ()
507 toolEndShape ();
509 addImageOrSelectionCommand (
510 new kpEffectReduceColorsCommand (1/*depth*/, true/*dither*/,
511 d->document->selection (),
512 commandEnvironment ()));
515 // private slot
516 void kpMainWindow::slotConvertToGrayscale ()
518 toolEndShape ();
520 addImageOrSelectionCommand (
521 new kpEffectGrayscaleCommand (d->document->selection (),
522 commandEnvironment ()));
525 // private slot
526 void kpMainWindow::slotInvertColors ()
528 toolEndShape ();
530 addImageOrSelectionCommand (
531 new kpEffectInvertCommand (d->document->selection (),
532 commandEnvironment ()));
535 // private slot
536 void kpMainWindow::slotClear ()
538 toolEndShape ();
540 addImageOrSelectionCommand (
541 new kpEffectClearCommand (
542 d->document->selection (),
543 backgroundColor (),
544 commandEnvironment ()));
547 // private slot
548 void kpMainWindow::slotMoreEffects ()
550 toolEndShape ();
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);
570 cfg.sync ();