File indexing completed on 2024-05-05 05:21:41
0001 /* 0002 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 0006 */ 0007 #include "insertimagewidget.h" 0008 0009 #include <KLineEdit> 0010 #include <KLocalizedString> 0011 #include <KSeparator> 0012 #include <KUrlRequester> 0013 0014 #include <QCheckBox> 0015 #include <QHBoxLayout> 0016 #include <QImageReader> 0017 #include <QLabel> 0018 #include <QMimeDatabase> 0019 #include <QSpinBox> 0020 #include <QVBoxLayout> 0021 0022 namespace KPIMTextEdit 0023 { 0024 static inline QString resolveAlias(const QString &name) 0025 { 0026 QMimeDatabase db; 0027 const QString str = db.mimeTypeForName(name).name(); 0028 return str; 0029 } 0030 0031 class InsertImageWidgetPrivate 0032 { 0033 public: 0034 explicit InsertImageWidgetPrivate(InsertImageWidget *qq) 0035 : q(qq) 0036 { 0037 auto lay = new QVBoxLayout(q); 0038 lay->setContentsMargins({}); 0039 auto hbox = new QHBoxLayout; 0040 auto lab = new QLabel(i18n("Image Location:")); 0041 imageUrlRequester = new KUrlRequester; 0042 0043 QStringList lstMimeTypes; 0044 const QList<QByteArray> mimetypes = QImageReader::supportedMimeTypes(); 0045 lstMimeTypes.reserve(mimetypes.count()); 0046 for (const QByteArray &ba : mimetypes) { 0047 const QString resolvedAlias = resolveAlias(QString::fromUtf8(ba)); 0048 if (!resolvedAlias.isEmpty()) { 0049 lstMimeTypes << resolvedAlias; 0050 } 0051 } 0052 imageUrlRequester->setMimeTypeFilters(lstMimeTypes); 0053 imageUrlRequester->setWindowTitle(i18nc("@title:window", "Add Image")); 0054 imageUrlRequester->setMode(KFile::File); 0055 q->connect(imageUrlRequester->lineEdit(), &KLineEdit::textChanged, q, [this](const QString &str) { 0056 _k_slotUrlChanged(str); 0057 }); 0058 0059 hbox->addWidget(lab); 0060 hbox->addWidget(imageUrlRequester); 0061 lab->setBuddy(imageUrlRequester); 0062 lay->addLayout(hbox); 0063 0064 keepOriginalSize = new QCheckBox(i18n("Keep Original Size")); 0065 q->connect(keepOriginalSize, &QCheckBox::clicked, q, [this](bool b) { 0066 _k_slotKeepOriginalSizeClicked(b); 0067 }); 0068 keepOriginalSize->setChecked(true); 0069 lay->addWidget(keepOriginalSize); 0070 0071 keepImageRatio = new QCheckBox(i18n("Keep Image Ratio")); 0072 keepImageRatio->setChecked(true); 0073 keepImageRatio->setEnabled(false); 0074 lay->addWidget(keepImageRatio); 0075 0076 hbox = new QHBoxLayout; 0077 lab = new QLabel(i18n("Width:")); 0078 width = new QSpinBox; 0079 width->setMinimum(1); 0080 width->setMaximum(99999); 0081 width->setEnabled(false); 0082 width->setSuffix(i18n(" px")); 0083 lab->setBuddy(width); 0084 q->connect(width, &QSpinBox::valueChanged, q, [this](int val) { 0085 _k_slotImageWidthChanged(val); 0086 }); 0087 hbox->addWidget(lab); 0088 hbox->addWidget(width); 0089 lay->addLayout(hbox); 0090 0091 hbox = new QHBoxLayout; 0092 lab = new QLabel(i18n("Height:")); 0093 height = new QSpinBox; 0094 height->setMinimum(1); 0095 height->setMaximum(99999); 0096 height->setEnabled(false); 0097 height->setSuffix(i18n(" px")); 0098 lab->setBuddy(height); 0099 q->connect(height, &QSpinBox::valueChanged, q, [this](int val) { 0100 _k_slotImageHeightChanged(val); 0101 }); 0102 hbox->addWidget(lab); 0103 hbox->addWidget(height); 0104 lay->addLayout(hbox); 0105 0106 auto sep = new KSeparator; 0107 lay->addWidget(sep); 0108 0109 hbox = new QHBoxLayout; 0110 lab = new QLabel(i18n("Image Preview:")); 0111 hbox->addWidget(lab); 0112 preview = new QLabel; 0113 preview->setFrameStyle(QFrame::Box); 0114 preview->setFixedSize(50, 50); 0115 hbox->addWidget(preview); 0116 lay->addLayout(hbox); 0117 } 0118 0119 void _k_slotKeepOriginalSizeClicked(bool); 0120 void _k_slotUrlChanged(const QString &); 0121 void _k_slotImageWidthChanged(int); 0122 void _k_slotImageHeightChanged(int); 0123 0124 qreal imageRatio = -1; 0125 QCheckBox *keepOriginalSize = nullptr; 0126 QCheckBox *keepImageRatio = nullptr; 0127 QSpinBox *width = nullptr; 0128 QSpinBox *height = nullptr; 0129 KUrlRequester *imageUrlRequester = nullptr; 0130 QLabel *preview = nullptr; 0131 InsertImageWidget *const q; 0132 }; 0133 0134 void InsertImageWidgetPrivate::_k_slotKeepOriginalSizeClicked(bool checked) 0135 { 0136 height->setEnabled(!checked); 0137 width->setEnabled(!checked); 0138 keepImageRatio->setEnabled(!checked); 0139 // Update default size 0140 _k_slotUrlChanged(imageUrlRequester->text()); 0141 } 0142 0143 void InsertImageWidgetPrivate::_k_slotUrlChanged(const QString &text) 0144 { 0145 QImage image(text); 0146 if (!image.isNull()) { 0147 height->setValue(image.height()); 0148 width->setValue(image.width()); 0149 0150 imageRatio = (double)((double)image.height() / (double)image.width()); 0151 preview->setPixmap(QPixmap::fromImage(image)); 0152 } else { 0153 preview->clear(); 0154 imageRatio = -1; 0155 } 0156 Q_EMIT q->enableButtonOk(!text.trimmed().isEmpty()); 0157 } 0158 0159 void InsertImageWidgetPrivate::_k_slotImageWidthChanged(int value) 0160 { 0161 if (keepImageRatio->isChecked() && !keepOriginalSize->isChecked()) { 0162 if (imageRatio != -1) { 0163 height->blockSignals(true); 0164 height->setValue(value * imageRatio); 0165 height->blockSignals(false); 0166 } 0167 } 0168 } 0169 0170 void InsertImageWidgetPrivate::_k_slotImageHeightChanged(int value) 0171 { 0172 if (keepImageRatio->isChecked() && !keepOriginalSize->isChecked()) { 0173 if (imageRatio != -1) { 0174 width->blockSignals(true); 0175 width->setValue(value / imageRatio); 0176 width->blockSignals(false); 0177 } 0178 } 0179 } 0180 0181 InsertImageWidget::InsertImageWidget(QWidget *parent) 0182 : QWidget(parent) 0183 , d(new InsertImageWidgetPrivate(this)) 0184 { 0185 } 0186 0187 InsertImageWidget::~InsertImageWidget() = default; 0188 0189 int InsertImageWidget::imageWidth() const 0190 { 0191 return d->width->value(); 0192 } 0193 0194 int InsertImageWidget::imageHeight() const 0195 { 0196 return d->height->value(); 0197 } 0198 0199 void InsertImageWidget::setImageWidth(int value) 0200 { 0201 d->width->setValue(value); 0202 } 0203 0204 void InsertImageWidget::setImageHeight(int value) 0205 { 0206 d->height->setValue(value); 0207 } 0208 0209 QUrl InsertImageWidget::imageUrl() const 0210 { 0211 return d->imageUrlRequester->url(); 0212 } 0213 0214 void InsertImageWidget::setImageUrl(const QUrl &url) 0215 { 0216 d->imageUrlRequester->setUrl(url); 0217 } 0218 0219 bool InsertImageWidget::keepOriginalSize() const 0220 { 0221 return d->keepOriginalSize->isChecked(); 0222 } 0223 } 0224 0225 #include "moc_insertimagewidget.cpp"