[gnome-games] ui: Add PreferencesPageBackupRestore



commit ccfef3445f31fb97f3f0145d81be5b81828de5fc
Author: Adwait Rawat <adwait rawat gmail com>
Date:   Wed May 8 02:06:11 2019 +0900

    ui: Add PreferencesPageBackupRestore
    
    Added feature to backup and restore save data.

 data/org.gnome.Games.gresource.xml          |   1 +
 data/ui/preferences-page-backup-restore.ui  | 119 ++++++++++++++++++++++++++++
 data/ui/preferences-page.ui                 |  66 +++++++++++++--
 data/ui/preferences-window.ui               |   5 ++
 po/POTFILES.in                              |   1 +
 src/meson.build                             |   1 +
 src/ui/application.vala                     |  14 ++++
 src/ui/preferences-page-backup-restore.vala |  60 ++++++++++++++
 src/ui/preferences-page.vala                |  15 ++++
 9 files changed, 274 insertions(+), 8 deletions(-)
---
diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml
index 86311a84..8c6cb252 100644
--- a/data/org.gnome.Games.gresource.xml
+++ b/data/org.gnome.Games.gresource.xml
@@ -34,6 +34,7 @@
     <file preprocess="xml-stripblanks">ui/platform-list-item.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-controllers.ui</file>
+    <file preprocess="xml-stripblanks">ui/preferences-page-backup-restore.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-platforms.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-platforms-generic-row.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-platforms-retro-row.ui</file>
diff --git a/data/ui/preferences-page-backup-restore.ui b/data/ui/preferences-page-backup-restore.ui
new file mode 100644
index 00000000..78aaa58f
--- /dev/null
+++ b/data/ui/preferences-page-backup-restore.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.24"/>
+  <template class="GamesPreferencesPageBackupRestore" parent="GamesPreferencesPage">
+    <property name="visible">True</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Backup save states and in-game saves. This can be used for 
moving the data to another device or for restoring it later. Desktop, Steam and LÖVE games cannot be backed 
up.</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+    <child>
+      <object class="GtkFrame">
+        <property name="visible">True</property>
+        <property name="shadow-type">in</property>
+        <child>
+          <object class="GtkListBox">
+            <property name="visible">True</property>
+            <property name="selection-mode">none</property>
+            <child>
+              <object class="GtkListBoxRow">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="valign">center</property>
+                    <property name="margin">6</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="expand">True</property>
+                        <property name="label" translatable="yes">Backup save data</property>
+                        <property name="ellipsize">end</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="use-underline">True</property>
+                        <property name="label" translatable="yes">_Backup</property>
+                        <signal name="clicked" handler="on_backup_clicked"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+         </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="margin-top">12</property>
+        <property name="label" translatable="yes">Restore save data for games from existing backup. This 
will replace existing saves and cannot be undone.</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+    <child>
+       <object class="GtkFrame">
+        <property name="visible">True</property>
+        <property name="shadow-type">in</property>
+        <child>
+          <object class="GtkListBox">
+            <property name="visible">True</property>
+            <property name="selection-mode">none</property>
+            <child>
+              <object class="GtkListBoxRow">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="valign">center</property>
+                    <property name="margin">6</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="expand">True</property>
+                        <property name="label" translatable="yes">Restore save data</property>
+                        <property name="ellipsize">end</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="use-underline">True</property>
+                        <property name="label" translatable="yes">_Restore</property>
+                        <signal name="clicked" handler="on_restore_clicked"/>
+                        <style>
+                          <class name="destructive-action"/>
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/ui/preferences-page.ui b/data/ui/preferences-page.ui
index 8597d6c7..1af35619 100644
--- a/data/ui/preferences-page.ui
+++ b/data/ui/preferences-page.ui
@@ -11,19 +11,69 @@
           <object class="GtkViewport">
             <property name="visible">True</property>
             <child>
-              <object class="HdyColumn">
+              <object class="GtkOverlay">
                 <property name="visible">True</property>
-                <property name="expand">True</property>
-                <property name="maximum-width">600</property>
-                <property name="linear-growth-width">300</property>
+                <property name="vexpand">True</property>
                 <child>
-                  <object class="GtkBox" id="box">
+                  <object class="HdyColumn">
                     <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="margin">12</property>
-                    <property name="spacing">12</property>
+                    <property name="expand">True</property>
+                    <property name="maximum-width">600</property>
+                    <property name="linear-growth-width">300</property>
+                    <child>
+                      <object class="GtkBox" id="box">
+                        <property name="visible">True</property>
+                        <property name="orientation">vertical</property>
+                        <property name="margin">12</property>
+                        <property name="spacing">12</property>
+                      </object>
+                    </child>
                   </object>
                 </child>
+                <child type="overlay">
+                  <object class="GtkRevealer" id="error_notification_revealer">
+                    <property name="visible">True</property>
+                    <property name="halign">center</property>
+                    <property name="valign">start</property>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="spacing">12</property>
+                        <style>
+                          <class name="app-notification"/>
+                        </style>
+                        <child>
+                          <object class="GtkLabel" id="error_label">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="wrap">True</property>
+                            <property name="wrap-mode">word-char</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkButton">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="valign">center</property>
+                            <signal name="clicked" handler="on_error_notification_closed"/>
+                            <style>
+                              <class name="flat"/>
+                            </style>
+                            <child>
+                              <object class="GtkImage">
+                                <property name="visible">True</property>
+                                <property name="icon-name">window-close-symbolic</property>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="pass-through">True</property>
+                  </packing>
+                </child>
               </object>
             </child>
           </object>
