panel_new_project.vala 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 NewProject : Gtk.Box
  8. {
  9. // Data
  10. User _user;
  11. // Widgets
  12. public Gtk.Label _new_project_label;
  13. public Gtk.Label _name_label;
  14. public InputString _entry_name;
  15. public Gtk.Label _create_folder_label;
  16. public Gtk.CheckButton _create_folder;
  17. public Gtk.Label _location_label;
  18. public InputFile _file_chooser_button_location;
  19. public Gtk.Label _template_label;
  20. public InputEnum _combo_box_map_template;
  21. public Gtk.Label _label_message;
  22. public Gtk.Button _button_back;
  23. public Gtk.Button _button_create;
  24. public Gtk.Box _buttons_box;
  25. public Gtk.Box _box;
  26. public Gtk.Grid _grid;
  27. public Clamp _clamp;
  28. public NewProject(User user, Project project)
  29. {
  30. Object(orientation: Gtk.Orientation.VERTICAL);
  31. // Data
  32. _user = user;
  33. _new_project_label = new Gtk.Label(null);
  34. _new_project_label.xalign = 0;
  35. _new_project_label.set_markup("<span font_weight=\"bold\" size=\"x-large\">New Project</span>");
  36. _name_label = new Gtk.Label("Name");
  37. _name_label.xalign = 1;
  38. _entry_name = new InputString();
  39. _location_label = new Gtk.Label("Location");
  40. _location_label.xalign = 1;
  41. _file_chooser_button_location = new InputFile(Gtk.FileChooserAction.SELECT_FOLDER);
  42. _file_chooser_button_location.value = _documents_dir.get_path();
  43. _create_folder_label = new Gtk.Label("Create Project Folder");
  44. _create_folder_label.xalign = 1;
  45. _create_folder = new Gtk.CheckButton();
  46. _create_folder.active = true;
  47. _template_label = new Gtk.Label("Template");
  48. _template_label.xalign = 1;
  49. _combo_box_map_template = new InputEnum();
  50. _combo_box_map_template.hexpand = true;
  51. _combo_box_map_template.append("", "None");
  52. _combo_box_map_template.value = "";
  53. _label_message = new Gtk.Label("");
  54. _label_message.xalign = 1;
  55. _button_back = new Gtk.Button.with_label("Back");
  56. _button_back.action_name = "app.open-projects-list";
  57. _button_create = new Gtk.Button.with_label("Create");
  58. _button_create.get_style_context().add_class("suggested-action");
  59. _button_create.clicked.connect(() => {
  60. if (_entry_name.value == "") {
  61. _label_message.label = "Choose project name";
  62. return;
  63. }
  64. string? source_dir = _file_chooser_button_location.value;
  65. if (source_dir == null) {
  66. _label_message.label = "Location is not valid";
  67. return;
  68. }
  69. if (_create_folder.active) {
  70. string name = (string)_entry_name.value;
  71. name = name.down();
  72. name = name.replace(" ", "_");
  73. name = name.replace("\f", "_");
  74. name = name.replace("\n", "_");
  75. name = name.replace("\r", "_");
  76. name = name.replace("\t", "_");
  77. name = name.replace("\v", "_");
  78. try {
  79. GLib.File project_folder = GLib.File.new_for_path(Path.build_filename(source_dir, name));
  80. project_folder.make_directory();
  81. source_dir = project_folder.get_path();
  82. } catch (GLib.Error e) {
  83. if (e.code == GLib.IOError.EXISTS)
  84. _label_message.label = "Project Folder already exists";
  85. else
  86. _label_message.label = "Project Folder cannot be created automatically";
  87. return;
  88. }
  89. } else {
  90. if (GLib.FileUtils.test(source_dir, FileTest.IS_REGULAR)) {
  91. _label_message.label = "Location must be an empty directory";
  92. return;
  93. }
  94. if (!is_directory_empty(source_dir)) {
  95. _label_message.label = "Location must be an empty directory";
  96. return;
  97. }
  98. }
  99. _label_message.label = "";
  100. _user.add_or_touch_recent_project(source_dir, _entry_name.value);
  101. if (_combo_box_map_template.value == "")
  102. Project.create_initial_files(source_dir);
  103. else
  104. copy_template_to_source_dir(source_dir, _combo_box_map_template.value);
  105. GLib.Application.get_default().activate_action("open-project", new GLib.Variant.tuple({source_dir, LEVEL_NONE}));
  106. });
  107. _buttons_box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
  108. _buttons_box.spacing = 6;
  109. _buttons_box.pack_end(_button_create, false, true);
  110. _buttons_box.pack_end(_button_back, false, true);
  111. _grid = new Gtk.Grid();
  112. _grid.hexpand = true;
  113. _grid.row_spacing = 6;
  114. _grid.column_spacing = 12;
  115. _grid.attach(_name_label, 0, 0);
  116. _grid.attach(_entry_name, 1, 0);
  117. _grid.attach(_create_folder_label, 0, 1);
  118. _grid.attach(_create_folder, 1, 1);
  119. _grid.attach(_location_label, 0, 2);
  120. _grid.attach(_file_chooser_button_location, 1, 2);
  121. _grid.attach(_template_label, 0, 3);
  122. _grid.attach(_combo_box_map_template, 1, 3);
  123. _grid.attach(_buttons_box, 1, 4);
  124. _box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
  125. _box.margin_start = 12;
  126. _box.margin_end = 12;
  127. _box.margin_top = 32;
  128. _box.margin_bottom = 32;
  129. _box.spacing = 12;
  130. _box.pack_start(_new_project_label, false, true);
  131. _box.pack_start(_grid, false, true);
  132. _box.pack_start(_label_message, false, true);
  133. _clamp = new Clamp();
  134. _clamp.set_child(_box);
  135. this.add(_clamp);
  136. }
  137. public void fill_templates_list(string path)
  138. {
  139. GLib.File file = GLib.File.new_for_path(path);
  140. try {
  141. FileEnumerator enumerator = file.enumerate_children("standard::*"
  142. , FileQueryInfoFlags.NOFOLLOW_SYMLINKS
  143. );
  144. for (GLib.FileInfo? info = enumerator.next_file(); info != null ; info = enumerator.next_file()) {
  145. GLib.File source_dir = GLib.File.new_for_path(GLib.Path.build_filename(path, info.get_name()));
  146. _combo_box_map_template.append(source_dir.get_path(), info.get_name());
  147. }
  148. } catch (GLib.Error e) {
  149. loge(e.message);
  150. }
  151. }
  152. public void copy_recursive(GLib.File dst, GLib.File src, GLib.FileCopyFlags flags = GLib.FileCopyFlags.NONE)
  153. {
  154. try {
  155. GLib.FileType src_type = src.query_file_type(GLib.FileQueryInfoFlags.NONE);
  156. if (src_type == GLib.FileType.DIRECTORY) {
  157. if (dst.query_exists() == false)
  158. dst.make_directory();
  159. string dst_path = dst.get_path();
  160. string src_path = src.get_path();
  161. GLib.FileEnumerator enum = src.enumerate_children(GLib.FileAttribute.STANDARD_NAME, GLib.FileQueryInfoFlags.NONE);
  162. for (GLib.FileInfo? info = enum.next_file(); info != null; info = enum.next_file()) {
  163. copy_recursive(GLib.File.new_for_path(GLib.Path.build_filename(dst_path, info.get_name()))
  164. , GLib.File.new_for_path(GLib.Path.build_filename(src_path, info.get_name()))
  165. , flags
  166. );
  167. }
  168. } else if (src_type == GLib.FileType.REGULAR) {
  169. src.copy(dst, flags);
  170. }
  171. } catch (Error e) {
  172. loge(e.message);
  173. }
  174. }
  175. public void copy_template_to_source_dir(string source_dir, string template_dir)
  176. {
  177. GLib.File dst = GLib.File.new_for_path(source_dir);
  178. GLib.File src = GLib.File.new_for_path(template_dir);
  179. copy_recursive(dst, src);
  180. }
  181. }
  182. } /* namespace Crown */