瀏覽代碼

FileManager: Allow creating desktop shortcut from FileManager

Alex McGrath 4 年之前
父節點
當前提交
abc98dea09
共有 3 個文件被更改,包括 46 次插入0 次删除
  1. 17 0
      Applications/FileManager/FileUtils.cpp
  2. 1 0
      Applications/FileManager/FileUtils.h
  3. 28 0
      Applications/FileManager/main.cpp

+ 17 - 0
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) {

+ 1 - 0
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);
 
 }

+ 28 - 0
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;