diff --git a/bin/sugar.in b/bin/sugar.in
index aebb8978ab..366ede2eec 100644
--- a/bin/sugar.in
+++ b/bin/sugar.in
@@ -20,6 +20,10 @@ if test -z "$SUGAR_SCALING"; then
export SUGAR_SCALING=72
fi
+if test -z "$SUGAR_GROUP_LABELS"; then
+ export SUGAR_GROUP_LABELS="$sugardatadir/group-labels.defaults"
+fi
+
if test -z "$SUGAR_MIME_DEFAULTS"; then
export SUGAR_MIME_DEFAULTS="$sugardatadir/mime.defaults"
fi
diff --git a/data/Makefile.am b/data/Makefile.am
index 01ceb525c8..2f7b6d5a99 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -11,6 +11,7 @@ sugar-100.gtkrc: gtkrc.em
sugardir = $(pkgdatadir)/data
sugar_DATA = \
activities.defaults \
+ group-labels.defaults \
ISO-639-2_utf-8.txt \
kbdconfig \
mime.defaults \
diff --git a/data/group-labels.defaults b/data/group-labels.defaults
new file mode 100644
index 0000000000..9bf3569729
--- /dev/null
+++ b/data/group-labels.defaults
@@ -0,0 +1 @@
+{"group-label": "Select grade:", "group-items": [{"female-icon": "female-1", "male-icon": "male-1", "label": "Preschool", "age": 4}, {"female-icon": "female-1", "male-icon": "male-1", "label": "Kindergarten", "age": 5}, {"female-icon": "female-2", "male-icon": "male-2", "label": "1st Grade", "age": 6}, {"female-icon": "female-3", "male-icon": "male-3", "label": "2nd Grade", "age": 7}, {"female-icon": "female-4", "male-icon": "male-4", "label": "3rd Grade", "age": 8}, {"female-icon": "female-5", "male-icon": "male-5", "label": "4th Grade", "age": 9}, {"female-icon": "female-5", "male-icon": "male-5", "label": "5th Grade", "age": 10}, {"female-icon": "female-6", "male-icon": "male-6", "label": "6th Grade", "age": 11}, {"female-icon": "female-6", "male-icon": "male-6", "label": "7th Grade", "age": 12}, {"female-icon": "female-7", "male-icon": "male-7", "label": "High School", "age": 13}, {"female-icon": "female-7", "male-icon": "male-7", "label": "Adult", "age": 25}]}
diff --git a/data/org.sugarlabs.gschema.xml b/data/org.sugarlabs.gschema.xml
index 3ae041cb49..1971c1b22f 100644
--- a/data/org.sugarlabs.gschema.xml
+++ b/data/org.sugarlabs.gschema.xml
@@ -82,6 +82,11 @@
User Birth Timestamp
Birth timestamp (seconds since the epoch)
+
+ ''
+ Group Label
+ Label associated with age, e.g., '2nd Grade'
+
diff --git a/extensions/cpsection/aboutme/model.py b/extensions/cpsection/aboutme/model.py
index a3d89bca76..e60e9c5fa1 100644
--- a/extensions/cpsection/aboutme/model.py
+++ b/extensions/cpsection/aboutme/model.py
@@ -24,9 +24,6 @@
from sugar3 import profile
-from jarabe.intro.window import calculate_birth_timestamp, calculate_age
-from jarabe.intro.agepicker import AGES
-
_COLORS = {
'red': {'dark': '#b20008', 'medium': '#e6000a', 'light': '#ffadce'},
'orange': {'dark': '#9a5200', 'medium': '#c97e00', 'light': '#ffc169'},
@@ -145,71 +142,3 @@ def set_color_xo(color):
client = GConf.Client.get_default()
client.set_string('/desktop/sugar/user/color', color)
return 1
-
-
-def get_gender():
- settings = Gio.Settings('org.sugarlabs.user')
- return settings.get_string('gender')
-
-
-def print_gender():
- print get_gender()
-
-
-def set_gender(gender):
- """Set the gender, e.g. 'female'
- """
- if not gender:
- gender = '' # default value in gsettings indicates no gender selected
- elif gender not in ['male', 'female', '']:
- raise ValueError(_('Gender must be male or female.'))
-
- settings = Gio.Settings('org.sugarlabs.user')
- settings.set_string('gender', gender)
- return
-
-
-def get_age():
- settings = Gio.Settings('org.sugarlabs.user')
- birth_timestamp = settings.get_int('birth-timestamp')
-
- if birth_timestamp == 0:
- return None
-
- birth_age = calculate_age(birth_timestamp)
-
- age = (AGES[-2] + AGES[-1]) / 2.
- if birth_age >= age:
- return AGES[-1]
-
- for i in range(len(AGES) - 1):
- age = (AGES[i] + AGES[i + 1]) / 2.
- if birth_age < age:
- return AGES[i]
-
- return None
-
-
-def print_age():
- print get_age()
-
-
-def set_age(age):
- """Set the age and an approximate birth timestamp
- age: e.g. 8
- birth_timestamp: time - age * #seconds per year
- """
- try:
- i = int(age)
- except ValueError, e:
- logging.error('set_age: %s' % (e))
- i = None
-
- if i is None or i < 1:
- raise ValueError(_('Age must be a positive integer.'))
-
- birth_timestamp = calculate_birth_timestamp(age)
-
- settings = Gio.Settings('org.sugarlabs.user')
- settings.set_int('birth-timestamp', birth_timestamp)
- return
diff --git a/extensions/cpsection/aboutme/view.py b/extensions/cpsection/aboutme/view.py
index 287bd02979..e4b95810b3 100644
--- a/extensions/cpsection/aboutme/view.py
+++ b/extensions/cpsection/aboutme/view.py
@@ -18,8 +18,10 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from gi.repository import Gtk
+from gi.repository import Gdk
from gi.repository import GObject
from gettext import gettext as _
+import logging
from sugar3.graphics import style
from sugar3.graphics.xocolor import XoColor, colors
@@ -27,7 +29,8 @@
from jarabe.controlpanel.sectionview import SectionView
from jarabe.controlpanel.inlinealert import InlineAlert
-from jarabe.intro.agepicker import AGES, AGE_LABELS
+from jarabe.intro.agepicker import AgePicker, save_age, load_age
+from jarabe.intro.genderpicker import GenderPicker, save_gender, load_gender
_STROKE_COLOR = 0
@@ -149,94 +152,11 @@ def __pressed_cb(self, button, event, picker):
self.color_changed_signal.emit(self._color)
-class GenderPicker(EventIcon):
- gender_changed_signal = GObject.Signal('gender-changed',
- arg_types=([str]))
-
- def __init__(self, color, gender):
- EventIcon.__init__(self, icon_name='%s-6' % (gender),
- pixel_size=style.XLARGE_ICON_SIZE)
- self._gender = gender
- self._color = color
-
- self.set_gender()
-
- self.connect('button_press_event', self.__pressed_cb)
-
- def set_color(self, color, gender):
- self._color = color
- self.set_gender(gender)
-
- def set_gender(self, gender=''):
- if gender is not '' and self._gender == gender:
- self.props.xo_color = self._color
- else:
- self.props.xo_color = _NOCOLOR
-
- gender = GObject.property(type=object, setter=set_gender)
-
- def __pressed_cb(self, button, event):
- self.gender_changed_signal.emit(self._gender)
-
-
-class AgePicker(Gtk.Grid):
-
- age_changed_signal = GObject.Signal('age-changed',
- arg_types=([int]))
-
- def __init__(self, color, gender, age):
- Gtk.Grid.__init__(self)
- self._color = color
- self._gender = gender
- self._age = age
-
- if self._gender is '':
- # Used for graphic only; does not set user's gender preference.
- self._gender = 'female'
-
- self._icon = EventIcon(icon_name='%s-%d' % (self._gender, self._age),
- pixel_size=style.LARGE_ICON_SIZE)
- self._icon.connect('button-press-event', self.__pressed_cb)
- self.attach(self._icon, 0, 0, 1, 1)
- self._icon.show()
-
- label = Gtk.Label()
- label.set_text(AGE_LABELS[self._age])
- self.attach(label, 0, 1, 1, 1)
- label.show()
-
- self.set_age()
-
- def set_color(self, color, age):
- self._color = color
- self.set_age(age)
-
- def set_age(self, age=None):
- if age in AGES:
- age_index = AGES.index(age)
- else:
- age_index = None
-
- if age_index == self._age:
- self._icon.props.xo_color = self._color
- else:
- self._icon.props.xo_color = _NOCOLOR
- self._icon.show()
-
- age = GObject.property(type=object, setter=set_age)
-
- def set_gender(self, gender):
- self._icon.set_icon_name('%s-%d' % (gender, self._age))
- self._icon.show()
-
- gender = GObject.property(type=object, setter=set_gender)
-
- def __pressed_cb(self, button, event):
- self.age_changed_signal.emit(self._age)
-
-
class AboutMe(SectionView):
+ age_changed_signal = GObject.Signal('age-changed', arg_types=([int]))
+ gender_changed_signal = GObject.Signal('gender-changed', arg_types=([str]))
+
def __init__(self, model, alerts):
SectionView.__init__(self)
@@ -272,11 +192,10 @@ def __init__(self, model, alerts):
for picker in self._pickers.values():
picker.connect('color-changed', self.__color_changed_cb)
- self._female_picker.connect('gender-changed', self.__gender_changed_cb)
- self._male_picker.connect('gender-changed', self.__gender_changed_cb)
+ self._gender_pickers.connect('gender-changed',
+ self.__gender_changed_cb)
+ self._age_pickers.connect('age-changed', self.__age_changed_cb)
- for picker in self._age_pickers:
- picker.connect('age-changed', self.__age_changed_cb)
def _setup_nick(self):
grid = Gtk.Grid()
@@ -366,7 +285,9 @@ def _setup_color(self):
center_in_panel.show()
def _setup_gender(self):
- self._gender = self._model.get_gender()
+ self._saved_gender = load_gender()
+
+ self._gender_pickers = GenderPicker()
grid = Gtk.Grid()
grid.set_row_spacing(style.DEFAULT_SPACING)
@@ -378,15 +299,8 @@ def _setup_gender(self):
grid.attach(label_gender, 0, 0, 1, 1)
label_gender.show()
- self._female_picker = GenderPicker(self._color, 'female')
- grid.attach(self._female_picker, 0, 1, 1, 1)
- self._female_picker.props.gender = self._gender
- self._female_picker.show()
-
- self._male_picker = GenderPicker(self._color, 'male')
- grid.attach(self._male_picker, 1, 1, 1, 1)
- self._male_picker.props.gender = self._gender
- self._male_picker.show()
+ grid.attach(self._gender_pickers, 0, 1, 1, 1)
+ self._gender_pickers.show()
center_in_panel = Gtk.Alignment.new(0.5, 0, 0, 0)
center_in_panel.add(grid)
@@ -396,26 +310,30 @@ def _setup_gender(self):
center_in_panel.show()
def _setup_age(self):
- self._age = self._model.get_age()
+ self._saved_age = load_age()
grid = Gtk.Grid()
grid.set_row_spacing(style.DEFAULT_SPACING)
grid.set_column_spacing(style.DEFAULT_SPACING)
- self._age_pickers = []
- for i in range(len(AGES)):
- self._age_pickers.append(AgePicker(self._color, self._gender, i))
+ self._age_pickers = AgePicker(self._saved_gender)
+ center_in_panel = Gtk.Alignment.new(0.5, 0, 0, 0)
+ center_in_panel.add(self._age_pickers)
+ self._age_pickers.show()
+
+ label = self._age_pickers.get_label()
- label_age = Gtk.Label(label=_('Select age:'))
+ label_age = Gtk.Label(label=_(label))
label_age.modify_fg(Gtk.StateType.NORMAL,
style.COLOR_SELECTION_GREY.get_gdk_color())
- grid.attach(label_age, 0, 0, 1, 1)
+ left_align = Gtk.Alignment.new(0, 0, 0, 0)
+ left_align.add(label_age)
label_age.show()
+ grid.attach(left_align, 0, 0, 1, 1)
+ left_align.show()
- for i in range(len(AGES)):
- grid.attach(self._age_pickers[i], i, 1, 1, 1)
- self._age_pickers[i].set_age(self._age)
- self._age_pickers[i].show()
+ grid.attach(center_in_panel, 0, 1, 1, 1)
+ center_in_panel.show()
center_in_panel = Gtk.Alignment.new(0.5, 0, 0, 0)
center_in_panel.add(grid)
@@ -431,16 +349,15 @@ def undo(self):
self._nick_alert.hide()
self._color_alert.hide()
- self._model.set_gender(self._gender)
- self._model.set_age(self._age)
+ # Undo gender or age changes
+ save_gender(self._saved_gender)
+ save_age(self._saved_age)
def _update_pickers(self, color):
for picker in self._pickers.values():
picker.props.color = color
- self._female_picker.set_color(color, self._gender)
- self._male_picker.set_color(color, self._gender)
- for i in range(len(AGES)):
- self._age_pickers[i].set_color(color, self._age)
+ self._gender_pickers.update_color(color)
+ self._age_pickers.update_color(color)
def _validate(self):
if self._nick_valid and self._color_valid:
@@ -498,16 +415,9 @@ def __color_changed_cb(self, colorpicker, color):
return False
def __gender_changed_cb(self, genderpicker, gender):
- self._model.set_gender(gender)
- self._female_picker.props.gender = gender
- self._female_picker.props.gender = gender
- self._male_picker.props.gender = gender
- for i in range(len(AGES)):
- self._age_pickers[i].props.gender = gender
+ save_gender(gender)
+ self._age_pickers.update_gender(gender)
return False
- def __age_changed_cb(self, agepicker, age):
- self._model.set_age(AGES[age])
- for i in range(len(AGES)):
- self._age_pickers[i].props.age = AGES[age]
- return False
+ def __age_changed_cb(self, event, age):
+ save_age(age)
diff --git a/src/jarabe/intro/__init__.py b/src/jarabe/intro/__init__.py
index 5c243025d1..2766f01198 100644
--- a/src/jarabe/intro/__init__.py
+++ b/src/jarabe/intro/__init__.py
@@ -1,5 +1,7 @@
import os
+from gi.repository import Gio
+
from sugar3 import env
from sugar3.profile import get_profile
@@ -12,3 +14,14 @@ def check_profile():
profile.convert_profile()
return profile.is_valid()
+
+
+def check_group_label():
+ settings = Gio.Settings('org.sugarlabs.user')
+ if len(settings.get_string('group-label')) > 0:
+ return True
+
+ # DEPRECATED
+ from gi.repository import GConf
+ client = GConf.Client.get_default()
+ return client.get_string('/desktop/sugar/user/group') is not None
diff --git a/src/jarabe/intro/agepicker.py b/src/jarabe/intro/agepicker.py
index 1e861654d5..87d1a73b63 100644
--- a/src/jarabe/intro/agepicker.py
+++ b/src/jarabe/intro/agepicker.py
@@ -17,6 +17,14 @@
from gi.repository import Gtk
from gi.repository import Gdk
+from gi.repository import Gio
+from gi.repository import GObject
+
+import os
+import json
+import time
+import math
+import logging
from gettext import gettext as _
@@ -24,65 +32,290 @@
from sugar3.graphics import style
from sugar3.graphics.xocolor import XoColor
-AGES = [3, 5, 7, 9, 11, 12, 15, 25]
-AGE_LABELS = [_('0-3'), _('4-5'), _('6-7'), _('8-9'), _('10-11'), _('12'),
- _('13-17'), _('Adult')]
+from jarabe.intro.genderpicker import GENDERS
+
+_group_labels = None
+_SECONDS_PER_YEAR = 365 * 24 * 60 * 60.
+
+
+def calculate_birth_timestamp(age):
+ age_in_seconds = age * _SECONDS_PER_YEAR
+ birth_timestamp = int(time.time() - age_in_seconds)
+ return birth_timestamp
+
+
+def calculate_age(birth_timestamp):
+ age_in_seconds = time.time() - birth_timestamp
+ # Round to nearest int
+ age = int(math.floor(age_in_seconds / _SECONDS_PER_YEAR) + 0.5)
+ return age
+
+
+def age_to_index(age):
+ group_labels = get_group_labels()
+
+ if age is None:
+ return int(len(group_labels.AGES) / 2.0)
+
+ age2 = age * 2
+ for i in range(len(group_labels.AGES) - 1):
+ if age2 < (group_labels.AGES[i] + group_labels.AGES[i + 1]):
+ return i
+
+ return len(group_labels.AGES) - 1
+
+
+def age_to_group_label(age):
+ group_labels = get_group_labels()
+
+ return group_labels.LABELS[age_to_index(age)]
+
+
+def group_label_to_age(label):
+ group_labels = get_group_labels()
+
+ if labels not in group_labels.LABELS:
+ return None
+
+ return group_labels.AGES[group_labels.LABELS.index(label)]
+
+
+def load_age():
+ group_labels = get_group_labels()
+
+ settings = Gio.Settings('org.sugarlabs.user')
+ birth_timestamp = settings.get_int('birth-timestamp')
+
+ if birth_timestamp == 0:
+ return None
+
+ birth_age = calculate_age(birth_timestamp)
+
+ age = (group_labels.AGES[-2] + group_labels.AGES[-1]) / 2.
+ if birth_age >= age:
+ return group_labels.AGES[-1]
+
+ for i in range(len(group_labels.AGES) - 1):
+ age = (group_labels.AGES[i] + group_labels.AGES[i + 1]) / 2.
+ if birth_age < age:
+ return group_labels.AGES[i]
+
+ return None
+
+
+def save_age(age):
+ birth_timestamp = calculate_birth_timestamp(age)
+ settings = Gio.Settings('org.sugarlabs.user')
+ settings.set_int('birth-timestamp', birth_timestamp)
+
+ # Record the label so we know it was set
+ settings.set_string('group-label', age_to_group_label(age))
+
+ # DEPRECATED
+ from gi.repository import GConf
+ client = GConf.Client.get_default()
+ client.set_int('/desktop/sugar/user/birth_timestamp', birth_timestamp)
+
+
+class GroupLabels():
+ GROUP_LABEL = []
+ AGES = []
+ LABELS = []
+ ICONS = []
+
+ def __init__(self):
+ f = open(os.environ['SUGAR_GROUP_LABELS'], 'r')
+ json_data = f.read()
+ f.close()
+ group_labels = json.loads(json_data)
+ self.GROUP_LABEL = group_labels['group-label']
+ for item in group_labels['group-items']:
+ self.ICONS.append([item['female-icon'], item['male-icon']])
+ self.LABELS.append(_(item['label']))
+ self.AGES.append(item['age'])
+
+
+def get_group_labels():
+ global _group_labels
+
+ if not _group_labels:
+ _group_labels = GroupLabels()
+
+ return _group_labels
+
+
+class Picker(Gtk.Grid):
+
+ def __init__(self, icon, label):
+ Gtk.Grid.__init__(self)
+
+ self._button = EventIcon(pixel_size=style.LARGE_ICON_SIZE,
+ icon_name=icon)
+ self.attach(self._button, 0, 0, 1, 1)
+ self._button.hide()
+
+ self._label = Gtk.Label(label)
+ self.attach(self._label, 0, 1, 1, 1)
+ self._label.hide()
+
+ def show_all(self):
+ self._button.show()
+ self._label.show()
+ self.show()
+
+ def hide_all(self):
+ self._button.hide()
+ self._label.hide()
+ self.hide()
+
+ def connect(self, callback, arg):
+ self._button.connect('button-press-event', callback, arg)
+
+ def set_color(self, color):
+ self._button.xo_color = color
+
+ def set_icon(self, icon):
+ self._button.set_icon_name(icon)
class AgePicker(Gtk.Grid):
- def __init__(self, gender):
+ age_changed_signal = GObject.Signal('age-changed', arg_types=([int]))
+
+ def __init__(self, gender, page=None):
Gtk.Grid.__init__(self)
+
self.set_row_spacing(style.DEFAULT_SPACING)
self.set_column_spacing(style.DEFAULT_SPACING)
+ self._group_labels = get_group_labels()
+
+ self._page = page
self._gender = gender
- self._age = 5
- self._buttons = []
+ self._age = self.get_age()
+ self._pickers = []
self._nocolor = XoColor('#010101,#ffffff')
self._color = XoColor()
- if self._gender is None or self._gender == 'None':
- self._gender = 'male'
+ if self._gender not in GENDERS:
+ self._gender = 'female'
+
+ gender_index = GENDERS.index(self._gender)
+ age_index = age_to_index(self._age)
+
+ width = Gdk.Screen.width()
+
+ num_ages = len(self._group_labels.AGES)
+ for i in range(num_ages):
+ self._pickers.append(
+ Picker(self._group_labels.ICONS[i][gender_index],
+ _(self._group_labels.LABELS[i])))
+ self._pickers[i].connect(self._button_press_cb, i)
+
+ self._fixed = Gtk.Fixed()
+ fixed_size = width - 4 * style.GRID_CELL_SIZE
+ self._fixed.set_size_request(fixed_size, -1)
+ self.attach(self._fixed, 0, 0, 1, 1)
+ self._fixed.show()
- for i in range(len(AGES)):
- self._buttons.append(
- EventIcon(pixel_size=style.LARGE_ICON_SIZE,
- icon_name='%s-%d' % (self._gender, i)))
- self._buttons[-1].show()
- self._buttons[-1].connect('button-press-event',
- self._button_press_cb, i)
+ self._age_adj = Gtk.Adjustment(value=age_index, lower=0,
+ upper=num_ages - 1, step_incr=1,
+ page_incr=3, page_size=0)
+ self._age_adj.connect('value-changed', self.__age_adj_changed_cb)
- label = Gtk.Label()
- label.set_text(AGE_LABELS[i])
- label.show()
+ self._age_slider = Gtk.HScale()
+ self._age_slider.set_draw_value(False)
+ self._age_slider.set_adjustment(self._age_adj)
+ self.attach(self._age_slider, 0, 1, 1, 1)
- self.attach(self._buttons[-1], i, 0, 1, 1)
- self.attach(label, i, 1, 1, 1)
+ for i in range(num_ages):
+ self._fixed.put(self._pickers[i], 0, 0)
- def _button_press_cb(self, widget, event, age):
+ self._configure(width)
+
+ Gdk.Screen.get_default().connect('size-changed', self._configure_cb)
+
+ def _configure_cb(self, event=None):
+ width = Gdk.Screen.width()
+ self._configure(width)
+
+ def _configure(self, width):
+ fixed_size = width - 4 * style.GRID_CELL_SIZE
+ self._fixed.set_size_request(fixed_size, -1)
+
+ num_ages = len(self._group_labels.AGES)
+
+ dx = int((fixed_size - style.LARGE_ICON_SIZE) / (num_ages - 1))
+ for i in range(num_ages):
+ self._fixed.move(self._pickers[i], dx * i, 0)
+
+ if num_ages + 2 < width / style.LARGE_ICON_SIZE:
+ for i in range(num_ages):
+ self._pickers[i].show_all()
+ self._age_slider.hide()
+ else:
+ self._age_slider.show()
+ value = self._age_adj.get_value()
+ self._set_age_picker(int(value + 0.5))
+
+ def get_label(self):
+ return self._group_labels.GROUP_LABEL
+
+ def _set_age_picker(self, age_index):
+ for i in range(len(self._group_labels.AGES)):
+ if i == age_index:
+ self._pickers[i].show_all()
+ else:
+ self._pickers[i].hide_all()
+ self._do_selected(age_index)
+
+ def __age_adj_changed_cb(self, widget):
+ value = self._age_adj.get_value()
+ self._set_age_picker(int(value + 0.5))
+
+ def _do_selected(self, age_index):
+ if self._age is not None:
+ i = age_to_index(self._age)
+ self._pickers[i].set_color(self._nocolor)
+ self._set_age(self._group_labels.AGES[age_index])
+ self._pickers[age_index].set_color(self._color)
+
+ def _button_press_cb(self, widget, event, age_index):
if event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
- if self._age is not None:
- self._buttons[self._age].xo_color = self._nocolor
- self._set_age(age)
- self._buttons[age].xo_color = self._color
+ self._do_selected(age_index)
def get_age(self):
- if self._age is None:
- return None
- else:
- return AGES[self._age]
+ if self._page is None:
+ return load_age()
+ elif hasattr(self, '_age'):
+ if self._age is None:
+ return None
+ i = age_to_index(self._age)
+ return self._group_labels.AGES[i]
+ return None
def _set_age(self, age):
+ if self._page is None:
+ if age != self._age:
+ self.age_changed_signal.emit(age)
+ else:
+ self._page.set_valid(True)
self._age = age
def update_color(self, color):
self._color = color
if self._age is not None:
- self._buttons[self._age].xo_color = self._color
+ i = age_to_index(self._age)
+ self._pickers[i].set_color(self._color)
def update_gender(self, gender):
self._gender = gender
- for i in range(8):
- self._buttons[i].set_icon_name('%s-%d' % (self._gender, i))
- self._buttons[i].show()
+
+ if self._gender in GENDERS:
+ gender_index = GENDERS.index(self._gender)
+ else:
+ gender_index = 0
+
+ for i in range(len(self._group_labels.AGES)):
+ self._pickers[i].set_icon(
+ self._group_labels.ICONS[i][gender_index])
diff --git a/src/jarabe/intro/colorpicker.py b/src/jarabe/intro/colorpicker.py
index 0ec8c00b4b..ca152fc3b2 100644
--- a/src/jarabe/intro/colorpicker.py
+++ b/src/jarabe/intro/colorpicker.py
@@ -32,6 +32,7 @@ def __init__(self):
self._set_random_colors()
self.connect('button-press-event', self._button_press_cb)
self.add(self._xo)
+ self._xo.show()
def _button_press_cb(self, widget, event):
if event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
diff --git a/src/jarabe/intro/genderpicker.py b/src/jarabe/intro/genderpicker.py
index 7df0e82674..3e8181e7cc 100644
--- a/src/jarabe/intro/genderpicker.py
+++ b/src/jarabe/intro/genderpicker.py
@@ -17,6 +17,8 @@
from gi.repository import Gtk
from gi.repository import Gdk
+from gi.repository import Gio
+from gi.repository import GObject
from sugar3.graphics.icon import EventIcon
from sugar3.graphics import style
@@ -26,13 +28,35 @@
GENDERS = ['female', 'male']
+def load_gender():
+ settings = Gio.Settings('org.sugarlabs.user')
+ return settings.get_string('gender')
+
+
+def save_gender(gender):
+ settings = Gio.Settings('org.sugarlabs.user')
+ if gender is not None:
+ settings.set_string('gender', gender)
+ else:
+ settings.set_string('gender', '')
+
+ # DEPRECATED
+ from gi.repository import GConf
+ if gender is not None:
+ client = GConf.Client.get_default()
+ client.set_string('/desktop/sugar/user/gender', gender)
+
+
class GenderPicker(Gtk.Grid):
+
+ gender_changed_signal = GObject.Signal('gender-changed', arg_types=([str]))
+
def __init__(self):
Gtk.Grid.__init__(self)
self.set_row_spacing(style.DEFAULT_SPACING)
self.set_column_spacing(style.DEFAULT_SPACING)
- self._gender = None
+ self._gender = load_gender()
self._buttons = []
self._nocolor = XoColor('#010101,#ffffff')
self._color = XoColor()
@@ -40,11 +64,23 @@ def __init__(self):
for i, gender in enumerate(GENDERS):
self._buttons.append(EventIcon(pixel_size=style.XLARGE_ICON_SIZE,
icon_name='%s-6' % (gender)))
- self._buttons[-1].show()
self._buttons[-1].connect('button-press-event',
self._button_press_cb, i)
+ self.attach(self._buttons[-1], i * 2, 0, 1, 1)
+ self._buttons[-1].show()
+
+ self.reset_button = EventIcon(pixel_size=style.SMALL_ICON_SIZE,
+ icon_name='entry-cancel')
+ self.reset_button.connect('button-press-event',
+ self._reset_button_press_cb)
+ self.attach(self.reset_button, 1, 0, 1, 1)
+ self.reset_button.xo_color = XoColor('#010101,#a0a0a0')
+ self.reset_button.show()
- self.attach(self._buttons[-1], i, 0, 1, 1)
+ def _reset_button_press_cb(self, widget, event):
+ self._set_gender('')
+ for i in range(len(GENDERS)):
+ self._buttons[i].xo_color = self._nocolor
def _button_press_cb(self, widget, event, gender_index):
if event.button == 1 and event.type == Gdk.EventType.BUTTON_PRESS:
@@ -56,6 +92,7 @@ def get_gender(self):
return self._gender
def _set_gender(self, gender):
+ self.gender_changed_signal.emit(gender)
self._gender = gender
def update_color(self, color):
diff --git a/src/jarabe/intro/window.py b/src/jarabe/intro/window.py
index 72de64c490..36fb027513 100644
--- a/src/jarabe/intro/window.py
+++ b/src/jarabe/intro/window.py
@@ -39,21 +39,6 @@
from jarabe.intro import colorpicker
from jarabe.intro import genderpicker
-_SECONDS_PER_YEAR = 365 * 24 * 60 * 60.
-
-
-def calculate_birth_timestamp(age):
- age_in_seconds = age * _SECONDS_PER_YEAR
- birth_timestamp = int(time.time() - age_in_seconds)
- return birth_timestamp
-
-
-def calculate_age(birth_timestamp):
- age_in_seconds = time.time() - birth_timestamp
- # Round to nearest int
- age = int(math.floor(age_in_seconds / _SECONDS_PER_YEAR) + 0.5)
- return age
-
def create_profile_with_nickname(nickname):
user_profile = UserProfile()
@@ -64,6 +49,11 @@ def create_profile_with_nickname(nickname):
def create_profile(user_profile):
settings = Gio.Settings('org.sugarlabs.user')
+ if user_profile.nickname in [None, '']:
+ nick = settings.get_string('nick')
+ if nick is not None:
+ logging.debug('recovering old nickname %s' % (nick))
+ user_profile.nickname = nick
settings.set_string('nick', user_profile.nickname)
colors = user_profile.colors
@@ -71,14 +61,9 @@ def create_profile(user_profile):
colors = XoColor()
settings.set_string('color', colors.to_string())
- if user_profile.gender is not None:
- settings.set_string('gender', user_profile.gender)
- else:
- settings.set_string('gender', '')
+ genderpicker.save_gender(user_profile.gender)
- settings.set_int('birth-timestamp',
- calculate_birth_timestamp(user_profile.age))
- # settings.sync()
+ agepicker.save_age(user_profile.age)
# DEPRECATED
from gi.repository import GConf
@@ -88,11 +73,6 @@ def create_profile(user_profile):
client.set_string('/desktop/sugar/user/color', colors.to_string())
- if user_profile.gender is not None:
- client.set_string('/desktop/sugar/user/gender', user_profile.gender)
-
- client.set_int('/desktop/sugar/user/birth_timestamp',
- calculate_birth_timestamp(user_profile.age))
client.suggest_sync()
if profile.get_pubkey() and profile.get_profile().privkey_hash:
@@ -163,6 +143,7 @@ def __init__(self, intro):
self._entry.set_size_request(style.zoom(300), -1)
self._entry.set_max_length(45)
grid.attach(self._entry, 0, 1, 1, 1)
+ self._entry.show()
grid.show()
alignment.show()
@@ -253,11 +234,12 @@ def __init__(self, gender):
grid.set_column_spacing(style.DEFAULT_SPACING)
alignment.add(grid)
- label = Gtk.Label(label=_('Select age:'))
+ self._ap = agepicker.AgePicker(gender, self)
+
+ label = Gtk.Label(label=_(self._ap.get_label()))
grid.attach(label, 0, 0, 1, 1)
label.show()
- self._ap = agepicker.AgePicker(gender)
grid.attach(self._ap, 0, 1, 1, 1)
self._ap.show()
@@ -265,7 +247,6 @@ def __init__(self, gender):
alignment.show()
self._age = self._ap.get_age()
- self.set_valid(True)
def update_gender(self, gender):
self._ap.update_gender(gender)
@@ -288,7 +269,7 @@ class _IntroBox(Gtk.VBox):
PAGE_FIRST = min(PAGE_NAME, PAGE_COLOR, PAGE_GENDER, PAGE_AGE)
PAGE_LAST = max(PAGE_NAME, PAGE_COLOR, PAGE_GENDER, PAGE_AGE)
- def __init__(self):
+ def __init__(self, start_on_age_page):
Gtk.VBox.__init__(self)
self.set_border_width(style.zoom(30))
@@ -310,6 +291,11 @@ def __init__(self):
pwd_entry.pw_name)
self._name_page.set_name(default_nick)
+ # XXX should also consider whether or not there is a nick
+ nick = settings.get_string('nick')
+ if start_on_age_page and nick:
+ self._page = self.PAGE_AGE
+
self._setup_page()
def _setup_page(self):
@@ -343,6 +329,7 @@ def _setup_age_page(self):
setup_methods[self._page](self)
self.pack_start(self._current_page, True, True, 0)
+ self._current_page.show()
button_box = Gtk.HButtonBox()
if self._page == self.PAGE_FIRST:
@@ -354,6 +341,7 @@ def _setup_age_page(self):
back_button.set_image(image)
back_button.connect('clicked', self._back_activated_cb)
button_box.pack_start(back_button, True, True, 0)
+ back_button.show()
self._next_button = Gtk.Button()
image = Icon(icon_name='go-right')
@@ -370,12 +358,13 @@ def _setup_age_page(self):
self._update_next_button()
button_box.pack_start(self._next_button, True, True, 0)
+ self._next_button.show()
self._current_page.connect('notify::valid',
self._page_valid_changed_cb)
self.pack_start(button_box, False, True, 0)
- self.show_all()
+ button_box.show()
def _update_next_button(self):
self._next_button.set_sensitive(self._current_page.props.valid)
@@ -420,7 +409,7 @@ def __init__(self):
self.nickname = None
self.colors = None
self.gender = None
- self.age = 12
+ self.age = 0
class IntroWindow(Gtk.Window):
@@ -430,13 +419,13 @@ class IntroWindow(Gtk.Window):
'done': (GObject.SignalFlags.RUN_FIRST, None, ([])),
}
- def __init__(self):
+ def __init__(self, start_on_age_page=False):
Gtk.Window.__init__(self)
self.props.decorated = False
self.maximize()
- self._intro_box = _IntroBox()
+ self._intro_box = _IntroBox(start_on_age_page)
self._intro_box.connect('done', self._done_cb)
self.add(self._intro_box)
diff --git a/src/jarabe/main.py b/src/jarabe/main.py
index 433b360c79..6fcbaaa518 100755
--- a/src/jarabe/main.py
+++ b/src/jarabe/main.py
@@ -352,10 +352,10 @@ def setup_theme():
Gtk.IconTheme.get_default().append_search_path(icons_path)
-def _start_intro():
- window = IntroWindow()
+def _start_intro(start_on_age_page=False):
+ window = IntroWindow(start_on_age_page=start_on_age_page)
window.connect('done', __intro_window_done_cb)
- window.show_all()
+ window.show()
def _check_profile():
@@ -370,6 +370,10 @@ def _check_profile():
return False
+def _check_group_label():
+ return intro.check_group_label()
+
+
def main():
# This can be removed once pygobject-3.10 is a requirement.
# https://bugzilla.gnome.org/show_bug.cgi?id=686914
@@ -399,6 +403,8 @@ def main():
if not _check_profile():
_start_intro()
+ elif not _check_group_label():
+ _start_intro(start_on_age_page=True)
else:
_begin_desktop_startup()