aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--include/DownloadUtils.hpp2
-rw-r--r--include/Path.hpp5
-rw-r--r--include/QuickMedia.hpp3
-rw-r--r--plugins/FileManager.hpp3
-rw-r--r--src/DownloadUtils.cpp11
-rw-r--r--src/QuickMedia.cpp58
-rw-r--r--src/plugins/FileManager.cpp29
8 files changed, 71 insertions, 42 deletions
diff --git a/README.md b/README.md
index 7448746..3ab5263 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ Press `Ctrl + V` to upload media to room in matrix if the clipboard contains a v
Press `Ctrl + D` to remove the file that was previously selected with `U` in a 4chan thread.\
Press `Ctrl + I` to reverse image search the selected image on 4chan or matrix, or to select the url in the text to open in a browser.\
Press `Ctrl+Alt+Arrow up` / `Ctrl+Alt+Arrow down` or `Ctrl+Alt+K` / `Ctrl+Alt+J` to view the room above/below the selected room in matrix.\
-Press `Ctrl + S` to save the displaying image/video/audio (does currently not work for manga pages).\
+Press `Ctrl + S` to save the selected/displaying image/video/audio (does currently not work for manga pages).\
Press `Ctrl + Enter` to submit text, ignoring the selected item (when saving a file or selecting a server for matrix room directory).\
Press `Ctrl + Enter` to save the file to the selected directory with the selected name, when downloading a file.
Text input in 4chan/matrix can be navigated with the arrow keys and if ctrl is pressed then the caret moves word by word.
diff --git a/include/DownloadUtils.hpp b/include/DownloadUtils.hpp
index 620b936..28684ef 100644
--- a/include/DownloadUtils.hpp
+++ b/include/DownloadUtils.hpp
@@ -30,6 +30,6 @@ namespace QuickMedia {
// Note: This function saves the content to the file atomically
DownloadResult download_to_file(const std::string &url, const std::string &destination_filepath, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false);
// Returns false if there was an error trying to create the download process
- bool download_async_gui(const std::string &url, bool use_youtube_dl, bool no_video);
+ bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool use_youtube_dl, bool no_video);
DownloadResult download_to_json(const std::string &url, rapidjson::Document &result, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false, bool fail_on_error = true);
} \ No newline at end of file
diff --git a/include/Path.hpp b/include/Path.hpp
index 571fb9e..fe49265 100644
--- a/include/Path.hpp
+++ b/include/Path.hpp
@@ -41,7 +41,10 @@ namespace QuickMedia {
size_t slash_index = data.rfind('/');
if(slash_index != std::string::npos && slash_index > 0)
return Path(data.substr(0, slash_index));
- return Path("/");
+ if(!data.empty() && data[0] == '/')
+ return Path("/");
+ else
+ return Path("");
}
std::string data;
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index 678451d..b2319ee 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -101,7 +101,7 @@ namespace QuickMedia {
Json::Value load_video_history_json();
private:
void init(Window parent_window, std::string &program_path);
- void load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir, int &start_tab_index, FileManagerMimeType fm_mime_type, FileSelectionHandler file_selection_handler);
+ void load_plugin_by_name(std::vector<Tab> &tabs, int &start_tab_index, FileManagerMimeType fm_mime_type, FileSelectionHandler file_selection_handler);
// Returns true if the window was closed
bool handle_window_close();
void base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_key_press = true, bool handle_searchbar = true);
@@ -200,5 +200,6 @@ namespace QuickMedia {
Window x11_window = None;
Atom wm_delete_window_atom;
XEvent xev;
+ std::filesystem::path file_manager_start_dir;
};
} \ No newline at end of file
diff --git a/plugins/FileManager.hpp b/plugins/FileManager.hpp
index e452c40..4e36b3c 100644
--- a/plugins/FileManager.hpp
+++ b/plugins/FileManager.hpp
@@ -27,6 +27,9 @@ namespace QuickMedia {
bool set_current_directory(const std::string &path);
const std::filesystem::path& get_current_directory() const { return current_dir; }
PluginResult get_files_in_directory(BodyItems &result_items);
+
+ // |fallback| is used if no directory has been accessed
+ static std::filesystem::path& get_last_accessed_directory(std::filesystem::path &fallback);
private:
std::filesystem::path current_dir;
FileManagerMimeType mime_type;
diff --git a/src/DownloadUtils.cpp b/src/DownloadUtils.cpp
index 7d2cbb8..b6d21b9 100644
--- a/src/DownloadUtils.cpp
+++ b/src/DownloadUtils.cpp
@@ -222,13 +222,12 @@ namespace QuickMedia {
return DownloadResult::OK;
}
- bool download_async_gui(const std::string &url, bool use_youtube_dl, bool no_video) {
- // TODO: Figure out why /proc/self/exe doesn't work when installed to /usr/bin/quickmedia
- char quickmedia_path[PATH_MAX] = "quickmedia";
- //if(readlink("/proc/self/exe", quickmedia_path, sizeof(quickmedia_path)) == -1)
- // return false;
+ bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool use_youtube_dl, bool no_video) {
+ char quickmedia_path[PATH_MAX];
+ if(readlink("/proc/self/exe", quickmedia_path, sizeof(quickmedia_path)) == -1)
+ strcpy(quickmedia_path, "quickmedia");
- std::vector<const char*> args = { quickmedia_path, "download", "-u", url.c_str() };
+ std::vector<const char*> args = { quickmedia_path, "download", "-u", url.c_str(), "--dir", file_manager_start_dir.c_str() };
if(use_youtube_dl) args.push_back("--youtube-dl");
if(no_video) args.push_back("--no-video");
args.push_back(nullptr);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 498de29..e93536b 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -319,7 +319,7 @@ namespace QuickMedia {
fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n");
fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n");
fprintf(stderr, " --upscale-images-always Upscale manga pages using waifu2x-ncnn-vulkan, no matter what the original image resolution is. Disabled by default\n");
- fprintf(stderr, " --dir <directory> Set the start directory when using file-manager. Default is the user home directory\n");
+ fprintf(stderr, " --dir <directory> Set the start directory when using file-manager. Default is the last accessed directory in QuickMedia or the users home directory\n");
fprintf(stderr, " -e <window> Embed QuickMedia into another window\n");
fprintf(stderr, "EXAMPLES:\n");
fprintf(stderr, " quickmedia launcher\n");
@@ -350,7 +350,6 @@ namespace QuickMedia {
return -1;
}
- const char *start_dir = nullptr;
Window parent_window = None;
std::vector<Tab> tabs;
const char *url = nullptr;
@@ -377,7 +376,7 @@ namespace QuickMedia {
upscale_image_action = UpscaleImageAction::FORCE;
} else if(strcmp(argv[i], "--dir") == 0) {
if(i < argc - 1) {
- start_dir = argv[i + 1];
+ file_manager_start_dir = argv[i + 1];
++i;
} else {
fprintf(stderr, "Missing directory after --dir argument\n");
@@ -471,15 +470,9 @@ namespace QuickMedia {
});
}
- if(strcmp(plugin_name, "file-manager") != 0 && start_dir) {
- fprintf(stderr, "Option --dir is only valid with file-manager\n");
- usage();
- return -1;
- }
-
- Path home_dir = get_home_dir();
- if(!start_dir)
- start_dir = home_dir.data.c_str();
+ std::filesystem::path home_path = get_home_dir().data;
+ if(file_manager_start_dir.empty())
+ file_manager_start_dir = FileManagerPage::get_last_accessed_directory(home_path);
int start_tab_index = 0;
FileManagerMimeType fm_mine_type = FILE_MANAGER_MIME_TYPE_ALL;
@@ -510,7 +503,7 @@ namespace QuickMedia {
file_selection_handler = std::move(saucenao_file_selection_handler);
}
- load_plugin_by_name(tabs, start_dir, start_tab_index, fm_mine_type, std::move(file_selection_handler));
+ load_plugin_by_name(tabs, start_tab_index, fm_mine_type, std::move(file_selection_handler));
while(!tabs.empty() || matrix) {
if(matrix) {
@@ -535,7 +528,7 @@ namespace QuickMedia {
fm_mine_type = FILE_MANAGER_MIME_TYPE_IMAGE;
file_selection_handler = std::move(saucenao_file_selection_handler);
}
- load_plugin_by_name(tabs, start_dir, start_tab_index, fm_mine_type, std::move(file_selection_handler));
+ load_plugin_by_name(tabs, start_tab_index, fm_mine_type, std::move(file_selection_handler));
}
}
@@ -671,6 +664,9 @@ namespace QuickMedia {
if(create_directory_recursive(get_cache_dir().join("thumbnails")) != 0)
throw std::runtime_error("Failed to create thumbnails directory");
+ if(create_directory_recursive(get_storage_dir().join("file-manager")) != 0)
+ throw std::runtime_error("Failed to create file-manager directory");
+
const char *qm_phone_factor = getenv("QM_PHONE_FACTOR");
if(qm_phone_factor && atoi(qm_phone_factor) == 1)
show_room_side_panel = false;
@@ -984,7 +980,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- void Program::load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir, int &start_tab_index, FileManagerMimeType fm_mime_type, FileSelectionHandler file_selection_handler) {
+ void Program::load_plugin_by_name(std::vector<Tab> &tabs, int &start_tab_index, FileManagerMimeType fm_mime_type, FileSelectionHandler file_selection_handler) {
if(!plugin_name || plugin_name[0] == '\0')
return;
@@ -1116,11 +1112,8 @@ namespace QuickMedia {
tabs.push_back(Tab{std::move(boards_body), std::move(boards_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "file-manager") == 0) {
auto file_manager_page = std::make_unique<FileManagerPage>(this, fm_mime_type, file_selection_handler);
- if(start_dir && !file_manager_page->set_current_directory(start_dir)) {
- fprintf(stderr, "Invalid directory provided with --dir: %s\n", start_dir);
- exit_code = -3;
- return;
- }
+ if(!file_manager_page->set_current_directory(file_manager_start_dir))
+ fprintf(stderr, "Warning: Invalid directory provided with --dir\n");
auto file_manager_body = create_body();
file_manager_page->get_files_in_directory(file_manager_body->items);
tabs.push_back(Tab{std::move(file_manager_body), std::move(file_manager_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
@@ -2453,7 +2446,7 @@ namespace QuickMedia {
} else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::C && event.key.control) {
save_video_url_to_clipboard();
} else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::S && event.key.control) {
- download_async_gui(original_video_url, !is_matrix, no_video);
+ download_async_gui(original_video_url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), !is_matrix, no_video);
}
}
handle_window_close();
@@ -2470,7 +2463,7 @@ namespace QuickMedia {
} else if(pressed_keysym == XK_f && pressing_ctrl) {
window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE);
} else if(pressed_keysym == XK_s && pressing_ctrl) {
- download_async_gui(original_video_url, !is_matrix, no_video);
+ download_async_gui(original_video_url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), !is_matrix, no_video);
} else if(pressed_keysym == XK_r && pressing_ctrl) {
if(!cursor_visible)
window.setMouseCursorVisible(true);
@@ -3411,8 +3404,9 @@ namespace QuickMedia {
}
}
} else if(event.key.code == sf::Keyboard::U) {
+ std::filesystem::path &fm_dir = FileManagerPage::get_last_accessed_directory(file_manager_start_dir);
auto file_manager_page = std::make_unique<FileManagerPage>(this, (FileManagerMimeType)(FILE_MANAGER_MIME_TYPE_IMAGE|FILE_MANAGER_MIME_TYPE_VIDEO));
- file_manager_page->set_current_directory(get_home_dir().data);
+ file_manager_page->set_current_directory(fm_dir.string());
auto file_manager_body = create_body();
file_manager_page->get_files_in_directory(file_manager_body->items);
std::vector<Tab> file_manager_tabs;
@@ -3453,6 +3447,10 @@ namespace QuickMedia {
redraw = true;
frame_skip_text_entry = true;
}
+ } else if(event.key.code == sf::Keyboard::S && event.key.control) {
+ BodyItem *selected_item = thread_body->get_selected();
+ if(selected_item && !selected_item->url.empty())
+ download_async_gui(selected_item->url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), false, false);
}
BodyItem *selected_item = thread_body->get_selected();
@@ -3572,7 +3570,7 @@ namespace QuickMedia {
redraw = true;
frame_skip_text_entry = true;
} else if(event.key.code == sf::Keyboard::S && event.key.control) {
- download_async_gui(attached_image_url, false, false);
+ download_async_gui(attached_image_url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), false, false);
}
}
}
@@ -4965,7 +4963,7 @@ namespace QuickMedia {
redraw = true;
return true;
} else if(message_type == MessageType::FILE) {
- download_async_gui(selected->url, false, no_video);
+ download_async_gui(selected->url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), false, no_video);
return true;
}
@@ -5006,7 +5004,7 @@ namespace QuickMedia {
if(selected_item_message) {
MessageType message_type = selected_item_message->type;
if(!selected->url.empty() && message_type >= MessageType::IMAGE && message_type <= MessageType::FILE) {
- download_async_gui(selected->url, false, no_video);
+ download_async_gui(selected->url, FileManagerPage::get_last_accessed_directory(file_manager_start_dir).string(), false, no_video);
return true;
}
}
@@ -5436,8 +5434,9 @@ namespace QuickMedia {
tab.body->clear_cache();
}
+ std::filesystem::path &fm_dir = FileManagerPage::get_last_accessed_directory(file_manager_start_dir);
auto file_manager_page = std::make_unique<FileManagerPage>(this);
- file_manager_page->set_current_directory(get_home_dir().data);
+ file_manager_page->set_current_directory(fm_dir.string());
auto file_manager_body = create_body();
file_manager_page->get_files_in_directory(file_manager_body->items);
std::vector<Tab> file_manager_tabs;
@@ -6510,14 +6509,13 @@ namespace QuickMedia {
sf::Event event;
auto file_manager_page = std::make_unique<FileManagerPage>(this);
- std::string home_dir = get_home_dir().data;
- file_manager_page->set_current_directory(home_dir);
+ file_manager_page->set_current_directory(file_manager_start_dir);
auto file_manager_body = create_body();
file_manager_page->get_files_in_directory(file_manager_body->items);
auto search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER);
Tabs ui_tabs(&rounded_rectangle_shader);
- const int tab_path_index = ui_tabs.add_tab(home_dir);
+ const int tab_path_index = ui_tabs.add_tab(file_manager_start_dir);
search_bar->onTextUpdateCallback = [&file_manager_body](const std::string &text) {
file_manager_body->filter_search_fuzzy(text);
diff --git a/src/plugins/FileManager.cpp b/src/plugins/FileManager.cpp
index 5ca7dc7..2207c65 100644
--- a/src/plugins/FileManager.cpp
+++ b/src/plugins/FileManager.cpp
@@ -4,6 +4,16 @@
#include "../../include/QuickMedia.hpp"
namespace QuickMedia {
+ static bool last_accessed_dir_loaded = false;
+ static std::filesystem::path last_accessed_dir;
+ static Path last_accessed_dir_path;
+ static void set_last_accessed_dir(const std::filesystem::path &path) {
+ if(last_accessed_dir_path.data.empty())
+ last_accessed_dir_path = get_storage_dir().join("file-manager").join("last_accessed_dir");
+ file_overwrite_atomic(last_accessed_dir_path, path.string());
+ last_accessed_dir = path;
+ }
+
// Returns empty string if no extension
static const char* get_ext(const std::filesystem::path &path) {
const char *path_c = path.c_str();
@@ -50,6 +60,7 @@ namespace QuickMedia {
if(result != PluginResult::OK)
return result;
+ set_last_accessed_dir(current_dir);
auto body = create_body();
body->items = std::move(result_items);
result_tabs.push_back(Tab{std::move(body), nullptr, nullptr});
@@ -57,9 +68,8 @@ namespace QuickMedia {
}
bool FileManagerPage::set_current_directory(const std::string &path) {
- if(!std::filesystem::is_directory(path))
- return false;
current_dir = path;
+ set_last_accessed_dir(current_dir);
return true;
}
@@ -144,4 +154,19 @@ namespace QuickMedia {
return PluginResult::OK;
}
+
+ // static
+ std::filesystem::path& FileManagerPage::get_last_accessed_directory(std::filesystem::path &fallback) {
+ if(!last_accessed_dir_loaded) {
+ last_accessed_dir_loaded = true;
+ std::string last_accessed_dir_str;
+ file_get_content(get_storage_dir().join("file-manager").join("last_accessed_dir"), last_accessed_dir_str);
+ last_accessed_dir = std::move(last_accessed_dir_str);
+ }
+
+ if(last_accessed_dir.empty())
+ return fallback;
+ else
+ return last_accessed_dir;
+ }
} \ No newline at end of file