KPimTextEdit

insertimagewidget.cpp
1/*
2 SPDX-FileCopyrightText: 2012-2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5
6*/
7#include "insertimagewidget.h"
8
9#include <KLineEdit>
10#include <KLocalizedString>
11#include <KSeparator>
12#include <KUrlRequester>
13
14#include <QCheckBox>
15#include <QHBoxLayout>
16#include <QImageReader>
17#include <QLabel>
18#include <QMimeDatabase>
19#include <QSpinBox>
20#include <QVBoxLayout>
21
22namespace KPIMTextEdit
23{
24static inline QString resolveAlias(const QString &name)
25{
26 QMimeDatabase db;
27 const QString str = db.mimeTypeForName(name).name();
28 return str;
29}
30
31class InsertImageWidgetPrivate
32{
33public:
34 explicit InsertImageWidgetPrivate(InsertImageWidget *qq)
35 : q(qq)
36 {
37 auto lay = new QVBoxLayout(q);
38 lay->setContentsMargins({});
39 auto hbox = new QHBoxLayout;
40 auto lab = new QLabel(i18nc("@label:textbox", "Image Location:"));
41 imageUrlRequester = new KUrlRequester;
42
43 QStringList lstMimeTypes;
44 const QList<QByteArray> mimetypes = QImageReader::supportedMimeTypes();
45 lstMimeTypes.reserve(mimetypes.count());
46 for (const QByteArray &ba : mimetypes) {
47 const QString resolvedAlias = resolveAlias(QString::fromUtf8(ba));
48 if (!resolvedAlias.isEmpty()) {
49 lstMimeTypes << resolvedAlias;
50 }
51 }
52 imageUrlRequester->setMimeTypeFilters(lstMimeTypes);
53 imageUrlRequester->setWindowTitle(i18nc("@title:window", "Add Image"));
54 imageUrlRequester->setMode(KFile::File);
55 q->connect(imageUrlRequester->lineEdit(), &KLineEdit::textChanged, q, [this](const QString &str) {
56 _k_slotUrlChanged(str);
57 });
58
59 hbox->addWidget(lab);
60 hbox->addWidget(imageUrlRequester);
61 lab->setBuddy(imageUrlRequester);
62 lay->addLayout(hbox);
63
64 keepOriginalSize = new QCheckBox(i18nc("@option:check", "Keep Original Size"));
65 q->connect(keepOriginalSize, &QCheckBox::clicked, q, [this](bool b) {
66 _k_slotKeepOriginalSizeClicked(b);
67 });
68 keepOriginalSize->setChecked(true);
69 lay->addWidget(keepOriginalSize);
70
71 keepImageRatio = new QCheckBox(i18nc("@option:check", "Keep Image Ratio"));
72 keepImageRatio->setChecked(true);
73 keepImageRatio->setEnabled(false);
74 lay->addWidget(keepImageRatio);
75
76 hbox = new QHBoxLayout;
77 lab = new QLabel(i18nc("@label:textbox", "Width:"));
78 width = new QSpinBox;
79 width->setMinimum(1);
80 width->setMaximum(99999);
81 width->setEnabled(false);
82 width->setValue(80);
83 width->setSuffix(i18n(" px"));
84 lab->setBuddy(width);
85 q->connect(width, &QSpinBox::valueChanged, q, [this](int val) {
86 _k_slotImageWidthChanged(val);
87 });
88 hbox->addWidget(lab);
89 hbox->addWidget(width);
90 lay->addLayout(hbox);
91
92 hbox = new QHBoxLayout;
93 lab = new QLabel(i18nc("@label:textbox", "Height:"));
94 height = new QSpinBox;
95 height->setMinimum(1);
96 height->setValue(80);
97 height->setMaximum(99999);
98 height->setEnabled(false);
99 height->setSuffix(i18n(" px"));
100 lab->setBuddy(height);
101 q->connect(height, &QSpinBox::valueChanged, q, [this](int val) {
102 _k_slotImageHeightChanged(val);
103 });
104 hbox->addWidget(lab);
105 hbox->addWidget(height);
106 lay->addLayout(hbox);
107
108 auto sep = new KSeparator;
109 lay->addWidget(sep);
110
111 hbox = new QHBoxLayout;
112 lab = new QLabel(i18nc("@label:textbox", "Image Preview:"));
113 hbox->addWidget(lab);
114 preview = new QLabel;
115 preview->setFrameStyle(QFrame::Box);
116 preview->setFixedSize(50, 50);
117 hbox->addWidget(preview);
118 lay->addLayout(hbox);
119 }
120
121 void _k_slotKeepOriginalSizeClicked(bool);
122 void _k_slotUrlChanged(const QString &);
123 void _k_slotImageWidthChanged(int);
124 void _k_slotImageHeightChanged(int);
125
126 qreal imageRatio = -1;
127 QCheckBox *keepOriginalSize = nullptr;
128 QCheckBox *keepImageRatio = nullptr;
129 QSpinBox *width = nullptr;
130 QSpinBox *height = nullptr;
131 KUrlRequester *imageUrlRequester = nullptr;
132 QLabel *preview = nullptr;
133 InsertImageWidget *const q;
134};
135
136void InsertImageWidgetPrivate::_k_slotKeepOriginalSizeClicked(bool checked)
137{
138 height->setEnabled(!checked);
139 width->setEnabled(!checked);
140 keepImageRatio->setEnabled(!checked);
141 // Update default size
142 _k_slotUrlChanged(imageUrlRequester->text());
143}
144
145void InsertImageWidgetPrivate::_k_slotUrlChanged(const QString &text)
146{
147 QImage image(text);
148 if (!image.isNull()) {
149 height->setValue(image.height());
150 width->setValue(image.width());
151
152 imageRatio = (double)((double)image.height() / (double)image.width());
153 preview->setPixmap(QPixmap::fromImage(image));
154 } else {
155 preview->clear();
156 imageRatio = -1;
157 }
158 Q_EMIT q->enableButtonOk(!text.trimmed().isEmpty());
159}
160
161void InsertImageWidgetPrivate::_k_slotImageWidthChanged(int value)
162{
163 if (keepImageRatio->isChecked() && !keepOriginalSize->isChecked()) {
164 if (imageRatio != -1) {
165 height->blockSignals(true);
166 height->setValue(value * imageRatio);
167 height->blockSignals(false);
168 }
169 }
170}
171
172void InsertImageWidgetPrivate::_k_slotImageHeightChanged(int value)
173{
174 if (keepImageRatio->isChecked() && !keepOriginalSize->isChecked()) {
175 if (imageRatio != -1) {
176 width->blockSignals(true);
177 width->setValue(value / imageRatio);
178 width->blockSignals(false);
179 }
180 }
181}
182
183InsertImageWidget::InsertImageWidget(QWidget *parent)
184 : QWidget(parent)
185 , d(new InsertImageWidgetPrivate(this))
186{
187}
188
189InsertImageWidget::~InsertImageWidget() = default;
190
191int InsertImageWidget::imageWidth() const
192{
193 return d->width->value();
194}
195
196int InsertImageWidget::imageHeight() const
197{
198 return d->height->value();
199}
200
201void InsertImageWidget::setImageWidth(int value)
202{
203 d->width->setValue(value);
204}
205
206void InsertImageWidget::setImageHeight(int value)
207{
208 d->height->setValue(value);
209}
210
211QUrl InsertImageWidget::imageUrl() const
212{
213 return d->imageUrlRequester->url();
214}
215
216void InsertImageWidget::setImageUrl(const QUrl &url)
217{
218 d->imageUrlRequester->setUrl(url);
219}
220
221bool InsertImageWidget::keepOriginalSize() const
222{
223 return d->keepOriginalSize->isChecked();
224}
225}
226
227#include "moc_insertimagewidget.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void clicked(bool checked)
QList< QByteArray > supportedMimeTypes()
void textChanged(const QString &text)
qsizetype count() const const
void reserve(qsizetype size)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
void valueChanged(int i)
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QString trimmed() const const
QString url(FormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:57:12 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.