From 5247da3543d86af7a3cc9f6aa142595b97c21ed4 Mon Sep 17 00:00:00 2001 From: yvbbrjdr Date: Sun, 16 May 2021 21:48:04 -0700 Subject: [PATCH] ui: Add drag and drop functionality --- LANDrop/LANDrop.pro | 3 + LANDrop/locales/LANDrop.zh_CN.qm | Bin 14490 -> 14748 bytes LANDrop/locales/LANDrop.zh_CN.ts | 63 +++++++++----- LANDrop/selectfilesdialog.cpp | 142 +++++++++++++++++++++++++++++++ LANDrop/selectfilesdialog.h | 64 ++++++++++++++ LANDrop/selectfilesdialog.ui | 102 ++++++++++++++++++++++ LANDrop/sendtodialog.cpp | 1 - LANDrop/sendtodialog.ui | 6 +- LANDrop/trayicon.cpp | 35 +------- 9 files changed, 361 insertions(+), 55 deletions(-) create mode 100644 LANDrop/selectfilesdialog.cpp create mode 100644 LANDrop/selectfilesdialog.h create mode 100644 LANDrop/selectfilesdialog.ui diff --git a/LANDrop/LANDrop.pro b/LANDrop/LANDrop.pro index 787d390..c30b649 100644 --- a/LANDrop/LANDrop.pro +++ b/LANDrop/LANDrop.pro @@ -12,6 +12,7 @@ SOURCES += \ filetransferserver.cpp \ filetransfersession.cpp \ main.cpp \ + selectfilesdialog.cpp \ sendtodialog.cpp \ settings.cpp \ settingsdialog.cpp \ @@ -26,6 +27,7 @@ HEADERS += \ filetransfersender.h \ filetransferserver.h \ filetransfersession.h \ + selectfilesdialog.h \ sendtodialog.h \ settings.h \ settingsdialog.h \ @@ -34,6 +36,7 @@ HEADERS += \ FORMS += \ aboutdialog.ui \ filetransferdialog.ui \ + selectfilesdialog.ui \ sendtodialog.ui \ settingsdialog.ui diff --git a/LANDrop/locales/LANDrop.zh_CN.qm b/LANDrop/locales/LANDrop.zh_CN.qm index ab6b8f12d9e5eb247f61c5fd17ecbe0413f9da89..29244deb702ef451e17769f952727d371a4a2a91 100644 GIT binary patch delta 645 zcmbPLIH!1moZ$)v1_mnz2IKt<42FCR45m5^EazDm7|gCRu$E0>U@*DLAiicF1B3ZI z2BldVK>4o|{pEs;7Bgq>e8<3`rNTVX0!W*uFmK+Xz`&qu&LSN3k%7VB5=&Jf&@{tu ztRl_x7#NInSS3_}eC@ZaHd}x;Y0qFSn|=VO&yuyr?I=*bc;b3R_0}U@K!?P$O}D=X z)Y{Izy5}*F|ByqOV;uv7o;*jo?joSWeocHYR&UzIF^e^hfkD5QS&plV%C`yQY{ zra_!JiC-8PG>tiPO6!2CmvI(yUuR&@`NO$r^AVtTcsY-x{|D0lIL}K1O*QD_N?!nU zi0)CYsv~|thkWDu$pqBLz`$J+#RpX9#lvmA18DAEp0u0)fUYRv*~R#dft$fBoo6>= zG0*~w$^DGVOy(ChZ(-~(oUCjX?I9SPnv_8@_uF1E}Or0==!G^I^{+^bCFeWH9H@_?uhcV6OjzXBmOt!QL z&%qQ1n=av>5d7ZnY0|Z%zp3qh-x@z>r&LW3e*9kwZlh9UeyKuoVxB@uQDVA68px{( sCHV>^8JWcj<(YXY`Q=vVu9>{hM0B&K@m;3LJ!YYk<;^oEUoy`C02FY*uK)l5 delta 325 zcmbPJJgabmoZ$op1_mnz2E%qB=3`(m`oh3+o`r$Il$n9GYzmM+mqC2ZJ_ZJ}5C)}L z8Vn4^dnfwKX_;PN&ffWsfk8`!d7=f7Hj`rByhVY5LD!r`IO-z+_oQ#2;d z7h^JAI&r_E`E>hx3=AfD?5leo1Fc%gq0F(4fk986BVBh9P+=NJVQ3!%gEkLGMJG_B z=5>yW$F4x@{3gpYifI{3apoj`0SX&)=9Ja}jk&^E$bFrGLFW(WqRmHu#$Dw+lKvm) z+GCUB8O4mu+PHo)0hKW@aF;~!0fmKlxUF{pO>5;zyZH}jYYERTMxe7z^m%qO76WO9 z$;%m)narMTKEv2yxVgvl71QK! 你的系统需要支持托盘图标。 + + SelectFilesDialog + + + + Select File(s) to be Sent + 请选择想要发送的文件 + + + + You can drag files to this window: + 你可以拖拽文件至此窗口: + + + + Add... + 添加... + + + + Remove + 移除 + + + + Unable to open file %1. Skipping. + 无法打开文件 %1。已跳过该文件。 + + + + %1 is not a regular file. Skipping. + %1 不是一个普通文件。已跳过该文件。 + + + + No file to be sent. + 无文件可发送。 + + SendToDialog @@ -240,12 +279,12 @@ Would you like to receive it? 端口 - + Invalid port. Please enter a number between 1 and 65535. 无效端口。请输入一个 1 到 65535 的数字。 - + Connection timed out 连接超时 @@ -320,25 +359,5 @@ Would you like to receive it? is launched here. 已隐藏于托盘。 - - - Select File(s) to be Sent - 请选择想要发送的文件 - - - - Unable to open file %1. Skipping. - 无法打开文件 %1。已跳过该文件。 - - - - %1 is not a regular file. Skipping. - %1 不是一个普通文件。已跳过该文件。 - - - - No file to be sent. - 无文件可发送。 - diff --git a/LANDrop/selectfilesdialog.cpp b/LANDrop/selectfilesdialog.cpp new file mode 100644 index 0000000..582a8f4 --- /dev/null +++ b/LANDrop/selectfilesdialog.cpp @@ -0,0 +1,142 @@ +/* + * BSD 3-Clause License + * + * Copyright (c) 2021, LANDrop + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "selectfilesdialog.h" +#include "sendtodialog.h" +#include "ui_selectfilesdialog.h" + +SelectFilesDialog::SelectFilesDialog(QWidget *parent, DiscoveryService &discoveryService) : + QDialog(parent), ui(new Ui::SelectFilesDialog), discoveryService(discoveryService) +{ + ui->setupUi(this); + setWindowFlag(Qt::WindowStaysOnTopHint); + connect(ui->addButton, &QPushButton::clicked, this, &SelectFilesDialog::addButtonClicked); + connect(ui->removeButton, &QPushButton::clicked, this, &SelectFilesDialog::removeButtonClicked); + ui->filesListView->setModel(&filesStringListModel); +} + +SelectFilesDialog::~SelectFilesDialog() +{ + delete ui; +} + +void SelectFilesDialog::addFile(const QString &filename) +{ + foreach (QSharedPointer file, files) { + if (file->fileName() == filename) + return; + } + + QSharedPointer fp = QSharedPointer::create(filename); + if (!fp->open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, QApplication::applicationName(), + tr("Unable to open file %1. Skipping.") + .arg(filename)); + return; + } + if (fp->isSequential()) { + QMessageBox::critical(this, QApplication::applicationName(), + tr("%1 is not a regular file. Skipping.") + .arg(filename)); + return; + } + files.append(fp); +} + +void SelectFilesDialog::updateFileStringListModel() +{ + QStringList l; + foreach (QSharedPointer file, files) { + l.append(QFileInfo(*file).fileName()); + } + filesStringListModel.setStringList(l); +} + +void SelectFilesDialog::addButtonClicked() +{ + QStringList filenames = QFileDialog::getOpenFileNames(nullptr, tr("Select File(s) to be Sent")); + if (filenames.empty()) + return; + + foreach (const QString &filename, filenames) { + addFile(filename); + } + + updateFileStringListModel(); +} + +void SelectFilesDialog::removeButtonClicked() +{ + QModelIndexList indexes = ui->filesListView->selectionModel()->selectedIndexes(); + QList *> removeList; + foreach (const QModelIndex &i, indexes) { + removeList.append(&files.at(i.row())); + } + foreach (const QSharedPointer *fp, removeList) { + files.removeOne(*fp); + } + updateFileStringListModel(); +} + +void SelectFilesDialog::accept() +{ + if (files.empty()) { + QMessageBox::warning(this, QApplication::applicationName(), tr("No file to be sent.")); + return; + } + + SendToDialog *d = new SendToDialog(nullptr, files, discoveryService); + d->setAttribute(Qt::WA_DeleteOnClose); + d->show(); + + done(Accepted); +} + +void SelectFilesDialog::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void SelectFilesDialog::dropEvent(QDropEvent *event) +{ + foreach (const QUrl &url, event->mimeData()->urls()) { + addFile(url.toLocalFile()); + } + updateFileStringListModel(); +} diff --git a/LANDrop/selectfilesdialog.h b/LANDrop/selectfilesdialog.h new file mode 100644 index 0000000..78751b4 --- /dev/null +++ b/LANDrop/selectfilesdialog.h @@ -0,0 +1,64 @@ +/* + * BSD 3-Clause License + * + * Copyright (c) 2021, LANDrop + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include + +#include "discoveryservice.h" + +namespace Ui { + class SelectFilesDialog; +} + +class SelectFilesDialog : public QDialog { + Q_OBJECT +public: + explicit SelectFilesDialog(QWidget *parent, DiscoveryService &discoveryService); + ~SelectFilesDialog(); +private: + Ui::SelectFilesDialog *ui; + DiscoveryService &discoveryService; + QList> files; + QStringListModel filesStringListModel; + void addFile(const QString &filename); + void updateFileStringListModel(); +private slots: + void addButtonClicked(); + void removeButtonClicked(); + void accept(); +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); +}; diff --git a/LANDrop/selectfilesdialog.ui b/LANDrop/selectfilesdialog.ui new file mode 100644 index 0000000..a13ef18 --- /dev/null +++ b/LANDrop/selectfilesdialog.ui @@ -0,0 +1,102 @@ + + + SelectFilesDialog + + + + 0 + 0 + 390 + 383 + + + + true + + + Select File(s) to be Sent + + + + + + You can drag files to this window: + + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::ExtendedSelection + + + + + + + + + Add... + + + + + + + Remove + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SelectFilesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SelectFilesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/LANDrop/sendtodialog.cpp b/LANDrop/sendtodialog.cpp index d5b225a..6a1d648 100644 --- a/LANDrop/sendtodialog.cpp +++ b/LANDrop/sendtodialog.cpp @@ -45,7 +45,6 @@ SendToDialog::SendToDialog(QWidget *parent, const QList> & ui->setupUi(this); setWindowFlag(Qt::WindowStaysOnTopHint); ui->hostsListView->setModel(&hostsStringListModel); - ui->hostsListView->setEditTriggers(QListView::NoEditTriggers); connect(ui->hostsListView, &QListView::clicked, this, &SendToDialog::hostsListViewClicked); connect(ui->hostsListView, &QListView::doubleClicked, ui->buttonBox, &QDialogButtonBox::accepted); diff --git a/LANDrop/sendtodialog.ui b/LANDrop/sendtodialog.ui index e3a6966..acf377e 100644 --- a/LANDrop/sendtodialog.ui +++ b/LANDrop/sendtodialog.ui @@ -46,7 +46,11 @@ - + + + QAbstractItemView::NoEditTriggers + + diff --git a/LANDrop/trayicon.cpp b/LANDrop/trayicon.cpp index ca9d7eb..747bef5 100644 --- a/LANDrop/trayicon.cpp +++ b/LANDrop/trayicon.cpp @@ -32,12 +32,12 @@ #include #include -#include -#include +#include #include #include +#include -#include "sendtodialog.h" +#include "selectfilesdialog.h" #include "settings.h" #include "trayicon.h" @@ -89,34 +89,7 @@ TrayIcon::TrayIcon(QObject *parent) : QSystemTrayIcon(parent) void TrayIcon::sendActionTriggered() { - QStringList filenames = QFileDialog::getOpenFileNames(nullptr, tr("Select File(s) to be Sent")); - if (filenames.empty()) - return; - - QList> files; - foreach (const QString &filename, filenames) { - QSharedPointer fp = QSharedPointer::create(filename); - if (!fp->open(QIODevice::ReadOnly)) { - QMessageBox::critical(nullptr, QApplication::applicationName(), - tr("Unable to open file %1. Skipping.") - .arg(filename)); - continue; - } - if (fp->isSequential()) { - QMessageBox::critical(nullptr, QApplication::applicationName(), - tr("%1 is not a regular file. Skipping.") - .arg(filename)); - continue; - } - files.append(fp); - } - - if (files.empty()) { - QMessageBox::warning(nullptr, QApplication::applicationName(), tr("No file to be sent.")); - return; - } - - SendToDialog *d = new SendToDialog(nullptr, files, discoveryService); + SelectFilesDialog *d = new SelectFilesDialog(nullptr, discoveryService); d->setAttribute(Qt::WA_DeleteOnClose); d->show(); }