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.
28 #define DEBUG_KP_DOCUMENT_SAVE_OPTIONS 0
31 #include <kpDocumentSaveOptions.h>
37 #include <kconfiggroup.h>
40 #include <ksharedconfig.h>
43 #include <kpPixmapFX.h>
46 class kpDocumentSaveOptionsPrivate
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
;
80 d
->m_quality
= quality
;
83 kpDocumentSaveOptions::~kpDocumentSaveOptions ()
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 ());
99 bool kpDocumentSaveOptions::operator!= (const kpDocumentSaveOptions
&rhs
) const
101 return !(*this == rhs
);
106 kpDocumentSaveOptions
&kpDocumentSaveOptions::operator= (const kpDocumentSaveOptions
&rhs
)
108 setMimeType (rhs
.mimeType ());
109 setColorDepth (rhs
.colorDepth ());
110 setDither (rhs
.dither ());
111 setQuality (rhs
.quality ());
118 void kpDocumentSaveOptions::printDebug (const QString
&prefix
) const
120 const QString usedPrefix
= !prefix
.isEmpty () ?
121 prefix
+ QLatin1String (": ") :
124 kDebug () << usedPrefix
125 << "mimeType=" << mimeType ()
126 << " colorDepth=" << colorDepth ()
127 << " dither=" << dither ()
128 << " quality=" << quality ()
134 QString
kpDocumentSaveOptions::mimeType () const
136 return d
->m_mimeType
;
140 void kpDocumentSaveOptions::setMimeType (const QString
&mimeType
)
142 d
->m_mimeType
= mimeType
;
147 QString
kpDocumentSaveOptions::invalidMimeType ()
153 bool kpDocumentSaveOptions::mimeTypeIsInvalid (const QString
&mimeType
)
155 return (mimeType
== invalidMimeType ());
159 bool kpDocumentSaveOptions::mimeTypeIsInvalid () const
161 return mimeTypeIsInvalid (mimeType ());
166 int kpDocumentSaveOptions::colorDepth () const
168 return d
->m_colorDepth
;
172 void kpDocumentSaveOptions::setColorDepth (int depth
)
174 d
->m_colorDepth
= depth
;
179 int kpDocumentSaveOptions::invalidColorDepth ()
185 bool kpDocumentSaveOptions::colorDepthIsInvalid (int colorDepth
)
187 return (colorDepth
!= 1 && colorDepth
!= 8 && colorDepth
!= 32);
191 bool kpDocumentSaveOptions::colorDepthIsInvalid () const
193 return colorDepthIsInvalid (colorDepth ());
198 bool kpDocumentSaveOptions::dither () const
204 void kpDocumentSaveOptions::setDither (bool dither
)
206 d
->m_dither
= dither
;
211 int kpDocumentSaveOptions::initialDither ()
213 return false; // to avoid accidental double dithering
218 int kpDocumentSaveOptions::quality () const
224 void kpDocumentSaveOptions::setQuality (int quality
)
226 d
->m_quality
= quality
;
231 int kpDocumentSaveOptions::invalidQuality ()
237 bool kpDocumentSaveOptions::qualityIsInvalid (int quality
)
239 return (quality
< -1 || quality
> 100);
243 bool kpDocumentSaveOptions::qualityIsInvalid () const
245 return qualityIsInvalid (quality ());
250 QString
kpDocumentSaveOptions::defaultMimeType (const KConfigGroup
&config
)
252 return config
.readEntry (kpSettingForcedMimeType
,
253 QString::fromLatin1 ("image/png"));
257 void kpDocumentSaveOptions::saveDefaultMimeType (KConfigGroup
&config
,
258 const QString
&mimeType
)
260 config
.writeEntry (kpSettingForcedMimeType
, mimeType
);
265 int kpDocumentSaveOptions::defaultColorDepth (const KConfigGroup
&config
)
268 config
.readEntry (kpSettingForcedColorDepth
, -1);
270 if (colorDepthIsInvalid (colorDepth
))
272 // (not screen depth, in case of transparency)
280 void kpDocumentSaveOptions::saveDefaultColorDepth (KConfigGroup
&config
, int colorDepth
)
282 config
.writeEntry (kpSettingForcedColorDepth
, colorDepth
);
287 int kpDocumentSaveOptions::defaultDither (const KConfigGroup
&config
)
289 return config
.readEntry (kpSettingForcedDither
, initialDither ());
293 void kpDocumentSaveOptions::saveDefaultDither (KConfigGroup
&config
, bool dither
)
295 config
.writeEntry (kpSettingForcedDither
, dither
);
300 int kpDocumentSaveOptions::defaultQuality (const KConfigGroup
&config
)
302 int val
= config
.readEntry (kpSettingForcedQuality
, -1);
303 if (qualityIsInvalid (val
))
310 void kpDocumentSaveOptions::saveDefaultQuality (KConfigGroup
&config
, int quality
)
312 config
.writeEntry (kpSettingForcedQuality
, quality
);
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()");
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");
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 ());
386 mimeTypeList
= defaultMimeTypesWithPropertyList
;
388 cfg
.writeEntry (property
, 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.
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).
429 // image/jpeg2000 [COULD NOT TEST]
434 // image/x-portable-bitmap
435 // image/x-portable-graymap
436 // image/x-portable-pixmap
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.
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 ();
473 if ((*it
).startsWith (mimeTypeColon
))
475 int number
= (*it
).mid (mimeTypeColon
.length ()).toInt ();
476 if (!colorDepthIsInvalid (number
))
487 int kpDocumentSaveOptions::mimeTypeMaximumColorDepth () const
489 return mimeTypeMaximumColorDepth (mimeType ());
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
,
516 bool kpDocumentSaveOptions::mimeTypeHasConfigurableColorDepth () const
518 return mimeTypeHasConfigurableColorDepth (mimeType ());
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
,
537 bool kpDocumentSaveOptions::mimeTypeHasConfigurableQuality () const
539 return mimeTypeHasConfigurableQuality (mimeType ());
544 int kpDocumentSaveOptions::isLossyForSaving (const QPixmap
&pixmap
) const
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 ())