compile
[kdegraphics.git] / kolourpaint / document / kpDocumentSaveOptions.cpp
blob7e8753cbd3c020527f7249554fe0963cd2eb74c1
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.
28 #define DEBUG_KP_DOCUMENT_SAVE_OPTIONS 0
31 #include <kpDocumentSaveOptions.h>
33 #include <qbitmap.h>
34 #include <qpixmap.h>
35 #include <qstring.h>
37 #include <kconfiggroup.h>
38 #include <kdebug.h>
39 #include <kglobal.h>
40 #include <ksharedconfig.h>
42 #include <kpDefs.h>
43 #include <kpPixmapFX.h>
46 class kpDocumentSaveOptionsPrivate
48 public:
49 QString m_mimeType;
50 int m_colorDepth;
51 bool m_dither;
52 int m_quality;
56 kpDocumentSaveOptions::kpDocumentSaveOptions ()
57 : d (new kpDocumentSaveOptionsPrivate ())
59 d->m_mimeType = invalidMimeType ();
60 d->m_colorDepth = invalidColorDepth ();
61 d->m_dither = initialDither ();
62 d->m_quality = invalidQuality ();
65 kpDocumentSaveOptions::kpDocumentSaveOptions (const kpDocumentSaveOptions &rhs)
66 : d (new kpDocumentSaveOptionsPrivate ())
68 d->m_mimeType = rhs.mimeType ();
69 d->m_colorDepth = rhs.colorDepth ();
70 d->m_dither = rhs.dither ();
71 d->m_quality = rhs.quality ();
74 kpDocumentSaveOptions::kpDocumentSaveOptions (QString mimeType, int colorDepth, bool dither, int quality)
75 : d (new kpDocumentSaveOptionsPrivate ())
77 d->m_mimeType = mimeType;
78 d->m_colorDepth = colorDepth;
79 d->m_dither = dither;
80 d->m_quality = quality;
83 kpDocumentSaveOptions::~kpDocumentSaveOptions ()
85 delete d;
89 // public
90 bool kpDocumentSaveOptions::operator== (const kpDocumentSaveOptions &rhs) const
92 return (mimeType () == rhs.mimeType () &&
93 colorDepth () == rhs.colorDepth () &&
94 dither () == rhs.dither () &&
95 quality () == rhs.quality ());
98 // public
99 bool kpDocumentSaveOptions::operator!= (const kpDocumentSaveOptions &rhs) const
101 return !(*this == rhs);
105 // public
106 kpDocumentSaveOptions &kpDocumentSaveOptions::operator= (const kpDocumentSaveOptions &rhs)
108 setMimeType (rhs.mimeType ());
109 setColorDepth (rhs.colorDepth ());
110 setDither (rhs.dither ());
111 setQuality (rhs.quality ());
113 return *this;
117 // public
118 void kpDocumentSaveOptions::printDebug (const QString &prefix) const
120 const QString usedPrefix = !prefix.isEmpty () ?
121 prefix + QLatin1String (": ") :
122 QString();
124 kDebug () << usedPrefix
125 << "mimeType=" << mimeType ()
126 << " colorDepth=" << colorDepth ()
127 << " dither=" << dither ()
128 << " quality=" << quality ()
129 << endl;
133 // public
134 QString kpDocumentSaveOptions::mimeType () const
136 return d->m_mimeType;
139 // public
140 void kpDocumentSaveOptions::setMimeType (const QString &mimeType)
142 d->m_mimeType = mimeType;
146 // public static
147 QString kpDocumentSaveOptions::invalidMimeType ()
149 return QString();
152 // public static
153 bool kpDocumentSaveOptions::mimeTypeIsInvalid (const QString &mimeType)
155 return (mimeType == invalidMimeType ());
158 // public
159 bool kpDocumentSaveOptions::mimeTypeIsInvalid () const
161 return mimeTypeIsInvalid (mimeType ());
165 // public
166 int kpDocumentSaveOptions::colorDepth () const
168 return d->m_colorDepth;
171 // public
172 void kpDocumentSaveOptions::setColorDepth (int depth)
174 d->m_colorDepth = depth;
178 // public static
179 int kpDocumentSaveOptions::invalidColorDepth ()
181 return -1;
184 // public static
185 bool kpDocumentSaveOptions::colorDepthIsInvalid (int colorDepth)
187 return (colorDepth != 1 && colorDepth != 8 && colorDepth != 32);
190 // public
191 bool kpDocumentSaveOptions::colorDepthIsInvalid () const
193 return colorDepthIsInvalid (colorDepth ());
197 // public
198 bool kpDocumentSaveOptions::dither () const
200 return d->m_dither;
203 // public
204 void kpDocumentSaveOptions::setDither (bool dither)
206 d->m_dither = dither;
210 // public static
211 int kpDocumentSaveOptions::initialDither ()
213 return false; // to avoid accidental double dithering
217 // public
218 int kpDocumentSaveOptions::quality () const
220 return d->m_quality;
223 // public
224 void kpDocumentSaveOptions::setQuality (int quality)
226 d->m_quality = quality;
230 // public static
231 int kpDocumentSaveOptions::invalidQuality ()
233 return -2;
236 // public static
237 bool kpDocumentSaveOptions::qualityIsInvalid (int quality)
239 return (quality < -1 || quality > 100);
242 // public
243 bool kpDocumentSaveOptions::qualityIsInvalid () const
245 return qualityIsInvalid (quality ());
249 // public static
250 QString kpDocumentSaveOptions::defaultMimeType (const KConfigGroup &config)
252 return config.readEntry (kpSettingForcedMimeType,
253 QString::fromLatin1 ("image/png"));
256 // public static
257 void kpDocumentSaveOptions::saveDefaultMimeType (KConfigGroup &config,
258 const QString &mimeType)
260 config.writeEntry (kpSettingForcedMimeType, mimeType);
264 // public static
265 int kpDocumentSaveOptions::defaultColorDepth (const KConfigGroup &config)
267 int colorDepth =
268 config.readEntry (kpSettingForcedColorDepth, -1);
270 if (colorDepthIsInvalid (colorDepth))
272 // (not screen depth, in case of transparency)
273 colorDepth = 32;
276 return colorDepth;
279 // public static
280 void kpDocumentSaveOptions::saveDefaultColorDepth (KConfigGroup &config, int colorDepth)
282 config.writeEntry (kpSettingForcedColorDepth, colorDepth);
286 // public static
287 int kpDocumentSaveOptions::defaultDither (const KConfigGroup &config)
289 return config.readEntry (kpSettingForcedDither, initialDither ());
292 // public static
293 void kpDocumentSaveOptions::saveDefaultDither (KConfigGroup &config, bool dither)
295 config.writeEntry (kpSettingForcedDither, dither);
299 // public static
300 int kpDocumentSaveOptions::defaultQuality (const KConfigGroup &config)
302 int val = config.readEntry (kpSettingForcedQuality, -1);
303 if (qualityIsInvalid (val))
304 val = -1;
306 return val;
309 // public static
310 void kpDocumentSaveOptions::saveDefaultQuality (KConfigGroup &config, int quality)
312 config.writeEntry (kpSettingForcedQuality, quality);
316 // public static
317 kpDocumentSaveOptions kpDocumentSaveOptions::defaultDocumentSaveOptions (const KConfigGroup &config)
319 kpDocumentSaveOptions saveOptions;
320 saveOptions.setMimeType (defaultMimeType (config));
321 saveOptions.setColorDepth (defaultColorDepth (config));
322 saveOptions.setDither (defaultDither (config));
323 saveOptions.setQuality (defaultQuality (config));
325 #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS
326 saveOptions.printDebug ("kpDocumentSaveOptions::defaultDocumentSaveOptions()");
327 #endif
329 return saveOptions;
332 // public static
333 bool kpDocumentSaveOptions::saveDefaultDifferences (KConfigGroup &config,
334 const kpDocumentSaveOptions &oldDocInfo,
335 const kpDocumentSaveOptions &newDocInfo)
337 bool savedSomething = false;
339 #if DEBUG_KP_DOCUMENT_SAVE_OPTIONS
340 kDebug () << "kpDocumentSaveOptions::saveDefaultDifferences()";
341 oldDocInfo.printDebug ("\told");
342 newDocInfo.printDebug ("\tnew");
343 #endif
345 if (newDocInfo.mimeType () != oldDocInfo.mimeType ())
347 saveDefaultMimeType (config, newDocInfo.mimeType ());
348 savedSomething = true;
351 if (newDocInfo.colorDepth () != oldDocInfo.colorDepth ())
353 saveDefaultColorDepth (config, newDocInfo.colorDepth ());
354 savedSomething = true;
357 if (newDocInfo.dither () != oldDocInfo.dither ())
359 saveDefaultDither (config, newDocInfo.dither ());
360 savedSomething = true;
363 if (newDocInfo.quality () != oldDocInfo.quality ())
365 saveDefaultQuality (config, newDocInfo.quality ());
366 savedSomething = true;
369 return savedSomething;
373 static QStringList mimeTypesSupportingProperty (const QString &property,
374 const QStringList &defaultMimeTypesWithPropertyList)
376 QStringList mimeTypeList;
378 KConfigGroup cfg (KGlobal::config (), kpSettingsGroupMimeTypeProperties);
380 if (cfg.hasKey (property))
382 mimeTypeList = cfg.readEntry (property, QStringList ());
384 else
386 mimeTypeList = defaultMimeTypesWithPropertyList;
388 cfg.writeEntry (property, mimeTypeList);
389 cfg.sync ();
392 return mimeTypeList;
395 static bool mimeTypeSupportsProperty (const QString &mimeType,
396 const QString &property, const QStringList &defaultMimeTypesWithPropertyList)
398 const QStringList mimeTypeList = mimeTypesSupportingProperty (
399 property, defaultMimeTypesWithPropertyList);
401 return mimeTypeList.contains (mimeType);
405 // SYNC: update mime info
407 // Only care about writable mimetypes.
409 // Run:
411 // branches/kolourpaint/control/scripts/gen_mimetype_line.sh Write |
412 // branches/kolourpaint/control/scripts/split_mimetype_line.pl
414 // in the version of kdelibs/kimgio/ (e.g. KDE 4.0) KolourPaint is shipped with,
415 // to check for any new mimetypes to add info for. In the methods below,
416 // you can specify this info (maximum color depth, whether it's lossy etc.).
418 // Update the below list and if you do change any of that info, bump up
419 // "kpSettingsGroupMimeTypeProperties" in kpDefs.h.
421 // Currently, Depth and Quality settings are mutually exclusive with
422 // Depth overriding Quality. I've currently favoured Quality with the
423 // below mimetypes (i.e. all lossy mimetypes are only given Quality settings,
424 // no Depth settings).
426 // Mimetypes done:
427 // image/bmp
428 // image/jpeg
429 // image/jpeg2000 [COULD NOT TEST]
430 // image/png
431 // image/tiff
432 // image/x-eps
433 // image/x-pcx
434 // image/x-portable-bitmap
435 // image/x-portable-graymap
436 // image/x-portable-pixmap
437 // image/x-rgb
438 // image/x-tga
439 // image/x-xbitmap
440 // image/x-xpixmap
441 // video/x-mng [COULD NOT TEST]
443 // To test whether depth is configurable, write an image in the new
444 // mimetype with all depths and read each one back. See what
445 // kpDocument thinks the depth is when it gets QImage to read it.
448 // public static
449 int kpDocumentSaveOptions::mimeTypeMaximumColorDepth (const QString &mimeType)
451 QStringList defaultList;
453 // SYNC: update mime info here
455 // Grayscale actually (unenforced since depth not set to configurable)
456 defaultList << QLatin1String ("image/x-eps:32");
458 defaultList << QLatin1String ("image/x-portable-bitmap:1");
460 // Grayscale actually (unenforced since depth not set to configurable)
461 defaultList << QLatin1String ("image/x-portable-graymap:8");
463 defaultList << QLatin1String ("image/x-xbitmap:1");
465 const QStringList mimeTypeList = mimeTypesSupportingProperty (
466 kpSettingMimeTypeMaximumColorDepth, defaultList);
468 const QString mimeTypeColon = mimeType + QLatin1String (":");
469 for (QStringList::const_iterator it = mimeTypeList.begin ();
470 it != mimeTypeList.end ();
471 it++)
473 if ((*it).startsWith (mimeTypeColon))
475 int number = (*it).mid (mimeTypeColon.length ()).toInt ();
476 if (!colorDepthIsInvalid (number))
478 return number;
483 return 32;
486 // public
487 int kpDocumentSaveOptions::mimeTypeMaximumColorDepth () const
489 return mimeTypeMaximumColorDepth (mimeType ());
493 // public static
494 bool kpDocumentSaveOptions::mimeTypeHasConfigurableColorDepth (const QString &mimeType)
496 QStringList defaultMimeTypes;
498 // SYNC: update mime info here
499 defaultMimeTypes << QLatin1String ("image/png");
500 defaultMimeTypes << QLatin1String ("image/bmp");
501 defaultMimeTypes << QLatin1String ("image/x-pcx");
503 // TODO: Only 1, 24 not 8; Qt only sees 32 but "file" cmd realises
504 // it's either 1 or 24.
505 defaultMimeTypes << QLatin1String ("image/x-rgb");
507 // TODO: Only 8 and 24 - no 1.
508 defaultMimeTypes << QLatin1String ("image/x-xpixmap");
510 return mimeTypeSupportsProperty (mimeType,
511 kpSettingMimeTypeHasConfigurableColorDepth,
512 defaultMimeTypes);
515 // public
516 bool kpDocumentSaveOptions::mimeTypeHasConfigurableColorDepth () const
518 return mimeTypeHasConfigurableColorDepth (mimeType ());
522 // public static
523 bool kpDocumentSaveOptions::mimeTypeHasConfigurableQuality (const QString &mimeType)
525 QStringList defaultMimeTypes;
527 // SYNC: update mime info here
528 defaultMimeTypes << QLatin1String ("image/jpeg2000");
529 defaultMimeTypes << QLatin1String ("image/jpeg");
531 return mimeTypeSupportsProperty (mimeType,
532 kpSettingMimeTypeHasConfigurableQuality,
533 defaultMimeTypes);
536 // public
537 bool kpDocumentSaveOptions::mimeTypeHasConfigurableQuality () const
539 return mimeTypeHasConfigurableQuality (mimeType ());
543 // public
544 int kpDocumentSaveOptions::isLossyForSaving (const QPixmap &pixmap) const
546 int ret = 0;
548 if (mimeTypeMaximumColorDepth () < pixmap.depth ())
550 ret |= MimeTypeMaximumColorDepthLow;
553 if (mimeTypeHasConfigurableColorDepth () &&
554 !colorDepthIsInvalid () /*REFACTOR: guarantee it is valid*/ &&
555 (colorDepth () < pixmap.depth () ||
556 colorDepth () < 32 && kpPixmapFX::hasMask (pixmap)))
558 ret |= ColorDepthLow;
561 if (mimeTypeHasConfigurableQuality () &&
562 !qualityIsInvalid ())
564 ret |= Quality;
567 return ret;