TDE graphics utilities
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kpmainwindow_image.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /*
  2. Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions
  6. are met:
  7. 1. Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. 2. Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  14. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  19. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. */
  23. #include <kpmainwindow.h>
  24. #include <kpmainwindow_p.h>
  25. #include <tqcolor.h>
  26. #include <tqsize.h>
  27. #include <tdeaction.h>
  28. #include <tdeapplication.h>
  29. #include <tdeconfig.h>
  30. #include <kdebug.h>
  31. #include <tdelocale.h>
  32. #include <tdemenubar.h>
  33. #include <kpcolor.h>
  34. #include <kpdefs.h>
  35. #include <kpcoloreffect.h>
  36. #include <kpcolortoolbar.h>
  37. #include <kpcommandhistory.h>
  38. #include <kpdocument.h>
  39. #include <kpeffectinvert.h>
  40. #include <kpeffectreducecolors.h>
  41. #include <kpeffectsdialog.h>
  42. #include <kpselection.h>
  43. #include <kptool.h>
  44. #include <kptoolautocrop.h>
  45. #include <kptoolclear.h>
  46. #include <kptoolconverttograyscale.h>
  47. #include <kptoolcrop.h>
  48. #include <kptoolflip.h>
  49. #include <kptoolresizescale.h>
  50. #include <kptoolrotate.h>
  51. #include <kptoolselection.h>
  52. #include <kptoolskew.h>
  53. #include <kpviewmanager.h>
  54. // private
  55. bool kpMainWindow::isSelectionActive () const
  56. {
  57. return (m_document ? bool (m_document->selection ()) : false);
  58. }
  59. // private
  60. bool kpMainWindow::isTextSelection () const
  61. {
  62. return (m_document && m_document->selection () &&
  63. m_document->selection ()->isText ());
  64. }
  65. // private
  66. TQString kpMainWindow::autoCropText () const
  67. {
  68. return kpToolAutoCropCommand::name (isSelectionActive (),
  69. kpToolAutoCropCommand::ShowAccel);
  70. }
  71. // private
  72. void kpMainWindow::setupImageMenuActions ()
  73. {
  74. TDEActionCollection *ac = actionCollection ();
  75. m_actionResizeScale = new TDEAction (i18n ("R&esize / Scale..."), TQt::CTRL + TQt::Key_E,
  76. TQT_TQOBJECT(this), TQT_SLOT (slotResizeScale ()), ac, "image_resize_scale");
  77. m_actionCrop = new TDEAction (i18n ("Se&t as Image (Crop)"), TQt::CTRL + TQt::Key_T,
  78. TQT_TQOBJECT(this), TQT_SLOT (slotCrop ()), ac, "image_crop");
  79. m_actionAutoCrop = new TDEAction (autoCropText (), TQt::CTRL + TQt::Key_U,
  80. TQT_TQOBJECT(this), TQT_SLOT (slotAutoCrop ()), ac, "image_auto_crop");
  81. m_actionFlip = new TDEAction (i18n ("&Flip..."), TQt::CTRL + TQt::Key_F,
  82. TQT_TQOBJECT(this), TQT_SLOT (slotFlip ()), ac, "image_flip");
  83. m_actionRotate = new TDEAction (i18n ("&Rotate..."), TQt::CTRL + TQt::Key_R,
  84. TQT_TQOBJECT(this), TQT_SLOT (slotRotate ()), ac, "image_rotate");
  85. m_actionSkew = new TDEAction (i18n ("S&kew..."), TQt::CTRL + TQt::Key_K,
  86. TQT_TQOBJECT(this), TQT_SLOT (slotSkew ()), ac, "image_skew");
  87. m_actionConvertToBlackAndWhite = new TDEAction (i18n ("Reduce to Mo&nochrome (Dithered)"), 0,
  88. TQT_TQOBJECT(this), TQT_SLOT (slotConvertToBlackAndWhite ()), ac, "image_convert_to_black_and_white");
  89. m_actionConvertToGrayscale = new TDEAction (i18n ("Reduce to &Grayscale"), 0,
  90. TQT_TQOBJECT(this), TQT_SLOT (slotConvertToGrayscale ()), ac, "image_convert_to_grayscale");
  91. m_actionInvertColors = new TDEAction (i18n ("&Invert Colors"), TQt::CTRL + TQt::Key_I,
  92. TQT_TQOBJECT(this), TQT_SLOT (slotInvertColors ()), ac, "image_invert_colors");
  93. m_actionClear = new TDEAction (i18n ("C&lear"), TQt::CTRL + TQt::SHIFT + TQt::Key_N,
  94. TQT_TQOBJECT(this), TQT_SLOT (slotClear ()), ac, "image_clear");
  95. m_actionMoreEffects = new TDEAction (i18n ("&More Effects..."), TQt::CTRL + TQt::Key_M,
  96. TQT_TQOBJECT(this), TQT_SLOT (slotMoreEffects ()), ac, "image_more_effects");
  97. enableImageMenuDocumentActions (false);
  98. }
  99. // private
  100. void kpMainWindow::enableImageMenuDocumentActions (bool enable)
  101. {
  102. m_actionResizeScale->setEnabled (enable);
  103. m_actionCrop->setEnabled (enable);
  104. m_actionAutoCrop->setEnabled (enable);
  105. m_actionFlip->setEnabled (enable);
  106. m_actionRotate->setEnabled (enable);
  107. m_actionSkew->setEnabled (enable);
  108. m_actionConvertToBlackAndWhite->setEnabled (enable);
  109. m_actionConvertToGrayscale->setEnabled (enable);
  110. m_actionInvertColors->setEnabled (enable);
  111. m_actionClear->setEnabled (enable);
  112. m_actionMoreEffects->setEnabled (enable);
  113. m_imageMenuDocumentActionsEnabled = enable;
  114. }
  115. // private slot
  116. void kpMainWindow::slotImageMenuUpdateDueToSelection ()
  117. {
  118. KMenuBar *mBar = menuBar ();
  119. if (!mBar) // just in case
  120. return;
  121. int mBarNumItems = (int) mBar->count ();
  122. for (int index = 0; index < mBarNumItems; index++)
  123. {
  124. int id = mBar->idAt (index);
  125. // SYNC: kolourpaintui.rc
  126. TQString menuBarItemTextImage = i18n ("&Image");
  127. TQString menuBarItemTextSelection = i18n ("Select&ion");
  128. const TQString menuBarItemText = mBar->text (id);
  129. if (menuBarItemText == menuBarItemTextImage ||
  130. menuBarItemText == menuBarItemTextSelection)
  131. {
  132. if (isSelectionActive ())
  133. mBar->changeItem (id, menuBarItemTextSelection);
  134. else
  135. mBar->changeItem (id, menuBarItemTextImage);
  136. break;
  137. }
  138. }
  139. m_actionResizeScale->setEnabled (m_imageMenuDocumentActionsEnabled);
  140. m_actionCrop->setEnabled (m_imageMenuDocumentActionsEnabled &&
  141. isSelectionActive ());
  142. const bool enable = (m_imageMenuDocumentActionsEnabled && !isTextSelection ());
  143. m_actionAutoCrop->setText (autoCropText ());
  144. m_actionAutoCrop->setEnabled (enable);
  145. m_actionFlip->setEnabled (enable);
  146. m_actionRotate->setEnabled (enable);
  147. m_actionSkew->setEnabled (enable);
  148. m_actionConvertToBlackAndWhite->setEnabled (enable);
  149. m_actionConvertToGrayscale->setEnabled (enable);
  150. m_actionInvertColors->setEnabled (enable);
  151. m_actionClear->setEnabled (enable);
  152. m_actionMoreEffects->setEnabled (enable);
  153. }
  154. // public
  155. kpColor kpMainWindow::backgroundColor (bool ofSelection) const
  156. {
  157. if (ofSelection)
  158. return kpColor::transparent;
  159. else
  160. {
  161. if (m_colorToolBar)
  162. return m_colorToolBar->backgroundColor ();
  163. else
  164. {
  165. kdError () << "kpMainWindow::backgroundColor() without colorToolBar" << endl;
  166. return kpColor::invalid;
  167. }
  168. }
  169. }
  170. // public
  171. void kpMainWindow::addImageOrSelectionCommand (kpCommand *cmd,
  172. bool addSelCreateCmdIfSelAvail,
  173. bool addSelPullCmdIfSelAvail)
  174. {
  175. #if DEBUG_KP_MAIN_WINDOW && 1
  176. kdDebug () << "kpMainWindow::addImageOrSelectionCommand()"
  177. << " addSelCreateCmdIfSelAvail=" << addSelCreateCmdIfSelAvail
  178. << " addSelPullCmdIfSelAvail=" << addSelPullCmdIfSelAvail
  179. << endl;
  180. #endif
  181. if (!m_document)
  182. {
  183. kdError () << "kpMainWindow::addImageOrSelectionCommand() without doc" << endl;
  184. return;
  185. }
  186. if (m_viewManager)
  187. m_viewManager->setQueueUpdates ();
  188. kpSelection *sel = m_document->selection ();
  189. #if DEBUG_KP_MAIN_WINDOW && 1
  190. kdDebug () << "\tsel=" << sel
  191. << " sel->pixmap=" << (sel ? sel->pixmap () : 0)
  192. << endl;
  193. #endif
  194. if (addSelCreateCmdIfSelAvail && sel && !sel->pixmap ())
  195. {
  196. // create selection region
  197. kpCommand *createCommand = new kpToolSelectionCreateCommand (
  198. i18n ("Selection: Create"),
  199. *sel,
  200. this);
  201. if (kpToolSelectionCreateCommand::nextUndoCommandIsCreateBorder (commandHistory ()))
  202. commandHistory ()->setNextUndoCommand (createCommand);
  203. else
  204. commandHistory ()->addCommand (createCommand,
  205. false/*no exec - user already dragged out sel*/);
  206. }
  207. if (addSelPullCmdIfSelAvail && sel && !sel->pixmap ())
  208. {
  209. kpMacroCommand *macroCmd = new kpMacroCommand (cmd->name (), this);
  210. macroCmd->addCommand (new kpToolSelectionPullFromDocumentCommand (
  211. TQString()/*uninteresting child of macro cmd*/,
  212. this));
  213. macroCmd->addCommand (cmd);
  214. m_commandHistory->addCommand (macroCmd);
  215. }
  216. else
  217. {
  218. m_commandHistory->addCommand (cmd);
  219. }
  220. if (m_viewManager)
  221. m_viewManager->restoreQueueUpdates ();
  222. }
  223. // private slot
  224. void kpMainWindow::slotResizeScale ()
  225. {
  226. if (toolHasBegunShape ())
  227. tool ()->endShapeInternal ();
  228. kpToolResizeScaleDialog dialog (this);
  229. dialog.setKeepAspectRatio (d->m_resizeScaleDialogLastKeepAspect);
  230. if (dialog.exec () && !dialog.isNoOp ())
  231. {
  232. kpToolResizeScaleCommand *cmd = new kpToolResizeScaleCommand (
  233. dialog.actOnSelection (),
  234. dialog.imageWidth (), dialog.imageHeight (),
  235. dialog.type (),
  236. this);
  237. bool addSelCreateCommand = (dialog.actOnSelection () ||
  238. cmd->scaleSelectionWithImage ());
  239. bool addSelPullCommand = dialog.actOnSelection ();
  240. addImageOrSelectionCommand (
  241. cmd,
  242. addSelCreateCommand,
  243. addSelPullCommand);
  244. // Resized document?
  245. if (!dialog.actOnSelection () &&
  246. dialog.type () == kpToolResizeScaleCommand::Resize)
  247. {
  248. // TODO: this should be the responsibility of kpDocument
  249. saveDefaultDocSize (TQSize (dialog.imageWidth (), dialog.imageHeight ()));
  250. }
  251. }
  252. if (d->m_resizeScaleDialogLastKeepAspect != dialog.keepAspectRatio ())
  253. {
  254. d->m_resizeScaleDialogLastKeepAspect = dialog.keepAspectRatio ();
  255. TDEConfigGroupSaver cfgGroupSaver (kapp->config (), kpSettingsGroupGeneral);
  256. TDEConfigBase *cfg = cfgGroupSaver.config ();
  257. cfg->writeEntry (kpSettingResizeScaleLastKeepAspect,
  258. d->m_resizeScaleDialogLastKeepAspect);
  259. cfg->sync ();
  260. }
  261. }
  262. // public slot
  263. void kpMainWindow::slotCrop ()
  264. {
  265. if (toolHasBegunShape ())
  266. tool ()->endShapeInternal ();
  267. if (!m_document || !m_document->selection ())
  268. {
  269. kdError () << "kpMainWindow::slotCrop() doc=" << m_document
  270. << " sel=" << (m_document ? m_document->selection () : 0)
  271. << endl;
  272. return;
  273. }
  274. ::kpToolCrop (this);
  275. }
  276. // private slot
  277. void kpMainWindow::slotAutoCrop ()
  278. {
  279. if (toolHasBegunShape ())
  280. tool ()->endShapeInternal ();
  281. ::kpToolAutoCrop (this);
  282. }
  283. // private slot
  284. void kpMainWindow::slotFlip ()
  285. {
  286. if (toolHasBegunShape ())
  287. tool ()->endShapeInternal ();
  288. kpToolFlipDialog dialog ((bool) m_document->selection (), this);
  289. if (dialog.exec () && !dialog.isNoOp ())
  290. {
  291. addImageOrSelectionCommand (
  292. new kpToolFlipCommand (m_document->selection (),
  293. dialog.getHorizontalFlip (), dialog.getVerticalFlip (),
  294. this));
  295. }
  296. }
  297. // private slot
  298. void kpMainWindow::slotRotate ()
  299. {
  300. if (toolHasBegunShape ())
  301. tool ()->endShapeInternal ();
  302. kpToolRotateDialog dialog ((bool) m_document->selection (), this);
  303. if (dialog.exec () && !dialog.isNoOp ())
  304. {
  305. addImageOrSelectionCommand (
  306. new kpToolRotateCommand (m_document->selection (),
  307. dialog.angle (),
  308. this));
  309. }
  310. }
  311. // private slot
  312. void kpMainWindow::slotSkew ()
  313. {
  314. if (toolHasBegunShape ())
  315. tool ()->endShapeInternal ();
  316. kpToolSkewDialog dialog ((bool) m_document->selection (), this);
  317. if (dialog.exec () && !dialog.isNoOp ())
  318. {
  319. addImageOrSelectionCommand (
  320. new kpToolSkewCommand (m_document->selection (),
  321. dialog.horizontalAngle (), dialog.verticalAngle (),
  322. this));
  323. }
  324. }
  325. // private slot
  326. void kpMainWindow::slotConvertToBlackAndWhite ()
  327. {
  328. if (toolHasBegunShape ())
  329. tool ()->endShapeInternal ();
  330. addImageOrSelectionCommand (
  331. new kpEffectReduceColorsCommand (1/*depth*/, true/*dither*/,
  332. m_document->selection (), this));
  333. }
  334. // private slot
  335. void kpMainWindow::slotConvertToGrayscale ()
  336. {
  337. if (toolHasBegunShape ())
  338. tool ()->endShapeInternal ();
  339. addImageOrSelectionCommand (
  340. new kpToolConvertToGrayscaleCommand (m_document->selection (), this));
  341. }
  342. // private slot
  343. void kpMainWindow::slotInvertColors ()
  344. {
  345. if (toolHasBegunShape ())
  346. tool ()->endShapeInternal ();
  347. addImageOrSelectionCommand (
  348. new kpEffectInvertCommand (m_document->selection (), this));
  349. }
  350. // private slot
  351. void kpMainWindow::slotClear ()
  352. {
  353. if (toolHasBegunShape ())
  354. tool ()->endShapeInternal ();
  355. addImageOrSelectionCommand (
  356. new kpToolClearCommand (m_document->selection (), this));
  357. }
  358. // private slot
  359. void kpMainWindow::slotMoreEffects ()
  360. {
  361. if (toolHasBegunShape ())
  362. tool ()->endShapeInternal ();
  363. kpEffectsDialog dialog ((bool) m_document->selection (), this);
  364. dialog.selectEffect (d->m_moreEffectsDialogLastEffect);
  365. if (dialog.exec () && !dialog.isNoOp ())
  366. {
  367. addImageOrSelectionCommand (dialog.createCommand ());
  368. }
  369. if (d->m_moreEffectsDialogLastEffect != dialog.selectedEffect ())
  370. {
  371. d->m_moreEffectsDialogLastEffect = dialog.selectedEffect ();
  372. TDEConfigGroupSaver cfgGroupSaver (kapp->config (), kpSettingsGroupGeneral);
  373. TDEConfigBase *cfg = cfgGroupSaver.config ();
  374. cfg->writeEntry (kpSettingMoreEffectsLastEffect,
  375. d->m_moreEffectsDialogLastEffect);
  376. cfg->sync ();
  377. }
  378. }