File indexing completed on 2024-04-21 03:55:18

0001 // -*- c++ -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 2003 Joseph Wenninger <jowenn@kde.org>
0005     SPDX-FileCopyrightText: 2003 Andras Mantia <amantia@freemail.hu>
0006     SPDX-FileCopyrightText: 2013 Teo Mrnjavac <teo@kde.org>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #include "kencodingfiledialog.h"
0012 
0013 #include "kfilewidget.h"
0014 
0015 #include <defaults-kfile.h>
0016 
0017 #include <KConfigGroup>
0018 #include <KLocalizedString>
0019 #include <KSharedConfig>
0020 #include <KWindowConfig>
0021 #include <krecentdocument.h>
0022 
0023 #include <QBoxLayout>
0024 #include <QComboBox>
0025 #include <QPushButton>
0026 #include <QTextCodec>
0027 
0028 struct KEncodingFileDialogPrivate {
0029     KEncodingFileDialogPrivate()
0030         : cfgGroup(KSharedConfig::openConfig(), ConfigGroup)
0031     {
0032     }
0033 
0034     QComboBox *encoding;
0035     KFileWidget *w;
0036     KConfigGroup cfgGroup;
0037 };
0038 
0039 KEncodingFileDialog::KEncodingFileDialog(const QUrl &startDir,
0040                                          const QString &encoding,
0041                                          const QString &filter,
0042                                          const QString &title,
0043                                          QFileDialog::AcceptMode type,
0044                                          QWidget *parent)
0045     : QDialog(parent, Qt::Dialog)
0046     , d(new KEncodingFileDialogPrivate)
0047 {
0048     d->w = new KFileWidget(startDir, this);
0049     d->w->setFilters(KFileFilter::fromFilterString(filter));
0050     if (type == QFileDialog::AcceptOpen) {
0051         d->w->setOperationMode(KFileWidget::Opening);
0052     } else {
0053         d->w->setOperationMode(KFileWidget::Saving);
0054     }
0055 
0056     setWindowTitle(title);
0057     // ops->clearHistory();
0058 
0059     KWindowConfig::restoreWindowSize(windowHandle(), d->cfgGroup);
0060 
0061     QBoxLayout *mainLayout = new QVBoxLayout(this);
0062     mainLayout->addWidget(d->w);
0063 
0064     d->w->okButton()->show();
0065     connect(d->w->okButton(), &QAbstractButton::clicked, this, &KEncodingFileDialog::slotOk);
0066     d->w->cancelButton()->show();
0067     connect(d->w->cancelButton(), &QAbstractButton::clicked, this, &KEncodingFileDialog::slotCancel);
0068     connect(d->w, &KFileWidget::accepted, this, &KEncodingFileDialog::accept);
0069 
0070     d->encoding = new QComboBox(this);
0071     d->w->setCustomWidget(i18n("Encoding:"), d->encoding);
0072 
0073     d->encoding->clear();
0074     QByteArray sEncoding = encoding.toUtf8();
0075     auto systemEncoding = QTextCodec::codecForLocale()->name();
0076     if (sEncoding.isEmpty() || sEncoding == "System") {
0077         sEncoding = systemEncoding;
0078     }
0079 
0080     auto encodings = QTextCodec::availableCodecs();
0081     std::sort(encodings.begin(), encodings.end(), [](auto &a, auto &b) {
0082         return (a.compare(b, Qt::CaseInsensitive) < 0);
0083     });
0084 
0085     int insert = 0;
0086     int system = 0;
0087     bool foundRequested = false;
0088     for (const auto &encoding : encodings) {
0089         QTextCodec *codecForEnc = QTextCodec::codecForName(encoding);
0090 
0091         if (codecForEnc) {
0092             d->encoding->addItem(QString::fromUtf8(encoding));
0093             auto codecName = codecForEnc->name();
0094             if ((codecName == sEncoding) || (encoding == sEncoding)) {
0095                 d->encoding->setCurrentIndex(insert);
0096                 foundRequested = true;
0097             }
0098 
0099             if ((codecName == systemEncoding) || (encoding == systemEncoding)) {
0100                 system = insert;
0101             }
0102             insert++;
0103         }
0104     }
0105 
0106     if (!foundRequested) {
0107         d->encoding->setCurrentIndex(system);
0108     }
0109 }
0110 
0111 KEncodingFileDialog::~KEncodingFileDialog() = default;
0112 
0113 QString KEncodingFileDialog::selectedEncoding() const
0114 {
0115     if (d->encoding) {
0116         return d->encoding->currentText();
0117     } else {
0118         return QString();
0119     }
0120 }
0121 
0122 KEncodingFileDialog::Result
0123 KEncodingFileDialog::getOpenFileNameAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
0124 {
0125     KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
0126 
0127     dlg.d->w->setMode(KFile::File | KFile::LocalOnly);
0128     dlg.exec();
0129 
0130     Result res;
0131     res.fileNames << dlg.d->w->selectedFile();
0132     res.encoding = dlg.selectedEncoding();
0133     return res;
0134 }
0135 
0136 KEncodingFileDialog::Result
0137 KEncodingFileDialog::getOpenFileNamesAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
0138 {
0139     KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
0140     dlg.d->w->setMode(KFile::Files | KFile::LocalOnly);
0141     dlg.exec();
0142 
0143     Result res;
0144     res.fileNames = dlg.d->w->selectedFiles();
0145     res.encoding = dlg.selectedEncoding();
0146     return res;
0147 }
0148 
0149 KEncodingFileDialog::Result
0150 KEncodingFileDialog::getOpenUrlAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
0151 {
0152     KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
0153 
0154     dlg.d->w->setMode(KFile::File);
0155     dlg.exec();
0156 
0157     Result res;
0158     res.URLs << dlg.d->w->selectedUrl();
0159     res.encoding = dlg.selectedEncoding();
0160     return res;
0161 }
0162 
0163 KEncodingFileDialog::Result
0164 KEncodingFileDialog::getOpenUrlsAndEncoding(const QString &encoding, const QUrl &startDir, const QString &filter, QWidget *parent, const QString &title)
0165 {
0166     KEncodingFileDialog dlg(startDir, encoding, filter, title.isNull() ? i18n("Open") : title, QFileDialog::AcceptOpen, parent);
0167 
0168     dlg.d->w->setMode(KFile::Files);
0169     dlg.exec();
0170 
0171     Result res;
0172     res.URLs = dlg.d->w->selectedUrls();
0173     res.encoding = dlg.selectedEncoding();
0174     return res;
0175 }
0176 
0177 KEncodingFileDialog::Result
0178 KEncodingFileDialog::getSaveFileNameAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &title)
0179 {
0180     KEncodingFileDialog dlg(dir, encoding, filter, title.isNull() ? i18n("Save As") : title, QFileDialog::AcceptSave, parent);
0181     dlg.d->w->setMode(KFile::File);
0182     dlg.exec();
0183 
0184     QString filename = dlg.d->w->selectedFile();
0185     if (!filename.isEmpty()) {
0186         KRecentDocument::add(QUrl::fromLocalFile(filename));
0187     }
0188 
0189     Result res;
0190     res.fileNames << filename;
0191     res.encoding = dlg.selectedEncoding();
0192     return res;
0193 }
0194 
0195 KEncodingFileDialog::Result
0196 KEncodingFileDialog::getSaveUrlAndEncoding(const QString &encoding, const QUrl &dir, const QString &filter, QWidget *parent, const QString &title)
0197 {
0198     KEncodingFileDialog dlg(dir, encoding, filter, title.isNull() ? i18n("Save As") : title, QFileDialog::AcceptSave, parent);
0199     dlg.d->w->setMode(KFile::File);
0200 
0201     Result res;
0202     if (dlg.exec() == QDialog::Accepted) {
0203         QUrl url = dlg.d->w->selectedUrl();
0204         if (url.isValid()) {
0205             KRecentDocument::add(url);
0206         }
0207         res.URLs << url;
0208         res.encoding = dlg.selectedEncoding();
0209     }
0210     return res;
0211 }
0212 
0213 QSize KEncodingFileDialog::sizeHint() const
0214 {
0215     return d->w->dialogSizeHint();
0216 }
0217 
0218 void KEncodingFileDialog::hideEvent(QHideEvent *e)
0219 {
0220     KWindowConfig::saveWindowSize(windowHandle(), d->cfgGroup, KConfigBase::Persistent);
0221 
0222     QDialog::hideEvent(e);
0223 }
0224 
0225 void KEncodingFileDialog::accept()
0226 {
0227     d->w->accept();
0228     QDialog::accept();
0229 }
0230 
0231 void KEncodingFileDialog::slotOk()
0232 {
0233     d->w->slotOk();
0234 }
0235 
0236 void KEncodingFileDialog::slotCancel()
0237 {
0238     d->w->slotCancel();
0239     reject();
0240 }
0241 
0242 #include "moc_kencodingfiledialog.cpp"