Skip to content

Commit 6b2bec5

Browse files
author
Andy Ibanez
authored
Merge pull request #1 from jonaknop/master
Noteworthy changes. Most requested feature in the rclone forums is to fix the output, as rclone 1.43 changes the output format.
2 parents 7106638 + 95a8569 commit 6b2bec5

File tree

9 files changed

+199
-15
lines changed

9 files changed

+199
-15
lines changed

‎bootstrap-vs15.cmd‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@echo off
2+
3+
if "%QTDIR%" EQU "" (
4+
set QT=C:\Qt\5.10.0\msvc2017_64
5+
) else (
6+
set QT=%QTDIR%
7+
)
8+
set Qt5Core_DIR=%QT%
9+
set Qt5Gui_DIR=%QT%
10+
set Qt5Widgets_DIR=%QT%
11+
set Qt5WinExtras_DIR=%QT%
12+
set PATH=%QT%\bin;%PATH%
13+
14+
set _IsNativeEnvironment=true
15+
call "%VS150COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" x64
16+
17+
set BUILD="%~dp0build"
18+
19+
mkdir "%BUILD%" 2>nul
20+
pushd "%BUILD%"
21+
22+
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ..
23+
if %ERRORLEVEL% neq 0 (
24+
popd
25+
exit /b 1
26+
)
27+
devenv /useenv rclone-browser.sln
28+
29+
popd

‎bootstrap.cmd‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ if "%QTDIR%" EQU "" (
55
) else (
66
set QT=%QTDIR%
77
)
8+
set Qt5Core_DIR=%QT%
9+
set Qt5Gui_DIR=%QT%
10+
set Qt5Widgets_DIR=%QT%
11+
set Qt5WinExtras_DIR=%QT%
812
set PATH=%QT%\bin;%PATH%
913

1014
set _IsNativeEnvironment=true

‎src/CMakeLists.txt‎

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
3+
if (NOT ${CMAKE_VERSION} VERSION_LESS "3.0.0")
4+
cmake_policy(SET CMP0028 NEW)
5+
endif()
6+
if (NOT ${CMAKE_VERSION} VERSION_LESS "2.8.11")
7+
cmake_policy(SET CMP0020 NEW)
8+
endif()
9+
110
if(WIN32)
211
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4100 /wd4189")
312
else()
413
add_definitions("-pedantic -Wall -Wextra -Werror -std=c++11")
514
endif()
615

716
project(rclone-browser)
17+
FIND_PACKAGE(Qt5Core REQUIRED)
18+
FIND_PACKAGE(Qt5Gui REQUIRED)
19+
FIND_PACKAGE(Qt5Widgets REQUIRED)
20+
21+
if (WIN32)
22+
FIND_PACKAGE(Qt5WinExtras REQUIRED)
23+
elseif(APPLE)
24+
FIND_PACKAGE(Qt5MacExtras REQUIRED)
25+
endif()
826

927
set(CMAKE_INCLUDE_CURRENT_DIR ON)
1028

@@ -74,8 +92,25 @@ qt5_add_resources(QRC_OUT ${QRC} OPTIONS "-no-compress")
7492
source_group("" FILES ${SOURCE} ${MOC} ${UI} ${QRC} ${OTHER})
7593
source_group("Generated" FILES ${MOC_OUT} ${UI_OUT} ${MOC_OUT} ${QRC_OUT})
7694

77-
use_pch(pch.h pch.cpp "${SOURCE}")
78-
use_pch(pch.h pch.cpp "${MOC_OUT}")
95+
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
96+
IF(MSVC)
97+
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
98+
SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
99+
SET(Sources ${${SourcesVar}})
100+
101+
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
102+
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
103+
OBJECT_OUTPUTS "${PrecompiledBinary}")
104+
SET_SOURCE_FILES_PROPERTIES(${Sources}
105+
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
106+
OBJECT_DEPENDS "${PrecompiledBinary}")
107+
# Add precompiled header to SourcesVar
108+
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
109+
ENDIF(MSVC)
110+
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
111+
112+
ADD_MSVC_PRECOMPILED_HEADER(pch.h pch.cpp SOURCE)
113+
ADD_MSVC_PRECOMPILED_HEADER(pch.h pch.cpp MOC_OUT)
79114

80115
if(WIN32)
81116
add_executable(RcloneBrowser WIN32 ${SOURCE} ${BACKEND} ${OTHER} ${MOC} ${MOC_OUT} ${UI_OUT} ${MOC_OUT} ${QRC_OUT})

