File indexing completed on 2024-04-21 05:43:21
0001 /*************************************************************************** 0002 * Copyright (C) 2006 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "dpimage.h" 0012 #include "itemdocument.h" 0013 #include "libraryitem.h" 0014 #include "resizeoverlay.h" 0015 0016 #include <KLocalizedString> 0017 0018 #include <QPainter> 0019 #include <QTimer> 0020 0021 #include <ktechlab_debug.h> 0022 0023 // BEGIN class ImageScaleThread 0024 ImageScaleThread::ImageScaleThread() 0025 { 0026 // Start with a blank (grey) image 0027 QPixmap pm(1, 1); 0028 pm.fill(Qt::gray); 0029 m_image = pm.toImage(); 0030 0031 m_width = -1; 0032 m_height = -1; 0033 m_bDoneNormalScale = false; 0034 m_bDoneSmoothScale = false; 0035 m_bSettingsChanged = false; 0036 } 0037 0038 bool ImageScaleThread::updateSettings(const QString &imageURL, int width, int height) 0039 { 0040 if (isRunning()) { 0041 qCWarning(KTL_LOG) << "Cannot update settings while running."; 0042 return false; 0043 } 0044 0045 bool changed = false; 0046 0047 if (m_width != width) { 0048 m_width = width; 0049 changed = true; 0050 } 0051 0052 if (m_height != height) { 0053 m_height = height; 0054 changed = true; 0055 } 0056 0057 if (m_imageURL != imageURL) { 0058 m_imageURL = imageURL; 0059 m_image.load(m_imageURL); 0060 if (m_image.isNull()) { 0061 QPixmap pm(1, 1); 0062 pm.fill(Qt::gray); 0063 m_image = pm.toImage(); 0064 } 0065 changed = true; 0066 } 0067 0068 if (changed) { 0069 m_bSettingsChanged = true; 0070 m_bDoneNormalScale = false; 0071 m_bDoneSmoothScale = false; 0072 } 0073 0074 return changed; 0075 } 0076 0077 QImage ImageScaleThread::bestScaling(BestScaling *scaling) const 0078 { 0079 BestScaling temp; 0080 if (!scaling) 0081 scaling = &temp; 0082 0083 if (m_bDoneSmoothScale) { 0084 *scaling = SmoothScaled; 0085 return m_smoothScaled; 0086 } 0087 0088 else if (m_bDoneNormalScale) { 0089 *scaling = NormalScaled; 0090 return m_normalScaled; 0091 } 0092 0093 else { 0094 *scaling = Unscaled; 0095 return m_image; 0096 } 0097 } 0098 0099 void ImageScaleThread::run() 0100 { 0101 do { 0102 m_bSettingsChanged = false; 0103 if (!m_bDoneNormalScale) { 0104 m_normalScaled = m_image.scaled(m_width, m_height); 0105 m_bDoneNormalScale = true; 0106 } 0107 } while (m_bSettingsChanged); 0108 0109 // If m_bSettingsChanged is true, then another thread called updateSettings 0110 // while we were doing normal scaling, so don't both doing smooth scaling 0111 // just yet. 0112 0113 if (!m_bDoneSmoothScale) { 0114 // m_smoothScaled = m_image.smoothScale( m_width, m_height ); // 2018.12.01 0115 m_smoothScaled = m_image.scaled(QSize(m_width, m_height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0116 m_bDoneSmoothScale = true; 0117 } 0118 } 0119 // END class ImageScaleThread 0120 0121 // BEGIN class DPImage 0122 Item *DPImage::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0123 { 0124 return new DPImage(itemDocument, newItem, id); 0125 } 0126 0127 LibraryItem *DPImage::libraryItem() 0128 { 0129 return new LibraryItem(QStringList(QString("dp/image")), i18n("Image"), i18n("Other"), QIcon::fromTheme("text"), LibraryItem::lit_drawpart, DPImage::construct); 0130 } 0131 0132 DPImage::DPImage(ItemDocument *itemDocument, bool newItem, const char *id) 0133 : DrawPart(itemDocument, newItem, id ? id : "image") 0134 { 0135 m_bSettingsChanged = false; 0136 m_bResizeToImage = newItem; 0137 m_imageScaling = ImageScaleThread::Unscaled; 0138 0139 m_pRectangularOverlay = new RectangularOverlay(this); 0140 0141 m_pCheckImageScalingTimer = new QTimer(this); 0142 connect(m_pCheckImageScalingTimer, &QTimer::timeout, this, &DPImage::checkImageScaling); 0143 m_pCheckImageScalingTimer->start(100); 0144 0145 m_name = i18n("Image"); 0146 0147 Variant *v = createProperty("image", Variant::Type::FileName); 0148 v->setCaption(i18n("Image File")); 0149 dataChanged(); 0150 } 0151 0152 DPImage::~DPImage() 0153 { 0154 m_imageScaleThread.wait(); 0155 } 0156 0157 void DPImage::setSelected(bool yes) 0158 { 0159 if (yes == isSelected()) 0160 return; 0161 0162 DrawPart::setSelected(yes); 0163 m_pRectangularOverlay->showResizeHandles(yes); 0164 } 0165 0166 void DPImage::postResize() 0167 { 0168 setItemPoints(QPolygon(m_sizeRect), false); 0169 m_bSettingsChanged = true; 0170 } 0171 0172 void DPImage::dataChanged() 0173 { 0174 m_imageURL = dataString("image"); 0175 m_image.load(m_imageURL); 0176 0177 if (m_image.isNull()) { 0178 // Make a grey image 0179 // m_image.resize( width(), height() ); // 2018.12.01 0180 m_image = m_image.copy(0, 0, width(), height()); 0181 m_image.fill(Qt::gray); 0182 0183 m_imageScaling = ImageScaleThread::SmoothScaled; 0184 } else { 0185 if (m_bResizeToImage) { 0186 int w = m_image.width(); 0187 int h = m_image.height(); 0188 setSize(0, 0, w, h); 0189 m_imageScaling = ImageScaleThread::SmoothScaled; 0190 } else { 0191 m_bResizeToImage = true; 0192 m_bSettingsChanged = true; 0193 } 0194 } 0195 } 0196 0197 void DPImage::checkImageScaling() 0198 { 0199 if (!m_bSettingsChanged && (m_imageScaling == ImageScaleThread::SmoothScaled)) { 0200 // Image scaling is already at its best, so return 0201 return; 0202 } 0203 0204 ImageScaleThread::BestScaling bs; 0205 QImage im = m_imageScaleThread.bestScaling(&bs); 0206 if (bs > m_imageScaling) { 0207 m_imageScaling = bs; 0208 m_image = QPixmap::fromImage(im); 0209 setChanged(); 0210 } 0211 0212 if (!m_imageScaleThread.isRunning()) { 0213 if (m_imageScaleThread.updateSettings(m_imageURL, width(), height())) { 0214 m_bSettingsChanged = false; 0215 m_imageScaling = ImageScaleThread::Unscaled; 0216 m_imageScaleThread.start(); 0217 } 0218 } 0219 } 0220 0221 void DPImage::drawShape(QPainter &p) 0222 { 0223 p.drawPixmap(int(x() + offsetX()), int(y() + offsetY()), m_image, 0, 0, width(), height()); 0224 } 0225 // END class DPImage 0226 0227 #include "moc_dpimage.cpp"