diff --git a/kcmshell/main.cpp b/kcmshell/main.cpp index f54f21a..5dbaff7 100644 --- a/kcmshell/main.cpp +++ b/kcmshell/main.cpp @@ -1,333 +1,333 @@ /* Copyright (c) 1999 Matthias Hoelzer-Kluepfel Copyright (c) 2000 Matthias Elter Copyright (c) 2004 Frans Englich This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "main.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; KService::List m_modules; static bool caseInsensitiveLessThan(const KService::Ptr s1, const KService::Ptr s2) { const int compare = QString::compare(s1->desktopEntryName(), s2->desktopEntryName(), Qt::CaseInsensitive); return (compare < 0); } static void listModules() { // First condition is what systemsettings does, second what kinfocenter does, make sure this is kept in sync // We need the exist calls because otherwise the trader language aborts if the property doesn't exist and the second part of the or is not evaluated const KService::List services = KServiceTypeTrader::self()->query( QStringLiteral("KCModule"), QStringLiteral("(exist [X-KDE-System-Settings-Parent-Category] and [X-KDE-System-Settings-Parent-Category] != '') or (exist [X-KDE-ParentApp] and [X-KDE-ParentApp] == 'kinfocenter')") ); for( KService::List::const_iterator it = services.constBegin(); it != services.constEnd(); ++it) { const KService::Ptr s = (*it); if (!KAuthorized::authorizeControlModule(s->menuId())) continue; m_modules.append(s); } std::stable_sort(m_modules.begin(), m_modules.end(), caseInsensitiveLessThan); } static KService::Ptr locateModule(const QString& module) { QString path = module; if (!path.endsWith(QLatin1String(".desktop"))) path += QStringLiteral(".desktop"); KService::Ptr service = KService::serviceByStorageId( path ); if (!service) { return KService::Ptr(); } if (!service->hasServiceType(QStringLiteral("KCModule"))) { // Not a KCModule. E.g. "kcmshell5 akonadi" finds services/kresources/kabc/akonadi.desktop, unrelated. return KService::Ptr(); } if (service->noDisplay()) { qDebug() << module << "should not be loaded."; return KService::Ptr(); } return service; } bool KCMShell::isRunning() { const QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName); if (owner == QDBusConnection::sessionBus().baseService()) { return false; // We are the one and only. } qDebug() << "kcmshell5 with modules '" << m_serviceName << "' is already running."; QDBusInterface iface(m_serviceName, QStringLiteral("/KCModule/dialog"), QStringLiteral("org.kde.KCMShellMultiDialog")); QDBusReply reply = iface.call(QStringLiteral("activate"), KStartupInfo::startupId()); if (!reply.isValid()) { qDebug() << "Calling D-Bus function dialog::activate() failed."; return false; // Error, we have to do it ourselves. } return true; } KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent) : KCMultiDialog(parent) { setFaceType(dialogFace); setModal(false); QDBusConnection::sessionBus().registerObject(QStringLiteral("/KCModule/dialog"), this, QDBusConnection::ExportScriptableSlots); connect(this, &KCMShellMultiDialog::currentPageChanged, - this, [this](KPageWidgetItem *newPage,KPageWidgetItem *oldPage) { + this, [](KPageWidgetItem *newPage,KPageWidgetItem *oldPage) { Q_UNUSED(oldPage); KCModuleProxy *activeModule = newPage->widget()->findChild(); if (activeModule) { KActivities::ResourceInstance::notifyAccessed(QUrl(QStringLiteral("kcm:") + activeModule->moduleInfo().service()->storageId()), QStringLiteral("org.kde.systemsettings")); } }); } void KCMShellMultiDialog::activate(const QByteArray& asn_id) { #ifdef HAVE_X11 setAttribute(Qt::WA_NativeWindow, true); KStartupInfo::setNewStartupId(windowHandle(), asn_id); #endif } void KCMShell::setServiceName(const QString &dbusName) { m_serviceName = QLatin1String( "org.kde.kcmshell_" ) + dbusName; QDBusConnection::sessionBus().registerService(m_serviceName); } void KCMShell::waitForExit() { QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this); watcher->setConnection(QDBusConnection::sessionBus()); watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange); watcher->addWatchedService(m_serviceName); - connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), - SLOT(appExit(QString,QString,QString))); + connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, + this, &KCMShell::appExit); exec(); } void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName) { Q_UNUSED(appId); Q_UNUSED(newName); if (!oldName.isEmpty()) { qDebug() << "'" << appId << "' closed, quitting."; qApp->quit(); } } extern "C" Q_DECL_EXPORT int kdemain(int _argc, char *_argv[]) { const bool qpaVariable = qEnvironmentVariableIsSet("QT_QPA_PLATFORM"); KWorkSpace::detectPlatform(_argc, _argv); KCMShell app(_argc, _argv); if (!qpaVariable) { // don't leak the env variable to processes we start qunsetenv("QT_QPA_PLATFORM"); } KLocalizedString::setApplicationDomain("kcmshell5"); KQuickAddons::QtQuickSettings::init(); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); KAboutData aboutData(QStringLiteral("kcmshell5"), i18n("System Settings Module"), QLatin1String(PROJECT_VERSION), i18n("A tool to start single system settings modules"), KAboutLicense::GPL, i18n("(c) 1999-2016, The KDE Developers")); aboutData.addAuthor(i18n("Frans Englich"), i18n("Maintainer"), QStringLiteral("frans.englich@kde.org")); aboutData.addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org")); aboutData.addAuthor(i18n("Matthias Hoelzer-Kluepfel"),QString(), QStringLiteral("hoelzer@kde.org")); aboutData.addAuthor(i18n("Matthias Elter"),QString(), QStringLiteral("elter@kde.org")); aboutData.addAuthor(i18n("Matthias Ettrich"),QString(), QStringLiteral("ettrich@kde.org")); aboutData.addAuthor(i18n("Waldo Bastian"),QString(), QStringLiteral("bastian@kde.org")); KAboutData::setApplicationData(aboutData); QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.addOption(QCommandLineOption(QStringLiteral("list"), i18n("List all possible modules"))); parser.addPositionalArgument(QStringLiteral("module"), i18n("Configuration module to open")); parser.addOption(QCommandLineOption(QStringLiteral("lang"), i18n("Specify a particular language"), QLatin1String("language"))); parser.addOption(QCommandLineOption(QStringLiteral("silent"), i18n("Do not display main window"))); parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the module"), QLatin1String("arguments"))); parser.addOption(QCommandLineOption(QStringLiteral("icon"), i18n("Use a specific icon for the window"), QLatin1String("icon"))); parser.addOption(QCommandLineOption(QStringLiteral("caption"), i18n("Use a specific caption for the window"), QLatin1String("caption"))); parser.parse(app.arguments()); aboutData.processCommandLine(&parser); parser.process(app); const QString lang = parser.value(QStringLiteral("lang")); if (!lang.isEmpty()) { cout << i18n("--lang is deprecated. Please set the LANGUAGE environment variable instead").toLocal8Bit().data() << endl; } if (parser.isSet(QStringLiteral("list"))) { cout << i18n("The following modules are available:").toLocal8Bit().data() << endl; listModules(); int maxLen=0; for (KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it) { int len = (*it)->desktopEntryName().length(); if (len > maxLen) maxLen = len; } for (KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it) { QString entry(QStringLiteral("%1 - %2")); entry = entry.arg((*it)->desktopEntryName().leftJustified(maxLen, QLatin1Char(' '))) .arg(!(*it)->comment().isEmpty() ? (*it)->comment() : i18n("No description available")); cout << entry.toLocal8Bit().data() << endl; } return 0; } if (parser.positionalArguments().count() < 1) { parser.showHelp(); return -1; } QString serviceName; KService::List modules; for (int i = 0; i < parser.positionalArguments().count(); i++) { const QString arg = parser.positionalArguments().at(i); KService::Ptr service = locateModule(arg); if (!service) { service = locateModule(QStringLiteral("kcm_") + arg); } if (!service) { service = locateModule(QStringLiteral("kcm") + arg); } if (service) { modules.append(service); if (!serviceName.isEmpty()) { serviceName += QLatin1Char('_'); } serviceName += arg; } else { cerr << i18n("Could not find module '%1'. See kcmshell5 --list for the full list of modules.", arg).toLocal8Bit().constData() << endl; } } /* Check if this particular module combination is already running */ app.setServiceName(serviceName); if (app.isRunning()) { app.waitForExit(); return 0; } KPageDialog::FaceType ftype = KPageDialog::Plain; if (modules.count() < 1) { return -1; } else if (modules.count() > 1) { ftype = KPageDialog::List; } QStringList moduleArgs; const QString x = parser.value(QStringLiteral("args")); moduleArgs << x.split(QRegExp(QStringLiteral(" +"))); KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype); dlg->setAttribute(Qt::WA_DeleteOnClose); if (parser.isSet(QStringLiteral("caption"))) { dlg->setWindowTitle(parser.value(QStringLiteral("caption"))); } else if (modules.count() == 1) { dlg->setWindowTitle(modules.first()->name()); } for (KService::List::ConstIterator it = modules.constBegin(); it != modules.constEnd(); ++it) { dlg->addModule(*it, nullptr, moduleArgs); } if (parser.isSet(QStringLiteral("icon"))) { dlg->setWindowIcon(QIcon::fromTheme(parser.value(QStringLiteral("icon")))); } else if (!parser.isSet(QStringLiteral("icon")) && !modules.isEmpty()) { const QString iconName = KCModuleInfo(modules.first()).icon(); dlg->setWindowIcon( QIcon::fromTheme(iconName) ); } if (modules.count() == 1 && app.desktopFileName() == QLatin1String("org.kde.kcmshell5")) { const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kservices5/%1.desktop").arg(modules.first()->desktopEntryName())); if (!path.isEmpty()) { app.setDesktopFileName(path); } } dlg->show(); app.exec(); return 0; } // vim: sw=4 et sts=4 diff --git a/kdesu/sudlg.cpp b/kdesu/sudlg.cpp index a0c7c5b..a2cfc3c 100644 --- a/kdesu/sudlg.cpp +++ b/kdesu/sudlg.cpp @@ -1,110 +1,110 @@ /* vi: ts=8 sts=4 sw=4 * * This file is part of the KDE project, module kdesu. * Copyright (C) 2000 Geert Jansen */ #include "sudlg.h" #include #include #include #include KDEsuDialog::KDEsuDialog(QByteArray user, QByteArray authUser, bool enableKeep, const QString& icon, bool withIgnoreButton) : KPasswordDialog(nullptr, enableKeep ? ShowKeepPassword : NoFlags) { if ( !icon.isEmpty() ) { setPixmap(QIcon::fromTheme(icon).pixmap(style()->pixelMetric(QStyle::PM_LargeIconSize))); } if ( withIgnoreButton ) { buttonBox()->addButton(QDialogButtonBox::Ignore); } QString superUserCommand = proc.superUserCommand(); proc.setUser(authUser); setWindowTitle(i18n("Run as %1", QString::fromLatin1(user))); QString prompt; if (proc.useUsersOwnPassword()) { prompt = i18n("Please enter your password below." ); } else { if (authUser == "root") { if(withIgnoreButton) prompt = QStringLiteral("") + i18n("The action you requested needs root privileges. " "Please enter root's password below or click " "Ignore to continue with your current privileges.") + QStringLiteral(""); else prompt = QStringLiteral("") + i18n("The action you requested needs root privileges. " "Please enter root's password below.") + QStringLiteral(""); } else { if(withIgnoreButton) prompt = QStringLiteral("") + i18n("The action you requested needs additional privileges. " "Please enter the password for %1 below or click " "Ignore to continue with your current privileges.", QString::fromLatin1(authUser)) + QStringLiteral(""); else prompt = QStringLiteral("") + i18n("The action you requested needs additional privileges. " "Please enter the password for %1 below.", QString::fromLatin1(authUser)) + QStringLiteral(""); } } setPrompt(prompt); if( withIgnoreButton ) { - connect(buttonBox()->button(QDialogButtonBox::Ignore), SIGNAL(clicked()), SLOT(slotUser1())); + connect(buttonBox()->button(QDialogButtonBox::Ignore), &QAbstractButton::clicked, this, &KDEsuDialog::slotUser1); } } KDEsuDialog::~KDEsuDialog() { } bool KDEsuDialog::checkPassword() { int status = proc.checkInstall(password().toLocal8Bit().constData()); switch (status) { case -1: showErrorMessage(i18n("Conversation with su failed."), UsernameError); return false; case 0: return true; case SuProcess::SuNotFound: showErrorMessage(i18n("The program 'su' could not be found.
" "Ensure your PATH is set correctly."), FatalError); return false; case SuProcess::SuNotAllowed: // This is actually never returned, as kdesu cannot tell the difference. showErrorMessage(QLatin1String("The impossible happened."), FatalError); return false; case SuProcess::SuIncorrectPassword: showErrorMessage(i18n("Permission denied.
" "Possibly incorrect password, please try again.
" "On some systems, you need to be in a special " "group (often: wheel) to use this program."), PasswordError); return false; default: showErrorMessage(i18n("Internal error: illegal return from " "SuProcess::checkInstall()"), FatalError); done(Rejected); return false; } } void KDEsuDialog::slotUser1() { done(AsUser); } diff --git a/keditfiletype/filetypedetails.cpp b/keditfiletype/filetypedetails.cpp index 547b4dc..4fda622 100644 --- a/keditfiletype/filetypedetails.cpp +++ b/keditfiletype/filetypedetails.cpp @@ -1,366 +1,366 @@ /* This file is part of the KDE project Copyright (C) 2000, 2007 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or at your option version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "filetypedetails.h" // Qt #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include #include // Local #include "kservicelistwidget.h" #include "typeslistitem.h" FileTypeDetails::FileTypeDetails( QWidget * parent ) : QWidget( parent ), m_mimeTypeData(nullptr), m_item(nullptr) { QVBoxLayout* topLayout = new QVBoxLayout(this); topLayout->setContentsMargins(0, 0, 0, 0); m_mimeTypeLabel = new QLabel(this); m_mimeTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); topLayout->addWidget(m_mimeTypeLabel, 0, Qt::AlignCenter); m_tabWidget = new QTabWidget(this); topLayout->addWidget(m_tabWidget); QString wtstr; // First tab - General QWidget * firstWidget = new QWidget(m_tabWidget); QVBoxLayout *firstLayout = new QVBoxLayout(firstWidget); QHBoxLayout *hBox = new QHBoxLayout(); firstLayout->addLayout(hBox); iconButton = new KIconButton(firstWidget); iconButton->setIconType(KIconLoader::Desktop, KIconLoader::MimeType); - connect(iconButton, SIGNAL(iconChanged(QString)), SLOT(updateIcon(QString))); + connect(iconButton, &KIconButton::iconChanged, this, &FileTypeDetails::updateIcon); iconButton->setWhatsThis( i18n("This button displays the icon associated" " with the selected file type. Click on it to choose a different icon.") ); iconButton->setFixedSize(70, 70); iconLabel = nullptr; hBox->addWidget(iconButton); QGroupBox *gb = new QGroupBox(i18n("Filename Patterns"), firstWidget); hBox->addWidget(gb); hBox = new QHBoxLayout(gb); extensionLB = new QListWidget(gb); - connect(extensionLB, SIGNAL(itemSelectionChanged()), SLOT(enableExtButtons())); + connect(extensionLB, &QListWidget::itemSelectionChanged, this, &FileTypeDetails::enableExtButtons); hBox->addWidget(extensionLB); extensionLB->setFixedHeight(extensionLB->minimumSizeHint().height()); extensionLB->setWhatsThis( i18n("This box contains a list of patterns that can be" " used to identify files of the selected type. For example, the pattern *.txt is" " associated with the file type 'text/plain'; all files ending in '.txt' are recognized" " as plain text files.") ); QVBoxLayout *vbox = new QVBoxLayout(); hBox->addLayout(vbox); addExtButton = new QPushButton(i18n("Add..."), gb); addExtButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); addExtButton->setEnabled(false); - connect(addExtButton, SIGNAL(clicked()), - this, SLOT(addExtension())); + connect(addExtButton, &QAbstractButton::clicked, + this, &FileTypeDetails::addExtension); vbox->addWidget(addExtButton); addExtButton->setWhatsThis( i18n("Add a new pattern for the selected file type.") ); removeExtButton = new QPushButton(i18n("Remove"), gb); removeExtButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); removeExtButton->setEnabled(false); - connect(removeExtButton, SIGNAL(clicked()), - this, SLOT(removeExtension())); + connect(removeExtButton, &QAbstractButton::clicked, + this, &FileTypeDetails::removeExtension); vbox->addWidget(removeExtButton); removeExtButton->setWhatsThis( i18n("Remove the selected filename pattern.") ); vbox->addStretch(1); gb->setFixedHeight(gb->minimumSizeHint().height()); description = new KLineEdit(firstWidget); description->setClearButtonEnabled(true); - connect(description, SIGNAL(textChanged(const QString &)), - SLOT(updateDescription(const QString &))); + connect(description, &QLineEdit::textChanged, + this, &FileTypeDetails::updateDescription); QHBoxLayout *descriptionBox = new QHBoxLayout; descriptionBox->addWidget(new QLabel(i18n("Description:"),firstWidget)); descriptionBox->addWidget(description); firstLayout->addLayout(descriptionBox); wtstr = i18n("You can enter a short description for files of the selected" " file type (e.g. 'HTML Page'). This description will be used by applications" " like Konqueror to display directory content."); description->setWhatsThis( wtstr ); serviceListWidget = new KServiceListWidget( KServiceListWidget::SERVICELIST_APPLICATIONS, firstWidget ); - connect( serviceListWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + connect( serviceListWidget, &KServiceListWidget::changed, this, &FileTypeDetails::changed); firstLayout->addWidget(serviceListWidget,5); // Second tab - Embedding QWidget * secondWidget = new QWidget(m_tabWidget); QVBoxLayout *secondLayout = new QVBoxLayout(secondWidget); m_autoEmbedBox = new QGroupBox( i18n("Left Click Action in Konqueror"), secondWidget ); secondLayout->addWidget( m_autoEmbedBox ); m_autoEmbedBox->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ); QRadioButton *embViewerRadio = new QRadioButton( i18n("Show file in embedded viewer") ); QRadioButton *sepViewerRadio = new QRadioButton( i18n("Show file in separate viewer") ); m_rbGroupSettings = new QRadioButton( QStringLiteral("Use settings for '%1' group") ); m_chkAskSave = new QCheckBox( i18n("Ask whether to save to disk instead (only for Konqueror browser)") ); - connect(m_chkAskSave, SIGNAL( toggled(bool) ), SLOT( slotAskSaveToggled(bool) )); + connect(m_chkAskSave, &QAbstractButton::toggled, this, &FileTypeDetails::slotAskSaveToggled); m_autoEmbedGroup = new QButtonGroup(m_autoEmbedBox); m_autoEmbedGroup->addButton(embViewerRadio, 0); m_autoEmbedGroup->addButton(sepViewerRadio, 1); m_autoEmbedGroup->addButton(m_rbGroupSettings, 2); connect(m_autoEmbedGroup, SIGNAL( buttonClicked(int) ), SLOT( slotAutoEmbedClicked(int) )); vbox = new QVBoxLayout(m_autoEmbedBox); vbox->addWidget(embViewerRadio); vbox->addWidget(sepViewerRadio); vbox->addWidget(m_rbGroupSettings); vbox->addWidget(m_chkAskSave); m_autoEmbedBox->setWhatsThis( i18n("Here you can configure what the Konqueror file manager" " will do when you click on a file of this type. Konqueror can either display the file in" " an embedded viewer, or start up a separate application. If set to 'Use settings for G group'," " the file manager will behave according to the settings of the group G to which this type belongs;" " for instance, 'image' if the current file type is image/png. Dolphin" " always shows files in a separate viewer.") ); embedServiceListWidget = new KServiceListWidget( KServiceListWidget::SERVICELIST_SERVICES, secondWidget ); // embedServiceListWidget->setMinimumHeight( serviceListWidget->sizeHint().height() ); - connect( embedServiceListWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); + connect( embedServiceListWidget, &KServiceListWidget::changed, this, &FileTypeDetails::changed); secondLayout->addWidget(embedServiceListWidget); m_tabWidget->addTab( firstWidget, i18n("&General") ); m_tabWidget->addTab( secondWidget, i18n("&Embedding") ); } void FileTypeDetails::updateRemoveButton() { removeExtButton->setEnabled(extensionLB->count()>0); } void FileTypeDetails::updateIcon(const QString &icon) { if (!m_mimeTypeData) return; m_mimeTypeData->setUserSpecifiedIcon(icon); if (m_item) m_item->setIcon(icon); emit changed(true); } void FileTypeDetails::updateDescription(const QString &desc) { if (!m_mimeTypeData) return; m_mimeTypeData->setComment(desc); emit changed(true); } void FileTypeDetails::addExtension() { if ( !m_mimeTypeData ) return; bool ok; QString ext = QInputDialog::getText(this, i18n( "Add New Extension" ), i18n( "Extension:" ), QLineEdit::Normal, QStringLiteral("*."), &ok); if (ok) { extensionLB->addItem(ext); QStringList patt = m_mimeTypeData->patterns(); patt += ext; m_mimeTypeData->setPatterns(patt); updateRemoveButton(); emit changed(true); } } void FileTypeDetails::removeExtension() { if (extensionLB->currentRow() == -1) return; if ( !m_mimeTypeData ) return; QStringList patt = m_mimeTypeData->patterns(); patt.removeAll(extensionLB->currentItem()->text()); m_mimeTypeData->setPatterns(patt); delete extensionLB->takeItem(extensionLB->currentRow()); updateRemoveButton(); emit changed(true); } void FileTypeDetails::slotAutoEmbedClicked( int button ) { if ( !m_mimeTypeData || (button > 2)) return; m_mimeTypeData->setAutoEmbed( (MimeTypeData::AutoEmbed) button ); updateAskSave(); emit changed(true); } void FileTypeDetails::updateAskSave() { if ( !m_mimeTypeData ) return; QMimeDatabase db; MimeTypeData::AutoEmbed autoEmbed = m_mimeTypeData->autoEmbed(); if (m_mimeTypeData->isMeta() && autoEmbed == MimeTypeData::UseGroupSetting) { // Resolve by looking at group (we could cache groups somewhere to avoid the re-parsing?) autoEmbed = MimeTypeData(m_mimeTypeData->majorType()).autoEmbed(); } const QString mimeType = m_mimeTypeData->name(); QString dontAskAgainName; if (autoEmbed == MimeTypeData::Yes) // Embedded dontAskAgainName = QStringLiteral("askEmbedOrSave")+mimeType; else dontAskAgainName = QStringLiteral("askSave")+mimeType; KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals); // default value bool ask = config->group("Notification Messages").readEntry(dontAskAgainName, QString()).isEmpty(); // per-mimetype override if there's one m_mimeTypeData->getAskSave(ask); bool neverAsk = false; if (autoEmbed == MimeTypeData::Yes) { const QMimeType mime = db.mimeTypeForName( mimeType ); if (mime.isValid()) { // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC // NOTE: Keep this function in sync with // kparts/src/browseropenorsavequestion.cpp BrowserOpenOrSaveQuestionPrivate::autoEmbedMimeType // Don't ask for: // - html (even new tabs would ask, due to about:blank!) // - dirs obviously (though not common over HTTP :), // - images (reasoning: no need to save, most of the time, because fast to see) // e.g. postscript is different, because takes longer to read, so // it's more likely that the user might want to save it. // - multipart/* ("server push", see kmultipart) if (mime.inherits(QStringLiteral("text/html")) || mime.inherits(QStringLiteral("application/xml")) || mime.inherits(QStringLiteral("inode/directory")) || mimeType.startsWith(QLatin1String("image")) || mime.inherits(QStringLiteral("multipart/x-mixed-replace")) || mime.inherits(QStringLiteral("multipart/replace"))) { neverAsk = true; } } } m_chkAskSave->blockSignals(true); m_chkAskSave->setChecked(ask && !neverAsk); m_chkAskSave->setEnabled(!neverAsk); m_chkAskSave->blockSignals(false); } void FileTypeDetails::slotAskSaveToggled(bool askSave) { if (!m_mimeTypeData) return; m_mimeTypeData->setAskSave(askSave); emit changed(true); } void FileTypeDetails::setMimeTypeData( MimeTypeData * mimeTypeData, TypesListItem* item ) { m_mimeTypeData = mimeTypeData; m_item = item; // can be 0 Q_ASSERT(mimeTypeData); m_mimeTypeLabel->setText(i18n("File type %1", mimeTypeData->name())); if (iconButton) { iconButton->setIcon(mimeTypeData->icon()); iconButton->setToolTip(mimeTypeData->icon()); } else iconLabel->setPixmap(DesktopIcon(mimeTypeData->icon())); description->setText(mimeTypeData->comment()); m_rbGroupSettings->setText( i18n("Use settings for '%1' group", mimeTypeData->majorType() ) ); extensionLB->clear(); addExtButton->setEnabled(true); removeExtButton->setEnabled(false); serviceListWidget->setMimeTypeData( mimeTypeData ); embedServiceListWidget->setMimeTypeData( mimeTypeData ); m_autoEmbedGroup->button(mimeTypeData->autoEmbed())->setChecked(true); m_rbGroupSettings->setEnabled( mimeTypeData->canUseGroupSetting() ); extensionLB->addItems(mimeTypeData->patterns()); updateAskSave(); } void FileTypeDetails::enableExtButtons() { removeExtButton->setEnabled(true); } void FileTypeDetails::refresh() { if (!m_mimeTypeData) return; // Called when ksycoca has been updated -> refresh data, then widgets m_mimeTypeData->refresh(); setMimeTypeData(m_mimeTypeData, m_item); } diff --git a/keditfiletype/filetypesview.cpp b/keditfiletype/filetypesview.cpp index bce4559..1690e5b 100644 --- a/keditfiletype/filetypesview.cpp +++ b/keditfiletype/filetypesview.cpp @@ -1,495 +1,495 @@ /* This file is part of the KDE project Copyright (C) 2000 - 2008 David Faure Copyright (C) 2008 Urs Wolfer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "filetypesview.h" #include "mimetypewriter.h" // Qt #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include // Local #include "newtypedlg.h" #include "filetypedetails.h" #include "filegroupdetails.h" K_PLUGIN_FACTORY(FileTypesViewFactory, registerPlugin();) FileTypesView::FileTypesView(QWidget *parent, const QVariantList &) : KCModule(parent) { m_fileTypesConfig = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals); setQuickHelp( i18n("

File Associations

" " This module allows you to choose which applications are associated" " with a given type of file. File types are also referred to as MIME types" " (MIME is an acronym which stands for \"Multipurpose Internet Mail" " Extensions\").

A file association consists of the following:" "

  • Rules for determining the MIME-type of a file, for example" " the filename pattern *.png, which means 'all files with names that end" " in .png', is associated with the MIME type \"image/png\";
  • " "
  • A short description of the MIME-type, for example the description" " of the MIME type \"image/png\" is simply 'PNG image';
  • " "
  • An icon to be used for displaying files of the given MIME-type," " so that you can easily identify the type of file in a file" " manager or file-selection dialog (at least for the types you use often);
  • " "
  • A list of the applications which can be used to open files of the" " given MIME-type -- if more than one application can be used then the" " list is ordered by priority.
" " You may be surprised to find that some MIME types have no associated" " filename patterns; in these cases, KDE is able to determine the" " MIME-type by directly examining the contents of the file.

")); setButtons(Help | Apply); QString wtstr; QHBoxLayout* l = new QHBoxLayout(this); QVBoxLayout* leftLayout = new QVBoxLayout(); l->addLayout( leftLayout ); patternFilterLE = new KLineEdit(this); patternFilterLE->setClearButtonEnabled(true); patternFilterLE->setTrapReturnKey(true); patternFilterLE->setPlaceholderText(i18n("Search for file type or filename pattern...")); leftLayout->addWidget(patternFilterLE); - connect(patternFilterLE, SIGNAL(textChanged(const QString &)), - this, SLOT(slotFilter(const QString &))); + connect(patternFilterLE, &QLineEdit::textChanged, + this, &FileTypesView::slotFilter); wtstr = i18n("Enter a part of a filename pattern, and only file types with a " "matching file pattern will appear in the list. Alternatively, enter " "a part of a file type name as it appears in the list."); patternFilterLE->setWhatsThis( wtstr ); typesLV = new TypesListTreeWidget(this); typesLV->setHeaderLabel(i18n("Known Types")); leftLayout->addWidget(typesLV); - connect(typesLV, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), - this, SLOT(updateDisplay(QTreeWidgetItem *))); - connect(typesLV, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), - this, SLOT(slotDoubleClicked(QTreeWidgetItem *))); + connect(typesLV, &QTreeWidget::currentItemChanged, + this, &FileTypesView::updateDisplay); + connect(typesLV, &QTreeWidget::itemDoubleClicked, + this, &FileTypesView::slotDoubleClicked); typesLV->setWhatsThis( i18n("Here you can see a hierarchical list of" " the file types which are known on your system. Click on the '+' sign" " to expand a category, or the '-' sign to collapse it. Select a file type" " (e.g. text/html for HTML files) to view/edit the information for that" " file type using the controls on the right.") ); QHBoxLayout* btnsLay = new QHBoxLayout(); leftLayout->addLayout(btnsLay); btnsLay->addStretch(1); QPushButton *addTypeB = new QPushButton(i18n("Add..."), this); addTypeB->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); - connect(addTypeB, SIGNAL(clicked()), SLOT(addType())); + connect(addTypeB, &QAbstractButton::clicked, this, &FileTypesView::addType); btnsLay->addWidget(addTypeB); addTypeB->setWhatsThis( i18n("Click here to add a new file type.") ); m_removeTypeB = new QPushButton(i18n("&Remove"), this); m_removeTypeB->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); - connect(m_removeTypeB, SIGNAL(clicked()), SLOT(removeType())); + connect(m_removeTypeB, &QAbstractButton::clicked, this, &FileTypesView::removeType); btnsLay->addWidget(m_removeTypeB); m_removeTypeB->setEnabled(false); m_removeButtonSaysRevert = false; // For the right panel, prepare a widget stack m_widgetStack = new QStackedWidget(this); l->addWidget( m_widgetStack ); // File Type Details m_details = new FileTypeDetails( m_widgetStack ); - connect( m_details, SIGNAL( changed(bool) ), - this, SLOT( setDirty(bool) ) ); - connect( m_details, SIGNAL( embedMajor(const QString &, bool &) ), - this, SLOT( slotEmbedMajor(const QString &, bool &))); + connect( m_details, &FileTypeDetails::changed, + this, &FileTypesView::setDirty ); + connect( m_details, &FileTypeDetails::embedMajor, + this, &FileTypesView::slotEmbedMajor); m_widgetStack->insertWidget( 1, m_details /*id*/ ); // File Group Details m_groupDetails = new FileGroupDetails( m_widgetStack ); - connect( m_groupDetails, SIGNAL( changed(bool) ), - this, SLOT( setDirty(bool) ) ); + connect( m_groupDetails, &FileGroupDetails::changed, + this, &FileTypesView::setDirty ); m_widgetStack->insertWidget( 2,m_groupDetails /*id*/ ); // Widget shown on startup m_emptyWidget = new QLabel( i18n("Select a file type by name or by extension"), m_widgetStack); m_emptyWidget->setAlignment( Qt::AlignCenter ); m_widgetStack->insertWidget( 3,m_emptyWidget ); m_widgetStack->setCurrentWidget( m_emptyWidget ); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), SLOT(slotDatabaseChanged(QStringList))); } FileTypesView::~FileTypesView() { } void FileTypesView::setDirty(bool state) { emit changed(state); m_dirty = state; } // To order the mimetype list static bool mimeTypeLessThan(const QMimeType& m1, const QMimeType& m2) { return m1.name() < m2.name(); } // Note that this method loses any newly-added (and not saved yet) mimetypes. // So this is really only for load(). void FileTypesView::readFileTypes() { typesLV->clear(); m_majorMap.clear(); m_itemList.clear(); QMimeDatabase db; QList mimetypes = db.allMimeTypes(); std::sort(mimetypes.begin(), mimetypes.end(), mimeTypeLessThan); auto it2(mimetypes.constBegin()); for (; it2 != mimetypes.constEnd(); ++it2) { const QString mimetype = (*it2).name(); const int index = mimetype.indexOf(QLatin1Char('/')); const QString maj = mimetype.left(index); const QString min = mimetype.right(mimetype.length() - index+1); TypesListItem* groupItem = m_majorMap.value(maj); if ( !groupItem ) { groupItem = new TypesListItem(typesLV, maj); m_majorMap.insert(maj, groupItem); } TypesListItem *item = new TypesListItem(groupItem, (*it2)); m_itemList.append( item ); } updateDisplay(nullptr); } void FileTypesView::slotEmbedMajor(const QString &major, bool &embed) { TypesListItem *groupItem = m_majorMap.value(major); if (!groupItem) return; embed = (groupItem->mimeTypeData().autoEmbed() == MimeTypeData::Yes); } void FileTypesView::slotFilter(const QString & patternFilter) { for (int i = 0; i < typesLV->topLevelItemCount(); ++i) { typesLV->topLevelItem(i)->setHidden(true); } // insert all items and their group that match the filter Q_FOREACH(TypesListItem* it, m_itemList) { const MimeTypeData& mimeTypeData = it->mimeTypeData(); if ( patternFilter.isEmpty() || mimeTypeData.matchesFilter(patternFilter) ) { TypesListItem *group = m_majorMap.value( mimeTypeData.majorType() ); Q_ASSERT(group); if (group) { group->setHidden(false); it->setHidden(false); } } else { it->setHidden(true); } } } void FileTypesView::addType() { const QStringList allGroups = m_majorMap.keys(); NewTypeDialog dialog(allGroups, this); if (dialog.exec()) { const QString newMimeType = dialog.group() + QLatin1Char('/') + dialog.text(); QTreeWidgetItemIterator it(typesLV); TypesListItem *group = m_majorMap.value(dialog.group()); if ( !group ) { group = new TypesListItem(typesLV, dialog.group()); m_majorMap.insert(dialog.group(), group); } // find out if our group has been filtered out -> insert if necessary QTreeWidgetItem *item = typesLV->topLevelItem(0); bool insert = true; while ( item ) { if ( item == group ) { insert = false; break; } item = typesLV->itemBelow(item); } if ( insert ) typesLV->addTopLevelItem( group ); TypesListItem *tli = new TypesListItem(group, newMimeType); m_itemList.append( tli ); group->setExpanded(true); tli->setSelected(true); setDirty(true); } } void FileTypesView::removeType() { TypesListItem *current = static_cast(typesLV->currentItem()); if (!current) { return; } const MimeTypeData& mimeTypeData = current->mimeTypeData(); // Can't delete groups nor essential mimetypes (but the button should be // disabled already in these cases, so this is just extra safety). if (mimeTypeData.isMeta() || mimeTypeData.isEssential()) { return; } if (!mimeTypeData.isNew()) { removedList.append(mimeTypeData.name()); } if (m_removeButtonSaysRevert) { // Nothing else to do for now, until saving updateDisplay(current); } else { QTreeWidgetItem *li = typesLV->itemAbove(current); if (!li) li = typesLV->itemBelow(current); if (!li) li = current->parent(); current->parent()->takeChild(current->parent()->indexOfChild(current)); m_itemList.removeAll(current); if (li) { li->setSelected(true); } } setDirty(true); } void FileTypesView::slotDoubleClicked(QTreeWidgetItem *item) { if ( !item ) return; item->setExpanded( !item->isExpanded() ); } void FileTypesView::updateDisplay(QTreeWidgetItem *item) { TypesListItem *tlitem = static_cast(item); updateRemoveButton(tlitem); if (!item) { m_widgetStack->setCurrentWidget(m_emptyWidget); return; } const bool wasDirty = m_dirty; MimeTypeData& mimeTypeData = tlitem->mimeTypeData(); if (mimeTypeData.isMeta()) { // is a group m_widgetStack->setCurrentWidget(m_groupDetails); m_groupDetails->setMimeTypeData(&mimeTypeData); } else { m_widgetStack->setCurrentWidget(m_details); m_details->setMimeTypeData(&mimeTypeData); } // Updating the display indirectly called change(true) if (!wasDirty) { setDirty(false); } } void FileTypesView::updateRemoveButton(TypesListItem* tlitem) { bool canRemove = false; m_removeButtonSaysRevert = false; if (tlitem) { const MimeTypeData& mimeTypeData = tlitem->mimeTypeData(); if (!mimeTypeData.isMeta() && !mimeTypeData.isEssential()) { if (mimeTypeData.isNew()) { canRemove = true; } else { // We can only remove mimetypes that we defined ourselves, not those from freedesktop.org const QString mimeType = mimeTypeData.name(); qDebug() << mimeType << "hasDefinitionFile:" << MimeTypeWriter::hasDefinitionFile(mimeType); if (MimeTypeWriter::hasDefinitionFile(mimeType)) { canRemove = true; // Is there a global definition for it? const QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + mimeType + QStringLiteral(".xml") ); qDebug() << mimeFiles; if (mimeFiles.count() >= 2 /*a local and a global*/) { m_removeButtonSaysRevert = true; qDebug() << removedList; if (removedList.contains(mimeType)) { canRemove = false; // already on the "to be reverted" list, user needs to save now } } } } } } if (m_removeButtonSaysRevert) { m_removeTypeB->setText(i18n("&Revert")); m_removeTypeB->setToolTip(i18n("Revert this file type to its initial system-wide definition")); m_removeTypeB->setWhatsThis(i18n("Click here to revert this file type to its initial system-wide definition, which undoes any changes made to the file type. Note that system-wide file types cannot be deleted. You can however empty their pattern list, to minimize the chances of them being used (but the file type determination from file contents can still end up using them).")); } else { m_removeTypeB->setText(i18n("&Remove")); m_removeTypeB->setToolTip(i18n("Delete this file type definition completely")); m_removeTypeB->setWhatsThis(i18n("Click here to delete this file type definition completely. This is only possible for user-defined file types. System-wide file types cannot be deleted. You can however empty their pattern list, to minimize the chances of them being used (but the file type determination from file contents can still end up using them).")); } m_removeTypeB->setEnabled(canRemove); } void FileTypesView::save() { bool needUpdateMimeDb = false; bool needUpdateSycoca = false; bool didIt = false; // first, remove those items which we are asked to remove. Q_FOREACH(const QString& mime, removedList) { MimeTypeWriter::removeOwnMimeType(mime); didIt = true; needUpdateMimeDb = true; needUpdateSycoca = true; // remove offers for this mimetype } removedList.clear(); // now go through all entries and sync those which are dirty. // don't use typesLV, it may be filtered QMap::iterator it1 = m_majorMap.begin(); while ( it1 != m_majorMap.end() ) { TypesListItem *tli = *it1; if (tli->mimeTypeData().isDirty()) { qDebug() << "Entry " << tli->name() << " is dirty. Saving."; if (tli->mimeTypeData().sync()) needUpdateMimeDb = true; didIt = true; } ++it1; } Q_FOREACH(TypesListItem* tli, m_itemList) { if (tli->mimeTypeData().isDirty()) { if (tli->mimeTypeData().isServiceListDirty()) needUpdateSycoca = true; qDebug() << "Entry " << tli->name() << " is dirty. Saving."; if (tli->mimeTypeData().sync()) needUpdateMimeDb = true; didIt = true; } } m_fileTypesConfig->sync(); setDirty(false); if (needUpdateMimeDb) { MimeTypeWriter::runUpdateMimeDatabase(); } if (needUpdateSycoca) { KBuildSycocaProgressDialog::rebuildKSycoca(this); } if (didIt) { // TODO make more specific: only if autoEmbed changed? Well, maybe this is useful for icon and glob changes too... // Trigger reparseConfiguration of filetypesrc in konqueror // TODO: the same for dolphin. Or we should probably define a global signal for this. // Or a KGlobalSettings thing. QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); } updateDisplay(typesLV->currentItem()); } void FileTypesView::load() { setEnabled(false); setCursor( Qt::WaitCursor ); readFileTypes(); unsetCursor(); setDirty(false); setEnabled(true); } void FileTypesView::slotDatabaseChanged(const QStringList& changedResources) { qDebug() << changedResources; if ( changedResources.contains(QStringLiteral("xdgdata-mime")) // changes in mimetype definitions || changedResources.contains(QStringLiteral("services")) ) { // changes in .desktop files m_details->refresh(); // ksycoca has new KMimeTypes objects for us, make sure to update // our 'copies' to be in sync with it. Not important for OK, but // important for Apply (how to differentiate those 2?). // See BR 35071. Q_FOREACH(TypesListItem* tli, m_itemList) { tli->mimeTypeData().refresh(); } } } void FileTypesView::defaults() { } #include "filetypesview.moc" diff --git a/keditfiletype/keditfiletype.cpp b/keditfiletype/keditfiletype.cpp index 5b2b77e..c8e2dd5 100644 --- a/keditfiletype/keditfiletype.cpp +++ b/keditfiletype/keditfiletype.cpp @@ -1,212 +1,212 @@ /* This file is part of the KDE project Copyright (C) 2000, 2007 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or at your option version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "keditfiletype.h" #include "mimetypewriter.h" // Qt #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include // Local #include "filetypedetails.h" #include "typeslistitem.h" FileTypeDialog::FileTypeDialog( MimeTypeData* mime ) : QDialog( nullptr ), m_mimeTypeData(mime) { init(); } FileTypeDialog::~FileTypeDialog() { delete m_details; } void FileTypeDialog::init() { m_details = new FileTypeDetails( this ); m_details->setMimeTypeData( m_mimeTypeData ); - connect(m_details, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool))); + connect(m_details, &FileTypeDetails::changed, this, &FileTypeDialog::clientChanged); m_buttonBox = new QDialogButtonBox; m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel); connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept())); - connect(m_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(save())); - connect(m_buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(m_buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &FileTypeDialog::save); + connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); // This code is very similar to kcdialog.cpp QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(m_details); layout->addWidget(m_buttonBox); // TODO setHelp() setApplyButtonEnabled(false); connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), SLOT(slotDatabaseChanged(QStringList))); } void FileTypeDialog::setApplyButtonEnabled(bool enabled) { m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(enabled); } void FileTypeDialog::save() { if (m_mimeTypeData->isDirty()) { const bool servicesDirty = m_mimeTypeData->isServiceListDirty(); if (m_mimeTypeData->sync()) MimeTypeWriter::runUpdateMimeDatabase(); if (servicesDirty) KBuildSycocaProgressDialog::rebuildKSycoca(this); // Trigger reparseConfiguration of filetypesrc in konqueror QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); } } void FileTypeDialog::accept() { save(); QDialog::accept(); } void FileTypeDialog::clientChanged(bool state) { m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(state); m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(state); } void FileTypeDialog::slotDatabaseChanged(const QStringList& changedResources) { qDebug() << changedResources; if ( changedResources.contains(QStringLiteral("xdgdata-mime")) // changes in mimetype definitions || changedResources.contains(QStringLiteral("services")) ) { // changes in .desktop files m_details->refresh(); } } int main(int argc, char ** argv) { QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-filetype-association"))); KAboutData aboutData( QStringLiteral("keditfiletype"), i18n("File Type Editor"), QLatin1String(PROJECT_VERSION), i18n("KDE file type editor - simplified version for editing a single file type"), KAboutLicense::GPL, i18n("(c) 2000, KDE developers") ); aboutData.addAuthor(i18n("Preston Brown"), QString(), QStringLiteral("pbrown@kde.org")); aboutData.addAuthor(i18n("David Faure"), QString(), QStringLiteral("faure@kde.org")); KAboutData::setApplicationData(aboutData); QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("parent"), i18n("Makes the dialog transient for the window specified by winid"), QStringLiteral("winid"))); parser.addPositionalArgument(QStringLiteral("mimetype"), i18n("File type to edit (e.g. text/html)")); parser.process(app); aboutData.processCommandLine(&parser); if (parser.positionalArguments().count() == 0) parser.showHelp(); QMimeDatabase db; QString arg = parser.positionalArguments().first(); MimeTypeData* mimeTypeData = nullptr; const bool createType = arg.startsWith(QLatin1Char('*')); if ( createType ) { QString mimeString = QStringLiteral("application/x-kdeuser%1"); QString mimeTypeName; int inc = 0; bool ok = false; do { ++inc; mimeTypeName = mimeString.arg(inc); ok = !db.mimeTypeForName(mimeTypeName).isValid(); } while (!ok); QStringList patterns; if ( arg.length() > 2 ) patterns << arg.toLower() << arg.toUpper(); QString comment; if ( arg.startsWith( QLatin1String("*.") ) && arg.length() >= 3 ) { const QString type = arg.mid( 3 ).prepend( arg[2].toUpper() ); comment = i18n( "%1 File", type ); } mimeTypeData = new MimeTypeData(mimeTypeName, true); // new mimetype mimeTypeData->setComment(comment); mimeTypeData->setPatterns(patterns); } else { const QString mimeTypeName = arg; QMimeType mime = db.mimeTypeForName(mimeTypeName); if (!mime.isValid()) { qCritical() << "Mimetype" << mimeTypeName << "not found" ; return 1; } mimeTypeData = new MimeTypeData(mime); } FileTypeDialog dlg( mimeTypeData ); if( parser.isSet( QStringLiteral("parent") )) { bool ok; long id = parser.value(QStringLiteral("parent")).toLong(&ok); if (ok) { dlg.setAttribute(Qt::WA_NativeWindow, true); KWindowSystem::setMainWindow(dlg.windowHandle(), WId(id)); } } if ( !createType ) dlg.setWindowTitle( i18n("Edit File Type %1", mimeTypeData->name()) ); else { dlg.setWindowTitle( i18n("Create New File Type %1", mimeTypeData->name()) ); dlg.setApplyButtonEnabled(true); } dlg.show(); // non-modal return app.exec(); } diff --git a/keditfiletype/kservicelistwidget.cpp b/keditfiletype/kservicelistwidget.cpp index cd2011d..02bf9e4 100644 --- a/keditfiletype/kservicelistwidget.cpp +++ b/keditfiletype/kservicelistwidget.cpp @@ -1,417 +1,417 @@ /* This file is part of the KDE project Copyright (C) 2003 Waldo Bastian Copyright (C) 2003 David Faure Copyright (C) 2002 Daniel Molkentin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "kservicelistwidget.h" // Qt #include #include #include #include #include // KDE #include #include #include #include // Local #include "kserviceselectdlg.h" #include "mimetypedata.h" KServiceListItem::KServiceListItem( const KService::Ptr& pService, int kind ) : QListWidgetItem(), storageId(pService->storageId()), desktopPath(pService->entryPath()) { if ( kind == KServiceListWidget::SERVICELIST_APPLICATIONS ) setText( pService->name() ); else setText( i18n( "%1 (%2)", pService->name(), pService->desktopEntryName() ) ); setIcon( QIcon::fromTheme( pService->icon() ) ); if (!pService->isApplication()) localPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kservices5/") + desktopPath; else localPath = pService->locateLocal(); } KServiceListWidget::KServiceListWidget(int kind, QWidget *parent) : QGroupBox( kind == SERVICELIST_APPLICATIONS ? i18n("Application Preference Order") : i18n("Services Preference Order"), parent ), m_kind( kind ), m_mimeTypeData( nullptr ) { QHBoxLayout *lay= new QHBoxLayout(this); servicesLB = new QListWidget(this); - connect(servicesLB, SIGNAL(itemSelectionChanged()), SLOT(enableMoveButtons())); + connect(servicesLB, &QListWidget::itemSelectionChanged, this, &KServiceListWidget::enableMoveButtons); lay->addWidget(servicesLB); - connect( servicesLB, SIGNAL( itemDoubleClicked(QListWidgetItem*)), this, SLOT( editService())); + connect( servicesLB, &QListWidget::itemDoubleClicked, this, &KServiceListWidget::editService); QString wtstr = (kind == SERVICELIST_APPLICATIONS ? i18n("This is a list of applications associated with files of the selected" " file type. This list is shown in Konqueror's context menus when you select" " \"Open With...\". If more than one application is associated with this file type," " then the list is ordered by priority with the uppermost item taking precedence" " over the others.") : i18n("This is a list of services associated with files of the selected" " file type. This list is shown in Konqueror's context menus when you select" " a \"Preview with...\" option. If more than one service is associated with this file type," " then the list is ordered by priority with the uppermost item taking precedence" " over the others.")); setWhatsThis( wtstr ); servicesLB->setWhatsThis( wtstr ); QVBoxLayout *btnsLay= new QVBoxLayout(); lay->addLayout(btnsLay); servUpButton = new QPushButton(i18n("Move &Up"), this); servUpButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up"))); servUpButton->setEnabled(false); - connect(servUpButton, SIGNAL(clicked()), SLOT(promoteService())); + connect(servUpButton, &QAbstractButton::clicked, this, &KServiceListWidget::promoteService); btnsLay->addWidget(servUpButton); servUpButton->setWhatsThis( kind == SERVICELIST_APPLICATIONS ? i18n("Assigns a higher priority to the selected\n" "application, moving it up in the list. Note: This\n" "only affects the selected application if the file type is\n" "associated with more than one application.") : i18n("Assigns a higher priority to the selected\n" "service, moving it up in the list.")); servDownButton = new QPushButton(i18n("Move &Down"), this); servDownButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down"))); servDownButton->setEnabled(false); - connect(servDownButton, SIGNAL(clicked()), SLOT(demoteService())); + connect(servDownButton, &QAbstractButton::clicked, this, &KServiceListWidget::demoteService); btnsLay->addWidget(servDownButton); servDownButton->setWhatsThis( kind == SERVICELIST_APPLICATIONS ? i18n("Assigns a lower priority to the selected\n" "application, moving it down in the list. Note: This \n" "only affects the selected application if the file type is\n" "associated with more than one application."): i18n("Assigns a lower priority to the selected\n" "service, moving it down in the list.")); servNewButton = new QPushButton(i18n("Add..."), this); servNewButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); servNewButton->setEnabled(false); - connect(servNewButton, SIGNAL(clicked()), SLOT(addService())); + connect(servNewButton, &QAbstractButton::clicked, this, &KServiceListWidget::addService); btnsLay->addWidget(servNewButton); servNewButton->setWhatsThis( i18n( "Add a new application for this file type." ) ); servEditButton = new QPushButton(i18n("Edit..."), this); servEditButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename"))); servEditButton->setEnabled(false); - connect(servEditButton, SIGNAL(clicked()), SLOT(editService())); + connect(servEditButton, &QAbstractButton::clicked, this, &KServiceListWidget::editService); btnsLay->addWidget(servEditButton); servEditButton->setWhatsThis( i18n( "Edit command line of the selected application." ) ); servRemoveButton = new QPushButton(i18n("Remove"), this); servRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); servRemoveButton->setEnabled(false); - connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeService())); + connect(servRemoveButton, &QAbstractButton::clicked, this, &KServiceListWidget::removeService); btnsLay->addWidget(servRemoveButton); servRemoveButton->setWhatsThis( i18n( "Remove the selected application from the list." ) ); btnsLay->addStretch(1); } void KServiceListWidget::setMimeTypeData( MimeTypeData * mimeTypeData ) { m_mimeTypeData = mimeTypeData; if ( servNewButton ) servNewButton->setEnabled(true); // will need a selection servUpButton->setEnabled(false); servDownButton->setEnabled(false); servicesLB->clear(); servicesLB->setEnabled(false); if (m_mimeTypeData) { const QStringList services = ( m_kind == SERVICELIST_APPLICATIONS ) ? m_mimeTypeData->appServices() : m_mimeTypeData->embedServices(); if (services.isEmpty()) { if (m_kind == SERVICELIST_APPLICATIONS) servicesLB->addItem(i18nc("No applications associated with this file type", "None")); else servicesLB->addItem(i18nc("No components associated with this file type", "None")); } else { Q_FOREACH(const QString& service, services) { KService::Ptr pService = KService::serviceByStorageId(service); if (pService) servicesLB->addItem( new KServiceListItem(pService, m_kind) ); } servicesLB->setEnabled(true); } } if (servRemoveButton) servRemoveButton->setEnabled(servicesLB->currentRow() > -1); if (servEditButton) servEditButton->setEnabled(servicesLB->currentRow() > -1); } void KServiceListWidget::promoteService() { if (!servicesLB->isEnabled()) { return; } int selIndex = servicesLB->currentRow(); if (selIndex == 0) { return; } QListWidgetItem *selItem = servicesLB->item(selIndex); servicesLB->takeItem(selIndex); servicesLB->insertItem(selIndex-1,selItem); servicesLB->setCurrentRow(selIndex - 1); updatePreferredServices(); emit changed(true); } void KServiceListWidget::demoteService() { if (!servicesLB->isEnabled()) { return; } int selIndex = servicesLB->currentRow(); if (selIndex == servicesLB->count() - 1) { return; } QListWidgetItem *selItem = servicesLB->item(selIndex); servicesLB->takeItem(selIndex); servicesLB->insertItem(selIndex + 1, selItem); servicesLB->setCurrentRow(selIndex + 1); updatePreferredServices(); emit changed(true); } void KServiceListWidget::addService() { if (!m_mimeTypeData) return; KService::Ptr service; if ( m_kind == SERVICELIST_APPLICATIONS ) { KOpenWithDialog dlg(m_mimeTypeData->name(), QString(), this); dlg.setSaveNewApplications(true); if (dlg.exec() != QDialog::Accepted) return; service = dlg.service(); Q_ASSERT(service); if (!service) return; // Don't crash if KOpenWith wasn't able to create service. } else { KServiceSelectDlg dlg(m_mimeTypeData->name(), QString(), this); if (dlg.exec() != QDialog::Accepted) return; service = dlg.service(); Q_ASSERT(service); if (!service) return; } // Did the list simply show "None"? const bool hadDummyEntry = ( m_kind == SERVICELIST_APPLICATIONS ) ? m_mimeTypeData->appServices().isEmpty() : m_mimeTypeData->embedServices().isEmpty(); if (hadDummyEntry) { delete servicesLB->takeItem(0); // Remove the "None" item. servicesLB->setEnabled(true); } else { // check if it is a duplicate entry for (int index = 0; index < servicesLB->count(); index++) { if (static_cast( servicesLB->item(index) )->desktopPath == service->entryPath()) { // ##### shouldn't we make the existing entry the default one? return; } } } servicesLB->insertItem(0, new KServiceListItem(service, m_kind)); servicesLB->setCurrentItem(nullptr); updatePreferredServices(); emit changed(true); } void KServiceListWidget::editService() { if (!m_mimeTypeData) return; const int selected = servicesLB->currentRow(); if (selected < 0) return; // Only edit applications, not services as // they don't have any parameters if (m_kind != SERVICELIST_APPLICATIONS) return; // Just like popping up an add dialog except that we // pass the current command line as a default KServiceListItem *selItem = (KServiceListItem*)servicesLB->item(selected); const QString desktopPath = selItem->desktopPath; KService::Ptr service = KService::serviceByDesktopPath(desktopPath); if (!service) return; QString path = service->entryPath(); { // If the path to the desktop file is relative, try to get the full // path from QStandardPaths. QString fullPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, path); if (!fullPath.isEmpty()) { path = fullPath; } } KFileItem item(QUrl::fromLocalFile(path), QStringLiteral("application/x-desktop"), KFileItem::Unknown); KPropertiesDialog dlg(item, this); if (dlg.exec() != QDialog::Accepted) return; // Note that at this point, ksycoca has been updated, // and setMimeTypeData has been called again, so all the items have been recreated. // Reload service service = KService::serviceByDesktopPath(desktopPath); if (!service) return; // Remove the old one... delete servicesLB->takeItem(selected); // ...check that it's not a duplicate entry... bool addIt = true; for (int index = 0; index < servicesLB->count(); index++) { if (static_cast(servicesLB->item(index))->desktopPath == service->entryPath()) { addIt = false; break; } } // ...and add it in the same place as the old one: if (addIt) { servicesLB->insertItem(selected, new KServiceListItem(service, m_kind)); servicesLB->setCurrentRow(selected); } updatePreferredServices(); emit changed(true); } void KServiceListWidget::removeService() { if (!m_mimeTypeData) return; int selected = servicesLB->currentRow(); if ( selected >= 0 ) { delete servicesLB->takeItem( selected ); updatePreferredServices(); emit changed(true); } // Update buttons and service list again (e.g. to re-add "None") setMimeTypeData(m_mimeTypeData); } void KServiceListWidget::updatePreferredServices() { if (!m_mimeTypeData) return; QStringList sl; unsigned int count = servicesLB->count(); for (unsigned int i = 0; i < count; i++) { KServiceListItem *sli = (KServiceListItem *) servicesLB->item(i); sl.append( sli->storageId ); } sl.removeDuplicates(); if ( m_kind == SERVICELIST_APPLICATIONS ) m_mimeTypeData->setAppServices(sl); else m_mimeTypeData->setEmbedServices(sl); } void KServiceListWidget::enableMoveButtons() { int idx = servicesLB->currentRow(); if (servicesLB->model()->rowCount() <= 1) { servUpButton->setEnabled(false); servDownButton->setEnabled(false); } else if ( idx == (servicesLB->model()->rowCount() - 1) ) { servUpButton->setEnabled(true); servDownButton->setEnabled(false); } else if (idx == 0) { servUpButton->setEnabled(false); servDownButton->setEnabled(true); } else { servUpButton->setEnabled(true); servDownButton->setEnabled(true); } if ( servRemoveButton ) servRemoveButton->setEnabled(true); if ( servEditButton ) servEditButton->setEnabled( m_kind == SERVICELIST_APPLICATIONS ); } diff --git a/keditfiletype/kserviceselectdlg.cpp b/keditfiletype/kserviceselectdlg.cpp index f00f85c..c086dda 100644 --- a/keditfiletype/kserviceselectdlg.cpp +++ b/keditfiletype/kserviceselectdlg.cpp @@ -1,72 +1,72 @@ /* This file is part of the KDE project Copyright (C) 2000 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "kserviceselectdlg.h" #include "kservicelistwidget.h" #include #include #include #include KServiceSelectDlg::KServiceSelectDlg( const QString& /*serviceType*/, const QString& /*value*/, QWidget *parent ) : QDialog( parent ) { setObjectName( QLatin1String( "serviceSelectDlg" ) ); setModal( true ); setWindowTitle( i18n( "Add Service" ) ); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget( new QLabel( i18n( "Select service:" ) ) ); m_listbox=new QListWidget(); m_buttonBox = new QDialogButtonBox; m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); // Can't make a KTrader query since we don't have a servicetype to give, // we want all services that are not applications....... // So we have to do it the slow way // ### Why can't we query for KParts/ReadOnlyPart as the servicetype? Should work fine! const KService::List allServices = KService::allServices(); KService::List::const_iterator it(allServices.constBegin()); for ( ; it != allServices.constEnd() ; ++it ) if ( (*it)->hasServiceType( QStringLiteral("KParts/ReadOnlyPart") ) ) { m_listbox->addItem( new KServiceListItem( (*it), KServiceListWidget::SERVICELIST_SERVICES ) ); } m_listbox->model()->sort(0); m_listbox->setMinimumHeight(350); m_listbox->setMinimumWidth(400); layout->addWidget( m_listbox ); layout->addWidget( m_buttonBox ); - connect(m_listbox,SIGNAL(itemDoubleClicked(QListWidgetItem*)),SLOT(accept())); - connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept())); - connect(m_buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(m_listbox,&QListWidget::itemDoubleClicked,this, &QDialog::accept); + connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } KServiceSelectDlg::~KServiceSelectDlg() { } KService::Ptr KServiceSelectDlg::service() { int selIndex = m_listbox->currentRow(); KServiceListItem *selItem = static_cast(m_listbox->item(selIndex)); return KService::serviceByDesktopPath( selItem->desktopPath ); } diff --git a/keditfiletype/newtypedlg.cpp b/keditfiletype/newtypedlg.cpp index 4471b87..bc40f50 100644 --- a/keditfiletype/newtypedlg.cpp +++ b/keditfiletype/newtypedlg.cpp @@ -1,90 +1,90 @@ /* This file is part of the KDE project Copyright 2000 Kurt Granroth 2008 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or at your option version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "newtypedlg.h" // Qt #include #include #include #include #include #include #include // KDE #include #include NewTypeDialog::NewTypeDialog(const QStringList &groups, QWidget *parent) : QDialog( parent ) { setModal( true ); setWindowTitle( i18n( "Create New File Type" ) ); QVBoxLayout *mainLayout = new QVBoxLayout(this); QFormLayout *formLayout = new QFormLayout; QLabel *l = new QLabel(i18n("Group:")); m_groupCombo = new QComboBox; m_groupCombo->setEditable(true); m_groupCombo->addItems(groups); m_groupCombo->setCurrentIndex(m_groupCombo->findText(QStringLiteral("application"))); // certainly a better default than "all" formLayout->addRow(l, m_groupCombo); m_groupCombo->setWhatsThis( i18n("Select the category under which" " the new file type should be added.") ); // Line 1: mimetype name l = new QLabel(i18n("Type name:")); m_typeEd = new KLineEdit; formLayout->addRow(l, m_typeEd); m_typeEd->setWhatsThis(i18n("Type the name of the file type. For instance, if you selected 'image' as category and you type 'custom' here, the file type 'image/custom' will be created.")); m_typeEd->setFocus(); m_buttonBox = new QDialogButtonBox; m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); mainLayout->addLayout(formLayout); mainLayout->addWidget(m_buttonBox); - connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept())); - connect(m_buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); // Set a minimum width so that caption is not half-hidden setMinimumWidth(300); } QString NewTypeDialog::group() const { return m_groupCombo->currentText(); } QString NewTypeDialog::text() const { return m_typeEd->text(); } diff --git a/kioclient/kioclient.cpp b/kioclient/kioclient.cpp index 9160843..5c083ea 100644 --- a/kioclient/kioclient.cpp +++ b/kioclient/kioclient.cpp @@ -1,455 +1,455 @@ /* This file is part of the KDE project Copyright (C) 1999-2006 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kioclient.h" #include "kio_version.h" #include "urlinfo.h" #include #include #include #include #ifndef KIOCORE_ONLY #include #include #include #include #include #endif #include #include #include #include #include #include #include #include bool ClientApp::m_ok = true; static bool s_interactive = false; static KIO::JobFlags s_jobFlags = KIO::DefaultFlags; static QUrl makeURL(const QString &urlArg) { return QUrl::fromUserInput(urlArg, QDir::currentPath()); } static QList makeUrls(const QStringList& urlArgs) { QList ret; foreach(const QString& url, urlArgs) { ret += makeURL(url); } return ret; } #ifdef KIOCLIENT_AS_KIOCLIENT5 static void usage() { puts(i18n("\nSyntax:\n").toLocal8Bit().constData()); puts(i18n(" kioclient openProperties 'url'\n" " # Opens a properties menu\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient exec 'url' ['mimetype']\n" " # Tries to open the document pointed to by 'url', in the application\n" " # associated with it in KDE. You may omit 'mimetype'.\n" " # In this case the mimetype is determined\n" " # automatically. Of course URL may be the URL of a\n" " # document, or it may be a *.desktop file.\n" " # 'url' can be an executable, too.\n").toLocal8Bit().constData()); puts(i18n(" kioclient move 'src' 'dest'\n" " # Moves the URL 'src' to 'dest'.\n" " # 'src' may be a list of URLs.\n").toLocal8Bit().constData()); puts(i18n(" # 'dest' may be \"trash:/\" to move the files\n" " # to the trash.\n").toLocal8Bit().constData()); puts(i18n(" # the short version kioclient mv\n" " # is also available.\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient download ['src']\n" " # Copies the URL 'src' to a user-specified location'.\n" " # 'src' may be a list of URLs, if not present then\n" " # a URL will be requested.\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient copy 'src' 'dest'\n" " # Copies the URL 'src' to 'dest'.\n" " # 'src' may be a list of URLs.\n").toLocal8Bit().constData()); puts(i18n(" # the short version kioclient cp\n" " # is also available.\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient cat 'url'\n" " # Writes out the contents of 'url' to stdout\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient ls 'url'\n" " # Lists the contents of the directory 'url' to stdout\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient remove 'url'\n" " # Removes the URL\n" " # 'url' may be a list of URLs.\n").toLocal8Bit().constData()); puts(i18n(" # the short version kioclient rm\n" " # is also available.\n\n").toLocal8Bit().constData()); puts(i18n("*** Examples:\n").toLocal8Bit().constData()); puts(i18n(" kioclient exec file:/home/weis/data/test.html\n" " // Opens the file with default binding\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient exec ftp://localhost/\n" " // Opens new window with URL\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient exec file:/root/Desktop/emacs.desktop\n" " // Starts emacs\n\n").toLocal8Bit().constData()); puts(i18n(" kioclient exec .\n" " // Opens the current directory. Very convenient.\n\n").toLocal8Bit().constData()); } #endif int main( int argc, char **argv ) { #ifdef KIOCORE_ONLY QCoreApplication app(argc, argv); #else QApplication app(argc, argv); #endif KLocalizedString::setApplicationDomain("kioclient5"); QString appName = QStringLiteral("kioclient"); QString programName = i18n("KIO Client"); QString description = i18n("Command-line tool for network-transparent operations"); QString version = QLatin1String(PROJECT_VERSION); KAboutData data(appName, programName, version, description, KAboutLicense::LGPL_V2); KAboutData::setApplicationData(data); QCommandLineParser parser; data.setupCommandLine(&parser); parser.addOption(QCommandLineOption(QStringLiteral("interactive"), i18n("Use message boxes and other native notifications"))); parser.addOption(QCommandLineOption(QStringLiteral("noninteractive"), i18n("Non-interactive use: no message boxes. If you don't want a " "graphical connection, use --platform offscreen"))); #if !defined(KIOCLIENT_AS_KDEOPEN) parser.addOption(QCommandLineOption(QStringLiteral("overwrite"), i18n("Overwrite destination if it exists (for copy and move)"))); #endif #if defined(KIOCLIENT_AS_KDEOPEN) parser.addPositionalArgument(QStringLiteral("url"), i18n("file or URL"), i18n("urls...")); #elif defined(KIOCLIENT_AS_KDECP5) parser.addPositionalArgument(QStringLiteral("src"), i18n("Source URL or URLs"), i18n("urls...")); parser.addPositionalArgument(QStringLiteral("dest"), i18n("Destination URL"), i18n("url")); #elif defined(KIOCLIENT_AS_KDEMV5) parser.addPositionalArgument(QStringLiteral("src"), i18n("Source URL or URLs"), i18n("urls...")); parser.addPositionalArgument(QStringLiteral("dest"), i18n("Destination URL"), i18n("url")); #elif defined(KIOCLIENT_AS_KIOCLIENT5) parser.addOption(QCommandLineOption(QStringLiteral("commands"), i18n("Show available commands"))); parser.addPositionalArgument(QStringLiteral("command"), i18n("Command (see --commands)"), i18n("command")); parser.addPositionalArgument(QStringLiteral("URLs"), i18n("Arguments for command"), i18n("urls...")); #endif // KCmdLineArgs::addTempFileOption(); parser.process(app); data.processCommandLine(&parser); #ifdef KIOCLIENT_AS_KIOCLIENT5 if ( argc == 1 || parser.isSet(QStringLiteral("commands")) ) { puts(parser.helpText().toLocal8Bit().constData()); puts("\n\n"); usage(); return 0; } #endif ClientApp client; return client.doIt(parser) ? 0 /*no error*/ : 1 /*error*/; } static bool krun_has_error = false; void ClientApp::delayedQuit() { #ifndef KIOCORE_ONLY // don't access the KRun instance later, it will be deleted after calling slots if( static_cast< const KRun* >( sender())->hasError()) krun_has_error = true; #endif } static void checkArgumentCount(int count, int min, int max) { if (count < min) { fputs( i18nc("@info:shell", "%1: Syntax error, not enough arguments\n", qAppName()).toLocal8Bit().constData(), stderr ); ::exit(1); } if (max && (count > max)) { fputs( i18nc("@info:shell", "%1: Syntax error, too many arguments\n", qAppName()).toLocal8Bit().constData(), stderr ); ::exit(1); } } #ifndef KIOCORE_ONLY bool ClientApp::kde_open(const QString& url, const QString& mimeType, bool allowExec) { UrlInfo info(url); if(!info.atStart()) { QUrlQuery q; q.addQueryItem(QStringLiteral("line"), QString::number(info.line)); q.addQueryItem(QStringLiteral("column"), QString::number(info.column)); info.url.setQuery(q); } if ( mimeType.isEmpty() ) { KRun * run = new KRun( info.url, nullptr ); run->setRunExecutables(allowExec); #if KIO_VERSION >= QT_VERSION_CHECK(5,55,0) run->setFollowRedirections(false); #endif - QObject::connect( run, SIGNAL( finished() ), this, SLOT( delayedQuit() )); - QObject::connect( run, SIGNAL( error() ), this, SLOT( delayedQuit() )); + QObject::connect( run, &KRun::finished, this, &ClientApp::delayedQuit); + QObject::connect( run, &KRun::error, this, &ClientApp::delayedQuit); qApp->exec(); return !krun_has_error; } else { return KRun::runUrl(info.url, mimeType, nullptr, KRun::RunFlags(KRun::RunExecutables)); } } #endif bool ClientApp::doCopy( const QStringList& urls ) { QList srcLst(makeUrls(urls)); QUrl dest = srcLst.takeLast(); KIO::Job * job = KIO::copy( srcLst, dest, s_jobFlags ); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } - connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotResult( KJob * ) ) ); + connect( job, &KJob::result, this, &ClientApp::slotResult ); qApp->exec(); return m_ok; } void ClientApp::slotEntries(KIO::Job*, const KIO::UDSEntryList& list) { KIO::UDSEntryList::ConstIterator it=list.begin(); for (; it != list.end(); ++it) { // For each file... QString name = (*it).stringValue( KIO::UDSEntry::UDS_NAME ); std::cout << qPrintable(name) << std::endl; } } bool ClientApp::doList( const QStringList& urls ) { QUrl dir = makeURL(urls.first()); KIO::Job * job = KIO::listDir(dir, KIO::HideProgressInfo); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList))); - connect(job, SIGNAL(result(KJob *)), this, SLOT(slotResult(KJob *))); + connect(job, &KJob::result, this, &ClientApp::slotResult); qApp->exec(); return m_ok; } bool ClientApp::doMove( const QStringList& urls ) { QList srcLst(makeUrls(urls)); QUrl dest = srcLst.takeLast(); KIO::Job * job = KIO::move( srcLst, dest, s_jobFlags ); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } - connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotResult( KJob * ) ) ); + connect( job, &KJob::result, this, &ClientApp::slotResult ); qApp->exec(); return m_ok; } bool ClientApp::doRemove( const QStringList& urls ) { KIO::Job * job = KIO::del( makeUrls(urls), s_jobFlags ); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } - connect( job, SIGNAL( result( KJob * ) ), this, SLOT( slotResult( KJob * ) ) ); + connect( job, &KJob::result, this, &ClientApp::slotResult ); qApp->exec(); return m_ok; } bool ClientApp::doIt(const QCommandLineParser& parser) { const int argc = parser.positionalArguments().count(); checkArgumentCount(argc, 1, 0); if (parser.isSet(QStringLiteral("interactive"))) { s_interactive = true; } else { // "noninteractive" is currently the default mode, so we don't check. // The argument still needs to exist for compatibility s_interactive = false; s_jobFlags = KIO::HideProgressInfo; } #if !defined(KIOCLIENT_AS_KDEOPEN) if (parser.isSet(QStringLiteral("overwrite"))) { s_jobFlags |= KIO::Overwrite; } #endif #ifdef KIOCLIENT_AS_KDEOPEN return kde_open(parser.positionalArguments().at(0), QString(), false); #elif defined(KIOCLIENT_AS_KDECP5) checkArgumentCount(argc, 2, 0); return doCopy(parser.positionalArguments()); #elif defined(KIOCLIENT_AS_KDEMV5) checkArgumentCount(argc, 2, 0); return doMove(parser.positionalArguments()); #else // Normal kioclient mode QString command = parser.positionalArguments().first(); #ifndef KIOCORE_ONLY if ( command == QLatin1String("openProperties") ) { checkArgumentCount(argc, 2, 2); // openProperties QUrl url = makeURL(parser.positionalArguments().last()); KPropertiesDialog * p = new KPropertiesDialog(url, nullptr /*no parent*/ ); QObject::connect( p, SIGNAL( destroyed() ), qApp, SLOT( quit() )); - QObject::connect( p, SIGNAL( canceled() ), this, SLOT( slotDialogCanceled() )); + QObject::connect( p, &KPropertiesDialog::canceled, this, &ClientApp::slotDialogCanceled); p->show(); qApp->exec(); return m_ok; } else #endif if ( command == QLatin1String("cat") ) { checkArgumentCount(argc, 2, 2); // cat QUrl url = makeURL(parser.positionalArguments().last()); KIO::TransferJob* job = KIO::get(url, KIO::NoReload, s_jobFlags); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } - connect(job, SIGNAL(data(KIO::Job*,QByteArray) ), this, SLOT(slotPrintData(KIO::Job*,QByteArray))); - connect(job, SIGNAL( result( KJob * ) ), this, SLOT( slotResult( KJob * ) ) ); + connect(job, &KIO::TransferJob::data, this, &ClientApp::slotPrintData); + connect(job, &KJob::result, this, &ClientApp::slotResult ); qApp->exec(); return m_ok; } #ifndef KIOCORE_ONLY else if ( command ==QLatin1String( "exec") ) { checkArgumentCount(argc, 2, 3); return kde_open( parser.positionalArguments()[1], argc == 3 ? parser.positionalArguments().last() : QString(), true ); } #endif else if ( command == QLatin1String("download") ) { checkArgumentCount(argc, 0, 0); QStringList args = parser.positionalArguments(); args.removeFirst(); QList srcLst = makeUrls(args); if (srcLst.isEmpty()) return m_ok; QUrl dsturl = QFileDialog::getSaveFileUrl(nullptr, i18n("Destination where to download the files"), (!srcLst.isEmpty()) ? QUrl() : srcLst.first() ); if (dsturl.isEmpty()) // canceled return m_ok; // AK - really okay? KIO::Job * job = KIO::copy( srcLst, dsturl, s_jobFlags ); if ( !s_interactive ) { job->setUiDelegate( nullptr ); job->setUiDelegateExtension( nullptr ); } connect( job, SIGNAL( result( KJob * ) ), qApp, SLOT( slotResult( KJob * ) ) ); qApp->exec(); return m_ok; } else if ( command == QLatin1String("copy") || command == QLatin1String("cp") ) { checkArgumentCount(argc, 3, 0); // cp QStringList args = parser.positionalArguments(); args.removeFirst(); return doCopy(args); } else if ( command == QLatin1String("move") || command == QLatin1String("mv") ) { checkArgumentCount(argc, 3, 0); // mv QStringList args = parser.positionalArguments(); args.removeFirst(); return doMove(args); } else if ( command == QLatin1String("list") || command == QLatin1String("ls") ) { checkArgumentCount(argc, 2, 2); // ls QStringList args = parser.positionalArguments(); args.removeFirst(); return doList(args); } else if ( command == QLatin1String("remove") || command == QLatin1String("rm") ) { checkArgumentCount(argc, 2, 0); // rm QStringList args = parser.positionalArguments(); args.removeFirst(); return doRemove(args); } else { fputs( i18nc("@info:shell", "%1: Syntax error, unknown command '%2'\n", qAppName(), command).toLocal8Bit().data(), stderr ); return false; } Q_UNREACHABLE(); #endif } void ClientApp::slotResult( KJob * job ) { if (job->error()) { #ifndef KIOCORE_ONLY if (s_interactive) { static_cast(job)->uiDelegate()->showErrorMessage(); } else #endif { qWarning() << job->errorString(); } } m_ok = !job->error(); if (qApp->topLevelWindows().isEmpty()) { qApp->quit(); } else { qApp->setQuitOnLastWindowClosed(true); } } void ClientApp::slotDialogCanceled() { m_ok = false; qApp->quit(); } void ClientApp::slotPrintData(KIO::Job*, const QByteArray &data) { if (!data.isEmpty()) std::cout.write(data.constData(), data.size()); } ClientApp::ClientApp() : QObject() { } diff --git a/kstart/kstart.cpp b/kstart/kstart.cpp index 3d04d7b..0a5165f 100644 --- a/kstart/kstart.cpp +++ b/kstart/kstart.cpp @@ -1,451 +1,451 @@ /* * kstart.C. Part of the KDE project. * * Copyright (C) 1997-2000 Matthias Ettrich * * First port to NETWM by David Faure * Send to system tray by Richard Moore * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "kstart.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // some globals static KProcess* proc = nullptr; static QString exe; static QString url; static QString windowtitle; static QString windowclass; static int desktop = 0; static bool activate = false; static bool iconify = false; static bool fullscreen = false; static NET::States state = {}; static NET::States mask = {}; static NET::WindowType windowtype = NET::Unknown; KStart::KStart() :QObject() { bool useRule = false; #ifdef HAVE_X11 if (QX11Info::isPlatformX11()) { NETRootInfo i( QX11Info::connection(), NET::Supported ); useRule = i.isSupported( NET::WM2KDETemporaryRules ); } #endif if( useRule ) sendRule(); else { // connect to window add to get the NEW windows - connect(KWindowSystem::self(), SIGNAL(windowAdded(WId)), SLOT(windowAdded(WId))); + connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &KStart::windowAdded); } // propagate the app startup notification info to the started app // We are not using KApplication, so the env remained set KStartupInfoId id = KStartupInfo::currentStartupIdEnv(); //finally execute the comand if (proc) { if( int pid = proc->startDetached() ) { KStartupInfoData data; data.addPid( pid ); data.setName( exe ); data.setBin( exe.mid( exe.lastIndexOf( QLatin1Char('/') ) + 1 )); KStartupInfo::sendChange( id, data ); } else KStartupInfo::sendFinish( id ); // failed to start } else { QString error; QString dbusService; int pid; if (KToolInvocation::startServiceByDesktopPath(exe, url, &error, &dbusService, &pid) == 0) { printf("%s\n", qPrintable(dbusService)); } else { qCritical() << error; } } QTimer::singleShot( useRule ? 0 : 120 * 1000, qApp, SLOT( quit())); } void KStart::sendRule() { KXMessages msg; QString message; if( !windowtitle.isEmpty() ) message += QStringLiteral("title=") + windowtitle + QStringLiteral("\ntitlematch=3\n"); // 3 = regexp match if( !windowclass.isEmpty() ) message += QStringLiteral("wmclass=") + windowclass + QStringLiteral("\nwmclassmatch=1\n") // 1 = exact match + QStringLiteral("wmclasscomplete=") // if windowclass contains a space (i.e. 2 words, use whole WM_CLASS) + ( windowclass.contains( QLatin1Char(' ') ) ? QStringLiteral("true") : QStringLiteral("false") ) + QLatin1Char('\n'); if( (!windowtitle.isEmpty()) || (!windowclass.isEmpty()) ) { // always ignore these window types message += QStringLiteral("types=") + QString().setNum( -1U & ~( NET::TopMenuMask | NET::ToolbarMask | NET::DesktopMask | NET::SplashMask | NET::MenuMask )) + QLatin1Char('\n'); } else { // accept only "normal" windows message += QStringLiteral("types=") + QString().setNum( NET::NormalMask | NET::DialogMask ) + QLatin1Char('\n'); } if ( ( desktop > 0 && desktop <= KWindowSystem::numberOfDesktops() ) || desktop == NETWinInfo::OnAllDesktops ) { message += QStringLiteral("desktop=") + QString().setNum( desktop ) + QStringLiteral("\ndesktoprule=3\n"); } if (activate) message += QStringLiteral("fsplevel=0\nfsplevelrule=2\n"); if (iconify) message += QStringLiteral("minimize=true\nminimizerule=3\n"); if ( windowtype != NET::Unknown ) { message += QStringLiteral("type=") + QString().setNum( windowtype ) + QStringLiteral("\ntyperule=2"); } if ( state ) { if( state & NET::KeepAbove ) message += QStringLiteral("above=true\naboverule=3\n"); if( state & NET::KeepBelow ) message += QStringLiteral("below=true\nbelowrule=3\n"); if( state & NET::SkipTaskbar ) message += QStringLiteral("skiptaskbar=true\nskiptaskbarrule=3\n"); if( state & NET::SkipPager ) message += QStringLiteral("skippager=true\nskippagerrule=3\n"); if( state & NET::MaxVert ) message += QStringLiteral("maximizevert=true\nmaximizevertrule=3\n"); if( state & NET::MaxHoriz ) message += QStringLiteral("maximizehoriz=true\nmaximizehorizrule=3\n"); if( state & NET::FullScreen ) message += QStringLiteral("fullscreen=true\nfullscreenrule=3\n"); } msg.broadcastMessage( "_KDE_NET_WM_TEMPORARY_RULES", message, -1 ); qApp->flush(); } const NET::WindowTypes SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask; void KStart::windowAdded(WId w){ KWindowInfo info( w, NET::WMWindowType | NET::WMName ); // always ignore these window types if( info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) == NET::TopMenu || info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) == NET::Toolbar || info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) == NET::Desktop ) return; if ( !windowtitle.isEmpty() ) { QString title = info.name().toLower(); QRegExp r( windowtitle.toLower()); if ( !r.exactMatch(title) ) return; // no match } if ( !windowclass.isEmpty() ) { #ifdef __GNUC__ #warning "Porting required" #endif #if 0 XClassHint hint; if( !XGetClassHint( QX11Info::display(), w, &hint )) return; Q3CString cls = windowclass.contains( ' ' ) ? Q3CString( hint.res_name ) + ' ' + hint.res_class : Q3CString( hint.res_class ); cls = cls.toLower(); XFree( hint.res_name ); XFree( hint.res_class ); if( cls != windowclass ) return; #endif } if( windowtitle.isEmpty() && windowclass.isEmpty() ) { // accept only "normal" windows if( info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Unknown && info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Normal && info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Dialog ) return; } applyStyle( w ); QApplication::exit(); } //extern Atom qt_wm_state; // defined in qapplication_x11.cpp static bool wstate_withdrawn( WId winid ) { Q_UNUSED(winid); #ifdef __GNUC__ #warning "Porting required." #endif //Porting info: The Qt4 equivalent for qt_wm_state is qt_x11Data->atoms[QX11Data::WM_STATE] //which can be accessed via the macro ATOM(WM_STATE). Unfortunately, neither of these seem //to be exported out of the Qt environment. This value may have to be acquired from somewhere else. /* Atom type; int format; unsigned long length, after; unsigned char *data; int r = XGetWindowProperty( QX11Info::display(), winid, qt_wm_state, 0, 2, false, AnyPropertyType, &type, &format, &length, &after, &data ); bool withdrawn = true; if ( r == Success && data && format == 32 ) { quint32 *wstate = (quint32*)data; withdrawn = (*wstate == WithdrawnState ); XFree( (char *)data ); } return withdrawn; */ return true; } void KStart::applyStyle(WId w ) { if ( state || iconify || windowtype != NET::Unknown || desktop >= 1 ) { XWithdrawWindow(QX11Info::display(), w, QX11Info::appScreen()); QApplication::flush(); while ( !wstate_withdrawn(w) ) ; } NETWinInfo info(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMState, NET::Properties2()); if ( ( desktop > 0 && desktop <= KWindowSystem::numberOfDesktops() ) || desktop == NETWinInfo::OnAllDesktops ) info.setDesktop( desktop ); if (iconify) { XWMHints * hints = XGetWMHints(QX11Info::display(), w ); if (hints ) { hints->flags |= StateHint; hints->initial_state = IconicState; XSetWMHints( QX11Info::display(), w, hints ); XFree(hints); } } if ( windowtype != NET::Unknown ) { info.setWindowType( windowtype ); } if ( state ) info.setState( state, mask ); if ( fullscreen ) { QRect r = QApplication::desktop()->screenGeometry(); XMoveResizeWindow( QX11Info::display(), w, r.x(), r.y(), r.width(), r.height() ); } XSync(QX11Info::display(), False); XMapWindow(QX11Info::display(), w ); XSync(QX11Info::display(), False); if (activate) KWindowSystem::forceActiveWindow( w ); QApplication::flush(); } int main( int argc, char *argv[] ) { QApplication app(argc, argv); KLocalizedString::setApplicationDomain( "kstart5" ); KAboutData aboutData(QStringLiteral("kstart"), i18n("KStart"), QString::fromLatin1(PROJECT_VERSION), i18n("" "Utility to launch applications with special window properties \n" "such as iconified, maximized, a certain virtual desktop, a special decoration\n" "and so on." ), KAboutLicense::GPL, i18n("(C) 1997-2000 Matthias Ettrich (ettrich@kde.org)")); aboutData.addAuthor( i18n("Matthias Ettrich"), QString(), QStringLiteral("ettrich@kde.org") ); aboutData.addAuthor( i18n("David Faure"), QString(), QStringLiteral("faure@kde.org") ); aboutData.addAuthor( i18n("Richard J. Moore"), QString(), QStringLiteral("rich@kde.org") ); KAboutData::setApplicationData(aboutData); QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+command"), i18n("Command to execute"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("service"), i18n("Alternative to : desktop file to start. D-Bus service will be printed to stdout"), QLatin1String("desktopfile"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("url"), i18n("Optional URL to pass , when using --service"), QLatin1String("url"))); // "!" means: all options after command are treated as arguments to the command parser.addOption(QCommandLineOption(QStringList() << QLatin1String("window"), i18n("A regular expression matching the window title"), QLatin1String("regexp"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowclass"), i18n("A string matching the window class (WM_CLASS property)\n" "The window class can be found out by running\n" "'xprop | grep WM_CLASS' and clicking on a window\n" "(use either both parts separated by a space or only the right part).\n" "NOTE: If you specify neither window title nor window class,\n" "then the very first window to appear will be taken;\n" "omitting both options is NOT recommended."), QLatin1String("class"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("desktop"), i18n("Desktop on which to make the window appear"), QLatin1String("number"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("currentdesktop"), i18n("Make the window appear on the desktop that was active\nwhen starting the application"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("alldesktops"), i18n("Make the window appear on all desktops"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("iconify"), i18n("Iconify the window"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize"), i18n("Maximize the window"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize-vertically"), i18n("Maximize the window vertically"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize-horizontally"), i18n("Maximize the window horizontally"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("fullscreen"), i18n("Show window fullscreen"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("type"), i18n("The window type: Normal, Desktop, Dock, Toolbar, \nMenu, Dialog, TopMenu or Override"), QLatin1String("type"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("activate"), i18n("Jump to the window even if it is started on a \n" "different virtual desktop"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("ontop") << QLatin1String("keepabove"), i18n("Try to keep the window above other windows"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("onbottom") << QLatin1String("keepbelow"), i18n("Try to keep the window below other windows"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skiptaskbar"), i18n("The window does not get an entry in the taskbar"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skippager"), i18n("The window does not get an entry on the pager"))); parser.process(app); aboutData.processCommandLine(&parser); if (parser.isSet(QStringLiteral("service"))) { exe = parser.value(QStringLiteral("service")); url = parser.value(QStringLiteral("url")); } else { if ( parser.positionalArguments().isEmpty() ) { qCritical() << i18n("No command specified"); parser.showHelp(1); } exe = parser.positionalArguments().at(0); proc = new KProcess; for(int i=0; i < parser.positionalArguments().count(); i++) (*proc) << parser.positionalArguments().at(i); } desktop = parser.value( QStringLiteral("desktop") ).toInt(); if ( parser.isSet ( QStringLiteral("alldesktops")) ) desktop = NETWinInfo::OnAllDesktops; if ( parser.isSet ( QStringLiteral("currentdesktop")) ) desktop = KWindowSystem::currentDesktop(); windowtitle = parser.value( QStringLiteral("window" )); windowclass = parser.value( QStringLiteral("windowclass" )); if( !windowclass.isEmpty() ) windowclass = windowclass.toLower(); if( windowtitle.isEmpty() && windowclass.isEmpty()) qWarning() << "Omitting both --window and --windowclass arguments is not recommended" ; QString s = parser.value( QStringLiteral("type") ); if ( !s.isEmpty() ) { s = s.toLower(); if ( s == QLatin1String("desktop") ) windowtype = NET::Desktop; else if ( s == QLatin1String("dock") ) windowtype = NET::Dock; else if ( s == QLatin1String("toolbar") ) windowtype = NET::Toolbar; else if ( s == QLatin1String("menu") ) windowtype = NET::Menu; else if ( s == QLatin1String("dialog") ) windowtype = NET::Dialog; else if ( s == QLatin1String("override") ) windowtype = NET::Override; else if ( s == QLatin1String("topmenu") ) windowtype = NET::TopMenu; else windowtype = NET::Normal; } if ( parser.isSet( QStringLiteral("keepabove") ) ) { state |= NET::KeepAbove; mask |= NET::KeepAbove; } else if ( parser.isSet( QStringLiteral("keepbelow") ) ) { state |= NET::KeepBelow; mask |= NET::KeepBelow; } if ( parser.isSet( QStringLiteral("skiptaskbar") ) ) { state |= NET::SkipTaskbar; mask |= NET::SkipTaskbar; } if ( parser.isSet( QStringLiteral("skippager") ) ) { state |= NET::SkipPager; mask |= NET::SkipPager; } activate = parser.isSet(QStringLiteral("activate")); if ( parser.isSet(QStringLiteral("maximize")) ) { state |= NET::Max; mask |= NET::Max; } if ( parser.isSet(QStringLiteral("maximize-vertically")) ) { state |= NET::MaxVert; mask |= NET::MaxVert; } if ( parser.isSet(QStringLiteral("maximize-horizontally")) ) { state |= NET::MaxHoriz; mask |= NET::MaxHoriz; } iconify = parser.isSet(QStringLiteral("iconify")); if ( parser.isSet(QStringLiteral("fullscreen")) ) { NETRootInfo i( QX11Info::connection(), NET::Supported ); if( i.isSupported( NET::FullScreen )) { state |= NET::FullScreen; mask |= NET::FullScreen; } else { windowtype = NET::Override; fullscreen = true; } } fcntl(XConnectionNumber(QX11Info::display()), F_SETFD, 1); KStart start; return app.exec(); }