Commit c3debf5f authored by Marco Martin's avatar Marco Martin

Support module commandline paramenter

Summary:
in prevision of more or less replacing kcmshell with systemsettings
itself, suppo loading a module as a paramenter as well as a --list
paramenter

Test Plan:
systemsettings5 kwindecoration loads the decoration kcm and the proper
category selected on the sidebar

Reviewers: #plasma, ngraham

Reviewed By: ngraham

Subscribers: broulik, bport, ngraham, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D29064
parent 37706f4c
......@@ -129,7 +129,7 @@ void SettingsBase::initApplication()
for( int pluginsDone = 0; pluginsDone < nbPlugins ; ++pluginsDone ) {
KService::Ptr activeService = pluginObjects.at( pluginsDone );
QString error;
BaseMode * controller = activeService->createInstance<BaseMode>(this, {m_mode}, &error);
BaseMode * controller = activeService->createInstance<BaseMode>(this, {m_mode, m_startupModule, m_startupModuleArgs}, &error);
if( error.isEmpty() ) {
possibleViews.insert( activeService->library(), controller );
controller->init( activeService );
......@@ -336,6 +336,31 @@ bool SettingsBase::queryClose()
return changes;
}
void SettingsBase::setStartupModule(const QString &startupModule)
{
m_startupModule = startupModule;
if (activeView) {
activeView->setStartupModule(startupModule);
}
}
void SettingsBase::setStartupModuleArgs(const QStringList &startupModuleArgs)
{
m_startupModuleArgs = startupModuleArgs;
if (activeView) {
activeView->setStartupModuleArgs(startupModuleArgs);
}
}
void SettingsBase::reloadStartupModule()
{
if (activeView) {
activeView->reloadStartupModule();
}
}
void SettingsBase::about()
{
delete aboutDialog;
......
......@@ -46,6 +46,10 @@ public:
bool isInfoCenterMode() const;
bool queryClose() override;
void setStartupModule(const QString &startupModule);
void setStartupModuleArgs(const QStringList &startupModuleArgs);
void reloadStartupModule();
protected:
QSize sizeHint() const override;
......@@ -96,5 +100,7 @@ private:
// The about dialog
KAboutApplicationDialog * aboutDialog = nullptr;
BaseMode::ApplicationMode m_mode = BaseMode::SystemSettings;
QString m_startupModule;
QStringList m_startupModuleArgs;
};
#endif
......@@ -26,10 +26,21 @@ SystemSettingsApp::SystemSettingsApp(int& argc, char* argv[])
{
setOrganizationDomain(QStringLiteral("kde.org"));
KDBusService* service = new KDBusService(KDBusService::Unique, this);
QObject::connect(service, &KDBusService::activateRequested, this, [=]() {
if (window) {
KWindowSystem::forceActiveWindow(window->winId());
QObject::connect(service, &KDBusService::activateRequested, this, [=](const QStringList &arguments, const QString &workingDirectory) {
if (!window) {
return;
}
if (arguments.size() > 1) {
window->setStartupModule(arguments[1]);
if (arguments.size() > 2) {
window->setStartupModuleArgs(arguments.mid(2));
}
window->reloadStartupModule();
}
KWindowSystem::forceActiveWindow(window->winId());
} );
}
......
......@@ -25,13 +25,41 @@
#include <KAboutData>
#include <KCrash>
#include <iostream>
#include <kworkspace.h>
#include <kdbusservice.h>
#include <KQuickAddons/QtQuickSettings>
#include <KServiceTypeTrader>
#include <KAuthorized>
#include "SystemSettingsApp.h"
#include "SettingsBase.h"
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);
}
int main( int argc, char *argv[] )
{
// Make sure the binary name is either kinfocenter or systemsettings,
......@@ -75,10 +103,39 @@ int main( int argc, char *argv[] )
QCommandLineParser parser;
parser.addOption(QCommandLineOption(QStringLiteral("list"), i18n("List all possible modules")));
parser.addPositionalArgument(QStringLiteral("module"), i18n("Configuration module to open"));
parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the module"), QLatin1String("arguments")));
aboutData.setupCommandLine(&parser);
parser.process(application);
aboutData.processCommandLine(&parser);
if (parser.isSet(QStringLiteral("list"))) {
std::cout << i18n("The following modules are available:").toLocal8Bit().data() << std::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"));
std::cout << entry.toLocal8Bit().data() << std::endl;
}
return 0;
}
if (mode == BaseMode::InfoCenter) {
aboutData.setDesktopFileName(QStringLiteral("org.kde.kinfocenter"));
application.setWindowIcon(QIcon::fromTheme(QStringLiteral("hwinfo")));
......@@ -98,5 +155,15 @@ int main( int argc, char *argv[] )
SettingsBase *mainWindow = new SettingsBase(mode);
application.setMainWindow(mainWindow);
if (parser.positionalArguments().count() == 1) {
QStringList moduleArgs;
const QString x = parser.value(QStringLiteral("args"));
moduleArgs << x.split(QRegExp(QStringLiteral(" +")));
mainWindow->setStartupModule(parser.positionalArguments().first());
mainWindow->setStartupModuleArgs(moduleArgs);
}
return application.exec();
}
......@@ -38,6 +38,8 @@ public:
KService::Ptr service;
MenuItem *rootItem = nullptr;
MenuItem *homeItem = nullptr;
QString startupModule;
QStringList startupModuleArgs;
KConfigGroup config;
bool showToolTips = true;
BaseMode::ApplicationMode applicationMode = BaseMode::SystemSettings;
......@@ -47,9 +49,15 @@ BaseMode::BaseMode( QObject* parent, const QVariantList &args )
: QObject( parent )
, d( new Private() )
{
if (!args.isEmpty() && args.first().canConvert<ApplicationMode>()) {
if (args.count() >= 1 && args.first().canConvert<ApplicationMode>()) {
d->applicationMode = args.first().value<ApplicationMode>();
}
if (args.count() >= 2 && args[1].canConvert<QString>()) {
d->startupModule = args[1].toString();
}
if (args.count() >= 3 && args[2].canConvert<QStringList>()) {
d->startupModuleArgs = args[2].toStringList();
}
}
BaseMode::~BaseMode()
......@@ -111,6 +119,26 @@ bool BaseMode::showToolTips() const
return d->showToolTips;
}
void BaseMode::setStartupModule(const QString &startupModule)
{
d->startupModule = startupModule;
}
QString BaseMode::startupModule() const
{
return d->startupModule;
}
void BaseMode::setStartupModuleArgs(const QStringList &startupModuleArgs)
{
d->startupModuleArgs = startupModuleArgs;
}
QStringList BaseMode::startupModuleArgs() const
{
return d->startupModuleArgs;
}
void BaseMode::searchChanged( const QString& text )
{
Q_UNUSED( text );
......
......@@ -183,6 +183,14 @@ public:
*/
bool showToolTips() const;
void setStartupModule(const QString &startupModule);
QString startupModule() const;
void setStartupModuleArgs(const QStringList &startupModuleArgs);
QStringList startupModuleArgs() const;
virtual void reloadStartupModule() = 0;
public Q_SLOTS:
/**
* Called when the text in the search box changes allowing the display to be filtered.
......
......@@ -139,3 +139,20 @@ void MenuItem::setService( const KService::Ptr& service )
d->weight = 100;
}
}
MenuItem *MenuItem::descendantForModule(const QString &moduleName)
{
if (d->service && d->service->desktopEntryName() == moduleName) {
return this;
}
for (auto *child : d->children) {
MenuItem *candidate = child->descendantForModule(moduleName);
if (candidate) {
return candidate;
}
}
return nullptr;
}
......@@ -155,6 +155,8 @@ public:
*/
void setService( const KService::Ptr& service );
MenuItem *descendantForModule(const QString &moduleName);
private:
class Private;
Private *const d;
......
......@@ -133,7 +133,7 @@ const KAboutData * ModuleView::aboutData() const
return aboutData;
}
void ModuleView::loadModule( const QModelIndex &menuItem )
void ModuleView::loadModule( const QModelIndex &menuItem, const QStringList &args )
{
if ( !menuItem.isValid() ) {
return;
......@@ -149,12 +149,12 @@ void ModuleView::loadModule( const QModelIndex &menuItem )
foreach ( const QModelIndex &module, indexes ) {
MenuItem *newMenuItem = module.data( Qt::UserRole ).value<MenuItem*>();
addModule( &newMenuItem->item() );
addModule( &newMenuItem->item(), args );
}
// changing state is not needed here as the adding / changing of pages does it
}
void ModuleView::addModule( KCModuleInfo *module )
void ModuleView::addModule( KCModuleInfo *module, const QStringList &args )
{
if( !module ) {
return;
......@@ -186,7 +186,7 @@ void ModuleView::addModule( KCModuleInfo *module )
QWidget * externalWidget = new ExternalAppModule( this, module );
moduleScroll->setWidget( externalWidget );
} else { // It must be a normal module then
KCModuleProxy * moduleProxy = new KCModuleProxy( *module, moduleScroll );
KCModuleProxy * moduleProxy = new KCModuleProxy( *module, moduleScroll, args );
moduleScroll->setWidget( moduleProxy );
moduleProxy->setAutoFillBackground( false );
connect( moduleProxy, SIGNAL(changed(bool)), this, SLOT(stateChanged()));
......
......@@ -144,7 +144,7 @@ public Q_SLOTS:
*
* @param menuItem the QModelIndex that you want to load. Must be sourced from either MenuModel or MenuProxyModel
*/
void loadModule(const QModelIndex &menuItem );
void loadModule(const QModelIndex &menuItem, const QStringList &args );
/**
* Will open KHelpCenter, and load the help for the active module.
......@@ -173,7 +173,7 @@ public Q_SLOTS:
private:
bool resolveChanges( KCModuleProxy *currentProxy );
void addModule( KCModuleInfo *module );
void addModule( KCModuleInfo *module, const QStringList &args );
bool moduleSave( KCModuleProxy *module );
void updatePageIconHeader( KPageWidgetItem * page, bool light = false );
......
......@@ -46,6 +46,7 @@ public:
KCategoryDrawer * categoryDrawer;
KCategorizedView * categoryView;
QStackedWidget * mainWidget;
MenuModel * model;
MenuProxyModel * proxyModel;
KAboutData * aboutIcon;
ModuleView * moduleView;
......@@ -101,14 +102,14 @@ QList<QAbstractItemView*> IconMode::views() const
void IconMode::initEvent()
{
MenuModel * model = new MenuModel( rootItem(), this );
d->model = new MenuModel( rootItem(), this );
foreach( MenuItem * child, rootItem()->children() ) {
model->addException( child );
d->model->addException( child );
}
d->proxyModel = new MenuProxyModel( this );
d->proxyModel->setCategorizedModel( true );
d->proxyModel->setSourceModel( model );
d->proxyModel->setSourceModel( d->model );
d->proxyModel->sort( 0 );
d->mainWidget = new QStackedWidget();
......@@ -136,6 +137,11 @@ void IconMode::searchChanged( const QString& text )
}
void IconMode::changeModule( const QModelIndex& activeModule )
{
changeModuleWithArgs(activeModule, QStringList());
}
void IconMode::changeModuleWithArgs( const QModelIndex& activeModule, const QStringList &args )
{
d->moduleView->closeModules();
d->mainWidget->setCurrentWidget( d->moduleView );
......@@ -147,7 +153,7 @@ void IconMode::changeModule( const QModelIndex& activeModule )
d->moduleView->setFaceType(KPageView::Plain);
}
d->moduleView->loadModule( activeModule );
d->moduleView->loadModule( activeModule, args );
}
void IconMode::moduleLoaded()
......@@ -194,6 +200,23 @@ void IconMode::initWidget()
d->mainWidget->setCurrentWidget( d->categoryView );
emit changeToolBarItems( BaseMode::Search | BaseMode::Configure | BaseMode::Quit );
d->mainWidget->installEventFilter(this);
if (!startupModule().isEmpty()) {
MenuItem *item = rootItem()->descendantForModule(startupModule());
if (item) {
changeModuleWithArgs(d->proxyModel->mapFromSource(d->model->indexForItem(item)), startupModuleArgs());
}
}
}
void IconMode::reloadStartupModule()
{
if (!startupModule().isEmpty()) {
MenuItem *item = rootItem()->descendantForModule(startupModule());
if (item) {
changeModuleWithArgs(d->proxyModel->mapFromSource(d->model->indexForItem(item)), startupModuleArgs());
}
}
}
bool IconMode::eventFilter(QObject* watched, QEvent* event)
......
......@@ -40,6 +40,7 @@ public:
void leaveModuleView() override;
KAboutData * aboutData() override;
ModuleView * moduleView() const override;
void reloadStartupModule() override;
protected:
QList<QAbstractItemView*> views() const override;
......@@ -49,12 +50,14 @@ public Q_SLOTS:
void searchChanged( const QString& text ) override;
private Q_SLOTS:
void changeModule( const QModelIndex& activeModule );
void moduleLoaded();
void backToOverview();
void initWidget();
private:
void changeModule( const QModelIndex& activeModule);
void changeModuleWithArgs( const QModelIndex& activeModule, const QStringList &args );
class Private;
Private *const d;
};
......
......@@ -440,7 +440,7 @@ void SidebarMode::showActionMenu(const QPoint &position)
d->setActionMenuVisible(this, true);
}
void SidebarMode::loadModule( const QModelIndex& activeModule )
void SidebarMode::loadModule( const QModelIndex& activeModule, const QStringList &args )
{
if (!activeModule.isValid()) {
return;
......@@ -466,9 +466,9 @@ void SidebarMode::loadModule( const QModelIndex& activeModule )
}
if ( mi->children().length() < 1) {
d->moduleView->loadModule( activeModule );
d->moduleView->loadModule( activeModule, args );
} else {
d->moduleView->loadModule( activeModule.model()->index(0, 0, activeModule) );
d->moduleView->loadModule( activeModule.model()->index(0, 0, activeModule), args );
}
if (activeModule.model() == d->categorizedModel) {
......@@ -526,7 +526,7 @@ void SidebarMode::loadModule( const QModelIndex& activeModule )
d->activeSearchRow = activeModule.row();
emit activeSearchRowChanged();
} else if (activeModule.model() == d->mostUsedModel) {
} else {
if (d->activeSearchRow > -1) {
d->activeSearchRow = -1;
emit activeSearchRowChanged();
......@@ -709,6 +709,23 @@ void SidebarMode::initWidget()
d->moduleView->show();
loadModule(d->categorizedModel->mapFromSource(d->model->indexForItem(homeItem())));
}
if (!startupModule().isEmpty()) {
MenuItem *item = rootItem()->descendantForModule(startupModule());
if (item) {
loadModule(d->model->indexForItem(item), startupModuleArgs());
}
}
}
void SidebarMode::reloadStartupModule()
{
if (!startupModule().isEmpty()) {
MenuItem *item = rootItem()->descendantForModule(startupModule());
if (item) {
loadModule(d->model->indexForItem(item), startupModuleArgs());
}
}
}
bool SidebarMode::eventFilter(QObject* watched, QEvent* event)
......
......@@ -85,6 +85,8 @@ public:
void giveFocus() override;
KAboutData * aboutData() override;
ModuleView * moduleView() const override;
void reloadStartupModule() override;
QAbstractItemModel *categoryModel() const;
QAbstractItemModel *searchModel() const;
QAbstractItemModel *subCategoryModel() const;
......@@ -110,7 +112,7 @@ public:
Q_INVOKABLE void hideMostUsedToolTip();
Q_INVOKABLE void showActionMenu(const QPoint &position);
Q_INVOKABLE void loadModule(const QModelIndex& activeModule);
Q_INVOKABLE void loadModule(const QModelIndex& activeModule, const QStringList &args = QStringList());
protected:
QList<QAbstractItemView*> views() const override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment