Subject: [Tecnologia] [sugar 4/4] Journal management control panel feature

From: "Jorge (jasg) Saldivar" <[email-masked]>
Date: Fri, 21 May 2010 17:18:15 -0400

From: Jorge Saldivar <jorge@jorge-laptop.(none)>

Signed-off-by: Jorge Saldivar Galli <[email-masked]>
---
 extensions/cpsection/journalmanagement/__init__.py |    8 +-
 extensions/cpsection/journalmanagement/model.py    |   43 +++-
 extensions/cpsection/journalmanagement/view.py     |  223 ++++++++++++++++++--
 3 files changed, 240 insertions(+), 34 deletions(-)

diff --git a/extensions/cpsection/journalmanagement/__init__.py b/extensions/cpsection/journalmanagement/__init__.py
index 6eace00..c98456b 100644
--- a/extensions/cpsection/journalmanagement/__init__.py
+++ b/extensions/cpsection/journalmanagement/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Paraguay Educa, Martin Abente
+# Copyright (C) 2010 Paraguay Educa, Martin Abente, Jorge Saldivar
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,8 +15,14 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US
 
 from gettext import gettext as _
+import gconf
+
+from sugar.graphics.xocolor import XoColor
 
 CLASS = 'JournalManagement'
 ICON = 'module-journalmanagement'
 TITLE = _('Journal Management')
+client = gconf.client_get_default()
+COLOR = XoColor(client.get_string('/desktop/sugar/user/color'))
+
 
diff --git a/extensions/cpsection/journalmanagement/model.py b/extensions/cpsection/journalmanagement/model.py
index 811bdfb..80642e8 100644
--- a/extensions/cpsection/journalmanagement/model.py
+++ b/extensions/cpsection/journalmanagement/model.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Paraguay Educa, Martin Abente, Bernie Innocenti
+# Copyright (C) 2010 Paraguay Educa, Martin Abente, Bernie Innocenti, Jorge Saldivar
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,19 +18,22 @@ import os
 import gobject
 import glib
 import gio
+import gconf
 import logging
 
+from jarabe.journal.volumestoolbar import MOUNT_DIRECTORY_PATH, MOUNT_DIRECTORY_VALUE
+
 BYTES_TO_READ = 100
 
-class JournalManagementModel(gobject.GObject):
+class JournalBackupRestoreModel(gobject.GObject):
 
-    __gtype_name__ = 'JournalManagementModel'
+    __gtype_name__ = 'JournalBackupRestoreModel'
 
     __gsignals__ = {
-        'journal-management-running'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([str])),
-        'journal-management-started'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
-        'journal-management-finished'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
-        'journal-management-failed'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
+        'journal-backuprestore-running'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([str])),
+        'journal-backuprestore-started'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+        'journal-backuprestore-finished'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
+        'journal-backuprestore-failed'    : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
     }
 
     def __init__(self):
@@ -50,7 +53,7 @@ class JournalManagementModel(gobject.GObject):
         data = stream.read_finish(result)
 
         if len(data):
-            self.emit('journal-management-running', data)
+            self.emit('journal-backuprestore-running', data)
             stream.read_async(BYTES_TO_READ, self.report_process_status)
 
     def run_cmd_async(self, cmd):
@@ -59,20 +62,36 @@ class JournalManagementModel(gobject.GObject):
                 pid, stdin, stdout, stderr = glib.spawn_async(cmd, flags=glib.SPAWN_DO_NOT_REAP_CHILD, standard_output=True)
                 gobject.child_watch_add(pid, _handle_process_end, (self))
             except Exception:
-                self.emit('journal-management-failed')
+                self.emit('journal-backuprestore-failed')
             else:
                 stdin_stream = gio.unix.InputStream(stdout, True)
                 stdin_stream.read_async(BYTES_TO_READ, self.report_process_status)
 
                 self._running  = True
-                self.emit('journal-management-started')
+                self.emit('journal-backuprestore-started')
 
 def _handle_process_end(pid, condition, myself):
     myself._running = False
 
     if os.WIFEXITED(condition) and\
         os.WEXITSTATUS(condition) == 0:
-            myself.emit('journal-management-finished')
+            myself.emit('journal-backuprestore-finished')
     else:
-        myself.emit('journal-management-failed')
+        myself.emit('journal-backuprestore-failed')
+
+def get_directory_path():
+    client = gconf.client_get_default()
+    value = client.get_string(MOUNT_DIRECTORY_PATH) or os.environ['HOME']
+    return value
+
+def get_mount_directory_option():
+    client = gconf.client_get_default()
+    return client.get_string(MOUNT_DIRECTORY_VALUE) or 'False'
+
+def set_directory_path(directory_path):
+    client = gconf.client_get_default()
+    client.set_string(MOUNT_DIRECTORY_PATH, directory_path)
 