‎src/item_model.cpp‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,15 @@ void ItemModel::load(const QPersistentModelIndex& parentIndex, Item* parent)
611611
timer->start(100);
612612
UseRclonePassword(lsd);
613613
UseRclonePassword(lsl);
614-
lsd->start(GetRclone(), QStringList() << "lsd" << GetRcloneConf() << mRemote + ":" + parent->path.path(), QIODevice::ReadOnly);
615-
lsl->start(GetRclone(), QStringList() << "lsl" << GetRcloneConf() << "--max-depth" << "1" << mRemote + ":" + parent->path.path(), QIODevice::ReadOnly);
614+
QString path = parent->path.path();
615+
if (path.trimmed().length() == 0) {
616+
path = "/";
617+
}
618+
else if (path.at(0) != '/') {
619+
path = "/" + path;
620+
}
621+
lsd->start(GetRclone(), QStringList() << "lsd" << GetRcloneConf() << mRemote + ":" + path, QIODevice::ReadOnly);
622+
lsl->start(GetRclone(), QStringList() << "lsl" << GetRcloneConf() << "--max-depth" << "1" << mRemote + ":" + path, QIODevice::ReadOnly);
616623
}
617624

618625
void ItemModel::sortRecursive(Item* item, const ItemSorter& sorter)

