diff --git a/.appveyor.yml b/.appveyor.yml index ee82e927..bc27c9cc 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,5 @@ version: '#{build}' +image: 'Visual Studio 2013' branches: only: - master @@ -7,7 +8,9 @@ clone_depth: 1 build_script: - mkdir build - cd build - - cmake -G "Visual Studio 12 Win64" -DCMAKE_PREFIX_PATH=C:\Qt\5.8\msvc2013_64 .. - - cmake --build . + - cmake -G "Visual Studio 12 Win64" -DCMAKE_CONFIGURATION_TYPES="Release" -DCMAKE_PREFIX_PATH=C:\Qt\5.8\msvc2013_64 .. + - cmake --build . --config Release +artifacts: +- path: build/build/Release/RcloneBrowser.exe test: off deploy: off diff --git a/.travis.yml b/.travis.yml index be8dca61..a227d2e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,17 @@ matrix: - os: osx language: cpp - osx_image: xcode8.2 + osx_image: xcode8.3 + install: + - brew update + - brew install qt5 + script: + - mkdir build && cd build + - cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake .. + - cmake --build . + - os: osx + language: cpp + osx_image: xcode9.4 install: - brew update - brew install qt5 diff --git a/README.md b/README.md index 9fa368cf..c3d4f254 100644 --- a/README.md +++ b/README.md @@ -80,21 +80,21 @@ This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. -[1]: https://travis-ci.org/mmozeiko/RcloneBrowser/ -[2]: https://ci.appveyor.com/project/mmozeiko/RcloneBrowser -[3]: https://github.com/mmozeiko/RcloneBrowser/releases -[4]: https://github.com/mmozeiko/RcloneBrowser/releases/latest -[5]: https://github.com/mmozeiko/RcloneBrowser/blob/master/LICENSE +[1]: https://travis-ci.org/DinCahill/RcloneBrowser/ +[2]: https://ci.appveyor.com/project/DinCahill/RcloneBrowser +[3]: https://github.com/DinCahill/RcloneBrowser/releases +[4]: https://github.com/DinCahill/RcloneBrowser/releases/latest +[5]: https://github.com/DinCahill/RcloneBrowser/blob/master/LICENSE [6]: https://mpv.io/ [7]: https://aur.archlinux.org/packages/rclone-browser [8]: https://www.visualstudio.com/en-us/news/releasenotes/vs2013-community-vs [9]: http://www.cmake.org/ [10]: https://www.qt.io/download-open-source/ -[img1]: https://api.travis-ci.org/mmozeiko/RcloneBrowser.svg?branch=master -[img2]: https://ci.appveyor.com/api/projects/status/7s24ixolrk3ueggm/branch/master?svg=true -[img3]: https://img.shields.io/github/downloads/mmozeiko/RcloneBrowser/total.svg?maxAge=3600 -[img4]: https://img.shields.io/github/release/mmozeiko/RcloneBrowser.svg?maxAge=3600 -[img5]: https://img.shields.io/github/license/mmozeiko/RcloneBrowser.svg?maxAge=2592000 +[img1]: https://api.travis-ci.org/DinCahill/RcloneBrowser.svg?branch=master +[img2]: https://ci.appveyor.com/api/projects/status/github/DinCahill/RcloneBrowser?branch=master&svg=true +[img3]: https://img.shields.io/github/downloads/DinCahill/RcloneBrowser/total.svg?maxAge=3600 +[img4]: https://img.shields.io/github/release/DinCahill/RcloneBrowser.svg?maxAge=3600 +[img5]: https://img.shields.io/github/license/DinCahill/RcloneBrowser.svg?maxAge=2592000 [screenshot1]: https://raw.githubusercontent.com/wiki/mmozeiko/RcloneBrowser/screenshot1.png [screenshot2]: https://raw.githubusercontent.com/wiki/mmozeiko/RcloneBrowser/screenshot2.png [screenshot3]: https://raw.githubusercontent.com/wiki/mmozeiko/RcloneBrowser/screenshot3.png diff --git a/src/images/mega.png b/src/images/mega.png new file mode 100644 index 00000000..0007bcec Binary files /dev/null and b/src/images/mega.png differ diff --git a/src/item_model.cpp b/src/item_model.cpp index 676970f3..74737a1a 100644 --- a/src/item_model.cpp +++ b/src/item_model.cpp @@ -618,8 +618,9 @@ void ItemModel::load(const QPersistentModelIndex& parentIndex, Item* parent) else if (path.at(0) != '/') { path = "/" + path; } - lsd->start(GetRclone(), QStringList() << "lsd" << GetRcloneConf() << mRemote + ":" + path, QIODevice::ReadOnly); - lsl->start(GetRclone(), QStringList() << "lsl" << GetRcloneConf() << "--max-depth" << "1" << mRemote + ":" + path, QIODevice::ReadOnly); + + lsd->start(GetRclone(), QStringList() << "lsd" << GetRcloneConf() << GetDriveSharedWithMe() << GetShowHidden() << mRemote + ":" + path, QIODevice::ReadOnly); + lsl->start(GetRclone(), QStringList() << "lsl" << GetRcloneConf() << GetDriveSharedWithMe() << GetShowHidden() << "--max-depth" << "1" << mRemote + ":" + path, QIODevice::ReadOnly); } void ItemModel::sortRecursive(Item* item, const ItemSorter& sorter) diff --git a/src/main_window.cpp b/src/main_window.cpp index 13b75203..e41faf5c 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -48,6 +48,7 @@ MainWindow::MainWindow() settings->setValue("Settings/showFolderIcons", dialog.getShowFolderIcons()); settings->setValue("Settings/showFileIcons", dialog.getShowFileIcons()); settings->setValue("Settings/rowColors", dialog.getRowColors()); + settings->setValue("Settings/showHidden", dialog.getShowHidden()); SetRclone(dialog.getRclone()); SetRcloneConf(dialog.getRcloneConf()); mFirstTime = true; diff --git a/src/preferences_dialog.cpp b/src/preferences_dialog.cpp index abdcb42b..ecc5f597 100644 --- a/src/preferences_dialog.cpp +++ b/src/preferences_dialog.cpp @@ -62,6 +62,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) } ui.showFileIcons->setChecked(settings->value("Settings/showFileIcons", true).toBool()); ui.rowColors->setChecked(settings->value("Settings/rowColors", false).toBool()); + ui.showHidden->setChecked(settings->value("Settings/showHidden", true).toBool()); #ifdef Q_OS_WIN32 ui.mount->hide(); @@ -124,3 +125,8 @@ bool PreferencesDialog::getRowColors() const { return ui.rowColors->isChecked(); } + +bool PreferencesDialog::getShowHidden() const +{ + return ui.showHidden->isChecked(); +} diff --git a/src/preferences_dialog.h b/src/preferences_dialog.h index 089dbe29..abbfc852 100644 --- a/src/preferences_dialog.h +++ b/src/preferences_dialog.h @@ -23,6 +23,7 @@ class PreferencesDialog : public QDialog bool getShowFolderIcons() const; bool getShowFileIcons() const; bool getRowColors() const; + bool getShowHidden() const; private: Ui::PreferencesDialog ui; diff --git a/src/preferences_dialog.ui b/src/preferences_dialog.ui index 30d99587..50a9277d 100644 --- a/src/preferences_dialog.ui +++ b/src/preferences_dialog.ui @@ -7,7 +7,7 @@ 0 0 475 - 407 + 547 @@ -128,7 +128,7 @@ User Interface - + Changing these options will require reopening remote tab. @@ -148,7 +148,7 @@ - + Alternating row colors @@ -168,6 +168,13 @@ + + + + Show hidden files and folders + + + diff --git a/src/progress_dialog.cpp b/src/progress_dialog.cpp index e2ccab57..390bfc5a 100644 --- a/src/progress_dialog.cpp +++ b/src/progress_dialog.cpp @@ -1,6 +1,6 @@ #include "progress_dialog.h" -ProgressDialog::ProgressDialog(const QString& title, const QString& operation, const QString& message, QProcess* process, QWidget* parent, bool close) +ProgressDialog::ProgressDialog(const QString& title, const QString& operation, const QString& message, QProcess* process, QWidget* parent, bool close, bool trim) : QDialog(parent) { ui.setupUi(this); @@ -45,6 +45,10 @@ ProgressDialog::ProgressDialog(const QString& title, const QString& operation, c QObject::connect(process, &QProcess::readyRead, this, [=]() { QString output = process->readAll(); + if (trim) + { + output = output.trimmed(); + } ui.output->appendPlainText(output); emit outputAvailable(output); }); diff --git a/src/progress_dialog.h b/src/progress_dialog.h index b8121246..a8662808 100644 --- a/src/progress_dialog.h +++ b/src/progress_dialog.h @@ -8,7 +8,7 @@ class ProgressDialog : public QDialog Q_OBJECT public: - ProgressDialog(const QString& title, const QString& operation, const QString& message, QProcess* process, QWidget* parent = nullptr, bool close = true); + ProgressDialog(const QString& title, const QString& operation, const QString& message, QProcess* process, QWidget* parent = nullptr, bool close = true, bool trim = false); ~ProgressDialog(); void expand(); diff --git a/src/remote_widget.cpp b/src/remote_widget.cpp index f5796555..864c691c 100644 --- a/src/remote_widget.cpp +++ b/src/remote_widget.cpp @@ -18,6 +18,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL #endif auto settings = GetSettings(); ui.tree->setAlternatingRowColors(settings->value("Settings/rowColors", false).toBool()); + ui.checkBoxShared->setChecked(settings->value("Settings/driveShared", false).toBool()); QStyle* style = QApplication::style(); ui.refresh->setIcon(style->standardIcon(QStyle::SP_BrowserReload)); @@ -32,6 +33,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL ui.download->setIcon(style->standardIcon(QStyle::SP_ArrowDown)); ui.getSize->setIcon(style->standardIcon(QStyle::SP_FileDialogInfoView)); ui.export_->setIcon(style->standardIcon(QStyle::SP_FileDialogDetailedView)); + ui.link->setIcon(style->standardIcon(QStyle::SP_FileLinkIcon)); ui.buttonRefresh->setDefaultAction(ui.refresh); ui.buttonMkdir->setDefaultAction(ui.mkdir); @@ -91,9 +93,11 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL else { ui.refresh->setDisabled(false); - ui.rename->setDisabled(topLevel); - ui.move->setDisabled(topLevel); - ui.purge->setDisabled(topLevel); + bool driveShared = ui.checkBoxShared->checkState(); + ui.rename->setDisabled(topLevel || driveShared); + ui.move->setDisabled(topLevel || driveShared); + ui.purge->setDisabled(topLevel || driveShared); + ui.upload->setDisabled(driveShared); ui.mount->setDisabled(!isFolder); ui.stream->setDisabled(isFolder); path = model->path(index); @@ -129,7 +133,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL QProcess process; UseRclonePassword(&process); process.setProgram(GetRclone()); - process.setArguments(QStringList() << "mkdir" << GetRcloneConf() << remote + ":" + folder); + process.setArguments(QStringList() << "mkdir" << GetRcloneConf() << GetDriveSharedWithMe() << remote + ":" + folder); process.setReadChannelMode(QProcess::MergedChannels); ProgressDialog progress("New Folder", "Creating...", folderMsg, &process, this); @@ -157,6 +161,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL process.setArguments(QStringList() << "moveto" << GetRcloneConf() + << GetDriveSharedWithMe() << remote + ":" + path << remote + ":" + model->path(index.parent()).filePath(name)); process.setReadChannelMode(QProcess::MergedChannels); @@ -186,6 +191,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL process.setArguments(QStringList() << "move" << GetRcloneConf() + << GetDriveSharedWithMe() << remote + ":" + path << remote + ":" + name); process.setReadChannelMode(QProcess::MergedChannels); @@ -211,7 +217,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL QProcess process; UseRclonePassword(&process); process.setProgram(GetRclone()); - process.setArguments(QStringList() << (model->isFolder(index) ? "purge" : "delete") << GetRcloneConf() << remote + ":" + path); + process.setArguments(QStringList() << (model->isFolder(index) ? "purge" : "delete") << GetRcloneConf() << GetDriveSharedWithMe() << remote + ":" + path); process.setReadChannelMode(QProcess::MergedChannels); ProgressDialog progress("Delete", "Deleting...", pathMsg, &process, this); @@ -268,6 +274,44 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL emit addStream(remote + ":" + path, stream); }); + QObject::connect(ui.checkBoxShared, &QCheckBox::toggled, ui.shared, &QAction::toggled); + + QObject::connect(ui.shared, &QAction::toggled, this, [=](const bool checked) + { + auto settings = GetSettings(); + settings->setValue("Settings/driveShared", checked); + ui.checkBoxShared->setChecked(checked); + + QModelIndex index = ui.tree->selectionModel()->selectedRows().front(); + QModelIndex top = index; + while (!model->isTopLevel(top)) + { + top = top.parent(); + } + ui.tree->selectionModel()->clear(); + ui.tree->selectionModel()->select(top, QItemSelectionModel::Select | QItemSelectionModel::Rows); + model->refresh(top); + }); + + QObject::connect(ui.link, &QAction::triggered, this, [=]() + { + QModelIndex index = ui.tree->selectionModel()->selectedRows().front(); + + QString path = model->path(index).path(); + QString pathMsg = isLocal ? QDir::toNativeSeparators(path) : path; + + QProcess process; + UseRclonePassword(&process); + process.setProgram(GetRclone()); + process.setArguments(QStringList() << "link" << GetRcloneConf() << GetDriveSharedWithMe() << remote + ":" + path); + process.setReadChannelMode(QProcess::MergedChannels); + + ProgressDialog progress("Fetch Public Link", "Fetching link for...", pathMsg, &process, this, false, true); + progress.expand(); + progress.allowToClose(); + progress.exec(); + }); + QObject::connect(ui.upload, &QAction::triggered, this, [=]() { QModelIndex index = ui.tree->selectionModel()->selectedRows().front(); @@ -314,7 +358,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL QProcess process; UseRclonePassword(&process); process.setProgram(GetRclone()); - process.setArguments(QStringList() << "size" << GetRcloneConf() << remote + ":" + path); + process.setArguments(QStringList() << "size" << GetRcloneConf() << GetDriveSharedWithMe() << remote + ":" + path); process.setReadChannelMode(QProcess::MergedChannels); ProgressDialog progress("Get Size", "Calculating...", pathMsg, &process, this, false); @@ -347,7 +391,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL QProcess process; UseRclonePassword(&process); process.setProgram(GetRclone()); - process.setArguments(QStringList() << GetRcloneConf() << e.getOptions()); + process.setArguments(QStringList() << GetRcloneConf() << GetDriveSharedWithMe() << e.getOptions()); process.setReadChannelMode(QProcess::MergedChannels); ProgressDialog progress("Export", "Exporting...", dst, &process, this); @@ -417,6 +461,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL menu.addAction(ui.stream); menu.addAction(ui.upload); menu.addAction(ui.download); + menu.addAction(ui.link); menu.exec(ui.tree->viewport()->mapToGlobal(pos)); }); diff --git a/src/remote_widget.ui b/src/remote_widget.ui index a66d58fe..826530ca 100644 --- a/src/remote_widget.ui +++ b/src/remote_widget.ui @@ -6,7 +6,7 @@ 0 0 - 784 + 879 552 @@ -161,6 +161,16 @@ + + + + Shared with Me (Google Drive) + + + Shared + + + @@ -290,6 +300,16 @@ M&ove + + + Shared + + + + + Public Link + + buttonRefresh diff --git a/src/resources.qrc b/src/resources.qrc index 04efd65f..d9ac1107 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -11,6 +11,7 @@ images/google_cloud_storage.png images/hubic.png images/local.png + images/mega.png images/onedrive.png images/s3.png images/swift.png diff --git a/src/transfer_dialog.cpp b/src/transfer_dialog.cpp index cddc4b4b..97c5d21f 100644 --- a/src/transfer_dialog.cpp +++ b/src/transfer_dialog.cpp @@ -272,6 +272,8 @@ QStringList TransferDialog::getOptions() const } } + list << GetDriveSharedWithMe(); + list << "--stats" << "1s"; list << ui.textSource->text(); diff --git a/src/utils.cpp b/src/utils.cpp index 50f18453..ca98b233 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -143,7 +143,7 @@ QStringList GetRcloneConf() { conf = QDir(qApp->applicationDirPath()).filePath(conf); } - return QStringList() << " --config" << conf; + return QStringList() << "--config" << conf; } void SetRcloneConf(const QString& rcloneConf) @@ -181,3 +181,24 @@ void SetRclonePassword(const QString& rclonePassword) { gRclonePassword = rclonePassword; } + +QStringList GetDriveSharedWithMe() { + auto settings = GetSettings(); + bool driveShared = settings->value("Settings/driveShared", false).toBool(); + QStringList driveSharedOption; + if (driveShared) { + driveSharedOption << "--drive-shared-with-me"; + } + return driveSharedOption; +} + +QStringList GetShowHidden() +{ + auto settings = GetSettings(); + bool showHidden = settings->value("Settings/showHidden", true).toBool(); + QStringList showHiddenOption; + if (!showHidden) { + showHiddenOption << "--exclude" << ".*/**"; + } + return showHiddenOption; +} diff --git a/src/utils.h b/src/utils.h index 28130ccf..9b7fed6c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -15,3 +15,6 @@ void SetRcloneConf(const QString& rcloneConf); void UseRclonePassword(QProcess* process); void SetRclonePassword(const QString& rclonePassword); + +QStringList GetDriveSharedWithMe(); +QStringList GetShowHidden();