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 <KCharsets>
18 #include <KConfigGroup>
19 #include <KLocalizedString>
20 #include <KSharedConfig>
21 #include <KWindowConfig>
22 #include <krecentdocument.h>
23
24 #include <QBoxLayout>
25 #include <QComboBox>
26 #include <QPushButton>
27 #include <QTextCodec>
28
29 struct KEncodingFileDialogPrivate {
KEncodingFileDialogPrivateKEncodingFileDialogPrivate30 KEncodingFileDialogPrivate()
31 : cfgGroup(KSharedConfig::openConfig(), ConfigGroup)
32 {
33 }
34
35 QComboBox *encoding;
36 KFileWidget *w;
37 KConfigGroup cfgGroup;
38 };
39
KEncodingFileDialog(const QUrl & startDir,const QString & encoding,const QString & filter,const QString & caption,QFileDialog::AcceptMode type,QWidget * parent)40 KEncodingFileDialog::KEncodingFileDialog(const QUrl &startDir,
41 const QString &encoding,
42 const QString &filter,
43 const QString &caption,
44 QFileDialog::AcceptMode type,
45 QWidget *parent)
46 : QDialog(parent, Qt::Dialog)
47 , d(new KEncodingFileDialogPrivate)
48 {
49 d->w = new KFileWidget(startDir, this);
50 d->w->setFilter(filter);
51 if (type == QFileDialog::AcceptOpen) {
52 d->w->setOperationMode(KFileWidget::Opening);
53 } else {
54 d->w->setOperationMode(KFileWidget::Saving);
55 }
56
57 setWindowTitle(caption);
58 // ops->clearHistory();
59
60 KWindowConfig::restoreWindowSize(windowHandle(), d->cfgGroup);
61
62 QBoxLayout *mainLayout = new QVBoxLayout(this);
63 mainLayout->addWidget(d->w);
64
65 d->w->okButton()->show();
66 connect(d->w->okButton(), &QAbstractButton::clicked, this, &KEncodingFileDialog::slotOk);
67 d->w->cancelButton()->show();
68 connect(d->w->cancelButton(), &QAbstractButton::clicked, this, &KEncodingFileDialog::slotCancel);
69 connect(d->w, &KFileWidget::accepted, this, &KEncodingFileDialog::accept);
70
71 d->encoding = new QComboBox(this);
72 d->w->setCustomWidget(i18n("Encoding:"), d->encoding);
73
74 d->encoding->clear();
75 QString sEncoding = encoding;
76 QString systemEncoding = QLatin1String(QTextCodec::codecForLocale()->name());
77 if (sEncoding.isEmpty() || sEncoding == QLatin1String("System")) {
78 sEncoding = systemEncoding;
79 }
80
81 const QStringList encodings(KCharsets::charsets()->availableEncodingNames());
82 int insert = 0;
83 int system = 0;
84 bool foundRequested = false;
85 for (const QString &encoding : encodings) {
86 bool found = false;
87 QTextCodec *codecForEnc = KCharsets::charsets()->codecForName(encoding, found);
88
89 if (found) {
90 d->encoding->addItem(encoding);
91 const QString codecName = QLatin1String(codecForEnc->name());
92 if ((codecName == sEncoding) || (encoding == sEncoding)) {
93 d->encoding->setCurrentIndex(insert);
94 foundRequested = true;
95 }
96
97 if ((codecName == systemEncoding) || (encoding == systemEncoding)) {
98 system = insert;
99 }
100 insert++;
101 }
102 }
103
104 if (!foundRequested) {
105 d->encoding->setCurrentIndex(system);
106 }
107 }
108
~KEncodingFileDialog()109 KEncodingFileDialog::~KEncodingFileDialog()
110 {
111 delete d;
112 }
113
selectedEncoding() const114 QString KEncodingFileDialog::selectedEncoding() const
115 {
116 if (d->encoding) {
117 return d->encoding->currentText();
118 } else {
119 return QString();
120 }
121 }
122
123 KEncodingFileDialog::Result
getOpenFileNameAndEncoding(const QString & encoding,const QUrl & startDir,const QString & filter,QWidget * parent,const QString & caption)124 KEncodingFileDialog::getOpenFileNameAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption)
125 {
126 KEncodingFileDialog dlg(startDir, encoding, filter, caption.isNull() ? i18n("Open") : caption, QFileDialog::AcceptOpen, parent);
127
128 dlg.d->w->setMode(KFile::File | KFile::LocalOnly);
129 dlg.exec();
130
131 Result res;
132 res.fileNames << dlg.d->w->selectedFile();
133 res.encoding = dlg.selectedEncoding();
134 return res;
135 }
136
137 KEncodingFileDialog::Result
getOpenFileNamesAndEncoding(const QString & encoding,const QUrl & startDir,const QString & filter,QWidget * parent,const QString & caption)138 KEncodingFileDialog::getOpenFileNamesAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption)
139 {
140 KEncodingFileDialog dlg(startDir, encoding, filter, caption.isNull() ? i18n("Open") : caption, QFileDialog::AcceptOpen, parent);
141 dlg.d->w->setMode(KFile::Files | KFile::LocalOnly);
142 dlg.exec();
143
144 Result res;
145 res.fileNames = dlg.d->w->selectedFiles();
146 res.encoding = dlg.selectedEncoding();
147 return res;
148 }
149
150 KEncodingFileDialog::Result
getOpenUrlAndEncoding(const QString & encoding,const QUrl & startDir,const QString & filter,QWidget * parent,const QString & caption)151 KEncodingFileDialog::getOpenUrlAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption)
152 {
153 KEncodingFileDialog dlg(startDir, encoding, filter, caption.isNull() ? i18n("Open") : caption, QFileDialog::AcceptOpen, parent);
154
155 dlg.d->w->setMode(KFile::File);
156 dlg.exec();
157
158 Result res;
159 res.URLs << dlg.d->w->selectedUrl();
160 res.encoding = dlg.selectedEncoding();
161 return res;
162 }
163
164 KEncodingFileDialog::Result
getOpenUrlsAndEncoding(const QString & encoding,const QUrl & startDir,const QString & filter,QWidget * parent,const QString & caption)165 KEncodingFileDialog::getOpenUrlsAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption)
166 {
167 KEncodingFileDialog dlg(startDir, encoding, filter, caption.isNull() ? i18n("Open") : caption, QFileDialog::AcceptOpen, parent);
168
169 dlg.d->w->setMode(KFile::Files);
170 dlg.exec();
171
172 Result res;
173 res.URLs = dlg.d->w->selectedUrls();
174 res.encoding = dlg.selectedEncoding();
175 return res;
176 }
177
178 KEncodingFileDialog::Result
getSaveFileNameAndEncoding(const QString & encoding,const QUrl & dir,const QString & filter,QWidget * parent,const QString & caption)179 KEncodingFileDialog::getSaveFileNameAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption)
180 {
181 KEncodingFileDialog dlg(dir, encoding, filter, caption.isNull() ? i18n("Save As") : caption, QFileDialog::AcceptSave, parent);
182 dlg.d->w->setMode(KFile::File);
183 dlg.exec();
184
185 QString filename = dlg.d->w->selectedFile();
186 if (!filename.isEmpty()) {
187 KRecentDocument::add(QUrl::fromLocalFile(filename));
188 }
189
190 Result res;
191 res.fileNames << filename;
192 res.encoding = dlg.selectedEncoding();
193 return res;
194 }
195
196 KEncodingFileDialog::Result
getSaveUrlAndEncoding(const QString & encoding,const QUrl & dir,const QString & filter,QWidget * parent,const QString & caption)197 KEncodingFileDialog::getSaveUrlAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption)
198 {
199 KEncodingFileDialog dlg(dir, encoding, filter, caption.isNull() ? i18n("Save As") : caption, QFileDialog::AcceptSave, parent);
200 dlg.d->w->setMode(KFile::File);
201
202 Result res;
203 if (dlg.exec() == QDialog::Accepted) {
204 QUrl url = dlg.d->w->selectedUrl();
205 if (url.isValid()) {
206 KRecentDocument::add(url);
207 }
208 res.URLs << url;
209 res.encoding = dlg.selectedEncoding();
210 }
211 return res;
212 }
213
sizeHint() const214 QSize KEncodingFileDialog::sizeHint() const
215 {
216 return d->w->dialogSizeHint();
217 }
218
hideEvent(QHideEvent * e)219 void KEncodingFileDialog::hideEvent(QHideEvent *e)
220 {
221 KWindowConfig::saveWindowSize(windowHandle(), d->cfgGroup, KConfigBase::Persistent);
222
223 QDialog::hideEvent(e);
224 }
225
accept()226 void KEncodingFileDialog::accept()
227 {
228 d->w->accept();
229 QDialog::accept();
230 }
231
slotOk()232 void KEncodingFileDialog::slotOk()
233 {
234 d->w->slotOk();
235 }
236
slotCancel()237 void KEncodingFileDialog::slotCancel()
238 {
239 d->w->slotCancel();
240 reject();
241 }
242
243 #include "moc_kencodingfiledialog.cpp"
244