File indexing completed on 2024-04-21 16:30:31
0001 // SPDX-License-Identifier: GPL-3.0-or-later 0002 /* 0003 Copyright 2017 - 2020 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 <AppMenu.hxx> 0022 #include <IconButton.hxx> 0023 #include <DesktopWidget.hxx> 0024 0025 #include <QGridLayout> 0026 #include <QToolButton> 0027 #include <QStandardPaths> 0028 #include <QDir> 0029 #include <QMimeDatabase> 0030 #include <QApplication> 0031 #include <QScreen> 0032 0033 #include <KFileItem> 0034 #include <KDesktopFile> 0035 #include <KIOWidgets/KRun> 0036 #include <KIconLoader> 0037 0038 //-------------------------------------------------------------------------------- 0039 0040 AppMenu::AppMenu(DesktopPanel *parent) 0041 : Launcher(parent, "AppMenu") 0042 { 0043 button = new QToolButton; // QToolButton is smaller than QPushButton 0044 adjustIconSize(); 0045 button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); 0046 0047 connect(button, &QToolButton::pressed, this, &AppMenu::showMenu); 0048 0049 layout()->addWidget(button); 0050 loadConfig(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); 0051 0052 connect(parent, &DesktopPanel::rowsChanged, this, &AppMenu::adjustIconSize); 0053 connect(KIconLoader::global(), &KIconLoader::iconLoaderSettingsChanged, this, &AppMenu::adjustIconSize); 0054 connect(KIconLoader::global(), &KIconLoader::iconLoaderSettingsChanged, this, &AppMenu::fill); 0055 } 0056 0057 //-------------------------------------------------------------------------------- 0058 0059 void AppMenu::adjustIconSize() 0060 { 0061 const int MAX_ROWS = qobject_cast<DesktopPanel *>(parentWidget())->getRows(); 0062 0063 if ( MAX_ROWS > 1 ) 0064 button->setIconSize(QSize(48, 48)); 0065 else 0066 { 0067 int size = KIconLoader::global()->currentSize(KIconLoader::Panel); 0068 button->setIconSize(QSize(size, size)); 0069 } 0070 } 0071 0072 //-------------------------------------------------------------------------------- 0073 0074 void AppMenu::fill() 0075 { 0076 KDesktopFile desktopFile(dirPath + "/.directory"); 0077 0078 if ( !desktopFile.readIcon().isEmpty() ) 0079 button->setIcon(QIcon::fromTheme(desktopFile.readIcon())); 0080 else if ( dirPath == QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) ) 0081 button->setIcon(QIcon::fromTheme("user-desktop")); 0082 else // fallback 0083 button->setIcon(QIcon::fromTheme("folder")); 0084 } 0085 0086 //-------------------------------------------------------------------------------- 0087 0088 void AppMenu::showMenu() 0089 { 0090 Menu *popup = new Menu(button); 0091 0092 QDir dir(dirPath); 0093 QFileInfoList entries = dir.entryInfoList(QDir::AllEntries | QDir::NoDotDot); 0094 0095 int row = 0, col = 0, h = 0; 0096 const int maxHeight = DesktopWidget::availableSize().height(); 0097 0098 for (const QFileInfo &info : entries) 0099 { 0100 QUrl url(QUrl::fromLocalFile(info.absoluteFilePath())); 0101 QString name; 0102 QIcon icon; 0103 0104 KFileItem item(url); 0105 0106 if ( item.isDesktopFile() ) 0107 { 0108 KDesktopFile desktopFile(info.absoluteFilePath()); 0109 if ( desktopFile.noDisplay() ) 0110 continue; 0111 0112 name = desktopFile.readName(); 0113 if ( name.isEmpty() ) 0114 name = desktopFile.readGenericName(); 0115 0116 QString iconName = desktopFile.readIcon(); 0117 icon = QIcon::fromTheme(iconName.isEmpty() ? name : iconName); 0118 } 0119 else if ( info.isDir() ) 0120 { 0121 if ( info.fileName() == "." ) 0122 { 0123 name = info.dir().dirName(); 0124 icon = button->icon(); 0125 } 0126 else 0127 icon = QIcon::fromTheme("folder"); 0128 } 0129 else 0130 { 0131 QMimeDatabase db; 0132 icon = QIcon::fromTheme(db.mimeTypeForFile(info.absoluteFilePath()).iconName()); 0133 } 0134 0135 if ( name.isEmpty() ) 0136 name = info.fileName(); 0137 0138 IconButton *entryButton = new IconButton(this, icon, 32, name); 0139 connect(entryButton, &IconButton::clicked, [this, url, popup]() { popup->close(); new KRun(url, nullptr); }); 0140 0141 h += entryButton->sizeHint().height(); 0142 0143 if ( h >= maxHeight ) 0144 { 0145 h = entryButton->sizeHint().height(); 0146 col++; 0147 row = 0; 0148 } 0149 0150 static_cast<QGridLayout *>(popup->layout())->addWidget(entryButton, row++, col); 0151 } 0152 0153 popup->exec(); 0154 button->setDown(false); 0155 delete popup; 0156 } 0157 0158 //-------------------------------------------------------------------------------- 0159 //-------------------------------------------------------------------------------- 0160 //-------------------------------------------------------------------------------- 0161 0162 Menu::Menu(QWidget *parent) 0163 : QMenu(parent) 0164 { 0165 QGridLayout *grid = new QGridLayout(this); 0166 grid->setContentsMargins(QMargins()); 0167 grid->setSpacing(0); 0168 } 0169 0170 //-------------------------------------------------------------------------------- 0171 0172 void Menu::hideEvent(QHideEvent *event) 0173 { 0174 Q_UNUSED(event); 0175 eventLoop.exit(); 0176 } 0177 0178 //-------------------------------------------------------------------------------- 0179 0180 void Menu::exec() 0181 { 0182 adjustSize(); 0183 QPoint p = parentWidget()->mapToGlobal(QPoint(0, 0)); 0184 move(p.x(), p.y() - height()); 0185 show(); 0186 eventLoop.exec(); 0187 } 0188 0189 //--------------------------------------------------------------------------------