File indexing completed on 2024-04-21 05:46:38
0001 // SPDX-License-Identifier: GPL-3.0-or-later 0002 /* 0003 Copyright 2017 Martin Koller, kollix@aon.at 0004 0005 This file is part of liquidshell. 0006 0007 liquidshell is free software: you can redistribute it and/or modify 0008 it under the terms of the GNU General Public License as published by 0009 the Free Software Foundation, either version 3 of the License, or 0010 (at your option) any later version. 0011 0012 liquidshell is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 GNU General Public License for more details. 0016 0017 You should have received a copy of the GNU General Public License 0018 along with liquidshell. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include <StartMenu.hxx> 0022 #include <PopupMenu.hxx> 0023 0024 #include <QAction> 0025 #include <QContextMenuEvent> 0026 #include <QDBusConnection> 0027 #include <QDBusMessage> 0028 0029 #include <kio_version.h> 0030 #if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0) 0031 # include <KIO/ApplicationLauncherJob> 0032 # include <KIO/CommandLauncherJob> 0033 # include <KIO/JobUiDelegateFactory> 0034 #else 0035 # include <KRun> 0036 #endif 0037 0038 #include <KSycoca> 0039 #include <KService> 0040 #include <KLocalizedString> 0041 #include <KIconLoader> 0042 0043 //-------------------------------------------------------------------------------- 0044 0045 StartMenu::StartMenu(DesktopPanel *parent) 0046 : QToolButton(parent) 0047 { 0048 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); 0049 0050 setThemeIcon("liquidshell"); 0051 0052 popup = new PopupMenu(this); 0053 connect(this, &QToolButton::pressed, this, &StartMenu::showMenu); 0054 0055 fill(); 0056 adjustIconSize(); 0057 0058 connect(KSycoca::self(), SIGNAL(databaseChanged()), this, SLOT(fill())); 0059 connect(parent, &DesktopPanel::rowsChanged, this, &StartMenu::adjustIconSize); 0060 connect(KIconLoader::global(), &KIconLoader::iconLoaderSettingsChanged, this, &StartMenu::adjustIconSize); 0061 } 0062 0063 //-------------------------------------------------------------------------------- 0064 0065 void StartMenu::adjustIconSize() 0066 { 0067 const int MAX_ROWS = qobject_cast<DesktopPanel *>(parentWidget())->getRows(); 0068 0069 if ( MAX_ROWS > 1 ) 0070 setIconSize(QSize(48, 48)); 0071 else 0072 { 0073 int size = KIconLoader::global()->currentSize(KIconLoader::Panel); 0074 setIconSize(QSize(size, size)); 0075 } 0076 } 0077 0078 //-------------------------------------------------------------------------------- 0079 0080 void StartMenu::setThemeIcon(const QString &icon) 0081 { 0082 themeIcon = icon; 0083 setIcon(QIcon::fromTheme(themeIcon)); 0084 } 0085 0086 //-------------------------------------------------------------------------------- 0087 0088 void StartMenu::fill() 0089 { 0090 popup->clear(); 0091 0092 fillFromGroup(popup, KServiceGroup::root()); 0093 0094 popup->addSeparator(); 0095 0096 // add important actions 0097 QAction *action = popup->addAction(QIcon::fromTheme("system-switch-user"), i18n("Switch User")); 0098 connect(action, &QAction::triggered, 0099 []() 0100 { 0101 QDBusConnection::sessionBus().send( 0102 QDBusMessage::createMethodCall("org.kde.ksmserver", "/KSMServer", 0103 "org.kde.KSMServerInterface", "openSwitchUserDialog")); 0104 }); 0105 0106 KService::Ptr sysSettings = KService::serviceByDesktopName("systemsettings"); 0107 if ( sysSettings ) 0108 { 0109 action = popup->addAction(QIcon::fromTheme(sysSettings->icon()), sysSettings->name()); 0110 connect(action, &QAction::triggered, 0111 [this, sysSettings]() 0112 { 0113 #if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0) 0114 auto *job = new KIO::ApplicationLauncherJob(sysSettings); 0115 job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0116 job->start(); 0117 #else 0118 KRun::runApplication(*sysSettings, QList<QUrl>(), this); 0119 #endif 0120 }); 0121 } 0122 0123 action = popup->addAction(QIcon::fromTheme("system-run"), i18n("Run Command...")); 0124 connect(action, &QAction::triggered, 0125 []() 0126 { 0127 QDBusConnection::sessionBus().send( 0128 QDBusMessage::createMethodCall("org.kde.krunner", "/App", 0129 "org.kde.krunner.App", "display")); 0130 }); 0131 } 0132 0133 //-------------------------------------------------------------------------------- 0134 0135 void StartMenu::fillFromGroup(QMenu *menu, KServiceGroup::Ptr group) 0136 { 0137 if ( !group || !group->isValid() ) 0138 return; 0139 0140 QList<KServiceGroup::Ptr> groupEntries = 0141 group->groupEntries(static_cast<KServiceGroup::EntriesOptions>(KServiceGroup::SortEntries | 0142 KServiceGroup::ExcludeNoDisplay)); 0143 0144 for (KServiceGroup::Ptr groupEntry : groupEntries) 0145 { 0146 if ( groupEntry->childCount() == 0 ) 0147 continue; 0148 0149 QMenu *submenu = new PopupMenu(menu); 0150 menu->addMenu(submenu); 0151 submenu->setTitle(groupEntry->caption()); 0152 submenu->setIcon(QIcon::fromTheme(groupEntry->icon())); 0153 fillFromGroup(submenu, groupEntry); 0154 } 0155 0156 KService::List serviceEntries = 0157 group->serviceEntries(static_cast<KServiceGroup::EntriesOptions>(KServiceGroup::SortEntries | 0158 KServiceGroup::ExcludeNoDisplay)); 0159 0160 for (KService::Ptr serviceEntry : serviceEntries) 0161 { 0162 if ( !serviceEntry->isType(KST_KService) ) 0163 continue; 0164 0165 QIcon icon = QIcon::fromTheme(serviceEntry->icon()); 0166 QString text = serviceEntry->name(); 0167 if ( !serviceEntry->genericName().isEmpty() && (serviceEntry->genericName() != serviceEntry->name()) ) 0168 text += QString(" (%1)").arg(serviceEntry->genericName()); 0169 0170 QAction *action = menu->addAction(icon, text); 0171 action->setData(QUrl::fromLocalFile(serviceEntry->entryPath())); 0172 0173 action->setToolTip(static_cast<const KService *>(serviceEntry.data())->comment()); 0174 0175 connect(action, &QAction::triggered, 0176 [this, serviceEntry]() 0177 { 0178 #if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0) 0179 auto *job = new KIO::ApplicationLauncherJob(serviceEntry); 0180 job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0181 job->start(); 0182 #else 0183 KRun::runApplication(*serviceEntry, QList<QUrl>(), nullptr); 0184 #endif 0185 }); 0186 } 0187 } 0188 0189 //-------------------------------------------------------------------------------- 0190 0191 void StartMenu::contextMenuEvent(QContextMenuEvent *event) 0192 { 0193 QMenu menu; 0194 0195 QAction *action = menu.addAction(QIcon::fromTheme("configure"), i18n("Configure Menu...")); 0196 connect(action, &QAction::triggered, 0197 [this]() 0198 { 0199 #if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0) 0200 auto *job = new KIO::CommandLauncherJob("kmenuedit"); 0201 job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this)); 0202 job->start(); 0203 #else 0204 KRun::runCommand("kmenuedit", nullptr); 0205 #endif 0206 }); 0207 0208 menu.exec(event->globalPos()); 0209 } 0210 0211 //-------------------------------------------------------------------------------- 0212 0213 void StartMenu::showMenu() 0214 { 0215 popup->adjustSize(); 0216 QPoint p = mapToGlobal(QPoint(0, 0)); 0217 popup->move(p.x(), p.y() - popup->sizeHint().height()); 0218 popup->exec(); 0219 setDown(false); 0220 } 0221 0222 //--------------------------------------------------------------------------------