[gnome-games] savestates-list: Allow renaming of savestates



commit 684725ca77b28e6bff9ef3f9c4598cb278bda9d5
Author: Yetizone <andreii lisita gmail com>
Date:   Sat Aug 10 22:15:55 2019 +0300

    savestates-list: Allow renaming of savestates

 data/ui/savestates-list.ui        | 69 +++++++++++++++++++++++++++++++++++
 src/core/savestate.vala           | 14 ++++++++
 src/ui/savestate-listbox-row.vala |  5 +++
 src/ui/savestates-list.vala       | 76 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 164 insertions(+)
---
diff --git a/data/ui/savestates-list.ui b/data/ui/savestates-list.ui
index 19d63731..640ae351 100644
--- a/data/ui/savestates-list.ui
+++ b/data/ui/savestates-list.ui
@@ -85,6 +85,17 @@
                     <property name="pack-type">end</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkButton" id="rename_btn">
+                    <property name="visible">True</property>
+                    <property name="use-underline">True</property>
+                    <property name="label" translatable="yes">_Rename</property>
+                    <signal name="clicked" handler="on_rename_clicked"/>
+                  </object>
+                  <packing>
+                    <property name="pack-type">start</property>
+                  </packing>
+                </child>
               </object>
             </child>
           </object>
@@ -92,4 +103,62 @@
       </object>
     </child>
   </template>
+  <object class="GtkPopover" id="rename_popover">
+    <property name="position">left</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">true</property>
+        <property name="orientation">vertical</property>
+        <property name="margin">12</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">true</property>
+            <property name="label" translatable="yes">Name</property>
+            <property name="halign">start</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">true</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkEntry" id="rename_entry">
+                <property name="visible">true</property>
+                <property name="hexpand">true</property>
+                <property name="width-chars">21</property>
+                <signal name="activate" handler="on_rename_entry_activated"/>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="rename_popover_btn">
+                <property name="visible">true</property>
+                <property name="use-underline">True</property>
+                <property name="label" translatable="yes">_Rename</property>
+                <signal name="clicked" handler="apply_rename"/>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel" id="rename_error_label">
+            <property name="visible">true</property>
+            <property name="halign">start</property>
+            <property name="wrap">true</property>
+            <property name="wrap-mode">word</property>
+            <property name="max-width-chars">35</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
 </interface>
diff --git a/src/core/savestate.vala b/src/core/savestate.vala
index 7abdce7e..711684e7 100644
--- a/src/core/savestate.vala
+++ b/src/core/savestate.vala
@@ -39,6 +39,20 @@ public class Games.Savestate : Object {
                }
        }
 
+       public void set_name (string name) {
+               var metadata = new KeyFile ();
+               var metadata_file_path = Path.build_filename (path, "metadata");
+
+               try {
+                       metadata.load_from_file (metadata_file_path, KeyFileFlags.NONE);
+                       metadata.set_string ("Metadata", "Name", name);
+                       metadata.save_to_file (metadata_file_path);
+               }
+               catch (Error e) {
+                       critical ("Failed to set name in metadata file for savestate at %s: %s", path, 
e.message);
+               }
+       }
+
        public DateTime? get_creation_date () {
                var metadata = get_metadata ();
 
diff --git a/src/ui/savestate-listbox-row.vala b/src/ui/savestate-listbox-row.vala
index 33cdf6b8..d2b6bdc8 100644
--- a/src/ui/savestate-listbox-row.vala
+++ b/src/ui/savestate-listbox-row.vala
@@ -72,5 +72,10 @@ private class Games.SavestateListBoxRow : Gtk.ListBoxRow {
        public SavestateListBoxRow (Savestate savestate) {
                Object (savestate: savestate);
        }
+
+       public void set_name (string name) {
+               name_label.label = name;
+               savestate.set_name (name);
+       }
 }
 
diff --git a/src/ui/savestates-list.vala b/src/ui/savestates-list.vala
index c8196cf7..35847c63 100644
--- a/src/ui/savestates-list.vala
+++ b/src/ui/savestates-list.vala
@@ -12,6 +12,17 @@ private class Games.SavestatesList : Gtk.Box {
        private Gtk.ScrolledWindow scrolled_window;
        [GtkChild]
        private Gtk.Button delete_btn;
+       [GtkChild]
+       private Gtk.Button rename_btn;
+
+       [GtkChild]
+       private Gtk.Popover rename_popover;
+       [GtkChild]
+       private Gtk.Entry rename_entry;
+       [GtkChild]
+       private Gtk.Button rename_popover_btn;
+       [GtkChild]
+       private Gtk.Label rename_error_label;
 
        private SavestatesListState _state;
        public SavestatesListState state {
@@ -35,6 +46,7 @@ private class Games.SavestatesList : Gtk.Box {
        construct {
                list_box.set_header_func (update_header);
                revealer.notify["child-revealed"].connect (on_revealer_transition_end);
+               rename_entry.notify["text"].connect (on_rename_entry_text_changed);
        }
 
        public void set_margin (int margin) {
@@ -153,6 +165,69 @@ private class Games.SavestatesList : Gtk.Box {
                select_savestate_row (next_row);
        }
 
+       [GtkCallback]
+       private void on_rename_clicked () {
+               var selected_row = list_box.get_selected_row ();
+
+               rename_entry.text = state.selected_savestate.get_name ();
+               rename_popover.relative_to = selected_row;
+               rename_popover.popup ();
+       }
+
+       [GtkCallback]
+       private void on_rename_entry_activated () {
+               if (check_rename_is_valid ())
+                       apply_rename ();
+       }
+
+       private void on_rename_entry_text_changed () {
+               check_rename_is_valid ();
+       }
+
+       private bool check_rename_is_valid () {
+               var entry_text = rename_entry.text.strip ();
+
+               if (entry_text == _("Autosave") || entry_text == "") {
+                       rename_entry.get_style_context ().add_class ("error");
+                       rename_popover_btn.sensitive = false;
+                       rename_error_label.label = _("Invalid name");
+
+                       return false;
+               }
+
+               foreach (var list_child in list_box.get_children ()) {
+                       var savestate_row = list_child as SavestateListBoxRow;
+                       var savestate = savestate_row.savestate;
+
+                       if (savestate.is_automatic ())
+                               continue;
+
+                       if (savestate.get_name () == entry_text) {
+                               rename_entry.get_style_context ().add_class ("error");
+                               rename_popover_btn.sensitive = false;
+                               rename_error_label.label = _("A savestate with this name already exists");
+
+                               return false;
+                       }
+               }
+
+               // All checks passed, rename operation is valid
+               rename_entry.get_style_context ().remove_class ("error");
+               rename_popover_btn.sensitive = true;
+               rename_error_label.label = "";
+
+               return true;
+       }
+
+       [GtkCallback]
+       private void apply_rename () {
+               var selected_row = list_box.get_selected_row ();
+               var savestate_row = selected_row as SavestateListBoxRow;
+
+               savestate_row.set_name (rename_entry.text.strip ());
+               rename_popover.popdown ();
+       }
+
        private void update_header (Gtk.ListBoxRow row, Gtk.ListBoxRow? before) {
                if (before != null && row.get_header () == null) {
                        var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
@@ -176,5 +251,6 @@ private class Games.SavestatesList : Gtk.Box {
                }
 
                delete_btn.sensitive = (state.selected_savestate != null);
+               rename_btn.sensitive = (state.selected_savestate != null && 
!state.selected_savestate.is_automatic ());
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]