diff --git a/src/appchooserdialog.cpp b/src/appchooserdialog.cpp index da31cc3..2bbfb31 100644 --- a/src/appchooserdialog.cpp +++ b/src/appchooserdialog.cpp @@ -1,166 +1,174 @@ /* * Copyright © 2017-2018 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Authors: * Jan Grulich */ #include "appchooserdialog.h" #include "appchooserdialogitem.h" #include #include #include #include #include #include #include #include #include #include Q_LOGGING_CATEGORY(XdgDesktopPortalKdeAppChooserDialog, "xdp-kde-app-chooser-dialog") AppChooserDialog::AppChooserDialog(const QStringList &choices, const QString &defaultApp, const QString &fileName, QDialog *parent, Qt::WindowFlags flags) : QDialog(parent, flags) , m_choices(choices) , m_defaultApp(defaultApp) { setMinimumWidth(640); QVBoxLayout *vboxLayout = new QVBoxLayout(this); vboxLayout->setSpacing(20); vboxLayout->setMargin(20); QLabel *label = new QLabel(this); label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); label->setScaledContents(true); label->setWordWrap(true); label->setText(i18n("Select application to open \"%1\". Other applications are available in Discover.", fileName)); label->setOpenExternalLinks(false); connect(label, &QLabel::linkActivated, this, [] () { KProcess::startDetached(QStringLiteral("plasma-discover")); }); vboxLayout->addWidget(label); m_gridLayout = new QGridLayout(); addDialogItems(); vboxLayout->addLayout(m_gridLayout); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, this); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Open, this); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); vboxLayout->addWidget(buttonBox, 0, Qt::AlignBottom | Qt::AlignRight); setLayout(vboxLayout); setWindowTitle(i18n("Open with")); } AppChooserDialog::~AppChooserDialog() { delete m_gridLayout; } void AppChooserDialog::updateChoices(const QStringList &choices) { bool changed = false; // Check if we will be adding something for (const QString &choice : choices) { if (!m_choices.contains(choice)) { changed = true; m_choices << choice; } } // Check if we will be removing something for (const QString &choice : m_choices) { if (!choices.contains(choice)) { changed = true; m_choices.removeAll(choice); } } // If something changed, clear the layout and add the items again if (changed) { int rowCount = m_gridLayout->rowCount(); int columnCount = m_gridLayout->columnCount(); for (int i = 0; i < rowCount; ++i) { for (int j = 0; j < columnCount; ++j) { QLayoutItem *item = m_gridLayout->itemAtPosition(i, j); if (item) { QWidget *widget = item->widget(); if (widget) { m_gridLayout->removeWidget(widget); widget->deleteLater(); } } } } addDialogItems(); } } QString AppChooserDialog::selectedApplication() const { + if (m_selectedApplication.isEmpty()) { + return m_defaultApp; + } + return m_selectedApplication; } void AppChooserDialog::addDialogItems() { int i = 0, j = 0; for (const QString &choice : m_choices) { const QString desktopFile = choice + QStringLiteral(".desktop"); const QStringList desktopFilesLocations = QStandardPaths::locateAll(QStandardPaths::ApplicationsLocation, desktopFile, QStandardPaths::LocateFile); for (const QString &desktopFile : desktopFilesLocations) { QString applicationIcon; QString applicationName; QSettings settings(desktopFile, QSettings::IniFormat); settings.beginGroup(QStringLiteral("Desktop Entry")); if (settings.contains(QStringLiteral("X-GNOME-FullName"))) { applicationName = settings.value(QStringLiteral("X-GNOME-FullName")).toString(); } else { applicationName = settings.value(QStringLiteral("Name")).toString(); } applicationIcon = settings.value(QStringLiteral("Icon")).toString(); AppChooserDialogItem *item = new AppChooserDialogItem(applicationName, applicationIcon, choice, this); m_gridLayout->addWidget(item, i, j++, Qt::AlignHCenter); + connect(item, &AppChooserDialogItem::clicked, this, [this] (const QString &selectedApplication) { + m_selectedApplication = selectedApplication; + }); connect(item, &AppChooserDialogItem::doubleClicked, this, [this] (const QString &selectedApplication) { m_selectedApplication = selectedApplication; QDialog::accept(); }); if (choice == m_defaultApp) { item->setDown(true); item->setChecked(true); } if (j == 3) { i++; j = 0; } } } } diff --git a/src/appchooserdialogitem.cpp b/src/appchooserdialogitem.cpp index 4200d10..3411359 100644 --- a/src/appchooserdialogitem.cpp +++ b/src/appchooserdialogitem.cpp @@ -1,80 +1,82 @@ /* * Copyright © 2018 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Authors: * Jan Grulich */ #include "appchooserdialogitem.h" #include #include #include #include AppChooserDialogItem::AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QWidget *parent) : QToolButton(parent) , m_applicationName(applicationExec) { setAutoRaise(true); setAutoExclusive(true); setStyleSheet(QStringLiteral("text-align: center")); setIcon(QIcon::fromTheme(icon)); setIconSize(QSize(64, 64)); setCheckable(true); setFixedWidth(150); setToolButtonStyle(Qt::ToolButtonTextUnderIcon); QFontMetrics metrics(font()); QString elidedText = metrics.elidedText(applicationName, Qt::ElideRight, 128); setText(elidedText); connect(this, &QToolButton::toggled, this, [this] (bool toggled) { if (!toggled) { setDown(false); } }); } AppChooserDialogItem::~AppChooserDialogItem() { } QString AppChooserDialogItem::applicationName() const { return m_applicationName; } void AppChooserDialogItem::mouseDoubleClickEvent(QMouseEvent *event) { Q_EMIT doubleClicked(m_applicationName); QToolButton::mouseDoubleClickEvent(event); } void AppChooserDialogItem::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { setDown(true); setChecked(true); + + Q_EMIT clicked(m_applicationName); } } void AppChooserDialogItem::mouseReleaseEvent(QMouseEvent *event) { event->ignore(); } diff --git a/src/appchooserdialogitem.h b/src/appchooserdialogitem.h index a6a3247..4ab5d56 100644 --- a/src/appchooserdialogitem.h +++ b/src/appchooserdialogitem.h @@ -1,50 +1,51 @@ /* * Copyright © 2018 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * * Authors: * Jan Grulich */ #ifndef XDG_DESKTOP_PORTAL_KDE_APPCHOOSER_DIALOG_ITEM_H #define XDG_DESKTOP_PORTAL_KDE_APPCHOOSER_DIALOG_ITEM_H class QMouseEvent; #include class AppChooserDialogItem : public QToolButton { Q_OBJECT public: explicit AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QWidget *parent = nullptr); ~AppChooserDialogItem() override; QString applicationName() const; void mouseDoubleClickEvent(QMouseEvent * event) override; void mousePressEvent(QMouseEvent * event) override; void mouseReleaseEvent(QMouseEvent * event) override; Q_SIGNALS: + void clicked(const QString &applicationName); void doubleClicked(const QString &applicationName); private: QString m_applicationName; }; #endif // XDG_DESKTOP_PORTAL_KDE_APPCHOOSER_DIALOG_ITEM_H