diff --git a/data/ui/preferences-window.ui b/data/ui/preferences-window.ui
index 476431c7..32d9d711 100644
--- a/data/ui/preferences-window.ui
+++ b/data/ui/preferences-window.ui
@@ -126,6 +126,11 @@
                     <property name="visible">True</property>
                   </object>
                 </child>
+                <child>
+                  <object class="GamesPreferencesPageBackupRestore" id="backup_restore_page">
+                    <property name="visible">True</property>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0af8c955..1133ae05 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -70,6 +70,7 @@ src/ui/gamepad-mapper.vala
 src/ui/keyboard-mapper.vala
 src/ui/media-selector.vala
 src/ui/preferences-page-controllers.vala
+src/ui/preferences-page-backup-restore.vala
 src/ui/preferences-page-platforms-retro-row.vala
 src/ui/preferences-page-platforms.vala
 src/ui/preferences-page-video.vala
diff --git a/src/meson.build b/src/meson.build
index 3f635d53..2ee9d301 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -161,6 +161,7 @@ vala_sources = [
   'ui/platforms-view.vala',
   'ui/preferences-page.vala',
   'ui/preferences-page-controllers.vala',
+  'ui/preferences-page-backup-restore.vala',
   'ui/preferences-page-platforms.vala',
   'ui/preferences-page-platforms-generic-row.vala',
   'ui/preferences-page-platforms-retro-row.vala',
diff --git a/src/ui/application.vala b/src/ui/application.vala
index 86fff343..2e622e52 100644
--- a/src/ui/application.vala
+++ b/src/ui/application.vala
@@ -446,4 +446,18 @@ public class Games.Application : Gtk.Application {
                device.button_release_event.connect (on_gamepad_button_release_event);
                device.absolute_axis_event.connect (on_gamepad_absolute_axis_event);
        }
+
+       public static void restore_from (string archive_path) throws ArchiveError {
+               var data_dir = Application.get_data_dir ();
+               string[] database = { Application.get_database_path () };
+
+               extract_archive (archive_path, data_dir, database);
+       }
+
+       public static void backup_to (string file_path) throws ArchiveError {
+               var data_dir = File.new_for_path (Application.get_data_dir ());
+               string[] database = { Application.get_database_path () };
+
+               compress_dir (file_path, data_dir, data_dir, database);
+       }
 }
diff --git a/src/ui/preferences-page-backup-restore.vala b/src/ui/preferences-page-backup-restore.vala
new file mode 100644
index 00000000..56957a8a
--- /dev/null
+++ b/src/ui/preferences-page-backup-restore.vala
@@ -0,0 +1,60 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/preferences-page-backup-restore.ui")]
+private class Games.PreferencesPageBackupRestore : PreferencesPage {
+       construct {
+               title = _("Backup & Restore");
+       }
+
+       [GtkCallback]
+       private void on_restore_clicked () {
+               var toplevel = get_toplevel () as Gtk.Window;
+               var chooser = new Gtk.FileChooserNative (_("Restore save data"), toplevel,
+                                                        Gtk.FileChooserAction.OPEN,
+                                                        _("_Restore"), _("_Cancel"));
+
+               if (chooser.run () == Gtk.ResponseType.ACCEPT) {
+                       var archive_name = chooser.get_filename ();
+
+                       try {
+                               Application.restore_from (archive_name);
+                       }
+                       catch (Error e) {
+                               var msg = _("Couldn't restore: %s").printf (e.message);
+                               show_error_message (msg);
+                       }
+               }
+
+               chooser.destroy ();
+       }
+
+       [GtkCallback]
+       private void on_backup_clicked () {
+               var toplevel = get_toplevel () as Gtk.Window;
+               var chooser = new Gtk.FileChooserNative (_("Backup save data"), toplevel,
+                                                       Gtk.FileChooserAction.SAVE,
+                                                       _("_Backup"), _("_Cancel"));
+
+               chooser.do_overwrite_confirmation = true;
+
+               var current_time = new DateTime.now_local ();
+               var creation_time = current_time.format ("%c");
+               var archive_filename = "gnome-games-backup-%s.tar.gz".printf (creation_time);
+
+               chooser.set_current_name (archive_filename);
+
+               if (chooser.run () == Gtk.ResponseType.ACCEPT) {
+                       var filename = chooser.get_filename ();
+
+                       try {
+                               Application.backup_to (filename);
+                       }
+                       catch (ArchiveError e) {
+                               var msg = _("Couldn't backup: %s").printf (e.message);
+                               show_error_message (msg);
+                       }
+               }
+
+               chooser.destroy ();
+       }
+}
diff --git a/src/ui/preferences-page.vala b/src/ui/preferences-page.vala
index 36e6e9df..16b6b28b 100644
--- a/src/ui/preferences-page.vala
+++ b/src/ui/preferences-page.vala
@@ -5,9 +5,24 @@ private class Games.PreferencesPage : Gtk.Bin, Gtk.Buildable {
        public PreferencesSubpage subpage { get; protected set; }
        public string title { get; construct set; }
 
+
+       [GtkChild]
+       private Gtk.Label error_label;
+       [GtkChild]
+       private Gtk.Revealer error_notification_revealer;
        [GtkChild]
        private Gtk.Box box;
 
+       [GtkCallback]
+       private void on_error_notification_closed () {
+               error_notification_revealer.reveal_child = false;
+       }
+
+       protected void show_error_message (string error_message) {
+               error_label.label = error_message;
+               error_notification_revealer.reveal_child = true;
+       }
+
        public void add_child (Gtk.Builder builder, Object child, string? type) {
                var widget = child as Gtk.Widget;
 


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