Add actions to create new folders and rename files/directories.

This commit is contained in:
Steven Smith 2016-06-01 20:49:32 -07:00
parent 2aa0ab559d
commit a20a389cd9
10 changed files with 212 additions and 24 deletions

View File

@ -7,6 +7,7 @@
#include "util.h"
#include "../ui/error.h"
#include "../ui/list.h"
#include "../ui/section/task/task.h"
extern void cleanup();
@ -356,6 +357,22 @@ bool util_filter_tickets(void* data, const char* name, u32 attributes) {
return len >= 4 && strncasecmp(name + len - 4, ".tik", 4) == 0;
}
int util_compare_file_infos(const void** p1, const void** p2) {
list_item* info1 = *(list_item**) p1;
list_item* info2 = *(list_item**) p2;
file_info* f1 = (file_info*) info1->data;
file_info* f2 = (file_info*) info2->data;
if(f1->isDirectory && !f2->isDirectory) {
return -1;
} else if(!f1->isDirectory && f2->isDirectory) {
return 1;
} else {
return strcasecmp(f1->name, f2->name);
}
}
static const char* path3dsx = NULL;
const char* util_get_3dsx_path() {

View File

@ -62,5 +62,7 @@ u8* util_get_tmd_content_chunk(u8* tmd, u32 index);
bool util_filter_cias(void* data, const char* name, u32 attributes);
bool util_filter_tickets(void* data, const char* name, u32 attributes);
int util_compare_file_infos(const void** p1, const void** p2);
const char* util_get_3dsx_path();
void util_set_3dsx_path(const char* path);

View File

@ -332,9 +332,9 @@ static void kbd_draw_bottom(ui_view* view, void* data, float x1, float y1, float
}
}
void kbd_display(const char* name, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2),
void (*finished)(void* data, char* input),
void (*canceled)(void* data)) {
void kbd_display(const char* name, const char* initialInput, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2),
void (*finished)(void* data, char* input),
void (*canceled)(void* data)) {
kbd_data* kbdData = (kbd_data*) calloc(1, sizeof(kbd_data));
if(kbdData == NULL) {
error_display(NULL, NULL, NULL, "Failed to allocate info data.");
@ -344,6 +344,11 @@ void kbd_display(const char* name, void* data, void (*drawTop)(ui_view* view, vo
memset(kbdData->input, '\0', MAX_INPUT_SIZE);
kbdData->inputPos = 0;
if(initialInput != NULL) {
strncpy(kbdData->input, initialInput, MAX_INPUT_SIZE);
kbdData->inputPos = strlen(kbdData->input);
}
kbdData->shift = false;
kbdData->capsLock = false;

View File

@ -2,6 +2,6 @@
typedef struct ui_view_s ui_view;
void kbd_display(const char* name, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2),
void (*finished)(void* data, char* input),
void (*canceled)(void* data));
void kbd_display(const char* name, const char* initialInput, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2),
void (*finished)(void* data, char* input),
void (*canceled)(void* data));

View File

@ -24,7 +24,9 @@ void action_delete_dir(linked_list* items, list_item* selected);
void action_delete_dir_contents(linked_list* items, list_item* selected);
void action_delete_dir_cias(linked_list* items, list_item* selected);
void action_delete_dir_tickets(linked_list* items, list_item* selected);
void action_new_folder(linked_list* items, list_item* selected);
void action_paste_contents(linked_list* items, list_item* selected);
void action_rename(linked_list* items, list_item* selected);
void action_delete_pending_title(linked_list* items, list_item* selected);
void action_delete_all_pending_titles(linked_list* items, list_item* selected);

View File

@ -0,0 +1,76 @@
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <3ds.h>
#include "action.h"
#include "../task/task.h"
#include "../../error.h"
#include "../../info.h"
#include "../../kbd.h"
#include "../../list.h"
#include "../../prompt.h"
#include "../../ui.h"
#include "../../../core/linkedlist.h"
#include "../../../core/screen.h"
#include "../../../core/util.h"
typedef struct {
linked_list* items;
file_info* parentDir;
} new_folder_data;
static void action_new_folder_kbd_finished(void* data, char* input) {
new_folder_data* newFolderData = (new_folder_data*) data;
if(strlen(input) == 0) {
error_display(NULL, NULL, NULL, "No name specified.");
}
Result res = 0;
char path[FILE_PATH_MAX] = {'\0'};
snprintf(path, FILE_PATH_MAX, "%s%s", newFolderData->parentDir->path, input);
FS_Path* fsPath = util_make_path_utf8(path);
if(fsPath != NULL) {
res = FSUSER_CreateDirectory(newFolderData->parentDir->archive, *fsPath, 0);
util_free_path_utf8(fsPath);
} else {
res = R_FBI_OUT_OF_MEMORY;
}
if(R_SUCCEEDED(res)) {
list_item* folderItem = NULL;
if(R_SUCCEEDED(task_create_file_item(&folderItem, newFolderData->parentDir->archive, path))) {
linked_list_add(newFolderData->items, folderItem);
linked_list_sort(newFolderData->items, util_compare_file_infos);
}
prompt_display("Success", "Folder created.", COLOR_TEXT, false, NULL, NULL, NULL);
} else {
error_display_res(NULL, NULL, NULL, res, "Failed to create folder.");
}
free(data);
}
static void action_new_folder_kbd_canceled(void* data) {
free(data);
}
void action_new_folder(linked_list* items, list_item* selected) {
new_folder_data* data = (new_folder_data*) calloc(1, sizeof(new_folder_data));
if(data == NULL) {
error_display(NULL, NULL, NULL, "Failed to allocate new folder data.");
return;
}
data->items = items;
data->parentDir = (file_info*) selected->data;
kbd_display("Enter Name", NULL, data, NULL, action_new_folder_kbd_finished, action_new_folder_kbd_canceled);
}

View File

@ -215,29 +215,13 @@ static void action_paste_files_free_data(paste_files_data* data) {
free(data);
}
static int action_paste_files_compare(const void** p1, const void** p2) {
list_item* info1 = *(list_item**) p1;
list_item* info2 = *(list_item**) p2;
file_info* f1 = (file_info*) info1->data;
file_info* f2 = (file_info*) info2->data;
if(f1->isDirectory && !f2->isDirectory) {
return -1;
} else if(!f1->isDirectory && f2->isDirectory) {
return 1;
} else {
return strcasecmp(f1->name, f2->name);
}
}
static void action_paste_files_update(ui_view* view, void* data, float* progress, char* text) {
paste_files_data* pasteData = (paste_files_data*) data;
if(pasteData->pasteInfo.finished) {
FSUSER_ControlArchive(pasteData->target->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
linked_list_sort(pasteData->items, action_paste_files_compare);
linked_list_sort(pasteData->items, util_compare_file_infos);
ui_pop();
info_destroy(view);

View File

@ -0,0 +1,92 @@
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <3ds.h>
#include "action.h"
#include "../task/task.h"
#include "../../error.h"
#include "../../info.h"
#include "../../kbd.h"
#include "../../list.h"
#include "../../prompt.h"
#include "../../ui.h"
#include "../../../core/linkedlist.h"
#include "../../../core/screen.h"
#include "../../../core/util.h"
typedef struct {
linked_list* items;
list_item* target;
} rename_data;
static void action_rename_kbd_finished(void* data, char* input) {
rename_data* renameData = (rename_data*) data;
if(strlen(input) == 0) {
error_display(NULL, NULL, NULL, "No name specified.");
}
file_info* targetInfo = (file_info*) renameData->target->data;
Result res = 0;
char parentPath[FILE_PATH_MAX] = {'\0'};
util_get_parent_path(parentPath, targetInfo->path, FILE_PATH_MAX);
char dstPath[FILE_PATH_MAX] = {'\0'};
snprintf(dstPath, FILE_PATH_MAX, "%s%s", parentPath, input);
FS_Path* srcFsPath = util_make_path_utf8(targetInfo->path);
if(srcFsPath != NULL) {
FS_Path* dstFsPath = util_make_path_utf8(dstPath);
if(dstFsPath != NULL) {
if(targetInfo->isDirectory) {
res = FSUSER_RenameDirectory(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath);
} else {
res = FSUSER_RenameFile(targetInfo->archive, *srcFsPath, targetInfo->archive, *dstFsPath);
}
util_free_path_utf8(dstFsPath);
} else {
res = R_FBI_OUT_OF_MEMORY;
}
util_free_path_utf8(srcFsPath);
} else {
res = R_FBI_OUT_OF_MEMORY;
}
if(R_SUCCEEDED(res)) {
strncpy(renameData->target->name, input, LIST_ITEM_NAME_MAX);
strncpy(targetInfo->name, input, FILE_NAME_MAX);
strncpy(targetInfo->path, dstPath, FILE_PATH_MAX);
linked_list_sort(renameData->items, util_compare_file_infos);
prompt_display("Success", "Renamed.", COLOR_TEXT, false, NULL, NULL, NULL);
} else {
error_display_res(NULL, NULL, NULL, res, "Failed to perform rename.");
}
free(data);
}
static void action_rename_kbd_canceled(void* data) {
free(data);
}
void action_rename(linked_list* items, list_item* selected) {
rename_data* data = (rename_data*) calloc(1, sizeof(rename_data));
if(data == NULL) {
error_display(NULL, NULL, NULL, "Failed to allocate rename data.");
return;
}
data->items = items;
data->target = selected;
kbd_display("Enter New Name", data->target->name, data, NULL, action_rename_kbd_finished, action_rename_kbd_canceled);
}

View File

@ -16,6 +16,7 @@
#include "../../core/screen.h"
#include "../../core/util.h"
static list_item rename_opt = {"Rename", COLOR_TEXT, action_rename};
static list_item copy = {"Copy", COLOR_TEXT, NULL};
static list_item paste = {"Paste", COLOR_TEXT, action_paste_contents};
@ -27,6 +28,7 @@ static list_item install_and_delete_cia = {"Install and delete CIA", COLOR_TEXT,
static list_item install_ticket = {"Install ticket", COLOR_TEXT, action_install_ticket};
static list_item install_and_delete_ticket = {"Install and delete ticket", COLOR_TEXT, action_install_ticket_delete};
static list_item new_folder = {"New folder", COLOR_TEXT, action_new_folder};
static list_item delete_dir = {"Delete", COLOR_TEXT, action_delete_dir};
static list_item delete_all_contents = {"Delete all contents", COLOR_TEXT, action_delete_dir_contents};
static list_item copy_all_contents = {"Copy all contents", COLOR_TEXT, NULL};
@ -120,6 +122,8 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l
linked_list_add(items, &delete_all_tickets);
}
linked_list_add(items, &new_folder);
linked_list_add(items, &delete_all_contents);
linked_list_add(items, &copy_all_contents);
@ -138,6 +142,7 @@ static void files_action_update(ui_view* view, void* data, linked_list* items, l
linked_list_add(items, &delete_file);
}
linked_list_add(items, &rename_opt);
linked_list_add(items, &copy);
linked_list_add(items, &paste);
}
@ -278,6 +283,11 @@ static void files_free_data(files_data* data) {
static void files_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
files_data* listData = (files_data*) data;
// Detect whether the current directory was renamed by an action.
if(listData->populated && listData->dirItem != NULL && strncmp(listData->currDir, ((file_info*) listData->dirItem->data)->path, FILE_PATH_MAX) != 0) {
strncpy(listData->currDir, ((file_info*) listData->dirItem->data)->path, FILE_PATH_MAX);
}
while(!util_is_dir(listData->archive, listData->currDir)) {
char parentDir[FILE_PATH_MAX] = {'\0'};
util_get_parent_path(parentDir, listData->currDir, FILE_PATH_MAX);

View File

@ -390,7 +390,7 @@ static void qrinstall_wait_update(ui_view* view, void* data, float* progress, ch
}
if(hidKeysDown() & KEY_X) {
kbd_display("Enter URL(s)", data, NULL, qrinstall_process_urls, NULL);
kbd_display("Enter URL(s)", NULL, data, NULL, qrinstall_process_urls, NULL);
return;
}