2
0

save_resource_dialog.vala 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright (c) 2012-2026 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: GPL-3.0-or-later
  4. */
  5. namespace Crown
  6. {
  7. public class SaveResourceDialog : Gtk.FileChooserDialog
  8. {
  9. public Project _project;
  10. public string _resource_type;
  11. public signal void safer_response(int response_id, string? path);
  12. public SaveResourceDialog(string? title, Gtk.Window? parent, string resource_type, string resource_name, Project p)
  13. {
  14. if (title != null)
  15. this.title = title;
  16. if (parent != null)
  17. this.set_transient_for(parent);
  18. this.set_action(Gtk.FileChooserAction.SAVE);
  19. this.add_button("Cancel", Gtk.ResponseType.CANCEL);
  20. this.add_button("Save", Gtk.ResponseType.ACCEPT);
  21. try {
  22. this.set_current_folder_file(GLib.File.new_for_path(p.source_dir()));
  23. } catch (GLib.Error e) {
  24. loge(e.message);
  25. }
  26. this.set_current_name(resource_name);
  27. this.set_modal(true);
  28. this.response.connect(on_response);
  29. Gtk.FileFilter ff = new Gtk.FileFilter();
  30. ff.set_filter_name("%s (*.%s)".printf(resource_type, resource_type));
  31. ff.add_pattern("*.%s".printf(resource_type));
  32. this.add_filter(ff);
  33. _project = p;
  34. _resource_type = resource_type;
  35. }
  36. public void on_response(int response_id)
  37. {
  38. string? path = this.get_file().get_path();
  39. if (response_id == Gtk.ResponseType.ACCEPT && path != null) {
  40. if (!path.has_suffix("." + _resource_type))
  41. path += "." + _resource_type;
  42. // If the path is outside the source dir, show a warning
  43. // and point the file chooser back to the source dir.
  44. if (!_project.path_is_within_source_dir(path)) {
  45. Gtk.MessageDialog md = new Gtk.MessageDialog(this
  46. , Gtk.DialogFlags.MODAL
  47. , Gtk.MessageType.WARNING
  48. , Gtk.ButtonsType.OK
  49. , "The file must be within the source directory."
  50. );
  51. md.set_default_response(Gtk.ResponseType.OK);
  52. md.response.connect(() => {
  53. try {
  54. this.set_current_folder_file(GLib.File.new_for_path(_project.source_dir()));
  55. } catch (GLib.Error e) {
  56. loge(e.message);
  57. }
  58. md.destroy();
  59. });
  60. md.show_all();
  61. return;
  62. }
  63. // If the path already exits, ask if it should be overwritten.
  64. if (GLib.FileUtils.test(path, FileTest.EXISTS)) {
  65. Gtk.MessageDialog md = new Gtk.MessageDialog(this
  66. , Gtk.DialogFlags.MODAL
  67. , Gtk.MessageType.QUESTION
  68. , Gtk.ButtonsType.NONE
  69. , "A file named `%s` already exists.\nOverwrite?".printf(GLib.Path.get_basename(path))
  70. );
  71. Gtk.Widget btn;
  72. md.add_button("_No", Gtk.ResponseType.NO);
  73. btn = md.add_button("_Yes", Gtk.ResponseType.YES);
  74. btn.get_style_context().add_class("destructive-action");
  75. md.set_default_response(Gtk.ResponseType.NO);
  76. md.response.connect((response_id) => {
  77. if (response_id == Gtk.ResponseType.YES)
  78. this.safer_response(Gtk.ResponseType.ACCEPT, path);
  79. md.destroy();
  80. });
  81. md.show_all();
  82. return;
  83. }
  84. }
  85. this.safer_response(response_id, path);
  86. }
  87. }
  88. } /* namespace Crown */