+def set_mount_directory_option(mount_directory_value):
+    client = gconf.client_get_default()
+    client.set_string(MOUNT_DIRECTORY_VALUE, mount_directory_value)
diff --git a/extensions/cpsection/journalmanagement/view.py b/extensions/cpsection/journalmanagement/view.py
index ae3194c..0fd6339 100644
--- a/extensions/cpsection/journalmanagement/view.py
+++ b/extensions/cpsection/journalmanagement/view.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Paraguay Educa, Martin Abente
+# Copyright (C) 2010 Paraguay Educa, Martin Abente, Jorge Saldivar
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -14,40 +14,96 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US.
 
+import os
 import gtk
 import gobject
-import logging
 from gettext import gettext as _
+import time
+import logging
 
-from jarabe.model.session import get_session_manager
-
-from sugar.graphics import style
-from sugar.graphics.alert import Alert
 from sugar.graphics.icon import Icon
+from sugar.graphics import style
+from sugar.graphics.xocolor import XoColor
 
 from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
 
-from model import JournalManagementModel
+from cpsection.modemconfiguration.view import EntryWithLabel
 
-class JournalManagement(SectionView):
-    def __init__(self, model, alerts):
-        SectionView.__init__(self)
+from model import JournalBackupRestoreModel
 
-        self._model = JournalManagementModel()
-        self._model.connect('journal-management-running', self._set_update_log)
-        self._model.connect('journal-management-started', self._set_status_started)
-        self._model.connect('journal-management-finished', self._set_status_finished)
-        self._model.connect('journal-management-failed', self._set_status_failed)
+APPLY_TIMEOUT = 1000
+
+class DirectoryPathEntry(EntryWithLabel):
+    def __init__(self, model):
+        EntryWithLabel.__init__(self, '')
+        self._entry.set_max_length(256)
+        self._entry.set_width_chars(40)
+        self._entry.modify_bg(gtk.STATE_INSENSITIVE, gtk.gdk.color_parse("white"))
+        self._entry.connect('changed', self.__entry_changed_cb)
+        self._model = model
+        self._fail = ''
+
+    def __entry_changed_cb(self, widget, data=None):
+        if self._timeout_sid:
+            gobject.source_remove(self._timeout_sid)
+        self._timeout_sid = gobject.timeout_add(APPLY_TIMEOUT,
+                                                self.__timeout_cb)
+
+    def __timeout_cb(self):
+        self._timeout_sid = 0
+
+        if not os.access(self._entry.get_text(), os.F_OK):
+            self._is_valid = False
+            self._fail = _("Directory path does not exist. Please write down a valid one.")
+        else:
+            try:
+                self.set_value(self._entry.get_text())
+            except ValueError, detail:
+                self._is_valid = False
+                self._fail = detail
+            else:
+                self._is_valid = True
+                self._fail = ''
+
+        self.notify('is-valid')
+
+        return False
+
+    def get_value(self):
+        value = self._model.get_directory_path()
+        return value
+
+    def set_value(self, directory_path):
+        self._model.set_directory_path(directory_path)
+
+    def set_enable(self):
+        self._entry.set_sensitive(True)
+        self._entry.set_editable(True)
+
+    def set_disable(self):
+        self._entry.set_sensitive(False)
+        self._entry.set_editable(False)
+
+    def get_fail(self):
+        return self._fail
+
+    def _get_is_valid(self):
+        return self._is_valid
+    is_valid = gobject.property(type=bool, getter=_get_is_valid, default=True)
+
+class JournalBackupRestore():
+    def __init__(self):
+        self._model = JournalBackupRestoreModel()
+        self._model.connect('journal-backuprestore-running', self._set_update_log)
+        self._model.connect('journal-backuprestore-started', self._set_status_started)
+        self._model.connect('journal-backuprestore-finished', self._set_status_finished)
+        self._model.connect('journal-backuprestore-failed', self._set_status_failed)
 
-        self.restart_alerts = alerts
         self._showing_alert = False
         self._process_name = None
         self._needs_restart = True
 
-        self.set_border_width(style.DEFAULT_SPACING)
-        self.set_spacing(style.DEFAULT_SPACING)
-        self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-
         self._vbox = gtk.VBox()
 
         self._setup_options()
@@ -55,7 +111,9 @@ class JournalManagement(SectionView):
         self._setup_more_info()
 
         self._vbox.show()
-        self.pack_start(self._vbox, expand=True)
+
+    def get_widgets(self):
+        return self._vbox
 
     def _setup_options(self):
         self._setup_separator(_('Options'))
@@ -234,3 +292,126 @@ class JournalManagement(SectionView):
         panel_control._section_toolbar.cancel_button.hide()
         panel_control._section_toolbar.accept_button.hide()
 
