File indexing completed on 2024-04-28 16:44:26

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
0005 */
0006 
0007 // Own
0008 #include "keditfiletype.h"
0009 #include "mimetypewriter.h"
0010 
0011 // Qt
0012 #include <QApplication>
0013 #include <QCommandLineOption>
0014 #include <QCommandLineParser>
0015 #include <QDBusConnection>
0016 #include <QDBusMessage>
0017 #include <QDebug>
0018 #include <QDialogButtonBox>
0019 #include <QMimeDatabase>
0020 #include <QPushButton>
0021 #include <QVBoxLayout>
0022 
0023 // KDE
0024 #include <kaboutdata.h>
0025 #include <kbuildsycocaprogressdialog.h>
0026 #include <klocalizedstring.h>
0027 
0028 #include <kservicetypeprofile.h>
0029 #include <ksycoca.h>
0030 
0031 #include <kwindowsystem.h>
0032 
0033 // Local
0034 #include "filetypedetails.h"
0035 #include "typeslistitem.h"
0036 
0037 FileTypeDialog::FileTypeDialog(MimeTypeData *mime)
0038     : QDialog(nullptr)
0039     , m_mimeTypeData(mime)
0040 {
0041     init();
0042 }
0043 
0044 FileTypeDialog::~FileTypeDialog()
0045 {
0046     delete m_details;
0047 }
0048 
0049 void FileTypeDialog::init()
0050 {
0051     m_details = new FileTypeDetails(this);
0052     m_details->setMimeTypeData(m_mimeTypeData);
0053     connect(m_details, &FileTypeDetails::changed, this, &FileTypeDialog::clientChanged);
0054 
0055     m_buttonBox = new QDialogButtonBox;
0056     m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel);
0057     connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept()));
0058     connect(m_buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &FileTypeDialog::save);
0059     connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0060 
0061     // This code is very similar to kcdialog.cpp
0062     QVBoxLayout *layout = new QVBoxLayout(this);
0063     layout->addWidget(m_details);
0064     layout->addWidget(m_buttonBox);
0065     // TODO setHelp()
0066 
0067     setApplyButtonEnabled(false);
0068 
0069     connect(KSycoca::self(), qOverload<>(&KSycoca::databaseChanged), this, &FileTypeDialog::slotDatabaseChanged);
0070 }
0071 
0072 void FileTypeDialog::setApplyButtonEnabled(bool enabled)
0073 {
0074     m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(enabled);
0075 }
0076 
0077 void FileTypeDialog::save()
0078 {
0079     if (m_mimeTypeData->isDirty()) {
0080         const bool servicesDirty = m_mimeTypeData->isServiceListDirty();
0081         if (m_mimeTypeData->sync()) {
0082             MimeTypeWriter::runUpdateMimeDatabase();
0083         }
0084         if (servicesDirty) {
0085             KBuildSycocaProgressDialog::rebuildKSycoca(this);
0086         }
0087         // Trigger reparseConfiguration of filetypesrc in konqueror
0088         QDBusMessage message =
0089             QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration"));
0090         QDBusConnection::sessionBus().send(message);
0091     }
0092 }
0093 
0094 void FileTypeDialog::accept()
0095 {
0096     save();
0097     QDialog::accept();
0098 }
0099 
0100 void FileTypeDialog::clientChanged(bool state)
0101 {
0102     m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(state);
0103     m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(state);
0104 }
0105 
0106 void FileTypeDialog::slotDatabaseChanged()
0107 {
0108     m_details->refresh();
0109 }
0110 
0111 int main(int argc, char **argv)
0112 {
0113     QApplication app(argc, argv);
0114 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0115     app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
0116 #endif
0117     QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-filetype-association")));
0118 
0119     KAboutData aboutData(QStringLiteral("keditfiletype"),
0120                          i18n("File Type Editor"),
0121                          QLatin1String(PROJECT_VERSION),
0122                          i18n("KDE file type editor - simplified version for editing a single file type"),
0123                          KAboutLicense::GPL,
0124                          i18n("(c) 2000, KDE developers"));
0125     aboutData.addAuthor(i18n("Preston Brown"), QString(), QStringLiteral("pbrown@kde.org"));
0126     aboutData.addAuthor(i18n("David Faure"), QString(), QStringLiteral("faure@kde.org"));
0127     KAboutData::setApplicationData(aboutData);
0128 
0129     QCommandLineParser parser;
0130     aboutData.setupCommandLine(&parser);
0131     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("parent"),
0132                                         i18n("Makes the dialog transient for the window specified by winid"),
0133                                         QStringLiteral("winid")));
0134     parser.addPositionalArgument(QStringLiteral("mimetype"), i18n("File type to edit (e.g. text/html)"));
0135 
0136     parser.process(app);
0137     aboutData.processCommandLine(&parser);
0138 
0139     if (parser.positionalArguments().count() == 0) {
0140         parser.showHelp();
0141     }
0142 
0143     QMimeDatabase db;
0144     const QString arg = parser.positionalArguments().at(0);
0145     MimeTypeData *mimeTypeData = nullptr;
0146     const bool createType = arg.startsWith(QLatin1Char('*'));
0147     if (createType) {
0148         QString mimeString = QStringLiteral("application/x-kdeuser%1");
0149         QString mimeTypeName;
0150         int inc = 0;
0151         bool ok = false;
0152         do {
0153             ++inc;
0154             mimeTypeName = mimeString.arg(inc);
0155             ok = !db.mimeTypeForName(mimeTypeName).isValid();
0156         } while (!ok);
0157 
0158         QStringList patterns;
0159         if (arg.length() > 2) {
0160             patterns << arg.toLower() << arg.toUpper();
0161         }
0162         QString comment;
0163         if (arg.startsWith(QLatin1String("*.")) && arg.length() >= 3) {
0164             const QString type = arg.mid(3).prepend(arg[2].toUpper());
0165             comment = i18n("%1 File", type);
0166         }
0167 
0168         mimeTypeData = new MimeTypeData(mimeTypeName, true); // new mimetype
0169         mimeTypeData->setComment(comment);
0170         mimeTypeData->setPatterns(patterns);
0171     } else {
0172         const QString mimeTypeName = arg;
0173         QMimeType mime = db.mimeTypeForName(mimeTypeName);
0174         if (!mime.isValid()) {
0175             qCritical() << "Mimetype" << mimeTypeName << "not found";
0176             return 1;
0177         }
0178 
0179         mimeTypeData = new MimeTypeData(mime);
0180     }
0181 
0182     FileTypeDialog dlg(mimeTypeData);
0183     if (parser.isSet(QStringLiteral("parent"))) {
0184         bool ok;
0185         long id = parser.value(QStringLiteral("parent")).toLong(&ok);
0186         if (ok) {
0187             dlg.setAttribute(Qt::WA_NativeWindow, true);
0188             KWindowSystem::setMainWindow(dlg.windowHandle(), WId(id));
0189         }
0190     }
0191     if (!createType) {
0192         dlg.setWindowTitle(i18n("Edit File Type %1", mimeTypeData->name()));
0193     } else {
0194         dlg.setWindowTitle(i18n("Create New File Type %1", mimeTypeData->name()));
0195         dlg.setApplyButtonEnabled(true);
0196     }
0197 
0198     dlg.show(); // non-modal
0199 
0200     return app.exec();
0201 }