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.

kpdocumentsaveoptionswidget.cpp 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  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. #define DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET 0
  24. #include <kpdocumentsaveoptionswidget.h>
  25. #include <tqapplication.h>
  26. #include <tqbuffer.h>
  27. #include <tqimage.h>
  28. #include <tqlabel.h>
  29. #include <tqlayout.h>
  30. #include <tqtimer.h>
  31. #include <kcombobox.h>
  32. #include <tdeconfig.h>
  33. #include <kdebug.h>
  34. #include <kdialog.h>
  35. #include <kdialogbase.h>
  36. #include <tdeglobal.h>
  37. #include <kimageio.h>
  38. #include <tdelocale.h>
  39. #include <knuminput.h>
  40. #include <kpushbutton.h>
  41. #include <kpdefs.h>
  42. #include <kpdocument.h>
  43. #include <kppixmapfx.h>
  44. #include <kpresizesignallinglabel.h>
  45. #include <kpselection.h>
  46. #include <kptoolpreviewdialog.h>
  47. #include <kpwidgetmapper.h>
  48. // protected static
  49. const TQSize kpDocumentSaveOptionsPreviewDialog::s_pixmapLabelMinimumSize (25, 25);
  50. kpDocumentSaveOptionsPreviewDialog::kpDocumentSaveOptionsPreviewDialog (
  51. TQWidget *parent,
  52. const char *name)
  53. : TQWidget (parent, name,
  54. TQt::WType_TopLevel |
  55. TQt::WStyle_Customize |
  56. TQt::WStyle_DialogBorder |
  57. TQt::WStyle_Title),
  58. #if 0
  59. KDialogBase (parent, name, false/*non-modal*/,
  60. i18n ("Save Preview"),
  61. 0/*no buttons*/),
  62. #endif
  63. m_filePixmap (0),
  64. m_fileSize (0)
  65. {
  66. setCaption (i18n ("Save Preview"));
  67. TQWidget *baseWidget = this;//new TQWidget (this);
  68. //setMainWidget (baseWidget);
  69. TQGridLayout *lay = new TQGridLayout (baseWidget, 2, 1,
  70. KDialog::marginHint (), KDialog::spacingHint ());
  71. m_filePixmapLabel = new kpResizeSignallingLabel (baseWidget);
  72. m_fileSizeLabel = new TQLabel (baseWidget);
  73. m_filePixmapLabel->setMinimumSize (s_pixmapLabelMinimumSize);
  74. lay->addWidget (m_filePixmapLabel, 0, 0);
  75. lay->addWidget (m_fileSizeLabel, 1, 0, TQt::AlignHCenter);
  76. lay->setRowStretch (0, 1);
  77. connect (m_filePixmapLabel, TQT_SIGNAL (resized ()),
  78. this, TQT_SLOT (updatePixmapPreview ()));
  79. }
  80. kpDocumentSaveOptionsPreviewDialog::~kpDocumentSaveOptionsPreviewDialog ()
  81. {
  82. delete m_filePixmap;
  83. }
  84. // public
  85. TQSize kpDocumentSaveOptionsPreviewDialog::preferredMinimumSize () const
  86. {
  87. const int contentsWidth = 180;
  88. const int totalMarginsWidth = 2 * KDialog::marginHint ();
  89. return TQSize (contentsWidth + totalMarginsWidth,
  90. contentsWidth * 3 / 4 + totalMarginsWidth);
  91. }
  92. // public slot
  93. void kpDocumentSaveOptionsPreviewDialog::setFilePixmapAndSize (const TQPixmap &pixmap,
  94. int fileSize)
  95. {
  96. delete m_filePixmap;
  97. m_filePixmap = new TQPixmap (pixmap);
  98. updatePixmapPreview ();
  99. m_fileSize = fileSize;
  100. const int pixmapSize = kpPixmapFX::pixmapSize (pixmap);
  101. const int percent = pixmapSize ?
  102. TQMAX (1, fileSize * 100 / pixmapSize) :
  103. 0;
  104. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  105. kdDebug () << "kpDocumentSaveOptionsPreviewDialog::setFilePixmapAndSize()"
  106. << " pixmapSize=" << pixmapSize
  107. << " fileSize=" << fileSize
  108. << " raw fileSize/pixmapSize%="
  109. << (pixmapSize ? fileSize * 100 / pixmapSize : 0)
  110. << endl;
  111. #endif
  112. // HACK: I don't know if the percentage thing will work well and we're
  113. // really close to the message freeze so provide alt. texts to choose
  114. // from during the message freeze :)
  115. const TQString alternateText0 = i18n ("%1 bytes");
  116. const TQString alternateText1 = i18n ("%1 bytes (%2%)");
  117. const TQString alternateText2 = i18n ("%1 B");
  118. const TQString alternateText3 = i18n ("%1 B (%2%)");
  119. const TQString alternateText4 = i18n ("%1 B (approx. %2%)");
  120. const TQString alternateText5 = i18n ("%1B");
  121. const TQString alternateText6 = i18n ("%1B (%2%)");
  122. const TQString alternateText7 = i18n ("%1B (approx. %2%)");
  123. m_fileSizeLabel->setText (i18n ("%1 bytes (approx. %2%)")
  124. .arg (TDEGlobal::locale ()->formatLong (m_fileSize))
  125. .arg (percent));
  126. }
  127. // public slot
  128. void kpDocumentSaveOptionsPreviewDialog::updatePixmapPreview ()
  129. {
  130. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  131. kdDebug () << "kpDocumentSaveOptionsPreviewDialog::updatePreviewPixmap()"
  132. << " filePixmapLabel.size=" << m_filePixmapLabel->size ()
  133. << " filePixmap.size=" << m_filePixmap->size ()
  134. << endl;
  135. #endif
  136. if (m_filePixmap)
  137. {
  138. int maxNewWidth = TQMIN (m_filePixmap->width (),
  139. m_filePixmapLabel->width ()),
  140. maxNewHeight = TQMIN (m_filePixmap->height (),
  141. m_filePixmapLabel->height ());
  142. double keepsAspect = kpToolPreviewDialog::aspectScale (
  143. maxNewWidth, maxNewHeight,
  144. m_filePixmap->width (), m_filePixmap->height ());
  145. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  146. kdDebug () << "\tmaxNewWidth=" << maxNewWidth
  147. << " maxNewHeight=" << maxNewHeight
  148. << " keepsAspect=" << keepsAspect
  149. << endl;
  150. #endif
  151. const int newWidth = kpToolPreviewDialog::scaleDimension (
  152. m_filePixmap->width (),
  153. keepsAspect,
  154. 1,
  155. maxNewWidth);
  156. const int newHeight = kpToolPreviewDialog::scaleDimension (
  157. m_filePixmap->height (),
  158. keepsAspect,
  159. 1,
  160. maxNewHeight);
  161. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  162. kdDebug () << "\tnewWidth=" << newWidth
  163. << " newHeight=" << newHeight
  164. << endl;
  165. #endif
  166. TQPixmap transformedPixmap =
  167. kpPixmapFX::scale (*m_filePixmap,
  168. newWidth, newHeight);
  169. TQPixmap labelPixmap (m_filePixmapLabel->width (),
  170. m_filePixmapLabel->height ());
  171. kpPixmapFX::fill (&labelPixmap, kpColor::transparent);
  172. kpPixmapFX::setPixmapAt (&labelPixmap,
  173. (labelPixmap.width () - transformedPixmap.width ()) / 2,
  174. (labelPixmap.height () - transformedPixmap.height ()) / 2,
  175. transformedPixmap);
  176. m_filePixmapLabel->setPixmap (labelPixmap);
  177. }
  178. else
  179. {
  180. m_filePixmapLabel->setPixmap (TQPixmap ());
  181. }
  182. }
  183. // protected virtual [base TQWidget]
  184. void kpDocumentSaveOptionsPreviewDialog::closeEvent (TQCloseEvent *e)
  185. {
  186. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  187. kdDebug () << "kpDocumentSaveOptionsPreviewDialog::closeEvent()" << endl;
  188. #endif
  189. TQWidget::closeEvent (e);
  190. emit finished ();
  191. }
  192. // protected virtual [base TQWidget]
  193. void kpDocumentSaveOptionsPreviewDialog::moveEvent (TQMoveEvent *e)
  194. {
  195. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  196. kdDebug () << "kpDocumentSaveOptionsPreviewDialog::moveEvent()" << endl;
  197. #endif
  198. TQWidget::moveEvent (e);
  199. emit moved ();
  200. }
  201. // protected virtual [base TQWidget]
  202. void kpDocumentSaveOptionsPreviewDialog::resizeEvent (TQResizeEvent *e)
  203. {
  204. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  205. kdDebug () << "kpDocumentSaveOptionsPreviewDialog::resizeEvent()" << endl;
  206. #endif
  207. TQWidget::resizeEvent (e);
  208. emit resized ();
  209. }
  210. kpDocumentSaveOptionsWidget::kpDocumentSaveOptionsWidget (
  211. const TQPixmap &docPixmap,
  212. const kpDocumentSaveOptions &saveOptions,
  213. const kpDocumentMetaInfo &metaInfo,
  214. TQWidget *parent, const char *name)
  215. : TQWidget (parent, name),
  216. m_visualParent (parent)
  217. {
  218. init ();
  219. setDocumentSaveOptions (saveOptions);
  220. setDocumentPixmap (docPixmap);
  221. setDocumentMetaInfo (metaInfo);
  222. }
  223. kpDocumentSaveOptionsWidget::kpDocumentSaveOptionsWidget (
  224. TQWidget *parent, const char *name)
  225. : TQWidget (parent, name),
  226. m_visualParent (parent)
  227. {
  228. init ();
  229. }
  230. // private
  231. void kpDocumentSaveOptionsWidget::init ()
  232. {
  233. m_documentPixmap = 0;
  234. m_previewDialog = 0;
  235. m_visualParent = 0;
  236. m_colorDepthLabel = new TQLabel (i18n ("Convert &to:"), this);
  237. m_colorDepthCombo = new KComboBox (this);
  238. m_colorDepthSpaceWidget = new TQWidget (this);
  239. m_qualityLabel = new TQLabel (i18n ("Quali&ty:"), this);
  240. m_qualityInput = new KIntNumInput (this);
  241. // Note that we set min to 1 not 0 since "0 Quality" is a bit misleading
  242. // and 101 quality settings would be weird. So we lose 1 quality setting
  243. // according to TQImage::save().
  244. // TODO: 100 quality is also misleading since that implies perfect quality.
  245. m_qualityInput->setRange (1, 100, 1/*step*/, true/*slider*/);
  246. m_previewButton = new KPushButton (i18n ("&Preview"), this);
  247. m_previewButton->setToggleButton (true);
  248. m_colorDepthLabel->setBuddy (m_colorDepthCombo);
  249. m_qualityLabel->setBuddy (m_qualityInput);
  250. TQHBoxLayout *lay = new TQHBoxLayout (this, 0/*margin*/, KDialog::spacingHint ());
  251. lay->addWidget (m_colorDepthLabel, 0/*stretch*/, TQt::AlignLeft);
  252. lay->addWidget (m_colorDepthCombo, 0/*stretch*/);
  253. lay->addWidget (m_colorDepthSpaceWidget, 1/*stretch*/);
  254. lay->addWidget (m_qualityLabel, 0/*stretch*/, TQt::AlignLeft);
  255. lay->addWidget (m_qualityInput, 2/*stretch*/);
  256. lay->addWidget (m_previewButton, 0/*stretch*/, TQt::AlignRight);
  257. connect (m_colorDepthCombo, TQT_SIGNAL (activated (int)),
  258. this, TQT_SLOT (slotColorDepthSelected ()));
  259. connect (m_colorDepthCombo, TQT_SIGNAL (activated (int)),
  260. this, TQT_SLOT (updatePreview ()));
  261. connect (m_qualityInput, TQT_SIGNAL (valueChanged (int)),
  262. this, TQT_SLOT (updatePreviewDelayed ()));
  263. connect (m_previewButton, TQT_SIGNAL (toggled (bool)),
  264. this, TQT_SLOT (showPreview (bool)));
  265. m_updatePreviewDelay = 200/*ms*/;
  266. m_updatePreviewTimer = new TQTimer (this);
  267. connect (m_updatePreviewTimer, TQT_SIGNAL (timeout ()),
  268. this, TQT_SLOT (updatePreview ()));
  269. m_updatePreviewDialogLastRelativeGeometryTimer = new TQTimer (this);
  270. connect (m_updatePreviewDialogLastRelativeGeometryTimer, TQT_SIGNAL (timeout ()),
  271. this, TQT_SLOT (updatePreviewDialogLastRelativeGeometry ()));
  272. setMode (None);
  273. slotColorDepthSelected ();
  274. }
  275. kpDocumentSaveOptionsWidget::~kpDocumentSaveOptionsWidget ()
  276. {
  277. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  278. kdDebug () << "kpDocumentSaveOptionsWidget::<dtor>()" << endl;
  279. #endif
  280. hidePreview ();
  281. delete m_documentPixmap;
  282. }
  283. // public
  284. void kpDocumentSaveOptionsWidget::setVisualParent (TQWidget *visualParent)
  285. {
  286. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  287. kdDebug () << "kpDocumentSaveOptionsWidget::setVisualParent("
  288. << visualParent << ")" << endl;
  289. #endif
  290. m_visualParent = visualParent;
  291. }
  292. // protected
  293. bool kpDocumentSaveOptionsWidget::mimeTypeHasConfigurableColorDepth () const
  294. {
  295. return kpDocumentSaveOptions::mimeTypeHasConfigurableColorDepth (mimeType ());
  296. }
  297. // protected
  298. bool kpDocumentSaveOptionsWidget::mimeTypeHasConfigurableQuality () const
  299. {
  300. return kpDocumentSaveOptions::mimeTypeHasConfigurableQuality (mimeType ());
  301. }
  302. // public
  303. TQString kpDocumentSaveOptionsWidget::mimeType () const
  304. {
  305. return m_baseDocumentSaveOptions.mimeType ();
  306. }
  307. // public slots
  308. void kpDocumentSaveOptionsWidget::setMimeType (const TQString &string)
  309. {
  310. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  311. kdDebug () << "kpDocumentSaveOptionsWidget::setMimeType(" << string
  312. << ") maxColorDepth="
  313. << kpDocumentSaveOptions::mimeTypeMaximumColorDepth (string)
  314. << endl;
  315. #endif
  316. const int newMimeTypeMaxDepth =
  317. kpDocumentSaveOptions::mimeTypeMaximumColorDepth (string);
  318. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  319. kdDebug () << "\toldMimeType=" << mimeType ()
  320. << " maxColorDepth="
  321. << kpDocumentSaveOptions::mimeTypeMaximumColorDepth (
  322. mimeType ())
  323. << endl;
  324. #endif
  325. if (mimeType ().isEmpty () ||
  326. kpDocumentSaveOptions::mimeTypeMaximumColorDepth (mimeType ()) !=
  327. newMimeTypeMaxDepth)
  328. {
  329. m_colorDepthCombo->clear ();
  330. m_colorDepthCombo->insertItem (i18n ("Monochrome"), 0);
  331. m_colorDepthCombo->insertItem (i18n ("Monochrome (Dithered)"), 1);
  332. if (newMimeTypeMaxDepth >= 8)
  333. {
  334. m_colorDepthCombo->insertItem (i18n ("256 Color"), 2);
  335. m_colorDepthCombo->insertItem (i18n ("256 Color (Dithered)"), 3);
  336. }
  337. if (newMimeTypeMaxDepth >= 24)
  338. {
  339. m_colorDepthCombo->insertItem (i18n ("24-bit Color"), 4);
  340. }
  341. if (m_colorDepthComboLastSelectedItem >= 0 &&
  342. m_colorDepthComboLastSelectedItem < m_colorDepthCombo->count ())
  343. {
  344. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  345. kdDebug () << "\tsetting colorDepthCombo to "
  346. << m_colorDepthComboLastSelectedItem << endl;
  347. #endif
  348. m_colorDepthCombo->setCurrentItem (m_colorDepthComboLastSelectedItem);
  349. }
  350. else
  351. {
  352. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  353. kdDebug () << "\tsetting colorDepthCombo to max item since"
  354. << " m_colorDepthComboLastSelectedItem="
  355. << m_colorDepthComboLastSelectedItem
  356. << " out of range" << endl;
  357. #endif
  358. m_colorDepthCombo->setCurrentItem (m_colorDepthCombo->count () - 1);
  359. }
  360. }
  361. m_baseDocumentSaveOptions.setMimeType (string);
  362. if (mimeTypeHasConfigurableColorDepth ())
  363. setMode (ColorDepth);
  364. else if (mimeTypeHasConfigurableQuality ())
  365. setMode (Quality);
  366. else
  367. setMode (None);
  368. updatePreview ();
  369. }
  370. // public
  371. int kpDocumentSaveOptionsWidget::colorDepth () const
  372. {
  373. if (mode () & ColorDepth)
  374. {
  375. switch (m_colorDepthCombo->currentItem ())
  376. {
  377. case 0:
  378. case 1:
  379. return 1;
  380. case 2:
  381. case 3:
  382. return 8;
  383. case 4:
  384. return 32;
  385. default:
  386. return kpDocumentSaveOptions::invalidColorDepth ();
  387. }
  388. }
  389. else
  390. {
  391. return m_baseDocumentSaveOptions.colorDepth ();
  392. }
  393. }
  394. // public
  395. bool kpDocumentSaveOptionsWidget::dither () const
  396. {
  397. if (mode () & ColorDepth)
  398. {
  399. return (m_colorDepthCombo->currentItem () == 1 ||
  400. m_colorDepthCombo->currentItem () == 3);
  401. }
  402. else
  403. {
  404. return m_baseDocumentSaveOptions.dither ();
  405. }
  406. }
  407. // protected static
  408. int kpDocumentSaveOptionsWidget::colorDepthComboItemFromColorDepthAndDither (
  409. int depth, bool dither)
  410. {
  411. if (depth == 1)
  412. {
  413. if (!dither)
  414. {
  415. return 0;
  416. }
  417. else
  418. {
  419. return 1;
  420. }
  421. }
  422. else if (depth == 8)
  423. {
  424. if (!dither)
  425. {
  426. return 2;
  427. }
  428. else
  429. {
  430. return 3;
  431. }
  432. }
  433. else if (depth == 32)
  434. {
  435. return 4;
  436. }
  437. else
  438. {
  439. return -1;
  440. }
  441. }
  442. // public slots
  443. void kpDocumentSaveOptionsWidget::setColorDepthDither (int newDepth, bool newDither)
  444. {
  445. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  446. kdDebug () << "kpDocumentSaveOptionsWidget::setColorDepthDither("
  447. << "depth=" << newDepth
  448. << ",dither=" << newDither
  449. << ")" << endl;
  450. #endif
  451. m_baseDocumentSaveOptions.setColorDepth (newDepth);
  452. m_baseDocumentSaveOptions.setDither (newDither);
  453. const int comboItem = colorDepthComboItemFromColorDepthAndDither (
  454. newDepth, newDither);
  455. // TODO: Ignoring when comboItem >= m_colorDepthCombo->count() is wrong.
  456. // This happens if this mimeType has configurable colour depth
  457. // and an incorrect maximum colour depth (less than a TQImage of
  458. // this mimeType, opened by kpDocument).
  459. if (comboItem >= 0 && comboItem < m_colorDepthCombo->count ())
  460. m_colorDepthCombo->setCurrentItem (comboItem);
  461. slotColorDepthSelected ();
  462. }
  463. // protected slot
  464. void kpDocumentSaveOptionsWidget::slotColorDepthSelected ()
  465. {
  466. if (mode () & ColorDepth)
  467. {
  468. m_colorDepthComboLastSelectedItem = m_colorDepthCombo->currentItem ();
  469. }
  470. else
  471. {
  472. m_colorDepthComboLastSelectedItem =
  473. colorDepthComboItemFromColorDepthAndDither (
  474. m_baseDocumentSaveOptions.colorDepth (),
  475. m_baseDocumentSaveOptions.dither ());
  476. }
  477. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  478. kdDebug () << "kpDocumentSaveOptionsWidget::slotColorDepthSelected()"
  479. << " mode&ColorDepth=" << (mode () & ColorDepth)
  480. << " colorDepthComboLastSelectedItem="
  481. << m_colorDepthComboLastSelectedItem
  482. << endl;
  483. #endif
  484. }
  485. // public
  486. int kpDocumentSaveOptionsWidget::quality () const
  487. {
  488. if (mode () & Quality)
  489. {
  490. return m_qualityInput->value ();
  491. }
  492. else
  493. {
  494. return m_baseDocumentSaveOptions.quality ();
  495. }
  496. }
  497. // public
  498. void kpDocumentSaveOptionsWidget::setQuality (int newQuality)
  499. {
  500. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  501. kdDebug () << "kpDocumentSaveOptionsWidget::setQuality("
  502. << newQuality << ")" << endl;
  503. #endif
  504. m_baseDocumentSaveOptions.setQuality (newQuality);
  505. m_qualityInput->setValue (newQuality == -1/*TQImage::save() default*/ ?
  506. 75 :
  507. newQuality);
  508. }
  509. // public
  510. kpDocumentSaveOptions kpDocumentSaveOptionsWidget::documentSaveOptions () const
  511. {
  512. return kpDocumentSaveOptions (mimeType (), colorDepth (), dither (), quality ());
  513. }
  514. // public
  515. void kpDocumentSaveOptionsWidget::setDocumentSaveOptions (
  516. const kpDocumentSaveOptions &saveOptions)
  517. {
  518. setMimeType (saveOptions.mimeType ());
  519. setColorDepthDither (saveOptions.colorDepth (), saveOptions.dither ());
  520. setQuality (saveOptions.quality ());
  521. }
  522. // public
  523. void kpDocumentSaveOptionsWidget::setDocumentPixmap (const TQPixmap &documentPixmap)
  524. {
  525. delete m_documentPixmap;
  526. m_documentPixmap = new TQPixmap (documentPixmap);
  527. updatePreview ();
  528. }
  529. // public
  530. void kpDocumentSaveOptionsWidget::setDocumentMetaInfo (
  531. const kpDocumentMetaInfo &metaInfo)
  532. {
  533. m_documentMetaInfo = metaInfo;
  534. updatePreview ();
  535. }
  536. // public
  537. kpDocumentSaveOptionsWidget::Mode kpDocumentSaveOptionsWidget::mode () const
  538. {
  539. return m_mode;
  540. }
  541. // public
  542. void kpDocumentSaveOptionsWidget::setMode (Mode mode)
  543. {
  544. m_mode = mode;
  545. // If mode == None, we show still show the Color Depth widgets but disabled
  546. m_colorDepthLabel->setShown (mode != Quality);
  547. m_colorDepthCombo->setShown (mode != Quality);
  548. m_colorDepthSpaceWidget->setShown (mode != Quality);
  549. m_qualityLabel->setShown (mode == Quality);
  550. m_qualityInput->setShown (mode == Quality);
  551. m_colorDepthLabel->setEnabled (mode == ColorDepth);
  552. m_colorDepthCombo->setEnabled (mode == ColorDepth);
  553. m_qualityLabel->setEnabled (mode == Quality);
  554. m_qualityInput->setEnabled (mode == Quality);
  555. // SYNC: HACK: When changing between color depth and quality widgets,
  556. // we change the height of "this", causing the text on the labels
  557. // to move but the first instance of the text doesn't get erased.
  558. // TQt bug.
  559. TQTimer::singleShot (0, this, TQT_SLOT (repaintLabels ()));
  560. }
  561. // protected slot
  562. void kpDocumentSaveOptionsWidget::repaintLabels ()
  563. {
  564. if (mode () != Quality)
  565. m_colorDepthLabel->repaint ();
  566. if (mode () == Quality)
  567. m_qualityLabel->repaint ();
  568. }
  569. // protected slot
  570. void kpDocumentSaveOptionsWidget::showPreview (bool yes)
  571. {
  572. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  573. kdDebug () << "kpDocumentSaveOptionsWidget::showPreview(" << yes << ")"
  574. << " m_previewDialog=" << bool (m_previewDialog)
  575. << endl;
  576. #endif
  577. if (yes == bool (m_previewDialog))
  578. return;
  579. if (!m_visualParent)
  580. return;
  581. if (yes)
  582. {
  583. m_previewDialog = new kpDocumentSaveOptionsPreviewDialog (m_visualParent, "previewSaveDialog");
  584. updatePreview ();
  585. connect (m_previewDialog, TQT_SIGNAL (finished ()),
  586. this, TQT_SLOT (hidePreview ()));
  587. TDEConfigGroupSaver cfgGroupSaver (TDEGlobal::config (), kpSettingsGroupPreviewSave);
  588. TDEConfigBase *cfg = cfgGroupSaver.config ();
  589. if (cfg->hasKey (kpSettingPreviewSaveUpdateDelay))
  590. {
  591. m_updatePreviewDelay = cfg->readNumEntry (kpSettingPreviewSaveUpdateDelay);
  592. }
  593. else
  594. {
  595. cfg->writeEntry (kpSettingPreviewSaveUpdateDelay, m_updatePreviewDelay);
  596. cfg->sync ();
  597. }
  598. if (m_updatePreviewDelay < 0)
  599. m_updatePreviewDelay = 0;
  600. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  601. kdDebug () << "\tread cfg preview dialog update delay="
  602. << m_updatePreviewDelay
  603. << endl;
  604. #endif
  605. if (m_previewDialogLastRelativeGeometry.isEmpty ())
  606. {
  607. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  608. kdDebug () << "\tread cfg preview dialog last rel geometry" << endl;
  609. #endif
  610. TDEConfigGroupSaver cfgGroupSaver (TDEGlobal::config (), kpSettingsGroupPreviewSave);
  611. TDEConfigBase *cfg = cfgGroupSaver.config ();
  612. m_previewDialogLastRelativeGeometry = cfg->readRectEntry (
  613. kpSettingPreviewSaveGeometry);
  614. }
  615. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  616. kdDebug () << "\tpreviewDialogLastRelativeGeometry="
  617. << m_previewDialogLastRelativeGeometry
  618. << " visualParent->rect()=" << m_visualParent->rect ()
  619. << endl;
  620. #endif
  621. TQRect relativeGeometry;
  622. if (!m_previewDialogLastRelativeGeometry.isEmpty () &&
  623. m_visualParent->rect ().intersects (m_previewDialogLastRelativeGeometry))
  624. {
  625. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  626. kdDebug () << "\tok" << endl;
  627. #endif
  628. relativeGeometry = m_previewDialogLastRelativeGeometry;
  629. }
  630. else
  631. {
  632. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  633. kdDebug () << "\t\tinvalid" << endl;
  634. #endif
  635. const int margin = 20;
  636. relativeGeometry =
  637. TQRect (m_visualParent->width () -
  638. m_previewDialog->preferredMinimumSize ().width () -
  639. margin,
  640. margin * 2, // Avoid folder combo
  641. m_previewDialog->preferredMinimumSize ().width (),
  642. m_previewDialog->preferredMinimumSize ().height ());
  643. }
  644. const TQRect globalGeometry =
  645. kpWidgetMapper::toGlobal (m_visualParent,
  646. relativeGeometry);
  647. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  648. kdDebug () << "\trelativeGeometry=" << relativeGeometry
  649. << " globalGeometry=" << globalGeometry
  650. << endl;
  651. #endif
  652. m_previewDialog->resize (globalGeometry.size ());
  653. m_previewDialog->move (globalGeometry.topLeft ());
  654. m_previewDialog->show ();
  655. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  656. kdDebug () << "\tgeometry after show="
  657. << TQRect (m_previewDialog->x (), m_previewDialog->y (),
  658. m_previewDialog->width (), m_previewDialog->height ())
  659. << endl;
  660. #endif
  661. updatePreviewDialogLastRelativeGeometry ();
  662. connect (m_previewDialog, TQT_SIGNAL (moved ()),
  663. this, TQT_SLOT (updatePreviewDialogLastRelativeGeometry ()));
  664. connect (m_previewDialog, TQT_SIGNAL (resized ()),
  665. this, TQT_SLOT (updatePreviewDialogLastRelativeGeometry ()));
  666. m_updatePreviewDialogLastRelativeGeometryTimer->start (200/*ms*/);
  667. }
  668. else
  669. {
  670. m_updatePreviewDialogLastRelativeGeometryTimer->stop ();
  671. TDEConfigGroupSaver cfgGroupSaver (TDEGlobal::config (), kpSettingsGroupPreviewSave);
  672. TDEConfigBase *cfg = cfgGroupSaver.config ();
  673. cfg->writeEntry (kpSettingPreviewSaveGeometry, m_previewDialogLastRelativeGeometry);
  674. cfg->sync ();
  675. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  676. kdDebug () << "\tsaving preview geometry "
  677. << m_previewDialogLastRelativeGeometry
  678. << " (TQt would have us believe "
  679. << kpWidgetMapper::fromGlobal (m_visualParent,
  680. TQRect (m_previewDialog->x (), m_previewDialog->y (),
  681. m_previewDialog->width (), m_previewDialog->height ()))
  682. << ")"
  683. << endl;
  684. #endif
  685. m_previewDialog->deleteLater ();
  686. m_previewDialog = 0;
  687. }
  688. }
  689. // protected slot
  690. void kpDocumentSaveOptionsWidget::hidePreview ()
  691. {
  692. if (m_previewButton->isOn ())
  693. m_previewButton->toggle ();
  694. }
  695. // protected slot
  696. void kpDocumentSaveOptionsWidget::updatePreviewDelayed ()
  697. {
  698. m_updatePreviewTimer->start (m_updatePreviewDelay, true/*single shot*/);
  699. }
  700. // protected slot
  701. void kpDocumentSaveOptionsWidget::updatePreview ()
  702. {
  703. if (!m_previewDialog || !m_documentPixmap)
  704. return;
  705. m_updatePreviewTimer->stop ();
  706. TQApplication::setOverrideCursor (TQt::waitCursor);
  707. TQByteArray data;
  708. TQBuffer buffer (data);
  709. buffer.open (IO_WriteOnly);
  710. kpDocument::savePixmapToDevice (*m_documentPixmap,
  711. TQT_TQIODEVICE(&buffer),
  712. documentSaveOptions (),
  713. m_documentMetaInfo,
  714. false/*no lossy prompt*/,
  715. this);
  716. buffer.close ();
  717. TQImage image;
  718. image.loadFromData (data,
  719. KImageIO::typeForMime (mimeType ()).latin1 ());
  720. // TODO: merge with kpDocument::getPixmapFromFile()
  721. m_previewDialog->setFilePixmapAndSize (
  722. kpPixmapFX::convertToPixmapAsLosslessAsPossible (image),
  723. data.size ());
  724. TQApplication::restoreOverrideCursor ();
  725. }
  726. // protected slot
  727. void kpDocumentSaveOptionsWidget::updatePreviewDialogLastRelativeGeometry ()
  728. {
  729. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  730. kdDebug () << "kpDocumentSaveOptionsWidget::"
  731. << "updatePreviewDialogLastRelativeGeometry()"
  732. << endl;
  733. #endif
  734. if (m_previewDialog && m_previewDialog->isVisible ())
  735. {
  736. m_previewDialogLastRelativeGeometry =
  737. kpWidgetMapper::fromGlobal (m_visualParent,
  738. TQRect (m_previewDialog->x (), m_previewDialog->y (),
  739. m_previewDialog->width (), m_previewDialog->height ()));
  740. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  741. kdDebug () << "\tcaching pos = "
  742. << m_previewDialogLastRelativeGeometry
  743. << endl;
  744. #endif
  745. }
  746. else
  747. {
  748. #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS_WIDGET
  749. kdDebug () << "\tnot visible - ignoring geometry" << endl;
  750. #endif
  751. }
  752. }
  753. #include <kpdocumentsaveoptionswidget.moc>