summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex McGrath <amk@amk.ie>2020-12-22 15:57:59 +0000
committerAndreas Kling <kling@serenityos.org>2020-12-22 23:35:41 +0100
commitabc98dea094fb888c92d88b917a7ad8dfb55ef71 (patch)
tree16dda89131b3e9a45a4208f3142541b3b046911d
parentca2e7b67466d0d7b0176f20674d72c8a1b5f2ed5 (diff)
downloadserenity-abc98dea094fb888c92d88b917a7ad8dfb55ef71.zip
FileManager: Allow creating desktop shortcut from FileManager
-rw-r--r--Applications/FileManager/FileUtils.cpp17
-rw-r--r--Applications/FileManager/FileUtils.h1
-rw-r--r--Applications/FileManager/main.cpp28
3 files changed, 46 insertions, 0 deletions
diff --git a/Applications/FileManager/FileUtils.cpp b/Applications/FileManager/FileUtils.cpp
index 86408c21b1..db933ae3c2 100644
--- a/Applications/FileManager/FileUtils.cpp
+++ b/Applications/FileManager/FileUtils.cpp
@@ -235,6 +235,23 @@ bool copy_file(const String& dst_path, const struct stat& src_stat, Core::File&
return true;
}
+bool link_file(const String& src_path, const String& dst_path)
+{
+ int duplicate_count = 0;
+ while (access(get_duplicate_name(dst_path, duplicate_count).characters(), F_OK) == 0) {
+ ++duplicate_count;
+ }
+ if (duplicate_count != 0) {
+ return link_file(src_path, get_duplicate_name(dst_path, duplicate_count));
+ }
+ int rc = symlink(src_path.characters(), dst_path.characters());
+ if (rc < 0) {
+ return false;
+ }
+
+ return true;
+}
+
String get_duplicate_name(const String& path, int duplicate_count)
{
if (duplicate_count == 0) {
diff --git a/Applications/FileManager/FileUtils.h b/Applications/FileManager/FileUtils.h
index 62999af0c0..bb293c7b94 100644
--- a/Applications/FileManager/FileUtils.h
+++ b/Applications/FileManager/FileUtils.h
@@ -39,5 +39,6 @@ bool copy_file_or_directory(const String& src_path, const String& dst_path);
String get_duplicate_name(const String& path, int duplicate_count);
bool copy_file(const String& dst_path, const struct stat& src_stat, Core::File&);
bool copy_directory(const String& src_path, const String& dst_path, const struct stat& src_stat);
+bool link_file(const String& src_path, const String& dst_path);
}
diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp
index 56083286f2..f7c650f321 100644
--- a/Applications/FileManager/main.cpp
+++ b/Applications/FileManager/main.cpp
@@ -76,6 +76,7 @@ static int run_in_desktop_mode(RefPtr<Core::ConfigFile>);
static int run_in_windowed_mode(RefPtr<Core::ConfigFile>, String initial_location);
static void do_copy(const Vector<String>& selected_file_paths);
static void do_paste(const String& target_directory, GUI::Window* window);
+static void do_create_link(const Vector<String>& selected_file_paths, GUI::Window* window);
static void show_properties(const String& container_dir_path, const String& path, const Vector<String>& selected, GUI::Window* window);
int main(int argc, char** argv)
@@ -171,6 +172,17 @@ void do_paste(const String& target_directory, GUI::Window* window)
}
}
+void do_create_link(const Vector<String>& selected_file_paths, GUI::Window* window)
+{
+ auto path = selected_file_paths.first();
+ auto title = LexicalPath(path.view()).title();
+ auto destination = String::formatted("{}/{}", Core::StandardPaths::desktop_directory(), title);
+ if (!FileUtils::link_file(path, destination)) {
+ GUI::MessageBox::show(window, "Could not create desktop shortcut", "File Manager",
+ GUI::MessageBox::Type::Error);
+ }
+}
+
void show_properties(const String& container_dir_path, const String& path, const Vector<String>& selected, GUI::Window* window)
{
RefPtr<PropertiesDialog> properties;
@@ -442,6 +454,20 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
window);
copy_action->set_enabled(false);
+ auto shortcut_action
+ = GUI::Action::create(
+ "Create desktop shortcut",
+ {},
+ Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-symlink.png"),
+ [&](const GUI::Action&) {
+ auto paths = directory_view.selected_file_paths();
+ if (paths.is_empty()) {
+ return;
+ }
+ do_create_link(paths, directory_view.window());
+ },
+ window);
+
auto properties_action
= GUI::Action::create(
"Properties...", { Mod_Alt, Key_Return }, Gfx::Bitmap::load_from_file("/res/icons/16x16/properties.png"), [&](const GUI::Action& action) {
@@ -695,6 +721,7 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
directory_context_menu->add_action(copy_action);
directory_context_menu->add_action(folder_specific_paste_action);
directory_context_menu->add_action(directory_view.delete_action());
+ directory_context_menu->add_action(shortcut_action);
directory_context_menu->add_separator();
directory_context_menu->add_action(properties_action);
@@ -736,6 +763,7 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
file_context_menu->add_action(copy_action);
file_context_menu->add_action(paste_action);
file_context_menu->add_action(directory_view.delete_action());
+ file_context_menu->add_action(shortcut_action);
file_context_menu->add_separator();
bool added_open_menu_items = false;