Skip to content

Commit 5f750eb

Browse files
committed
Add a duplicate button
1 parent de589e8 commit 5f750eb

File tree

5 files changed

+69
-13
lines changed

5 files changed

+69
-13
lines changed

src/AppInfoView.vala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
public class AppEditor.AppInfoView : Gtk.Box {
2121
public DesktopApp desktop_app { get; construct set; }
2222
public signal void removed ();
23+
public signal void duplicate ();
2324

2425
public string save_display_name {
2526
get {
@@ -211,14 +212,19 @@ public class AppEditor.AppInfoView : Gtk.Box {
211212
var open_source_button = new Gtk.Button.with_label (_("Open in Text Editor"));
212213
open_source_button.clicked.connect (on_open_source_button_clicked);
213214

215+
var duplicate_button = new Gtk.Button.with_label (_("Duplicate"));
216+
duplicate_button.clicked.connect (() => duplicate ());
217+
214218
var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
215219
size_group.add_widget (save_button);
216220
size_group.add_widget (restore_defaults_button);
221+
size_group.add_widget (duplicate_button);
217222
size_group.add_widget (open_source_button);
218223

219224
var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
220225
button_box.margin = 6;
221226
button_box.pack_start (open_source_button, false, false);
227+
button_box.pack_start (duplicate_button, false, false);
222228
button_box.pack_end (save_button, false, false);
223229
button_box.pack_end (restore_defaults_button, false, false);
224230

@@ -415,11 +421,7 @@ public class AppEditor.AppInfoView : Gtk.Box {
415421
try {
416422
desktop_app.open_default_handler (get_screen ());
417423
} catch (Error e) {
418-
var dialog = new MessageDialog (_("Could Not Open This Entry"), e.message, "dialog-error");
419-
dialog.add_button (_("Close"), Gtk.ResponseType.CLOSE);
420-
dialog.show_all ();
421-
dialog.run ();
422-
dialog.destroy ();
424+
MessageDialog.show_default_dialog (_("Could Not Open This Entry"), e.message, "dialog-error");
423425
}
424426
}
425427

src/AppInfoViewSaver.vala

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
public class AppEditor.AppInfoViewSaver : Object {
2121
public AppInfoView target { get; set; }
2222

23-
public static DesktopApp? create_new_local_app (AppCategory? category) {
23+
// TODO: make these functions fully async
24+
public static DesktopApp? create_new_local_app (AppCategory? category) throws Error {
2425
string lang = Intl.get_language_names ()[0];
2526

2627
var key = new KeyFile ();
@@ -32,19 +33,43 @@ public class AppEditor.AppInfoViewSaver : Object {
3233
key.set_string_list (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_CATEGORIES, categories);
3334
}
3435

35-
string path = AppDirectoryScanner.get_config_path ();
36-
37-
uint next_index = get_next_local_app_index (path);
38-
string new_filename = Path.build_filename (path, "%s%u%s".printf (DesktopApp.LOCAL_APP_NAME_PREFIX, next_index, DesktopApp.LOCAL_APP_NAME_SUFFIX));
36+
string config_path = AppDirectoryScanner.get_config_path ();
37+
string new_filename = get_next_local_filename (config_path);
3938
try {
4039
key.save_to_file (new_filename);
4140

4241
var app_info = new DesktopAppInfo.from_filename (new_filename);
4342
var desktop_app = new DesktopApp (app_info);
4443
return desktop_app;
4544
} catch (Error e) {
46-
return null;
45+
throw e;
46+
}
47+
}
48+
49+
public static DesktopApp? create_new_clone_app (DesktopApp app) throws Error {
50+
string target_filename = app.info.get_filename ();
51+
string contents;
52+
try {
53+
FileUtils.get_contents (target_filename, out contents);
54+
} catch (FileError e) {
55+
throw e;
56+
}
57+
58+
string config_path = AppDirectoryScanner.get_config_path ();
59+
string new_filename = get_next_local_filename (config_path);
60+
var file = File.new_for_path (new_filename);
61+
try {
62+
var os = file.create (FileCreateFlags.NONE);
63+
os.write_all (contents.data, null);
64+
os.close ();
65+
66+
var app_info = new DesktopAppInfo.from_filename (new_filename);
67+
var desktop_app = new DesktopApp (app_info);
68+
return desktop_app;
69+
} catch (Error e) {
70+
throw e;
4771
}
72+
4873
}
4974

5075
public async void save () throws Error {
@@ -125,6 +150,11 @@ public class AppEditor.AppInfoViewSaver : Object {
125150
return str.escape ();
126151
}
127152

153+
private static string get_next_local_filename (string path) {
154+
uint next_index = get_next_local_app_index (path);
155+
return Path.build_filename (path, "%s%u%s".printf (DesktopApp.LOCAL_APP_NAME_PREFIX, next_index, DesktopApp.LOCAL_APP_NAME_SUFFIX));
156+
}
157+
128158
private static uint get_next_local_app_index (string path) {
129159
uint index = 1;
130160

src/AppInfoViewStack.vala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
public class AppEditor.AppInfoViewStack : Gtk.Stack {
2121
public signal void view_removed (AppInfoView view);
22+
public signal void duplicate_app (DesktopApp app);
2223

2324
construct {
2425
transition_type = Gtk.StackTransitionType.SLIDE_UP_DOWN;
@@ -68,6 +69,7 @@ public class AppEditor.AppInfoViewStack : Gtk.Stack {
6869
if (widget == null) {
6970
widget = new AppInfoView (desktop_app);
7071
widget.removed.connect (() => view_removed (widget));
72+
widget.duplicate.connect (() => duplicate_app (desktop_app));
7173
add (widget);
7274
}
7375

src/MainWindow.vala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class AppEditor.MainWindow : Gtk.Window {
5151

5252
app_info_view_stack = new AppInfoViewStack ();
5353
app_info_view_stack.view_removed.connect (on_view_removed);
54+
app_info_view_stack.duplicate_app.connect (on_duplicate_app);
5455

5556
var show_hidden_label = new Gtk.Label (_("Show hidden entries"));
5657
show_hidden_label.get_style_context ().add_class ("h4");
@@ -262,6 +263,15 @@ public class AppEditor.MainWindow : Gtk.Window {
262263
app_source_list.remove_app (view.desktop_app);
263264
}
264265

266+
private void on_duplicate_app (DesktopApp desktop_app) {
267+
try {
268+
var new_app = AppInfoViewSaver.create_new_clone_app (desktop_app);
269+
app_source_list.add_app (new_app, true);
270+
} catch (Error e) {
271+
MessageDialog.show_default_dialog (_("Could Not Duplicate %s").printf (desktop_app.get_display_name ()), e.message, "dialog-error");
272+
}
273+
}
274+
265275
private void on_new_button_clicked () {
266276
search_entry.text = "";
267277

@@ -271,8 +281,12 @@ public class AppEditor.MainWindow : Gtk.Window {
271281
current_category = current_view.desktop_app.get_main_category ();
272282
}
273283

274-
var new_app = AppInfoViewSaver.create_new_local_app (current_category);
275-
app_source_list.add_app (new_app, true);
284+
try {
285+
var new_app = AppInfoViewSaver.create_new_local_app (current_category);
286+
app_source_list.add_app (new_app, true);
287+
} catch (Error e) {
288+
MessageDialog.show_default_dialog (_("Could Not Create a New Application"), e.message, "dialog-error");
289+
}
276290
}
277291

278292
private void on_show_hidden_switch_active_changed () {

src/MessageDialog.vala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ public class AppEditor.MessageDialog : Gtk.Dialog {
2222
public string secondary_text { get; construct set; }
2323
public string image_icon_name { get; construct set; }
2424

25+
public static void show_default_dialog (string primary_text, string secondary_text, string image_icon_name) {
26+
var dialog = new MessageDialog (primary_text, secondary_text, image_icon_name);
27+
dialog.add_button (_("Close"), Gtk.ResponseType.CLOSE);
28+
dialog.show_all ();
29+
dialog.run ();
30+
dialog.destroy ();
31+
}
32+
2533
public MessageDialog (string primary_text, string secondary_text, string image_icon_name) {
2634
Object (
2735
resizable: false,

0 commit comments

Comments
 (0)