1// -*- c++ -*-
2/*
3 This file is part of the KDE libraries
4 SPDX-FileCopyrightText: 2003 Joseph Wenninger <jowenn@kde.org>
5 SPDX-FileCopyrightText: 2003 Andras Mantia <amantia@freemail.hu>
6 SPDX-FileCopyrightText: 2013 Teo Mrnjavac <teo@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "kencodingfiledialog.h"
12
13#include "kfilewidget.h"
14
15#include <defaults-kfile.h>
16
17#include <KConfigGroup>
18#include <KLocalizedString>
19#include <KSharedConfig>
20#include <KWindowConfig>
21#include <krecentdocument.h>
22
23#include <QBoxLayout>
24#include <QComboBox>
25#include <QPushButton>
26#include <QTextCodec>
27
28struct KEncodingFileDialogPrivate {
29 KEncodingFileDialogPrivate()
30 : cfgGroup(KSharedConfig::openConfig(), ConfigGroup)
31 {
32 }
33
34 QComboBox *encoding;
35 KFileWidget *w;
36 KConfigGroup cfgGroup;
37};
38
39KEncodingFileDialog::KEncodingFileDialog(const QUrl &startDir,
40 const QString &encoding,
41 const QString &filter,
42 const QString &title,
43 QFileDialog::AcceptMode type,
44 QWidget *parent)
45 : QDialog(parent, Qt::Dialog)
46 , d(new KEncodingFileDialogPrivate)
47{
48 d->w = new KFileWidget(startDir, this);
49 d->w->setFilters(filters: KFileFilter::fromFilterString(filterString: filter));
50 if (type == QFileDialog::AcceptOpen) {
51 d->w->setOperationMode(KFileWidget::Opening);
52 } else {
53 d->w->setOperationMode(KFileWidget::Saving);
54 }
55
56 setWindowTitle(title);
57 // ops->clearHistory();
58
59 KWindowConfig::restoreWindowSize(window: windowHandle(), config: d->cfgGroup);
60
61 QBoxLayout *mainLayout = new QVBoxLayout(this);
62 mainLayout->addWidget(d->w);
63
64 d->w->okButton()->show();
65 connect(sender: d->w->okButton(), signal: &QAbstractButton::clicked, context: this, slot: &KEncodingFileDialog::slotOk);
66 d->w->cancelButton()->show();
67 connect(sender: d->w->cancelButton(), signal: &QAbstractButton::clicked, context: this, slot: &KEncodingFileDialog::slotCancel);
68 connect(sender: d->w, signal: &KFileWidget::accepted, context: this, slot: &KEncodingFileDialog::accept);
69
70 d->encoding = new QComboBox(this);
71 d->w->setCustomWidget(i18n("Encoding:"), widget: d->encoding);
72
73 d->encoding->clear();
74 QByteArray sEncoding = encoding.toUtf8();
75 auto systemEncoding = QTextCodec::codecForLocale()->name();
76 if (sEncoding.isEmpty() || sEncoding == "System") {
77 sEncoding = systemEncoding;
78 }
79
80 auto encodings = QTextCodec::availableCodecs();
81 std::sort(first: encodings.begin(), last: encodings.end(), comp: [](auto &a, auto &b) {
82 return (a.compare(b, Qt::CaseInsensitive) < 0);
83 });
84
85 int insert = 0;
86 int system = 0;
87 bool foundRequested = false;
88 for (const auto &encoding : encodings) {
89 QTextCodec *codecForEnc = QTextCodec::codecForName(name: encoding);
90
91 if (codecForEnc) {
92 d->encoding->addItem(atext: QString::fromUtf8(ba: encoding));
93 auto codecName = codecForEnc->name();
94 if ((codecName == sEncoding) || (encoding == sEncoding)) {
95 d->encoding->setCurrentIndex(insert);
96 foundRequested = true;
97 }
98
99 if ((codecName == systemEncoding) || (encoding == systemEncoding)) {
100 system = insert;
101 }
102 insert++;
103 }
104 }
105
106 if (!foundRequested) {
107 d->encoding->setCurrentIndex(system);
108 }
109}
110
111KEncodingFileDialog::~KEncodingFileDialog() = default;
112
113QString KEncodingFileDialog::selectedEncoding() const
114{
115 if (d->encoding) {
116 return d->encoding->currentText();
117 } else {
118 return QString();
119 }
120}
121
122KEncodingFileDialog::Result
123KEncodingFileDialog::getOpenFileNameAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
124{
125 KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
126
127 dlg.d->w->setMode(KFile::File | KFile::LocalOnly);
128 dlg.exec();
129
130 Result res;
131 res.fileNames << dlg.d->w->selectedFile();
132 res.encoding = dlg.selectedEncoding();
133 return res;
134}
135
136KEncodingFileDialog::Result
137KEncodingFileDialog::getOpenFileNamesAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
138{
139 KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
140 dlg.d->w->setMode(KFile::Files | KFile::LocalOnly);
141 dlg.exec();
142
143 Result res;
144 res.fileNames = dlg.d->w->selectedFiles();
145 res.encoding = dlg.selectedEncoding();
146 return res;
147}
148
149KEncodingFileDialog::Result
150KEncodingFileDialog::getOpenUrlAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
151{
152 KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
153
154 dlg.d->w->setMode(KFile::File);
155 dlg.exec();
156
157 Result res;
158 res.URLs << dlg.d->w->selectedUrl();
159 res.encoding = dlg.selectedEncoding();
160 return res;
161}
162
163KEncodingFileDialog::Result
164KEncodingFileDialog::getOpenUrlsAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
165{
166 KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
167
168 dlg.d->w->setMode(KFile::Files);
169 dlg.exec();
170
171 Result res;
172 res.URLs = dlg.d->w->selectedUrls();
173 res.encoding = dlg.selectedEncoding();
174 return res;
175}
176
177KEncodingFileDialog::Result
178KEncodingFileDialog::getSaveFileNameAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &title)
179{
180 KEncodingFileDialog dlg(dir, encoding, filter, title.isNull() ? i18n("Save As") : title, QFileDialog::AcceptSave, parent);
181 dlg.d->w->setMode(KFile::File);
182 dlg.exec();
183
184 QString filename = dlg.d->w->selectedFile();
185 if (!filename.isEmpty()) {
186 KRecentDocument::add(url: QUrl::fromLocalFile(localfile: filename));
187 }
188
189 Result res;
190 res.fileNames << filename;
191 res.encoding = dlg.selectedEncoding();
192 return res;
193}
194
195KEncodingFileDialog::Result
196KEncodingFileDialog::getSaveUrlAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &title)
197{
198 KEncodingFileDialog dlg(dir, encoding, filter, title.isNull() ? i18n("Save As") : title, QFileDialog::AcceptSave, parent);
199 dlg.d->w->setMode(KFile::File);
200
201 Result res;
202 if (dlg.exec() == QDialog::Accepted) {
203 QUrl url = dlg.d->w->selectedUrl();
204 if (url.isValid()) {
205 KRecentDocument::add(url);
206 }
207 res.URLs << url;
208 res.encoding = dlg.selectedEncoding();
209 }
210 return res;
211}
212
213QSize KEncodingFileDialog::sizeHint() const
214{
215 return d->w->dialogSizeHint();
216}
217
218void KEncodingFileDialog::hideEvent(QHideEvent *e)
219{
220 KWindowConfig::saveWindowSize(window: windowHandle(), config&: d->cfgGroup, options: KConfigBase::Persistent);
221
222 QDialog::hideEvent(event: e);
223}
224
225void KEncodingFileDialog::accept()
226{
227 d->w->accept();
228 QDialog::accept();
229}
230
231void KEncodingFileDialog::slotOk()
232{
233 d->w->slotOk();
234}
235
236void KEncodingFileDialog::slotCancel()
237{
238 d->w->slotCancel();
239 reject();
240}
241
242#include "moc_kencodingfiledialog.cpp"
243

source code of kio/src/filewidgets/kencodingfiledialog.cpp