File indexing completed on 2024-04-28 04:20:13

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 
0029 #define DEBUG_KP_DOCUMENT 0
0030 
0031 
0032 #include "kpDocument.h"
0033 #include "kpDocumentPrivate.h"
0034 
0035 #include "layers/selections/kpAbstractSelection.h"
0036 #include "layers/selections/image/kpAbstractImageSelection.h"
0037 #include "imagelib/kpColor.h"
0038 #include "widgets/toolbars/kpColorToolBar.h"
0039 #include "kpDefs.h"
0040 #include "environments/document/kpDocumentEnvironment.h"
0041 #include "document/kpDocumentSaveOptions.h"
0042 #include "imagelib/kpDocumentMetaInfo.h"
0043 #include "imagelib/effects/kpEffectReduceColors.h"
0044 #include "tools/kpTool.h"
0045 #include "widgets/toolbars/kpToolToolBar.h"
0046 #include "lgpl/generic/kpUrlFormatter.h"
0047 #include <kio_version.h>
0048 
0049 #include "kpLogCategories.h"
0050 #include <KJobWidgets>
0051 #include <KLocalizedString>
0052 #include <KIO/StatJob>
0053 
0054 #include <QColor>
0055 #include <QImage>
0056 #include <QRect>
0057 #include <QSize>
0058 
0059 //---------------------------------------------------------------------
0060 
0061 kpDocument::kpDocument (int w, int h,
0062         kpDocumentEnvironment *environ)
0063     : QObject (),
0064       m_constructorWidth (w), m_constructorHeight (h),
0065       m_isFromExistingURL (false),
0066       m_savedAtLeastOnceBefore (false),
0067       m_saveOptions (new kpDocumentSaveOptions ()),
0068       m_metaInfo (new kpDocumentMetaInfo ()),
0069       m_modified (false),
0070       m_selection (nullptr),
0071       m_oldWidth (-1), m_oldHeight (-1),
0072       d (new kpDocumentPrivate ())
0073 {
0074 #if DEBUG_KP_DOCUMENT && 0
0075     qCDebug(kpLogDocument) << "kpDocument::kpDocument (" << w << "," << h << ")";
0076 #endif
0077 
0078     m_image = new kpImage(w, h, QImage::Format_ARGB32_Premultiplied);
0079     m_image->fill(QColor(Qt::white).rgb());
0080 
0081     d->environ = environ;
0082 }
0083 
0084 //---------------------------------------------------------------------
0085 
0086 kpDocument::~kpDocument ()
0087 {
0088     delete d;
0089 
0090     delete m_image;
0091 
0092     delete m_saveOptions;
0093     delete m_metaInfo;
0094 
0095     delete m_selection;
0096 }
0097 
0098 //---------------------------------------------------------------------
0099 
0100 // public
0101 kpDocumentEnvironment *kpDocument::environ () const
0102 {
0103     return d->environ;
0104 }
0105 
0106 //---------------------------------------------------------------------
0107 
0108 // public
0109 void kpDocument::setEnviron (kpDocumentEnvironment *environ)
0110 {
0111     d->environ = environ;
0112 }
0113 
0114 //---------------------------------------------------------------------
0115 
0116 // public
0117 bool kpDocument::savedAtLeastOnceBefore () const
0118 {
0119     return m_savedAtLeastOnceBefore;
0120 }
0121 
0122 //---------------------------------------------------------------------
0123 
0124 // public
0125 QUrl kpDocument::url () const
0126 {
0127     return m_url;
0128 }
0129 
0130 //---------------------------------------------------------------------
0131 
0132 // public
0133 void kpDocument::setURL (const QUrl &url, bool isFromExistingURL)
0134 {
0135     m_url = url;
0136     m_isFromExistingURL = isFromExistingURL;
0137 }
0138 
0139 //---------------------------------------------------------------------
0140 
0141 // public
0142 bool kpDocument::isFromExistingURL () const
0143 {
0144     return m_isFromExistingURL;
0145 }
0146 
0147 //---------------------------------------------------------------------
0148 
0149 // public
0150 bool kpDocument::urlExists (const QUrl &url) const
0151 {
0152     if (url.isEmpty()) {
0153         return false;
0154     }
0155 #if KIO_VERSION >= QT_VERSION_CHECK(5, 240, 0)
0156     KIO::StatJob *job = KIO::stat(url, KIO::StatJob::SourceSide, KIO::StatNoDetails);
0157 #else
0158     KIO::StatJob *job = KIO::statDetails(url, KIO::StatJob::SourceSide, KIO::StatNoDetails);
0159 #endif    
0160     KJobWidgets::setWindow (job, d->environ->dialogParent ());
0161     return job->exec();
0162 }
0163 
0164 //---------------------------------------------------------------------
0165 
0166 // public
0167 QString kpDocument::prettyUrl () const
0168 {
0169     return kpUrlFormatter::PrettyUrl (m_url);
0170 }
0171 
0172 //---------------------------------------------------------------------
0173 
0174 // public
0175 QString kpDocument::prettyFilename () const
0176 {
0177     return kpUrlFormatter::PrettyFilename (m_url);
0178 }
0179 
0180 //---------------------------------------------------------------------
0181 
0182 // public
0183 const kpDocumentSaveOptions *kpDocument::saveOptions () const
0184 {
0185     return m_saveOptions;
0186 }
0187 
0188 //---------------------------------------------------------------------
0189 
0190 // public
0191 void kpDocument::setSaveOptions (const kpDocumentSaveOptions &saveOptions)
0192 {
0193     *m_saveOptions = saveOptions;
0194 }
0195 
0196 //---------------------------------------------------------------------
0197 
0198 // public
0199 const kpDocumentMetaInfo *kpDocument::metaInfo () const
0200 {
0201     return m_metaInfo;
0202 }
0203 
0204 //---------------------------------------------------------------------
0205 
0206 // public
0207 void kpDocument::setMetaInfo (const kpDocumentMetaInfo &metaInfo)
0208 {
0209     *m_metaInfo = metaInfo;
0210 }
0211 
0212 //---------------------------------------------------------------------
0213 
0214 /*
0215  * Properties
0216  */
0217 
0218 void kpDocument::setModified (bool yes)
0219 {
0220     if (yes == m_modified) {
0221         return;
0222     }
0223 
0224     m_modified = yes;
0225 
0226     if (yes) {
0227         Q_EMIT documentModified ();
0228     }
0229 }
0230 
0231 //---------------------------------------------------------------------
0232 
0233 bool kpDocument::isModified () const
0234 {
0235     return m_modified;
0236 }
0237 
0238 //---------------------------------------------------------------------
0239 
0240 bool kpDocument::isEmpty () const
0241 {
0242     return url ().isEmpty () && !isModified ();
0243 }
0244 
0245 //---------------------------------------------------------------------
0246 
0247 int kpDocument::constructorWidth () const
0248 {
0249     return m_constructorWidth;
0250 }
0251 
0252 //---------------------------------------------------------------------
0253 
0254 int kpDocument::width (bool ofSelection) const
0255 {
0256     return (ofSelection && m_selection) ? m_selection->width() : m_image->width();
0257 }
0258 
0259 //---------------------------------------------------------------------
0260 
0261 int kpDocument::oldWidth () const
0262 {
0263     return m_oldWidth;
0264 }
0265 
0266 //---------------------------------------------------------------------
0267 
0268 void kpDocument::setWidth (int w, const kpColor &backgroundColor)
0269 {
0270     resize (w, height (), backgroundColor);
0271 }
0272 
0273 //---------------------------------------------------------------------
0274 
0275 int kpDocument::constructorHeight () const
0276 {
0277     return m_constructorHeight;
0278 }
0279 
0280 //---------------------------------------------------------------------
0281 
0282 int kpDocument::height (bool ofSelection) const
0283 {
0284     return (ofSelection && m_selection) ? m_selection->height() : m_image->height();
0285 }
0286 
0287 //---------------------------------------------------------------------
0288 
0289 int kpDocument::oldHeight () const
0290 {
0291     return m_oldHeight;
0292 }
0293 
0294 //---------------------------------------------------------------------
0295 
0296 void kpDocument::setHeight (int h, const kpColor &backgroundColor)
0297 {
0298     resize (width (), h, backgroundColor);
0299 }
0300 
0301 //---------------------------------------------------------------------
0302 
0303 QRect kpDocument::rect (bool ofSelection) const
0304 {
0305     return (ofSelection && m_selection) ? m_selection->boundingRect() : m_image->rect();
0306 }
0307 
0308 //---------------------------------------------------------------------
0309 
0310 // public
0311 kpImage kpDocument::getImageAt (const QRect &rect) const
0312 {
0313     return kpPixmapFX::getPixmapAt (*m_image, rect);
0314 }
0315 
0316 //---------------------------------------------------------------------
0317 
0318 // public
0319 void kpDocument::setImageAt (const kpImage &image, const QPoint &at)
0320 {
0321 #if DEBUG_KP_DOCUMENT && 0
0322     qCDebug(kpLogDocument) << "kpDocument::setImageAt (image (w="
0323                << image.width ()
0324                << ",h=" << image.height ()
0325                << "), x=" << at.x ()
0326                << ",y=" << at.y ();
0327 #endif
0328 
0329     kpPixmapFX::setPixmapAt (m_image, at, image);
0330     slotContentsChanged (QRect (at.x (), at.y (), image.width (), image.height ()));
0331 }
0332 
0333 //---------------------------------------------------------------------
0334 
0335 // public
0336 kpImage kpDocument::image (bool ofSelection) const
0337 {
0338     kpImage ret;
0339 
0340     if (ofSelection)
0341     {
0342         kpAbstractImageSelection *imageSel = imageSelection ();
0343         Q_ASSERT (imageSel);
0344 
0345         ret = imageSel->baseImage ();
0346     }
0347     else {
0348         ret = *m_image;
0349     }
0350 
0351     return ret;
0352 }
0353 
0354 //---------------------------------------------------------------------
0355 
0356 // public
0357 kpImage *kpDocument::imagePointer () const
0358 {
0359     return m_image;
0360 }
0361 
0362 //---------------------------------------------------------------------
0363 
0364 // public
0365 void kpDocument::setImage (const kpImage &image)
0366 {
0367     m_oldWidth = width ();
0368     m_oldHeight = height ();
0369 
0370     *m_image = image;
0371 
0372     if (m_oldWidth == width () && m_oldHeight == height ()) {
0373         slotContentsChanged (image.rect ());
0374     }
0375     else {
0376         slotSizeChanged (QSize (width (), height ()));
0377     }
0378 }
0379 
0380 //---------------------------------------------------------------------
0381 
0382 // public
0383 void kpDocument::setImage (bool ofSelection, const kpImage &image)
0384 {
0385     if (ofSelection)
0386     {
0387         kpAbstractImageSelection *imageSel = imageSelection ();
0388 
0389         // Have to have an image selection in order to set its pixmap.
0390         Q_ASSERT (imageSel);
0391 
0392         imageSel->setBaseImage (image);
0393     }
0394     else {
0395         setImage (image);
0396     }
0397 }
0398 
0399 //---------------------------------------------------------------------
0400 
0401 void kpDocument::fill (const kpColor &color)
0402 {
0403 #if DEBUG_KP_DOCUMENT
0404     qCDebug(kpLogDocument) << "kpDocument::fill ()";
0405 #endif
0406 
0407     m_image->fill(color.toQRgb());
0408     slotContentsChanged (m_image->rect ());
0409 }
0410 
0411 //---------------------------------------------------------------------
0412 
0413 void kpDocument::resize (int w, int h, const kpColor &backgroundColor)
0414 {
0415 #if DEBUG_KP_DOCUMENT
0416     qCDebug(kpLogDocument) << "kpDocument::resize (" << w << "," << h << ")";
0417 #endif
0418 
0419     m_oldWidth = width ();
0420     m_oldHeight = height ();
0421 
0422 #if DEBUG_KP_DOCUMENT && 1
0423     qCDebug(kpLogDocument) << "\toldWidth=" << m_oldWidth
0424                << " oldHeight=" << m_oldHeight;
0425 #endif
0426 
0427     if (w == m_oldWidth && h == m_oldHeight) {
0428         return;
0429     }
0430 
0431     kpPixmapFX::resize (m_image, w, h, backgroundColor);
0432 
0433     slotSizeChanged (QSize (width (), height ()));
0434 }
0435 
0436 //---------------------------------------------------------------------
0437 
0438 void kpDocument::slotContentsChanged (const QRect &rect)
0439 {
0440     setModified ();
0441     Q_EMIT contentsChanged (rect);
0442 }
0443 
0444 //---------------------------------------------------------------------
0445 
0446 void kpDocument::slotSizeChanged (const QSize &newSize)
0447 {
0448     setModified ();
0449     Q_EMIT sizeChanged (newSize.width(), newSize.height());
0450     Q_EMIT sizeChanged (newSize);
0451 }
0452 
0453 //---------------------------------------------------------------------
0454 
0455 #include "moc_kpDocument.cpp"