1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2005 David Faure <faure@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "pastedialog_p.h"
9
10#include <KLocalizedString>
11
12#include <QApplication>
13#include <QClipboard>
14#include <QComboBox>
15#include <QDialogButtonBox>
16#include <QLabel>
17#include <QLineEdit>
18#include <QMimeDatabase>
19#include <QMimeType>
20#include <QVBoxLayout>
21
22KIO::PasteDialog::PasteDialog(const QString &title, const QString &label, const QString &suggestedFileName, const QStringList &formats, QWidget *parent)
23 : QDialog(parent)
24{
25 setWindowTitle(title);
26 setModal(true);
27
28 QVBoxLayout *topLayout = new QVBoxLayout(this);
29
30 QFrame *frame = new QFrame(this);
31 topLayout->addWidget(frame);
32
33 QVBoxLayout *layout = new QVBoxLayout(frame);
34
35 m_label = new QLabel(label, frame);
36 m_label->setWordWrap(true);
37 layout->addWidget(m_label);
38
39 m_lineEdit = new QLineEdit(suggestedFileName, frame);
40 layout->addWidget(m_lineEdit);
41
42 m_lineEdit->setFocus();
43 m_label->setBuddy(m_lineEdit);
44
45 layout->addWidget(new QLabel(i18n("Data format:"), frame));
46 m_comboBox = new QComboBox(frame);
47
48 // Populate the combobox with nice human-readable labels
49 QMimeDatabase db;
50 for (const QString &format : formats) {
51 QMimeType mime = db.mimeTypeForName(nameOrAlias: format);
52 if (mime.isValid()) {
53 auto label = i18n("%1 (%2)", mime.comment(), format);
54 m_comboBox->addItem(atext: label, auserData: mime.name());
55 } else {
56 m_comboBox->addItem(atext: format);
57 }
58 }
59
60 m_lastValidComboboxFormat = formats.value(i: comboItem());
61
62 // Get fancy: if the user changes the format, try to replace the filename extension
63 connect(sender: m_comboBox, signal: &QComboBox::activated, context: this, slot: [this, formats]() {
64 const auto format = formats.value(i: comboItem());
65 const auto currentText = m_lineEdit->text();
66
67 QMimeDatabase db;
68 const QMimeType oldMimetype = db.mimeTypeForName(nameOrAlias: m_lastValidComboboxFormat);
69 const QMimeType newMimetype = db.mimeTypeForName(nameOrAlias: format);
70
71 const QString newExtension = newMimetype.preferredSuffix();
72 const QString oldExtension = oldMimetype.preferredSuffix();
73
74 m_lastValidComboboxFormat = format;
75 if (newMimetype.isValid()) {
76 if (oldMimetype.isValid() && currentText.endsWith(s: oldMimetype.preferredSuffix())) {
77 m_lineEdit->setText(m_lineEdit->text().replace(before: oldExtension, after: newExtension));
78 } else {
79 m_lineEdit->setText(currentText + QLatin1String(".") + newMimetype.preferredSuffix());
80 }
81 m_lineEdit->setSelection(0, m_lineEdit->text().length() - newExtension.length() - 1);
82 m_lineEdit->setFocus();
83 } else if (oldMimetype.isValid() && currentText.endsWith(s: oldMimetype.preferredSuffix())) {
84 // remove the extension
85 m_lineEdit->setText(currentText.chopped(n: oldExtension.length() + 1));
86 m_lineEdit->setFocus();
87 }
88 });
89
90 // update the selected format depending on the text
91 connect(sender: m_lineEdit, signal: &QLineEdit::textChanged, context: this, slot: [this, formats]() {
92 const auto format = formats.value(i: comboItem());
93 const auto currentText = m_lineEdit->text();
94
95 QMimeDatabase db;
96 const QMimeType oldMimetype = db.mimeTypeForName(nameOrAlias: m_lastValidComboboxFormat);
97 QMimeType newMimetype = db.mimeTypeForFile(fileName: currentText, mode: QMimeDatabase::MatchMode::MatchExtension);
98 if (newMimetype.isValid() && newMimetype != oldMimetype && formats.contains(str: newMimetype.name())) {
99 auto idxMime = m_comboBox->findData(data: newMimetype.name(), role: Qt::UserRole);
100 if (idxMime != -1) {
101 m_lastValidComboboxFormat = format;
102 m_comboBox->setCurrentIndex(idxMime);
103 }
104 }
105 });
106
107 layout->addWidget(m_comboBox);
108
109 layout->addStretch();
110
111 // Pre-fill the filename extension and select everything before it, or just
112 // move the cursor appropriately
113 const QMimeType mimetype = db.mimeTypeForName(nameOrAlias: formats.value(i: comboItem()));
114 if (mimetype.isValid()) {
115 if (suggestedFileName.endsWith(s: mimetype.preferredSuffix())) {
116 m_lineEdit->setSelection(0, suggestedFileName.length() - mimetype.preferredSuffix().length() - 1);
117 } else {
118 m_lineEdit->setText(suggestedFileName + QLatin1String(".") + mimetype.preferredSuffix());
119 m_lineEdit->setSelection(0, suggestedFileName.length());
120 }
121 }
122 m_lineEdit->setFocus();
123
124 QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
125 buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
126 connect(sender: buttonBox, signal: &QDialogButtonBox::accepted, context: this, slot: &QDialog::accept);
127 connect(sender: buttonBox, signal: &QDialogButtonBox::rejected, context: this, slot: &QDialog::reject);
128 topLayout->addWidget(buttonBox);
129
130 setMinimumWidth(350);
131}
132
133QString KIO::PasteDialog::lineEditText() const
134{
135 return m_lineEdit->text();
136}
137
138int KIO::PasteDialog::comboItem() const
139{
140 return m_comboBox->currentIndex();
141}
142
143#include "moc_pastedialog_p.cpp"
144

source code of kio/src/widgets/pastedialog.cpp