+class JournalMountDirectory():
+    def __init__(self, main_view, model):
+        self._model = model
+        self._main_view = main_view
+        self._vbox = gtk.VBox()
+        self._setup_widgets()
+        self._directory_path_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+        self._directory_path_alert = InlineAlert()
+        self._directory_path_alert_box.pack_start(self._directory_path_alert, False)
+        self._vbox.pack_start(self._directory_path_alert_box)
+        self._vbox.show()
+
+    def get_widgets(self):
+        return self._vbox
+
+    def _setup_separator(self, label_text):
+        separator_vbox = gtk.VBox()
+
+        separator = gtk.HSeparator()
+        separator.show()
+        separator_vbox.pack_start(separator, expand=False)
+
+        label = gtk.Label(label_text)
+        label.set_alignment(0, 0)
+        label.show()
+        separator_vbox.pack_start(label, expand=False)
+
+        separator_vbox.show()
+        self._vbox.pack_start(separator_vbox, expand=False, padding=10)
+
+    def _setup_directory_path_entry(self):
+        self._directory_path_entry = DirectoryPathEntry(self._model)
+        self._directory_path_entry.set_text_from_model()
+        self._directory_path_entry.connect('notify::is-valid', self.__notify_is_valid_cb)
+        self._directory_path_entry.show()
+        self._vbox.pack_start(self._directory_path_entry, expand=False)
+
+    def _setup_option_checkbox(self):
+        self._check_box = gtk.CheckButton(_('Mount GNOME Directory'))
+        self._check_box.connect('clicked', self.__checkbox_state_change_cb)
+        if self._model.get_mount_directory_option() == "True":
+            self._check_box.set_active(True)
+        else:
+            self._check_box.set_active(False)
+        self._check_box.show()
+
+        self._vbox.pack_start(self._check_box, False)
+
+    def _setup_widgets(self):
+        self._setup_separator(_("Options"))
+        self._setup_option_checkbox()
+        self._setup_separator(_("Directory Path"))
+        self._setup_directory_path_entry()
+        self.__set_directory_path_entry_state()
+
+        self._main_view.needs_restart = False
+
+    def __checkbox_state_change_cb(self, checkbox, data=None):
+        if checkbox.get_active():
+            self._model.set_mount_directory_option("True")
+        else:
+            self._model.set_mount_directory_option("False")
+        self.__set_directory_path_entry_state()
+
+    def __set_directory_path_entry_state(self):
+        if self._check_box.get_active():
+            self._directory_path_entry.set_enable()
+        else:
+            self._directory_path_entry.set_disable()
+
+    def _validate(self):
+        if self._directory_path_entry.is_valid:
+            self._main_view.props.is_valid = True
+            self._directory_path_alert.hide()
+            self._directory_path_alert_box.hide()
+        else:
+            self._main_view.props.is_valid = False
+            self._directory_path_alert.props.msg = self._directory_path_entry.get_fail()
+            self._directory_path_alert_box.show()
+            self._directory_path_alert.show()
+
+    def __notify_is_valid_cb(self, entry, pspec):
+        if entry.is_valid:
+            self._main_view.needs_restart = True
+        self._validate()
+
+class JournalManagement(SectionView):
+    def __init__(self, model, alerts):
+        SectionView.__init__(self)
+
+        self._model = model
+        self.restart_alerts = alerts
+
+        self._showing_alert = False
+        self._needs_restart = True
+
+        self.set_border_width(style.DEFAULT_SPACING)
+        self.set_spacing(style.DEFAULT_SPACING)
+        self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+
+        self._configurations_tabs = gtk.Notebook()
+        self._configurations_tabs.set_tab_pos(gtk.POS_TOP)
+        self._configurations_tabs.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white"))
+
+        label = gtk.Label(_("Mount Directory"))
+        self._configurations_tabs.append_page(self._setup_mount_directory_tab(self, model), label)
+
+        label = gtk.Label(_("Restore/Backup"))
+        self._configurations_tabs.append_page(self._setup_restore_backup_tab(), label)
+
+        self._group.add_widget(self._configurations_tabs)
+        self.pack_start(self._configurations_tabs, expand=False)
+        self._configurations_tabs.show()
+
+    def _setup_mount_directory_tab(self, main_view, model):
+        return JournalMountDirectory(main_view, model).get_widgets()
+
+    def _setup_restore_backup_tab(self):
+        return JournalBackupRestore().get_widgets()
+
+    def undo(self):
+        self._model.undo()
+
-- 
1.7.0.4

_______________________________________________
Tecnologia mailing list
[email-masked]
http://mail.paraguayeduca.org/mailman/listinfo/tecnologia