File indexing completed on 2024-09-15 04:26:37
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Aleix Pol Gonzalez <aleixpol@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include <QAbstractButton> 0008 #include <QApplication> 0009 #include <QComboBox> 0010 #include <QCommandLineParser> 0011 #include <QDBusMessage> 0012 #include <QDialog> 0013 #include <QFileDialog> 0014 #include <QMessageBox> 0015 #include <QTextStream> 0016 #include <QUrl> 0017 0018 #include <KAboutData> 0019 #include <KColorSchemeManager> 0020 #include <KDBusService> 0021 #include <KLocalizedString> 0022 #include <KUrlRequester> 0023 0024 #include <dbushelper.h> 0025 0026 #include "kdeconnect-version.h" 0027 #include "ui_dialog.h" 0028 #include <interfaces/dbushelpers.h> 0029 #include <interfaces/dbusinterfaces.h> 0030 #include <interfaces/devicesmodel.h> 0031 #include <interfaces/devicespluginfilterproxymodel.h> 0032 0033 /** 0034 * Show only devices that can be shared to 0035 */ 0036 0037 int main(int argc, char **argv) 0038 { 0039 QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 0040 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 0041 QApplication app(argc, argv); 0042 app.setWindowIcon(QIcon::fromTheme(QStringLiteral("kdeconnect"))); 0043 const QString description = i18n("KDE Connect URL handler"); 0044 KAboutData about(QStringLiteral("kdeconnect.handler"), 0045 description, 0046 QStringLiteral(KDECONNECT_VERSION_STRING), 0047 description, 0048 KAboutLicense::GPL, 0049 i18n("(C) 2017 Aleix Pol Gonzalez")); 0050 about.addAuthor(QStringLiteral("Aleix Pol Gonzalez"), QString(), QStringLiteral("aleixpol@kde.org")); 0051 about.setProgramLogo(QIcon(QStringLiteral(":/icons/kdeconnect/kdeconnect.svg"))); 0052 KAboutData::setApplicationData(about); 0053 KDBusService dbusService(KDBusService::Unique); 0054 0055 #ifdef Q_OS_WIN 0056 KColorSchemeManager manager; 0057 QApplication::setStyle(QStringLiteral("breeze")); 0058 #endif 0059 0060 QUrl urlToShare; 0061 bool open; 0062 QString deviceId; 0063 { 0064 QCommandLineParser parser; 0065 parser.addPositionalArgument(QStringLiteral("url"), i18n("URL to share")); 0066 parser.addOption(QCommandLineOption(QStringLiteral("device"), i18n("Select a device"), i18n("id"))); 0067 parser.addOption(QCommandLineOption(QStringLiteral("open"), QStringLiteral("Open the file on the remote device"))); 0068 about.setupCommandLine(&parser); 0069 parser.process(app); 0070 about.processCommandLine(&parser); 0071 if (parser.positionalArguments().count() == 1) { 0072 urlToShare = QUrl::fromUserInput(parser.positionalArguments().constFirst(), QDir::currentPath(), QUrl::AssumeLocalFile); 0073 } 0074 open = parser.isSet(QStringLiteral("open")); 0075 deviceId = parser.value(QStringLiteral("device")); 0076 } 0077 0078 DevicesModel model; 0079 model.setDisplayFilter(DevicesModel::Paired | DevicesModel::Reachable); 0080 DevicesPluginFilterProxyModel proxyModel; 0081 proxyModel.setPluginFilter(QStringLiteral("kdeconnect_share")); 0082 proxyModel.setSourceModel(&model); 0083 0084 QDialog dialog; 0085 0086 Ui::Dialog uidialog; 0087 uidialog.setupUi(&dialog); 0088 uidialog.devicePicker->setModel(&proxyModel); 0089 0090 if (!deviceId.isEmpty()) { 0091 uidialog.devicePicker->setCurrentIndex(model.rowForDevice(deviceId)); 0092 } 0093 0094 uidialog.openOnPeerCheckBox->setChecked(open); 0095 0096 KUrlRequester *urlRequester = new KUrlRequester(&dialog); 0097 urlRequester->setStartDir(QUrl::fromLocalFile(QDir::homePath())); 0098 uidialog.urlHorizontalLayout->addWidget(urlRequester); 0099 0100 QObject::connect(uidialog.sendUrlRadioButton, &QRadioButton::toggled, [&uidialog, urlRequester](const bool checked) { 0101 if (checked) { 0102 urlRequester->setPlaceholderText(i18n("Enter URL here")); 0103 urlRequester->button()->setVisible(false); 0104 uidialog.openOnPeerCheckBox->setVisible(false); 0105 } 0106 }); 0107 0108 QObject::connect(uidialog.sendFileRadioButton, &QAbstractButton::toggled, [&uidialog, urlRequester](const bool checked) { 0109 if (checked) { 0110 urlRequester->setPlaceholderText(i18n("Enter file location here")); 0111 urlRequester->button()->setVisible(true); 0112 uidialog.openOnPeerCheckBox->setVisible(true); 0113 } 0114 }); 0115 0116 QObject::connect(urlRequester, &KUrlRequester::textChanged, [&urlRequester, &uidialog]() { 0117 QUrl fileUrl(urlRequester->url()); 0118 bool isLocalFileUrl = false; 0119 if (fileUrl.isLocalFile()) { 0120 QFileInfo fileInfo(fileUrl.toLocalFile()); 0121 isLocalFileUrl = fileInfo.exists() && fileInfo.isFile(); // we don't support sending directories yet! 0122 } 0123 uidialog.sendFileRadioButton->setChecked(isLocalFileUrl); 0124 uidialog.sendUrlRadioButton->setChecked(!isLocalFileUrl); 0125 }); 0126 0127 if (!urlToShare.isEmpty()) { 0128 uidialog.sendUrlRadioButton->setVisible(false); 0129 uidialog.sendFileRadioButton->setVisible(false); 0130 urlRequester->setVisible(false); 0131 0132 QString displayUrl; 0133 if (urlToShare.scheme() == QLatin1String("tel")) { 0134 displayUrl = urlToShare.toDisplayString(QUrl::RemoveScheme); 0135 uidialog.label->setText(i18n("Device to call %1 with:", displayUrl)); 0136 } else if (urlToShare.isLocalFile() && open) { 0137 displayUrl = urlToShare.toDisplayString(QUrl::PreferLocalFile); 0138 uidialog.label->setText(i18n("Device to open %1 on:", displayUrl)); 0139 } else if (urlToShare.scheme() == QLatin1String("sms")) { 0140 displayUrl = urlToShare.toDisplayString(QUrl::PreferLocalFile); 0141 uidialog.label->setText(i18n("Device to send a SMS with:")); 0142 } else { 0143 displayUrl = urlToShare.toDisplayString(QUrl::PreferLocalFile); 0144 uidialog.label->setText(i18n("Device to send %1 to:", displayUrl)); 0145 } 0146 } 0147 0148 if (open || urlToShare.isLocalFile()) { 0149 uidialog.sendFileRadioButton->setChecked(true); 0150 urlRequester->setUrl(QUrl(urlToShare.toLocalFile())); 0151 0152 } else { 0153 uidialog.sendUrlRadioButton->setChecked(true); 0154 urlRequester->setUrl(urlToShare); 0155 } 0156 0157 if (dialog.exec() == QDialog::Accepted) { 0158 const QUrl url = urlRequester->url(); 0159 open = uidialog.openOnPeerCheckBox->isChecked(); 0160 const int currentDeviceIndex = uidialog.devicePicker->currentIndex(); 0161 if (!url.isEmpty() && currentDeviceIndex >= 0) { 0162 const QString device = proxyModel.index(currentDeviceIndex, 0).data(DevicesModel::IdModelRole).toString(); 0163 const QString action = open && url.isLocalFile() ? QStringLiteral("openFile") : QStringLiteral("shareUrl"); 0164 0165 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), 0166 QLatin1String("/modules/kdeconnect/devices/%1/share").arg(device), 0167 QStringLiteral("org.kde.kdeconnect.device.share"), 0168 action); 0169 msg.setArguments({url.toString()}); 0170 blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); 0171 return 0; 0172 } else { 0173 QMessageBox::critical(nullptr, description, i18n("Couldn't share %1", url.toString())); 0174 return 1; 0175 } 0176 } else { 0177 return 1; 0178 } 0179 }