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