[gnome-games] ui: Add PreferencesPageBackupRestore
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] ui: Add PreferencesPageBackupRestore
- Date: Fri, 17 May 2019 06:30:25 +0000 (UTC)
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]