‎src/job_widget.cpp‎

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,16 @@ JobWidget::JobWidget(QProcess* process, const QString& info, const QStringList&
6464

6565
QObject::connect(mProcess, &QProcess::readyRead, this, [=]()
6666
{
67-
QRegExp rxSize(R"(^Transferred:\s+(\S+ \S+) \(([^)]+)\)$)");
67+
QRegExp rxSize(R"(^Transferred:\s+(\S+ \S+) \(([^)]+)\)$)"); // Until rclone 1.42
68+
QRegExp rxSize2(R"(^Transferred:\s+([0-9.]+)(\S)? \/ (\S+) (\S+), ([0-9%-]+), (\S+ \S+), (\S+) (\S+)$)"); // Starting with rclone 1.43
6869
QRegExp rxErrors(R"(^Errors:\s+(\S+)$)");
69-
QRegExp rxChecks(R"(^Checks:\s+(\S+)$)");
70-
QRegExp rxTransferred(R"(^Transferred:\s+(\S+)$)");
70+
QRegExp rxChecks(R"(^Checks:\s+(\S+)$)"); // Until rclone 1.42
71+
QRegExp rxChecks2(R"(^Checks:\s+(\S+) \/ (\S+), [0-9%-]+$)"); // Starting with rclone 1.43
72+
QRegExp rxTransferred(R"(^Transferred:\s+(\S+)$)"); // Until rclone 1.42
73+
QRegExp rxTransferred2(R"(^Transferred:\s+(\S+) \/ (\S+), [0-9%-]+$)"); // Starting with rclone 1.43
7174
QRegExp rxTime(R"(^Elapsed time:\s+(\S+)$)");
72-
QRegExp rxProgress(R"(^\*([^:]+):\s*([^%]+)% done.+(ETA: [^)]+)$)");
75+
QRegExp rxProgress(R"(^\*([^:]+):\s*([^%]+)% done.+(ETA: [^)]+)$)"); // Until rclone 1.38
76+
QRegExp rxProgress2(R"(\*([^:]+):\s*([^%]+)% \/[a-zA-z0-9.]+, [a-zA-z0-9.]+\/s, (\w+)$)"); // Starting with rclone 1.39
7377

7478
while (mProcess->canReadLine())
7579
{
@@ -108,6 +112,11 @@ JobWidget::JobWidget(QProcess* process, const QString& info, const QStringList&
108112
ui.size->setText(rxSize.cap(1));
109113
ui.bandwidth->setText(rxSize.cap(2));
110114
}
115+
else if (rxSize2.exactMatch(line))
116+
{
117+
ui.size->setText(rxSize2.cap(1) + " " + rxSize2.cap(2) + "Bytes");
118+
ui.bandwidth->setText(rxSize2.cap(6));
119+
}
111120
else if (rxErrors.exactMatch(line))
112121
{
113122
ui.errors->setText(rxErrors.cap(1));
@@ -116,10 +125,18 @@ JobWidget::JobWidget(QProcess* process, const QString& info, const QStringList&
116125
{
117126
ui.checks->setText(rxChecks.cap(1));
118127
}
128+
else if (rxChecks2.exactMatch(line))
129+
{
130+
ui.checks->setText(rxChecks2.cap(1));
131+
}
119132
else if (rxTransferred.exactMatch(line))
120133
{
121134
ui.transferred->setText(rxTransferred.cap(1));
122135
}
136+
else if (rxTransferred2.exactMatch(line))
137+
{
138+
ui.transferred->setText(rxTransferred2.cap(1));
139+
}
123140
else if (rxTime.exactMatch(line))
124141
{
125142
ui.elapsed->setText(rxTime.cap(1));
@@ -157,6 +174,41 @@ JobWidget::JobWidget(QProcess* process, const QString& info, const QStringList&
157174
bar->setValue(rxProgress.cap(2).toInt());
158175
bar->setToolTip(rxProgress.cap(3));
159176

177+
mUpdated.insert(label);
178+
}
179+
else if (rxProgress2.exactMatch(line))
180+
{
181+
QString name = rxProgress2.cap(1).trimmed();
182+
183+
auto it = mActive.find(name);
184+
185+
QLabel* label;
186+
QProgressBar* bar;
187+
if (it == mActive.end())
188+
{
189+
label = new QLabel();
190+
label->setText(name);
191+
192+
bar = new QProgressBar();
193+
bar->setMinimum(0);
194+
bar->setMaximum(100);
195+
bar->setTextVisible(true);
196+
197+
label->setBuddy(bar);
198+
199+
ui.progress->addRow(label, bar);
200+
201+
mActive.insert(name, label);
202+
}
203+
else
204+
{
205+
label = it.value();
206+
bar = static_cast<QProgressBar*>(label->buddy());
207+
}
208+
209+
bar->setValue(rxProgress2.cap(2).toInt());
210+
bar->setToolTip("ETA: " + rxProgress2.cap(3));
211+
160212
mUpdated.insert(label);
161213
}
162214
}

‎src/main_window.cpp‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ MainWindow::MainWindow()
171171
}
172172
if (rclone.isEmpty())
173173
{
174-
QMessageBox::information(this, "Error", "Cannot check rclone verison!\nPlease verify rclone location.");
174+
QMessageBox::information(this, "Error", "Cannot check rclone version!\nPlease verify rclone location.");
175175
emit ui.preferences->trigger();
176176
}
177177
else
@@ -198,6 +198,11 @@ void MainWindow::rcloneGetVersion()
198198
if (code == 0)
199199
{
200200
QString version = p->readAllStandardOutput().trimmed();
201+
int lineBreak = version.indexOf('\n');
202+
if (lineBreak != -1)
203+
{
204+
version.remove(lineBreak, version.length() - lineBreak);
205+
}
201206
mStatusMessage->setText(version + " in " + QDir::toNativeSeparators(GetRclone()));
202207
rcloneListRemotes();
203208
}
@@ -570,6 +575,8 @@ void MainWindow::addMount(const QString& remote, const QString& folder)
570575

571576
QStringList args;
572577
args << "mount";
578+
args << "--vfs-cache-mode";
579+
args << "writes";
573580
args.append(GetRcloneConf());
574581
if (!opt.isEmpty())
575582
{

‎src/remote_widget.cpp‎

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
1313

1414
QString root = isLocal ? "/" : QString();
1515

16-
#ifdef Q_OS_WIN32
17-
ui.mount->setVisible(false);
18-
ui.buttonMount->setVisible(false);
19-
#else
16+
#ifndef Q_OS_WIN32
2017
isLocal = false;
2118
#endif
2219
auto settings = GetSettings();
@@ -26,6 +23,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
2623
ui.refresh->setIcon(style->standardIcon(QStyle::SP_BrowserReload));
2724
ui.mkdir->setIcon(style->standardIcon(QStyle::SP_FileDialogNewFolder));
2825
ui.rename->setIcon(style->standardIcon(QStyle::SP_FileIcon));
26+
ui.move->setIcon(style->standardIcon(QStyle::SP_DirOpenIcon));
2927
ui.purge->setIcon(style->standardIcon(QStyle::SP_TrashIcon));
3028
ui.mount->setIcon(style->standardIcon(QStyle::SP_DirLinkIcon));
3129
ui.stream->setIcon(style->standardIcon(QStyle::SP_MediaPlay));
@@ -38,6 +36,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
3836
ui.buttonRefresh->setDefaultAction(ui.refresh);
3937
ui.buttonMkdir->setDefaultAction(ui.mkdir);
4038
ui.buttonRename->setDefaultAction(ui.rename);
39+
ui.buttonMove->setDefaultAction(ui.move);
4140
ui.buttonPurge->setDefaultAction(ui.purge);
4241
ui.buttonMount->setDefaultAction(ui.mount);
4342
ui.buttonStream->setDefaultAction(ui.stream);
@@ -82,6 +81,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
8281
if (model->isLoading(index))
8382
{
8483
ui.refresh->setDisabled(true);
84+
ui.move->setDisabled(true);
8585
ui.rename->setDisabled(true);
8686
ui.purge->setDisabled(true);
8787
ui.mount->setDisabled(true);
@@ -92,6 +92,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
9292
{
9393
ui.refresh->setDisabled(false);
9494
ui.rename->setDisabled(topLevel);
95+
ui.move->setDisabled(topLevel);
9596
ui.purge->setDisabled(topLevel);
9697
ui.mount->setDisabled(!isFolder);
9798
ui.stream->setDisabled(isFolder);
@@ -154,7 +155,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
154155
UseRclonePassword(&process);
155156
process.setProgram(GetRclone());
156157
process.setArguments(QStringList()
157-
<< "move"
158+
<< "moveto"
158159
<< GetRcloneConf()
159160
<< remote + ":" + path
160161
<< remote + ":" + model->path(index.parent()).filePath(name));
@@ -168,6 +169,35 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
168169
}
169170
});
170171

172+
QObject::connect(ui.move, &QAction::triggered, this, [=]()
173+
{
174+
QModelIndex index = ui.tree->selectionModel()->selectedRows().front();
175+
176+
QString path = model->path(index).path();
177+
QString pathMsg = isLocal ? QDir::toNativeSeparators(path) : path;
178+
179+
QString name = model->path(index.parent()).path() + "/";
180+
name = QInputDialog::getText(this, "Move", QString("New location for %1").arg(pathMsg), QLineEdit::Normal, name);
181+
if (!name.isEmpty())
182+
{
183+
QProcess process;
184+
UseRclonePassword(&process);
185+
process.setProgram(GetRclone());
186+
process.setArguments(QStringList()
187+
<< "move"
188+
<< GetRcloneConf()
189+
<< remote + ":" + path
190+
<< remote + ":" + name);
191+
process.setReadChannelMode(QProcess::MergedChannels);
192+
193+
ProgressDialog progress("Move", "Moving...", pathMsg, &process, this);
194+
if (progress.exec() == QDialog::Accepted)
195+
{
196+
model->refresh(index);
197+
}
198+
}
199+
});
200+
171201
QObject::connect(ui.purge, &QAction::triggered, this, [=]()
172202
{
173203
QModelIndex index = ui.tree->selectionModel()->selectedRows().front();
@@ -202,7 +232,11 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
202232
QString path = model->path(index).path();
203233
QString pathMsg = isLocal ? QDir::toNativeSeparators(path) : path;
204234

235+
#ifdef Q_OS_WIN32
236+
QString folder = QInputDialog::getText(this, "Mount", QString("Drive to mount %1 to").arg(pathMsg), QLineEdit::Normal, "Z:");
237+
#else
205238
QString folder = QFileDialog::getExistingDirectory(this, QString("Mount %1").arg(pathMsg));
239+
#endif
206240
if (!folder.isEmpty())
207241
{
208242
emit addMount(remote + ":" + path, folder);
@@ -376,6 +410,7 @@ RemoteWidget::RemoteWidget(IconCache* iconCache, const QString& remote, bool isL
376410
menu.addSeparator();
377411
menu.addAction(ui.mkdir);
378412
menu.addAction(ui.rename);
413+
menu.addAction(ui.move);
379414
menu.addAction(ui.purge);
380415
menu.addSeparator();
381416
menu.addAction(ui.mount);

‎src/remote_widget.ui‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@
8181
</property>
8282
</widget>
8383
</item>
84+
<item>
85+
<widget class="QToolButton" name="buttonMove">
86+
<property name="text">
87+
<string>M&amp;ove</string>
88+
</property>
89+
<property name="toolButtonStyle">
90+
<enum>Qt::ToolButtonTextBesideIcon</enum>
91+
</property>
92+
</widget>
93+
</item>
8494
<item>
8595
<widget class="QToolButton" name="buttonPurge">
8696
<property name="text">
@@ -275,6 +285,11 @@
275285
<string>E&amp;xport</string>
276286
</property>
277287
</action>
288+
<action name="move">
289+
<property name="text">
290+
<string>M&amp;ove</string>
291+
</property>
292+
</action>
278293
</widget>
279294
<tabstops>
280295
<tabstop>buttonRefresh</tabstop>

‎src/utils.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ QStringList GetRcloneConf()
143143
{
144144
conf = QDir(qApp->applicationDirPath()).filePath(conf);
145145
}
146-
return QStringList() << "--config" << conf;
146+
return QStringList() << " --config" << conf;
147147
}
148148

149149
void SetRcloneConf(const QString& rcloneConf)

0 commit comments

Comments
 (0)