diff --git a/core/debug.cpp b/core/debug.cpp
index 38a27094..aef97886 100644
--- a/core/debug.cpp
+++ b/core/debug.cpp
@@ -357,7 +357,16 @@ int process_debug_cmd(char *cmdline) {
if (*(file + len - 1) == '"')
*(file + len - 1) = '\0';
usblink_connect();
- usblink_queue_put_file(std::string(file), std::string(ln_target_folder), nullptr, nullptr);
+
+ const char *file_name = file;
+ for (const char *p = file; *p; p++)
+ if (*p == ':' || *p == '/' || *p == '\\')
+ file_name = p + 1;
+
+ if (ln_target_folder.length() < 1 || *ln_target_folder.rbegin() != '/')
+ ln_target_folder += '/';
+
+ usblink_queue_put_file(std::string(file), ln_target_folder + std::string(file_name), nullptr, nullptr);
}
} else if (!strcasecmp(ln_cmd, "st")) {
char *dir = strtok(NULL, " \n\r");
diff --git a/core/usblink.c b/core/usblink.c
index 8a0e9a40..f4b89577 100644
--- a/core/usblink.c
+++ b/core/usblink.c
@@ -278,7 +278,8 @@ void put_file_next(struct packet *in) {
teardown:
throttle_timer_on();
put_file_state = 0;
- fclose(put_file);
+ if (put_file)
+ fclose(put_file);
put_file = NULL;
}
@@ -524,10 +525,10 @@ void usblink_received_packet(const uint8_t *data, uint32_t size) {
}
}
-bool usblink_put_file(const char *filepath, const char *folder, usblink_progress_cb callback, void *user_data) {
+bool usblink_put_file(const char *local, const char *remote, usblink_progress_cb callback, void *user_data) {
mode = File_Send;
- char *dot = strrchr(filepath, '.');
+ char *dot = local ? strrchr(local, '.') : NULL;
// TODO (thanks for the reminder, Excale :P) : Filter depending on which model is being emulated
if (dot && (!strcmp(dot, ".tno") || !strcmp(dot, ".tnc")
|| !strcmp(dot, ".tco") || !strcmp(dot, ".tcc")
@@ -535,37 +536,30 @@ bool usblink_put_file(const char *filepath, const char *folder, usblink_progress
|| !strcmp(dot, ".tco2") || !strcmp(dot, ".tcc2")
|| !strcmp(dot, ".tct2")) ) {
emuprintf("File is an OS, calling usblink_send_os\n");
- usblink_send_os(filepath, callback, user_data);
+ usblink_send_os(local, callback, user_data);
return 1;
}
current_user_data = user_data;
current_file_callback = callback;
- const char *filename = filepath;
- // Hack for android content:// urls
- if(strncmp(filepath, "content://", 10) == 0) {
- for (const char *p = filepath; *p; p++)
- if (strncasecmp(p, "%2F", 3) == 0)
- filename = p + 3;
- }
- else {
- for (const char *p = filepath; *p; p++)
- if (*p == ':' || *p == '/' || *p == '\\')
- filename = p + 1;
- }
-
- FILE *f = fopen_utf8(filepath, "rb");
- if (!f) {
- gui_perror(filepath);
- return 0;
- }
if (put_file)
fclose(put_file);
- put_file = f;
- fseek(f, 0, SEEK_END);
- put_file_size_orig = put_file_size = ftell(f);
- fseek(f, 0, SEEK_SET);
+
+ if (local && local[0] != '\0') {
+ put_file = fopen_utf8(local, "rb");
+ if (!put_file) {
+ gui_perror(local);
+ return 0;
+ }
+ fseek(put_file, 0, SEEK_END);
+ put_file_size_orig = put_file_size = ftell(put_file);
+ fseek(put_file, 0, SEEK_SET);
+ } else {
+ put_file = NULL;
+ put_file_size_orig = put_file_size = 0;
+ }
+
put_file_state = SENDING_03;
/* Send the first packet */
@@ -577,7 +571,7 @@ bool usblink_put_file(const char *filepath, const char *folder, usblink_progress
uint8_t *data = out->data;
*data++ = File_Put;
*data++ = 1;
- data += sprintf((char *)data, "%s/%s", folder, filename) + 1;
+ data += sprintf((char *)data, "%s", remote) + 1;
*(uint32_t *)data = BSWAP32(put_file_size); data += 4;
out->data_size = data - out->data;
usblink_send_packet();
diff --git a/core/usblink.h b/core/usblink.h
index 7a81567c..6b998fdd 100644
--- a/core/usblink.h
+++ b/core/usblink.h
@@ -27,7 +27,8 @@ typedef void (*usblink_progress_cb)(int progress, void *user_data);
void usblink_delete(const char *path, bool is_dir, usblink_progress_cb callback, void *user_data);
void usblink_dirlist(const char *path, usblink_dirlist_cb callback, void *user_data);
bool usblink_get_file(const char *path, const char *dest, usblink_progress_cb callback, void *user_data);
-bool usblink_put_file(const char *filepath, const char *folder, usblink_progress_cb callback, void *user_data);
+/* local = NULL or empty creates an empty file */
+bool usblink_put_file(const char *local, const char *remote, usblink_progress_cb callback, void *user_data);
void usblink_new_dir(const char *path, usblink_progress_cb callback, void *user_data);
void usblink_move(const char *old_path, const char *new_path, usblink_progress_cb callback, void *user_data);
bool usblink_send_os(const char *filepath, usblink_progress_cb callback, void *user_data);
diff --git a/core/usblink_queue.cpp b/core/usblink_queue.cpp
index 7af90a7a..fab99287 100644
--- a/core/usblink_queue.cpp
+++ b/core/usblink_queue.cpp
@@ -19,8 +19,8 @@ struct usblink_queue_action {
} action;
//Members only used if the appropriate action is set
- std::string filepath;
- std::string path;
+ std::string local;
+ std::string remote;
usblink_progress_cb progress_callback = nullptr;
usblink_dirlist_cb dirlist_callback = nullptr;
void *user_data;
@@ -81,36 +81,36 @@ void usblink_queue_do()
switch(action.action)
{
case usblink_queue_action::PUT_FILE:
- if(!usblink_put_file(action.filepath.c_str(), action.path.c_str(), progress_callback, action.user_data))
+ if(!usblink_put_file(action.local.c_str(), action.remote.c_str(), progress_callback, action.user_data))
{
progress_callback(-1, action.user_data);
busy = false;
}
break;
case usblink_queue_action::SEND_OS:
- if(!usblink_send_os(action.filepath.c_str(), progress_callback, action.user_data))
+ if(!usblink_send_os(action.local.c_str(), progress_callback, action.user_data))
{
progress_callback(-1, action.user_data);
busy = false;
}
break;
case usblink_queue_action::DIRLIST:
- usblink_dirlist(action.path.c_str(), dirlist_callback, action.user_data);
+ usblink_dirlist(action.remote.c_str(), dirlist_callback, action.user_data);
break;
case usblink_queue_action::MOVE:
- usblink_move(action.filepath.c_str(), action.path.c_str(), progress_callback, action.user_data);
+ usblink_move(action.local.c_str(), action.remote.c_str(), progress_callback, action.user_data);
break;
case usblink_queue_action::NEW_DIR:
- usblink_new_dir(action.path.c_str(), progress_callback, action.user_data);
+ usblink_new_dir(action.remote.c_str(), progress_callback, action.user_data);
break;
case usblink_queue_action::DEL_DIR:
- usblink_delete(action.path.c_str(), true, progress_callback, action.user_data);
+ usblink_delete(action.remote.c_str(), true, progress_callback, action.user_data);
break;
case usblink_queue_action::DEL_FILE:
- usblink_delete(action.path.c_str(), false, progress_callback, action.user_data);
+ usblink_delete(action.remote.c_str(), false, progress_callback, action.user_data);
break;
case usblink_queue_action::GET_FILE:
- if(!usblink_get_file(action.path.c_str(), action.filepath.c_str(), progress_callback, action.user_data))
+ if(!usblink_get_file(action.remote.c_str(), action.local.c_str(), progress_callback, action.user_data))
{
progress_callback(-1, action.user_data);
busy = false;
@@ -150,7 +150,7 @@ void usblink_queue_delete(std::string path, bool is_dir, usblink_progress_cb cal
usblink_queue_action action;
action.action = is_dir ? usblink_queue_action::DEL_DIR : usblink_queue_action::DEL_FILE;
action.user_data = user_data;
- action.path = path;
+ action.remote = path;
action.progress_callback = callback;
usblink_queue_add(action);
@@ -161,7 +161,7 @@ void usblink_queue_dirlist(std::string path, usblink_dirlist_cb callback, void *
usblink_queue_action action;
action.action = usblink_queue_action::DIRLIST;
action.user_data = user_data;
- action.path = path;
+ action.remote = path;
action.dirlist_callback = callback;
usblink_queue_add(action);
@@ -172,20 +172,20 @@ void usblink_queue_download(std::string path, std::string destpath, usblink_prog
usblink_queue_action action;
action.action = usblink_queue_action::GET_FILE;
action.user_data = user_data;
- action.filepath = destpath;
- action.path = path;
+ action.local = destpath;
+ action.remote = path;
action.progress_callback = callback;
usblink_queue_add(action);
}
-void usblink_queue_put_file(std::string filepath, std::string folder, usblink_progress_cb callback, void *user_data)
+void usblink_queue_put_file(std::string local, std::string remote, usblink_progress_cb callback, void *user_data)
{
usblink_queue_action action;
action.action = usblink_queue_action::PUT_FILE;
action.user_data = user_data;
- action.filepath = filepath;
- action.path = folder;
+ action.local = local;
+ action.remote = remote;
action.progress_callback = callback;
usblink_queue_add(action);
@@ -196,7 +196,7 @@ void usblink_queue_send_os(std::string filepath, usblink_progress_cb callback, v
usblink_queue_action action;
action.action = usblink_queue_action::SEND_OS;
action.user_data = user_data;
- action.filepath = filepath;
+ action.local = filepath;
action.progress_callback = callback;
usblink_queue_add(action);
@@ -207,7 +207,7 @@ void usblink_queue_new_dir(std::string path, usblink_progress_cb callback, void
usblink_queue_action action;
action.action = usblink_queue_action::NEW_DIR;
action.user_data = user_data;
- action.path = path;
+ action.remote = path;
action.progress_callback = callback,
usblink_queue_add(action);
@@ -218,8 +218,8 @@ void usblink_queue_move(std::string old_path, std::string new_path, usblink_prog
usblink_queue_action action;
action.action = usblink_queue_action::MOVE;
action.user_data = user_data;
- action.filepath = old_path;
- action.path = new_path;
+ action.local = old_path;
+ action.remote = new_path;
action.progress_callback = callback,
usblink_queue_add(action);
diff --git a/core/usblink_queue.h b/core/usblink_queue.h
index 45dad052..cf8df3e2 100644
--- a/core/usblink_queue.h
+++ b/core/usblink_queue.h
@@ -13,7 +13,7 @@
void usblink_queue_delete(std::string path, bool is_dir, usblink_progress_cb callback, void *user_data);
void usblink_queue_dirlist(std::string path, usblink_dirlist_cb callback, void *user_data);
void usblink_queue_download(std::string path, std::string destpath, usblink_progress_cb callback, void *user_data);
-void usblink_queue_put_file(std::string filepath, std::string folder, usblink_progress_cb callback, void *user_data);
+void usblink_queue_put_file(std::string local, std::string remote, usblink_progress_cb callback, void *user_data);
void usblink_queue_move(std::string old_path, std::string new_path, usblink_progress_cb callback, void *user_data);
void usblink_queue_new_dir(std::string path, usblink_progress_cb callback, void *user_data);
void usblink_queue_send_os(std::string filepath, usblink_progress_cb callback, void *user_data);
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 7e42a95c..1a8a577d 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -98,6 +98,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(&lcd, SIGNAL(closed()), ui->actionLCD_Window, SLOT(toggle()));
connect(ui->actionXModem, SIGNAL(triggered()), this, SLOT(xmodemSend()));
connect(ui->actionSwitch_to_Mobile_UI, SIGNAL(triggered()), this, SLOT(switchToMobileUI()));
+ connect(ui->actionLeavePTT, &QAction::triggered, the_qml_bridge, &QMLBridge::sendExitPTT);
ui->actionConnect->setShortcut(QKeySequence(Qt::Key_F10));
ui->actionConnect->setAutoRepeat(false);
@@ -288,8 +289,9 @@ void MainWindow::dropEvent(QDropEvent *e)
for(auto &&url : mime_data->urls())
{
- auto local = QDir::toNativeSeparators(url.toLocalFile()).toStdString();
- usblink_queue_put_file(local, the_qml_bridge->getUSBDir().toStdString(), usblink_progress_callback, this);
+ auto local = QDir::toNativeSeparators(url.toLocalFile());
+ auto remote = the_qml_bridge->getUSBDir() + QLatin1Char('/') + QFileInfo(local).fileName();
+ usblink_queue_put_file(local.toStdString(), remote.toStdString(), usblink_progress_callback, this);
}
}
@@ -494,6 +496,7 @@ void MainWindow::updateUIActionState(bool emulation_running)
ui->actionConnect->setEnabled(emulation_running);
ui->actionDebugger->setEnabled(emulation_running);
ui->actionXModem->setEnabled(emulation_running);
+ ui->actionLeavePTT->setEnabled(emulation_running);
ui->actionSuspend->setEnabled(emulation_running);
ui->actionSuspend_to_file->setEnabled(emulation_running);
diff --git a/mainwindow.ui b/mainwindow.ui
index 2daea3ba..ddda493c 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -451,6 +451,7 @@
+
@@ -662,6 +663,11 @@
Switch to Mobile UI
+
+
+ Leave &PTT
+
+
diff --git a/qml/ConfigPageFileTransfer.qml b/qml/ConfigPageFileTransfer.qml
index b20a1480..0b0b77ea 100644
--- a/qml/ConfigPageFileTransfer.qml
+++ b/qml/ConfigPageFileTransfer.qml
@@ -61,11 +61,13 @@ ColumnLayout {
}
}
- ProgressBar {
- id: transferProgress
- Layout.fillWidth: true
- minimumValue: 0
- maximumValue: 100
+ Button {
+ text: qsTr("Leave Press-to-Test mode")
+ Layout.topMargin: 5
+ Layout.bottomMargin: 5
+ onClicked: {
+ Emu.sendExitPTT();
+ }
}
}
@@ -86,10 +88,11 @@ ColumnLayout {
Connections {
target: Emu
function onUsblinkProgressChanged(percent) {
- if(percent < 0)
+ if(percent < 0) {
transferStatus.text = qsTr("Failed!");
- else
- {
+ transferProgress.value = 0;
+ transferProgress.indeterminate = false;
+ } else {
transferStatus.text = (percent >= 100) ? qsTr("Done!") : (percent + "%");
transferProgress.value = percent;
transferProgress.indeterminate = false;
@@ -98,6 +101,13 @@ ColumnLayout {
}
}
+ ProgressBar {
+ id: transferProgress
+ Layout.fillWidth: true
+ minimumValue: 0
+ maximumValue: 100
+ }
+
FBLabel {
text: qsTr("Target Directory")
font.pixelSize: TextMetrics.title2Size
diff --git a/qmlbridge.cpp b/qmlbridge.cpp
index f1233f9e..d0c11b1c 100644
--- a/qmlbridge.cpp
+++ b/qmlbridge.cpp
@@ -278,7 +278,15 @@ bool QMLBridge::isMobile()
void QMLBridge::sendFile(QUrl url, QString dir)
{
- usblink_queue_put_file(toLocalFile(url).toStdString(), dir.toStdString(), QMLBridge::usblink_progress_changed, this);
+ auto local = toLocalFile(url);
+ auto remote = dir + QLatin1Char('/') + basename(local);
+ usblink_queue_put_file(local.toStdString(), remote.toStdString(), QMLBridge::usblink_progress_changed, this);
+}
+
+void QMLBridge::sendExitPTT()
+{
+ usblink_queue_new_dir("/Press-to-Test", nullptr, nullptr);
+ usblink_queue_put_file(std::string(), "/Press-to-Test/Exit Test Mode.tns", QMLBridge::usblink_progress_changed, this);
}
QString QMLBridge::basename(QString path)
diff --git a/qmlbridge.h b/qmlbridge.h
index bac8576d..606a2ada 100644
--- a/qmlbridge.h
+++ b/qmlbridge.h
@@ -86,6 +86,7 @@ class QMLBridge : public QObject
Q_INVOKABLE bool isMobile();
Q_INVOKABLE void sendFile(QUrl url, QString dir);
+ Q_INVOKABLE void sendExitPTT();
// Various utility functions
Q_INVOKABLE QString basename(QString path);
diff --git a/usblinktreewidget.cpp b/usblinktreewidget.cpp
index 14231c24..4ec58e47 100644
--- a/usblinktreewidget.cpp
+++ b/usblinktreewidget.cpp
@@ -174,11 +174,12 @@ bool USBLinkTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index, const Q
(void) index;
(void) action;
- auto parentDir = usblink_path_item(parent).toStdString();
+ auto parentDir = usblink_path_item(parent);
for(auto &&url : data->urls())
{
- auto local = QDir::toNativeSeparators(url.toLocalFile()).toStdString();
- usblink_queue_put_file(local, parentDir, usblink_upload_callback, this);
+ auto local = QDir::toNativeSeparators(url.toLocalFile());
+ auto remote = parentDir + QLatin1Char('/') + QFileInfo(local).fileName();
+ usblink_queue_put_file(local.toStdString(), parentDir.toStdString(), usblink_upload_callback, this);
}
return true;