From ae5ce06ccb1f604fa1e4eaeb16d9ba8122b4923d Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 04 Feb 2008 22:36:12 +0000 Subject: Refactor directory structure a bit, preliminary to the library split-out. --- (limited to 'shell') diff --git a/shell/.gitignore b/shell/.gitignore deleted file mode 100644 index 4acd06b..0000000 --- a/shell/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.py diff --git a/shell/Makefile.am b/shell/Makefile.am deleted file mode 100644 index 7b45960..0000000 --- a/shell/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -SUBDIRS = controlpanel hardware model view intro - -sugardir = $(pkgdatadir)/shell -sugar_PYTHON = \ - config.py \ - logsmanager.py \ - main.py \ - shellservice.py - -EXTRA_DIST = $(bin_SCRIPTS) $(conf_DATA) diff --git a/shell/__init__.py b/shell/__init__.py deleted file mode 100644 index 41b4b1c..0000000 --- a/shell/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -"""OLPC Sugar Graphical "Shell" Interface - -Provides the shell-level operations for managing -the OLPC laptop computers. It interacts heavily -with (and depends upon) the Sugar UI libraries. - -This is a "graphical" shell, the name does not -refer to a command-line "shell" interface. -""" - -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/config.py.in b/shell/config.py.in deleted file mode 100644 index c1a7a4a..0000000 --- a/shell/config.py.in +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2008 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -prefix = '@prefix@' -bin_path = '@prefix@/bin' -data_path = '@prefix@/share/sugar/data' diff --git a/shell/controlpanel/Makefile.am b/shell/controlpanel/Makefile.am deleted file mode 100644 index f89132c..0000000 --- a/shell/controlpanel/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -sugardir = $(pkgdatadir)/shell/controlpanel -sugar_PYTHON = \ - __init__.py \ - cmd.py \ - control.py diff --git a/shell/controlpanel/__init__.py b/shell/controlpanel/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/controlpanel/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/controlpanel/cmd.py b/shell/controlpanel/cmd.py deleted file mode 100644 index 634faa9..0000000 --- a/shell/controlpanel/cmd.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import sys -import getopt -from gettext import gettext as _ - -from sugar import env - -from controlpanel import control - -def cmd_help(): - print _('Usage: sugar-control-panel [ option ] key [ args ... ] \n\ - Control for the sugar environment. \n\ - Options: \n\ - -h show this help message and exit \n\ - -l list all the available options \n\ - -h key show information about this key \n\ - -g key get the current value of the key \n\ - -s key set the current value for the key \n\ - ') - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "h:s:g:l", []) - except getopt.GetoptError: - cmd_help() - sys.exit(2) - - output = None - verbose = False - - if not opts: - cmd_help() - sys.exit() - - for opt, key in opts: - if opt in ("-h"): - method = getattr(control, 'set_' + key, None) - if method is None: - print _("sugar-control-panel: key=%s not an available option"% key) - sys.exit() - else: - print method.__doc__ - if opt in ("-l"): - elems = dir(control) - for elem in elems: - if elem.startswith('set_'): - print elem[4:] - if opt in ("-g"): - method = getattr(control, 'print_' + key, None) - if method is None: - print _("sugar-control-panel: key=%s not an available option"% key) - sys.exit() - else: - method() - if opt in ("-s"): - method = getattr(control, 'set_' + key, None) - if method is None: - print _("sugar-control-panel: key=%s not an available option"% key) - sys.exit() - else: - try: - method(*args) - except Exception, e: - print _("sugar-control-panel: %s"% e) diff --git a/shell/controlpanel/control.py b/shell/controlpanel/control.py deleted file mode 100644 index a26132e..0000000 --- a/shell/controlpanel/control.py +++ /dev/null @@ -1,481 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# -# The language config is based on the system-config-language -# (http://fedoraproject.org/wiki/SystemConfig/language) tool -# and the timezone config on the system-config-date -# (http://fedoraproject.org/wiki/SystemConfig/date) tool. -# Parts of the code were reused. -# - -import os -import string -import shutil -from gettext import gettext as _ -import dbus - -from sugar import profile -from sugar.graphics.xocolor import XoColor - -NM_SERVICE_NAME = 'org.freedesktop.NetworkManager' -NM_SERVICE_PATH = '/org/freedesktop/NetworkManager' -NM_SERVICE_IFACE = 'org.freedesktop.NetworkManager' -NM_ASLEEP = 1 - -_COLORS = {'red': {'dark':'#b20008', 'medium':'#e6000a', 'light':'#ffadce'}, - 'orange': {'dark':'#9a5200', 'medium':'#c97e00', 'light':'#ffc169'}, - 'yellow': {'dark':'#807500', 'medium':'#be9e00', 'light':'#fffa00'}, - 'green': {'dark':'#008009', 'medium':'#00b20d', 'light':'#8bff7a'}, - 'blue': {'dark':'#00588c', 'medium':'#005fe4', 'light':'#bccdff'}, - 'purple': {'dark':'#5e008c', 'medium':'#7f00bf', 'light':'#d1a3ff'} - } - -_MODIFIERS = ('dark', 'medium', 'light') - -_TIMEZONE_CONFIG = '/etc/sysconfig/clock' - -_LANGUAGES = { - 'Afrikaans/South_Africa': 'af_ZA', - 'Albanian': 'sq_AL.UTF-8', - 'Amharic/Ethiopian': 'am_ET.UTF-8', - 'Arabic/Algeria': 'ar_DZ.UTF-8', - 'Arabic/Bahrain': 'ar_BH.UTF-8', - 'Arabic/Egypt': 'ar_EG.UTF-8', - 'Arabic/India': 'ar_IN.UTF-8', - 'Arabic/Iraq': 'ar_IQ.UTF-8', - 'Arabic/Jordan': 'ar_JO.UTF-8', - 'Arabic/Kuwait': 'ar_KW.UTF-8', - 'Arabic/Lebanon': 'ar_LB.UTF-8', - 'Arabic/Libyan_Arab_Jamahiriya': 'ar_LY.UTF-8', - 'Arabic/Morocco': 'ar_MA.UTF-8', - 'Arabic/Oman': 'ar_OM.UTF-8', - 'Arabic/Qatar': 'ar_QA.UTF-8', - 'Arabic/Saudi_Arabia': 'ar_SA.UTF-8', - 'Arabic/Sudan': 'ar_SD.UTF-8', - 'Arabic/Syrian_Arab_Republic': 'ar_SY.UTF-8', - 'Arabic/Tunisia': 'ar_TN.UTF-8', - 'Arabic/United_Arab_Emirates': 'ar_AE.UTF-8', - 'Arabic/Yemen': 'ar_YE.UTF-8', - 'Basque/Spain': 'eu_ES.UTF-8', - 'Belarusian': 'be_BY.UTF-8', - 'Bengali/BD': 'bn_BD.UTF-8', - 'Bengali/India': 'bn_IN.UTF-8', - 'Bosnian/Bosnia_and_Herzegowina': 'bs_BA', - 'Breton/France': 'br_FR', - 'Bulgarian': 'bg_BG.UTF-8', - 'Catalan/Spain': 'ca_ES.UTF-8', - 'Chinese/Hong_Kong': 'zh_HK.UTF-8', - 'Chinese/P.R._of_China': 'zh_CN.UTF-8', - 'Chinese/Taiwan': 'zh_TW.UTF-8', - 'Cornish/Britain': 'kw_GB.UTF-8', - 'Croatian': 'hr_HR.UTF-8', - 'Czech': 'cs_CZ.UTF-8', - 'Danish': 'da_DK.UTF-8', - 'Dutch/Belgium': 'nl_BE.UTF-8', - 'Dutch/Netherlands': 'nl_NL.UTF-8', - 'English/Australia': 'en_AU.UTF-8', - 'English/Botswana': 'en_BW.UTF-8', - 'English/Canada': 'en_CA.UTF-8', - 'English/Denmark': 'en_DK.UTF-8', - 'English/Great_Britain': 'en_GB.UTF-8', - 'English/Hong_Kong': 'en_HK.UTF-8', - 'English/India': 'en_IN.UTF-8', - 'English/Ireland': 'en_IE.UTF-8', - 'English/New_Zealand': 'en_NZ.UTF-8', - 'English/Philippines': 'en_PH.UTF-8', - 'English/Singapore': 'en_SG.UTF-8', - 'English/South_Africa': 'en_ZA.UTF-8', - 'English/USA': 'en_US.UTF-8', - 'English/Zimbabwe': 'en_ZW.UTF-8', - 'Estonian': 'et_EE.UTF-8', - 'Faroese/Faroe_Islands': 'fo_FO.UTF-8', - 'Finnish': 'fi_FI.UTF-8', - 'French/Belgium': 'fr_BE.UTF-8', - 'French/Canada': 'fr_CA.UTF-8', - 'French/France': 'fr_FR.UTF-8', - 'French/Luxemburg': 'fr_LU.UTF-8', - 'French/Switzerland': 'fr_CH.UTF-8', - 'Galician/Spain': 'gl_ES.UTF-8', - 'German/Austria': 'de_AT.UTF-8', - 'German/Belgium': 'de_BE.UTF-8', - 'German/Germany': 'de_DE.UTF-8', - 'German/Luxemburg': 'de_LU.UTF-8', - 'German/Switzerland': 'de_CH.UTF-8', - 'Greek': 'el_GR.UTF-8', - 'Greenlandic/Greenland': 'kl_GL.UTF-8', - 'Gujarati/India': 'gu_IN.UTF-8', - 'Hausa/Nigeria': 'ha_NG.UTF-8', - 'Hebrew/Israel': 'he_IL.UTF-8', - 'Hindi/India': 'hi_IN.UTF-8', - 'Hungarian': 'hu_HU.UTF-8', - 'Icelandic': 'is_IS.UTF-8', - 'Igbo/Nigeria': 'ig_NG.UTF-8', - 'Indonesian': 'id_ID.UTF-8', - 'Irish': 'ga_IE.UTF-8', - 'Italian/Italy': 'it_IT.UTF-8', - 'Italian/Switzerland': 'it_CH.UTF-8', - 'Japanese': 'ja_JP.UTF-8', - 'Korean/Republic_of_Korea': 'ko_KR.UTF-8', - 'Lao/Laos': 'lo_LA.UTF-8', - 'Latvian/Latvia': 'lv_LV.UTF-8', - 'Lithuanian': 'lt_LT.UTF-8', - 'Macedonian': 'mk_MK.UTF-8', - 'Malay/Malaysia': 'ms_MY.UTF-8', - 'Maltese/malta': 'mt_MT.UTF-8', - 'Manx/Britain': 'gv_GB.UTF-8', - 'Marathi/India': 'mr_IN.UTF-8', - 'Mongolian': 'mn_MN.UTF-8', - 'Nepali': 'ne_NP.UTF-8', - 'Northern/Norway': 'se_NO', - 'Norwegian': 'nb_NO.UTF-8', - 'Norwegian,/Norway': 'nn_NO.UTF-8', - 'Occitan/France': 'oc_FR', - 'Oriya/India': 'or_IN.UTF-8', - 'Persian/Iran': 'fa_IR.UTF-8', - 'Polish': 'pl_PL.UTF-8', - 'Portuguese/Brasil': 'pt_BR.UTF-8', - 'Portuguese/Portugal': 'pt_PT.UTF-8', - 'Punjabi/India': 'pa_IN.UTF-8', - 'Romanian': 'ro_RO.UTF-8', - 'Russian': 'ru_RU.UTF-8', - 'Russian/Ukraine': 'ru_UA.UTF-8', - 'Serbian': 'sr_CS.UTF-8', - 'Serbian/Latin': 'sr_CS.UTF-8@Latn', - 'Slovak': 'sk_SK.UTF-8', - 'Slovenian/Slovenia': 'sl_SI.UTF-8', - 'Spanish/Argentina': 'es_AR.UTF-8', - 'Spanish/Bolivia': 'es_BO.UTF-8', - 'Spanish/Chile': 'es_CL.UTF-8', - 'Spanish/Colombia': 'es_CO.UTF-8', - 'Spanish/Costa_Rica': 'es_CR.UTF-8', - 'Spanish/Dominican_Republic': 'es_DO.UTF-8', - 'Spanish/El_Salvador': 'es_SV.UTF-8', - 'Spanish/Equador': 'es_EC.UTF-8', - 'Spanish/Guatemala': 'es_GT.UTF-8', - 'Spanish/Honduras': 'es_HN.UTF-8', - 'Spanish/Mexico': 'es_MX.UTF-8', - 'Spanish/Nicaragua': 'es_NI.UTF-8', - 'Spanish/Panama': 'es_PA.UTF-8', - 'Spanish/Paraguay': 'es_PY.UTF-8', - 'Spanish/Peru': 'es_PE.UTF-8', - 'Spanish/Puerto_Rico': 'es_PR.UTF-8', - 'Spanish/Spain': 'es_ES.UTF-8', - 'Spanish/USA': 'es_US.UTF-8', - 'Spanish/Uruguay': 'es_UY.UTF-8', - 'Spanish/Venezuela': 'es_VE.UTF-8', - 'Swedish/Finland': 'sv_FI.UTF-8', - 'Swedish/Sweden': 'sv_SE.UTF-8', - 'Tagalog/Philippines': 'tl_PH', - 'Tamil/India': 'ta_IN.UTF-8', - 'Telugu/India': 'te_IN.UTF-8', - 'Thai': 'th_TH.UTF-8', - 'Turkish': 'tr_TR.UTF-8', - 'Ukrainian': 'uk_UA.UTF-8', - 'Urdu/Pakistan': 'ur_PK', - 'Uzbek/Uzbekistan': 'uz_UZ', - 'Walloon/Belgium': 'wa_BE@euro', - 'Welsh/Great_Britain': 'cy_GB.UTF-8', - 'Xhosa/South_Africa': 'xh_ZA.UTF-8', - 'Yoruba/Nigeria': 'yo_NG.UTF-8', - 'Zulu/South_Africa': 'zu_ZA.UTF-8' - } - - -def _initialize(): - timezones = _read_zonetab() - - j=0 - for timezone in timezones: - set_timezone.__doc__ += timezone+', ' - j+=1 - if j%3 == 0: - set_timezone.__doc__ += '\n' - - keys = _LANGUAGES.keys() - keys.sort() - i = 0 - for key in keys: - set_language.__doc__ += key+', ' - i+=1 - if i%3 == 0: - set_language.__doc__ += '\n' - -def _note_restart(): - print _('To apply your changes you have to restart sugar.\n' + - 'Hit at the same time ctrl+alt+erase on the keyboard to do this.') - -def get_jabber(): - pro = profile.get_profile() - return pro.jabber_server - -def print_jabber(): - print get_jabber() - -def set_jabber(server): - """Set the jabber server - server : e.g. 'olpc.collabora.co.uk' - """ - pro = profile.get_profile() - pro.jabber_server = server - pro.jabber_registered = False - pro.save() - _note_restart() - -def get_color(): - return profile.get_color() - -def print_color(): - color = get_color().to_string() - str = color.split(',') - - stroke = None - fill = None - for color in _COLORS: - for hue in _COLORS[color]: - if _COLORS[color][hue] == str[0]: - stroke = (color, hue) - if _COLORS[color][hue] == str[1]: - fill = (color, hue) - - if stroke is not None: - print 'stroke: color=%s hue=%s'%(stroke[0], stroke[1]) - else: - print 'stroke: %s'%(str[0]) - if fill is not None: - print 'fill: color=%s hue=%s'%(fill[0], fill[1]) - else: - print 'fill: %s'%(str[1]) - -def set_color(stroke, fill, modstroke='medium', modfill='medium'): - """Set the system color by setting a fill and stroke color. - fill : [red, orange, yellow, blue, purple] - stroke : [red, orange, yellow, blue, purple] - hue stroke : [dark, medium, light] (optional) - hue fill : [dark, medium, light] (optional) - """ - - if modstroke not in _MODIFIERS or modfill not in _MODIFIERS: - print (_("Error in specified color modifiers.")) - return - if stroke not in _COLORS or fill not in _COLORS: - print (_("Error in specified colors.")) - return - - if modstroke == modfill: - if modfill == 'medium': - modfill = 'light' - else: - modfill = 'medium' - - color = _COLORS[stroke][modstroke] + ',' + _COLORS[fill][modfill] - pro = profile.get_profile() - pro.color = XoColor(color) - pro.save() - _note_restart() - -def get_nick(): - return profile.get_nick_name() - -def print_nick(): - print get_nick() - -def set_nick(nick): - """Set the nickname. - nick : e.g. 'walter' - """ - pro = profile.get_profile() - pro.nick_name = nick - pro.save() - _note_restart() - -def get_radio(): - bus = dbus.SystemBus() - proxy = bus.get_object(NM_SERVICE_NAME, NM_SERVICE_PATH) - nm = dbus.Interface(proxy, NM_SERVICE_IFACE) - state = nm.getWirelessEnabled() - if state == 0: - return _('off') - elif state == 1: - return _('on') - else: - return _('State is unknown.') - -def print_radio(): - print get_radio() - -def set_radio(state): - """Turn Radio 'on' or 'off' - state : 'on/off' - """ - if state == 'on': - bus = dbus.SystemBus() - proxy = bus.get_object(NM_SERVICE_NAME, NM_SERVICE_PATH) - nm = dbus.Interface(proxy, NM_SERVICE_IFACE) - nm.setWirelessEnabled(True) - elif state == 'off': - bus = dbus.SystemBus() - proxy = bus.get_object(NM_SERVICE_NAME, NM_SERVICE_PATH) - nm = dbus.Interface(proxy, NM_SERVICE_IFACE) - nm.setWirelessEnabled(False) - else: - print (_("Error in specified radio argument use on/off.")) - -def _check_for_superuser(): - if os.getuid(): - print _("Permission denied. You need to be root to run this method.") - return False - return True - -def get_timezone(): - if not os.access(_TIMEZONE_CONFIG, os.R_OK): - # this is what the default is for the /etc/localtime - return "America/New_York" - fd = open(_TIMEZONE_CONFIG, "r") - lines = fd.readlines() - fd.close() - try: - for line in lines: - line = string.strip(line) - if len (line) and line[0] == '#': - continue - try: - tokens = string.split(line, "=") - if tokens[0] == "ZONE": - timezone = string.replace(tokens[1], '"', '') - return timezone - except Exception, e: - print "get_timezone: %s" % e - except Exception, e: - print "get_timezone: %s" % e - return None - -def print_timezone(): - timezone = get_timezone() - if timezone is None: - print (_("Error in reading timezone")) - else: - print timezone - -def _read_zonetab(fn='/usr/share/zoneinfo/zone.tab'): - fd = open (fn, 'r') - lines = fd.readlines() - fd.close() - timezones = [] - for line in lines: - if line.startswith('#'): - continue - line = line.split() - if len(line) > 1: - timezones.append(line[2]) - timezones.sort() - return timezones - -def set_timezone(timezone): - """Set the system timezone - timezone : - """ - if not _check_for_superuser(): - return - - timezones = _read_zonetab() - if timezone in timezones: - fromfile = os.path.join("/usr/share/zoneinfo/", timezone) - try: - shutil.copyfile(fromfile, "/etc/localtime") - except OSError, (errno, msg): - print (_("Error copying timezone (from %s): %s") % (fromfile, msg)) - return - try: - os.chmod("/etc/localtime", 0644) - except OSError, (errno, msg): - print (_("Changing permission of timezone: %s") % (msg)) - return - - # Write info to the /etc/sysconfig/clock file - fd = open(_TIMEZONE_CONFIG, "w") - fd.write('# use sugar-control-panel to change this\n') - fd.write('ZONE="%s"\n' % timezone) - fd.write('UTC=true\n') - fd.close() - else: - print (_("Error timezone does not exist.")) - -def _writeI18N(lang): - path = os.path.join(os.environ.get("HOME"), '.i18n') - if os.access(path, os.W_OK) == 0: - print(_("Could not access %s. Create standard settings.") % path) - fd = open(path, 'w') - fd.write('LANG="en_US.UTF-8"\n') - fd.close() - else: - fd = open(path, 'r') - lines = fd.readlines() - fd.close() - for i in range(len(lines)): - if lines[i][:5] == "LANG=": - lines[i] = 'LANG="' + lang + '"\n' - fd = open(path, 'w') - fd.writelines(lines) - fd.close() - -def get_language(): - originalFile = None - path = os.path.join(os.environ.get("HOME"), '.i18n') - if os.access(path, os.R_OK) == 0: - print(_("Could not access %s. Create standard settings.") % path) - fd = open(path, 'w') - default = 'en_US.UTF-8' - fd.write('LANG="%s"\n'%default) - fd.close() - return default - - fd = open(path, "r") - lines = fd.readlines() - fd.close() - - lang = None - - for line in lines: - if line[:5] == "LANG=": - lang = line[5:].replace('"', '') - lang = lang.strip() - - return lang - -def print_language(): - code = get_language() - - for lang in _LANGUAGES: - if _LANGUAGES[lang] == code: - print lang - return - print (_("Language for code=%s could not be determined.") % code) - -def set_language(language): - """Set the system language. - languages : - """ - if language in _LANGUAGES: - _writeI18N(_LANGUAGES[language]) - _note_restart() - else: - print (_("Sorry I do not speak \'%s\'.") % language) - -# inilialize the docstrings for the timezone and language -_initialize() - diff --git a/shell/hardware/Makefile.am b/shell/hardware/Makefile.am deleted file mode 100644 index 8cd9c77..0000000 --- a/shell/hardware/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -sugardir = $(pkgdatadir)/shell/hardware -sugar_PYTHON = \ - __init__.py \ - hardwaremanager.py \ - keydialog.py \ - nmclient.py \ - nminfo.py \ - schoolserver.py - -dbusservicedir = $(sysconfdir)/dbus-1/system.d/ -dbusservice_DATA = NetworkManagerInfo.conf - -EXTRA_DIST = $(dbusservice_DATA) diff --git a/shell/hardware/NetworkManagerInfo.conf b/shell/hardware/NetworkManagerInfo.conf deleted file mode 100644 index 4fb8270..0000000 --- a/shell/hardware/NetworkManagerInfo.conf +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - 512 - - diff --git a/shell/hardware/__init__.py b/shell/hardware/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/hardware/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/hardware/hardwaremanager.py b/shell/hardware/hardwaremanager.py deleted file mode 100644 index 4eeac03..0000000 --- a/shell/hardware/hardwaremanager.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging - -import dbus -import gst -import gst.interfaces - -from hardware.nmclient import NMClient -from sugar.profile import get_profile -from sugar import env - -_HARDWARE_MANAGER_INTERFACE = 'org.laptop.HardwareManager' -_HARDWARE_MANAGER_SERVICE = 'org.laptop.HardwareManager' -_HARDWARE_MANAGER_OBJECT_PATH = '/org/laptop/HardwareManager' - -COLOR_MODE = 0 -B_AND_W_MODE = 1 - -class HardwareManager(object): - def __init__(self): - try: - bus = dbus.SystemBus() - proxy = bus.get_object(_HARDWARE_MANAGER_SERVICE, - _HARDWARE_MANAGER_OBJECT_PATH) - self._service = dbus.Interface(proxy, _HARDWARE_MANAGER_INTERFACE) - except dbus.DBusException, e: - self._service = None - logging.info('Hardware manager service not found.') - - self._mixer = gst.element_factory_make('alsamixer') - self._mixer.set_state(gst.STATE_PAUSED) - - self._master = None - for track in self._mixer.list_tracks(): - if track.flags & gst.interfaces.MIXER_TRACK_MASTER: - self._master = track - - def get_volume(self): - if not self._mixer or not self._master: - logging.error('Cannot get the volume') - return self._convert_volume(0) - - max_volume = self._master.max_volume - min_volume = self._master.min_volume - volume = self._mixer.get_volume(self._master)[0] - - return volume * 100.0 / (max_volume - min_volume) + min_volume - - def set_volume(self, volume): - if not self._mixer or not self._master: - logging.error('Cannot set the volume') - - if volume < 0 or volume > 100: - logging.error('Trying to set an invalid volume value.') - return - - max_volume = self._master.max_volume - min_volume = self._master.min_volume - - volume = volume * (max_volume - min_volume) / 100.0 + min_volume - volume_list = [ volume ] * self._master.num_channels - - self._mixer.set_volume(self._master, tuple(volume_list)) - - def set_mute(self, mute): - if not self._mixer or not self._master: - logging.error('Cannot mute the audio channel') - self._mixer.set_mute(self._master, mute) - - def startup(self): - if env.is_emulator() is False: - profile = get_profile() - self.set_volume(profile.sound_volume) - - def shutdown(self): - if env.is_emulator() is False: - profile = get_profile() - profile.sound_volume = self.get_volume() - profile.save() - - def set_dcon_freeze(self, frozen): - if not self._service: - return - - self._service.set_dcon_freeze(frozen) - - def set_display_mode(self, mode): - if not self._service: - return - - self._service.set_display_mode(mode) - - def set_display_brightness(self, level): - if not self._service: - logging.error('Cannot set display brightness') - return - - self._service.set_display_brightness(level) - - def get_display_brightness(self): - if not self._service: - logging.error('Cannot get display brightness') - return - - return self._service.get_display_brightness() - - def toggle_keyboard_brightness(self): - if not self._service: - return - - if self._service.get_keyboard_brightness(): - self._service.set_keyboard_brightness(False) - else: - self._service.set_keyboard_brightness(True) - -def get_manager(): - return _manager - -def get_network_manager(): - return _network_manager - -_manager = HardwareManager() - -try: - _network_manager = NMClient() -except dbus.DBusException, e: - _network_manager = None - logging.info('Network manager service not found.') diff --git a/shell/hardware/keydialog.py b/shell/hardware/keydialog.py deleted file mode 100644 index d336ab9..0000000 --- a/shell/hardware/keydialog.py +++ /dev/null @@ -1,351 +0,0 @@ -# vi: ts=4 ai noet -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import md5 -from gettext import gettext as _ - -import gobject, gtk - -IW_AUTH_ALG_OPEN_SYSTEM = 0x00000001 -IW_AUTH_ALG_SHARED_KEY = 0x00000002 - -IW_AUTH_WPA_VERSION_DISABLED = 0x00000001 -IW_AUTH_WPA_VERSION_WPA = 0x00000002 -IW_AUTH_WPA_VERSION_WPA2 = 0x00000004 - -NM_802_11_CAP_NONE = 0x00000000 -NM_802_11_CAP_PROTO_NONE = 0x00000001 -NM_802_11_CAP_PROTO_WEP = 0x00000002 -NM_802_11_CAP_PROTO_WPA = 0x00000004 -NM_802_11_CAP_PROTO_WPA2 = 0x00000008 -NM_802_11_CAP_KEY_MGMT_PSK = 0x00000040 -NM_802_11_CAP_KEY_MGMT_802_1X = 0x00000080 -NM_802_11_CAP_CIPHER_WEP40 = 0x00001000 -NM_802_11_CAP_CIPHER_WEP104 = 0x00002000 -NM_802_11_CAP_CIPHER_TKIP = 0x00004000 -NM_802_11_CAP_CIPHER_CCMP = 0x00008000 - -NM_AUTH_TYPE_WPA_PSK_AUTO = 0x00000000 -IW_AUTH_CIPHER_NONE = 0x00000001 -IW_AUTH_CIPHER_WEP40 = 0x00000002 -IW_AUTH_CIPHER_TKIP = 0x00000004 -IW_AUTH_CIPHER_CCMP = 0x00000008 -IW_AUTH_CIPHER_WEP104 = 0x00000010 - -IW_AUTH_KEY_MGMT_802_1X = 0x1 -IW_AUTH_KEY_MGMT_PSK = 0x2 - -def string_is_hex(key): - is_hex = True - for c in key: - if not 'a' <= c.lower() <= 'f' and not '0' <= c <= '9': - is_hex = False - return is_hex - -def string_is_ascii(string): - try: - string.encode('ascii') - return True - except: - return False - -def string_to_hex(passphrase): - key = '' - for c in passphrase: - key += '%02x' % ord(c) - return key - -def hash_passphrase(passphrase): - # passphrase must have a length of 64 - if len(passphrase) > 64: - passphrase = passphrase[:64] - elif len(passphrase) < 64: - while len(passphrase) < 64: - passphrase += passphrase[:64 - len(passphrase)] - passphrase = md5.new(passphrase).digest() - return string_to_hex(passphrase)[:26] - -class KeyDialog(gtk.Dialog): - def __init__(self, net, async_cb, async_err_cb): - gtk.Dialog.__init__(self, flags=gtk.DIALOG_MODAL) - self.set_title("Wireless Key Required") - - self._net = net - self._async_cb = async_cb - self._async_err_cb = async_err_cb - - self.set_has_separator(False) - - label = gtk.Label("A wireless encryption key is required for\n" \ - " the wireless network '%s'." % net.get_ssid()) - self.vbox.pack_start(label) - - self.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OK, gtk.RESPONSE_OK) - self.set_default_response(gtk.RESPONSE_OK) - self.set_has_separator(True) - - def add_key_entry(self): - self._entry = gtk.Entry() - #self._entry.props.visibility = False - self._entry.connect('changed', self._update_response_sensitivity) - self._entry.connect('activate', self._entry_activate_cb) - self.vbox.pack_start(self._entry) - self.vbox.set_spacing(6) - self.vbox.show_all() - - self._update_response_sensitivity() - self._entry.grab_focus() - - def _entry_activate_cb(self, entry): - self.response(gtk.RESPONSE_OK) - - def create_security(self): - raise NotImplementedError - - def get_network(self): - return self._net - - def get_callbacks(self): - return (self._async_cb, self._async_err_cb) - -WEP_PASSPHRASE = 1 -WEP_HEX = 2 -WEP_ASCII = 3 - -class WEPKeyDialog(KeyDialog): - def __init__(self, net, async_cb, async_err_cb): - KeyDialog.__init__(self, net, async_cb, async_err_cb) - - # WEP key type - self.key_store = gtk.ListStore(str, int) - self.key_store.append(["Passphrase (128-bit)", WEP_PASSPHRASE]) - self.key_store.append(["Hex (40/128-bit)", WEP_HEX]) - self.key_store.append(["ASCII (40/128-bit)", WEP_ASCII]) - - self.key_combo = gtk.ComboBox(self.key_store) - cell = gtk.CellRendererText() - self.key_combo.pack_start(cell, True) - self.key_combo.add_attribute(cell, 'text', 0) - self.key_combo.set_active(0) - self.key_combo.connect('changed', self._key_combo_changed_cb) - - hbox = gtk.HBox() - hbox.pack_start(gtk.Label(_("Key Type:"))) - hbox.pack_start(self.key_combo) - hbox.show_all() - self.vbox.pack_start(hbox) - - # Key entry field - self.add_key_entry() - - # WEP authentication mode - self.auth_store = gtk.ListStore(str, int) - self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM]) - self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY]) - - self.auth_combo = gtk.ComboBox(self.auth_store) - cell = gtk.CellRendererText() - self.auth_combo.pack_start(cell, True) - self.auth_combo.add_attribute(cell, 'text', 0) - self.auth_combo.set_active(0) - - hbox = gtk.HBox() - hbox.pack_start(gtk.Label(_("Authentication Type:"))) - hbox.pack_start(self.auth_combo) - hbox.show_all() - - self.vbox.pack_start(hbox) - - def _key_combo_changed_cb(self, widget): - self._update_response_sensitivity() - - def _get_security(self): - key = self._entry.get_text() - - it = self.key_combo.get_active_iter() - (key_type, ) = self.key_store.get(it, 1) - - if key_type == WEP_PASSPHRASE: - key = hash_passphrase(key) - elif key_type == WEP_ASCII: - key = string_to_hex(key) - - it = self.auth_combo.get_active_iter() - (auth_alg, ) = self.auth_store.get(it, 1) - - we_cipher = None - if len(key) == 26: - we_cipher = IW_AUTH_CIPHER_WEP104 - elif len(key) == 10: - we_cipher = IW_AUTH_CIPHER_WEP40 - - return (we_cipher, key, auth_alg) - - def print_security(self): - (we_cipher, key, auth_alg) = self._get_security() - print "Cipher: %d" % we_cipher - print "Key: %s" % key - print "Auth: %d" % auth_alg - - def create_security(self): - (we_cipher, key, auth_alg) = self._get_security() - from nminfo import Security - return Security.new_from_args(we_cipher, (key, auth_alg)) - - def _update_response_sensitivity(self, ignored=None): - key = self._entry.get_text() - it = self.key_combo.get_active_iter() - (key_type, ) = self.key_store.get(it, 1) - - valid = False - if key_type == WEP_PASSPHRASE: - # As the md5 passphrase can be of any length and has no indicator, - # we cannot check for the validity of the input. - if len(key) > 0: - valid = True - elif key_type == WEP_ASCII: - if len(key) == 5 or len(key) == 13: - valid = string_is_ascii(key) - elif key_type == WEP_HEX: - if len(key) == 10 or len(key) == 26: - valid = string_is_hex(key) - - self.set_response_sensitive(gtk.RESPONSE_OK, valid) - -class WPAKeyDialog(KeyDialog): - def __init__(self, net, async_cb, async_err_cb): - KeyDialog.__init__(self, net, async_cb, async_err_cb) - self.add_key_entry() - - self.store = gtk.ListStore(str, int) - self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO]) - if net.get_caps() & NM_802_11_CAP_CIPHER_CCMP: - self.store.append(["AES-CCMP", IW_AUTH_CIPHER_CCMP]) - if net.get_caps() & NM_802_11_CAP_CIPHER_TKIP: - self.store.append(["TKIP", IW_AUTH_CIPHER_TKIP]) - - self.combo = gtk.ComboBox(self.store) - cell = gtk.CellRendererText() - self.combo.pack_start(cell, True) - self.combo.add_attribute(cell, 'text', 0) - self.combo.set_active(0) - - self.hbox = gtk.HBox() - self.hbox.pack_start(gtk.Label(_("Encryption Type:"))) - self.hbox.pack_start(self.combo) - self.hbox.show_all() - - self.vbox.pack_start(self.hbox) - - def _get_security(self): - ssid = self.get_network().get_ssid() - key = self._entry.get_text() - is_hex = string_is_hex(key) - - real_key = None - if len(key) == 64 and is_hex: - # Hex key - real_key = key - elif len(key) >= 8 and len(key) <= 63: - # passphrase - import commands - (s, o) = commands.getstatusoutput("/usr/sbin/wpa_passphrase '%s' '%s'" % (ssid, key)) - if s != 0: - raise RuntimeError("Error hashing passphrase: %s" % o) - lines = o.split("\n") - for line in lines: - if line.strip().startswith("psk="): - real_key = line.strip()[4:] - if real_key and len(real_key) != 64: - real_key = None - - if not real_key: - raise RuntimeError("Invalid key") - - it = self.combo.get_active_iter() - (we_cipher, ) = self.store.get(it, 1) - - wpa_ver = IW_AUTH_WPA_VERSION_WPA - caps = self.get_network().get_caps() - if caps & NM_802_11_CAP_PROTO_WPA2: - wpa_ver = IW_AUTH_WPA_VERSION_WPA2 - - return (we_cipher, real_key, wpa_ver) - - def print_security(self): - (we_cipher, key, wpa_ver) = self._get_security() - print "Cipher: %d" % we_cipher - print "Key: %s" % key - print "WPA Ver: %d" % wpa_ver - - def create_security(self): - (we_cipher, key, wpa_ver) = self._get_security() - from nminfo import Security - return Security.new_from_args(we_cipher, (key, wpa_ver, IW_AUTH_KEY_MGMT_PSK)) - - def _update_response_sensitivity(self, ignored=None): - key = self._entry.get_text() - is_hex = string_is_hex(key) - - valid = False - if len(key) == 64 and is_hex: - # hex key - valid = True - elif len(key) >= 8 and len(key) <= 63: - # passphrase - valid = True - self.set_response_sensitive(gtk.RESPONSE_OK, valid) - return False - -def new_key_dialog(net, async_cb, async_err_cb): - caps = net.get_caps() - if (caps & NM_802_11_CAP_CIPHER_TKIP or caps & NM_802_11_CAP_CIPHER_CCMP) and \ - (caps & NM_802_11_CAP_PROTO_WPA or caps & NM_802_11_CAP_PROTO_WPA2): - return WPAKeyDialog(net, async_cb, async_err_cb) - elif (caps & NM_802_11_CAP_CIPHER_WEP40 or caps & NM_802_11_CAP_CIPHER_WEP104) and \ - (caps & NM_802_11_CAP_PROTO_WEP): - return WEPKeyDialog(net, async_cb, async_err_cb) - else: - raise RuntimeError("Unhandled network capabilities %x" % caps) - - - -class FakeNet(object): - def get_ssid(self): - return "olpcwpa" - - def get_caps(self): -# return NM_802_11_CAP_CIPHER_WEP104 | NM_802_11_CAP_PROTO_WEP - return NM_802_11_CAP_CIPHER_CCMP | NM_802_11_CAP_CIPHER_TKIP | NM_802_11_CAP_PROTO_WPA - -def response_cb(widget, response_id): - if response_id == gtk.RESPONSE_OK: - print dialog.print_security() - else: - print "canceled" - widget.hide() - widget.destroy() - - -if __name__ == "__main__": - net = FakeNet() - dialog = new_key_dialog(net, None, None) - dialog.connect("response", response_cb) - dialog.run() - diff --git a/shell/hardware/nmclient.py b/shell/hardware/nmclient.py deleted file mode 100644 index d23a206..0000000 --- a/shell/hardware/nmclient.py +++ /dev/null @@ -1,721 +0,0 @@ -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging -import os - -import dbus -import dbus.glib -import dbus.decorators -import gobject -import gtk - -from hardware import nminfo -from sugar.graphics import xocolor - -IW_AUTH_ALG_OPEN_SYSTEM = 0x00000001 -IW_AUTH_ALG_SHARED_KEY = 0x00000002 - -NM_DEVICE_STAGE_STRINGS=("Unknown", - "Prepare", - "Config", - "Need Users Key", - "IP Config", - "IP Config Get", - "IP Config Commit", - "Activated", - "Failed", - "Canceled" -) - -NM_SERVICE = 'org.freedesktop.NetworkManager' -NM_IFACE = 'org.freedesktop.NetworkManager' -NM_IFACE_DEVICES = 'org.freedesktop.NetworkManager.Devices' -NM_PATH = '/org/freedesktop/NetworkManager' - -DEVICE_TYPE_UNKNOWN = 0 -DEVICE_TYPE_802_3_ETHERNET = 1 -DEVICE_TYPE_802_11_WIRELESS = 2 -DEVICE_TYPE_802_11_MESH_OLPC = 3 - -NM_DEVICE_CAP_NONE = 0x00000000 -NM_DEVICE_CAP_NM_SUPPORTED = 0x00000001 -NM_DEVICE_CAP_CARRIER_DETECT = 0x00000002 -NM_DEVICE_CAP_WIRELESS_SCAN = 0x00000004 - -sys_bus = dbus.SystemBus() - -NM_802_11_CAP_NONE = 0x00000000 -NM_802_11_CAP_PROTO_NONE = 0x00000001 -NM_802_11_CAP_PROTO_WEP = 0x00000002 -NM_802_11_CAP_PROTO_WPA = 0x00000004 -NM_802_11_CAP_PROTO_WPA2 = 0x00000008 -NM_802_11_CAP_KEY_MGMT_PSK = 0x00000040 -NM_802_11_CAP_KEY_MGMT_802_1X = 0x00000080 -NM_802_11_CAP_CIPHER_WEP40 = 0x00001000 -NM_802_11_CAP_CIPHER_WEP104 = 0x00002000 -NM_802_11_CAP_CIPHER_TKIP = 0x00004000 -NM_802_11_CAP_CIPHER_CCMP = 0x00008000 - -NETWORK_STATE_CONNECTING = 0 -NETWORK_STATE_CONNECTED = 1 -NETWORK_STATE_NOTCONNECTED = 2 - -DEVICE_STATE_ACTIVATING = 0 -DEVICE_STATE_ACTIVATED = 1 -DEVICE_STATE_INACTIVE = 2 - -IW_MODE_ADHOC = 1 -IW_MODE_INFRA = 2 - -class Network(gobject.GObject): - __gsignals__ = { - 'initialized' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_BOOLEAN])), - 'strength-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'state-changed' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) - } - - def __init__(self, client, op): - gobject.GObject.__init__(self) - self._client = client - self._op = op - self._ssid = None - self._mode = None - self._strength = 0 - self._caps = 0 - self._valid = False - self._favorite = False - self._state = NETWORK_STATE_NOTCONNECTED - - obj = sys_bus.get_object(NM_SERVICE, self._op) - net = dbus.Interface(obj, NM_IFACE_DEVICES) - net.getProperties(reply_handler=self._update_reply_cb, - error_handler=self._update_error_cb) - - def _update_reply_cb(self, *props): - self._ssid = props[1] - self._strength = props[3] - self._mode = props[6] - self._caps = props[7] - if self._caps & NM_802_11_CAP_PROTO_WPA or self._caps & NM_802_11_CAP_PROTO_WPA2: - if not (self._caps & NM_802_11_CAP_KEY_MGMT_PSK): - # 802.1x is not supported at this time - logging.debug("Net(%s): ssid '%s' dropping because 802.1x is unsupported" % (self._op, - self._ssid)) - self._valid = False - self.emit('initialized', self._valid) - return - if self._mode != IW_MODE_INFRA: - # Don't show Ad-Hoc networks; they usually don't DHCP and therefore - # won't work well here. This also works around the bug where we show - # our own mesh SSID on the Mesh view when in mesh mode - logging.debug("Net(%s): ssid '%s' is adhoc; not showing" % (self._op, - self._ssid)) - self._valid = False - self.emit('initialized', self._valid) - return - - fav_nets = [] - if self._client.nminfo: - fav_nets = self._client.nminfo.get_networks(nminfo.NETWORK_TYPE_ALLOWED) - if self._ssid in fav_nets: - self._favorite = True - - self._valid = True - logging.debug("Net(%s): caps 0x%X" % (self._ssid, self._caps)) - self.emit('initialized', self._valid) - - def _update_error_cb(self, err): - logging.debug("Net(%s): failed to update. (%s)" % (self._op, err)) - self._valid = False - self.emit('initialized', self._valid) - - def get_colors(self): - import sha - sh = sha.new() - data = self._ssid + hex(self._caps) + hex(self._mode) - sh.update(data) - h = hash(sh.digest()) - idx = h % len(xocolor._colors) - # stroke, fill - return (xocolor._colors[idx][0], xocolor._colors[idx][1]) - - def get_ssid(self): - return self._ssid - - def get_caps(self): - return self._caps - - def get_mode(self): - return self._mode - - def get_state(self): - return self._state - - def set_state(self, state): - if state == self._state: - return - self._state = state - if self._valid: - self.emit('state-changed') - - def get_op(self): - return self._op - - def get_strength(self): - return self._strength - - def set_strength(self, strength): - if strength == self._strength: - return - self._strength = strength - if self._valid: - self.emit('strength-changed') - - def is_valid(self): - return self._valid - - def is_favorite(self): - return self._favorite - -class Device(gobject.GObject): - __gsignals__ = { - 'initialized': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'init-failed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'ssid-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'strength-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'state-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'activation-stage-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'network-appeared': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'network-disappeared': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self, client, op): - gobject.GObject.__init__(self) - self._client = client - self._op = op - self._iface = None - self._type = DEVICE_TYPE_UNKNOWN - self._udi = None - self._active = False - self._act_stage = 0 - self._strength = 0 - self._freq = 0.0 - self._link = False - self._valid = False - self._networks = {} - self._caps = 0 - self._state = DEVICE_STATE_INACTIVE - self._active_network = None - self._active_net_sigid = 0 - - obj = sys_bus.get_object(NM_SERVICE, self._op) - self.dev = dbus.Interface(obj, NM_IFACE_DEVICES) - self.dev.getProperties(reply_handler=self._update_reply_cb, - error_handler=self._update_error_cb) - - def _is_activating(self): - if self._active and self._act_stage >= 1 and self._act_stage <= 6: - return True - return False - - def _is_activated(self): - if self._active and self._act_stage == 7: - return True - return False - - def _update_reply_cb(self, *props): - self._iface = props[1] - self._type = props[2] - self._udi = props[3] - self._active = props[4] - self._act_stage = props[5] - self._link = props[15] - self._caps = props[17] - - if self._type == DEVICE_TYPE_802_11_WIRELESS: - old_strength = self._strength - self._strength = props[14] - if self._strength != old_strength: - if self._valid: - self.emit('strength-changed') - self._update_networks(props[20], props[19]) - elif self._type == DEVICE_TYPE_802_11_MESH_OLPC: - old_strength = self._strength - self._strength = props[14] - if self._strength != old_strength: - if self._valid: - self.emit('strength-changed') - - self._valid = True - - if self._is_activating(): - self.set_state(DEVICE_STATE_ACTIVATING) - elif self._is_activated(): - self.set_state(DEVICE_STATE_ACTIVATED) - else: - self.set_state(DEVICE_STATE_INACTIVE) - - self.emit('initialized') - - def _update_networks(self, net_ops, active_op): - for op in net_ops: - net = Network(self._client, op) - self._networks[op] = net - net.connect('initialized', lambda *args: self._net_initialized_cb(active_op, *args)) - - def _update_error_cb(self, err): - logging.debug("Device(%s): failed to update. (%s)" % (self._op, err)) - self._valid = False - self.emit('init-failed') - - def _net_initialized_cb(self, active_op, net, valid): - net_op = net.get_op() - if not self._networks.has_key(net_op): - return - - if not valid: - # init failure - del self._networks[net_op] - return - - # init success - if self._valid: - self.emit('network-appeared', net) - if active_op and net_op == active_op: - self.set_active_network(net) - - def get_op(self): - return self._op - - def get_networks(self): - ret = [] - for net in self._networks.values(): - if net.is_valid(): - ret.append(net) - return ret - - def get_network(self, op): - if self._networks.has_key(op) and self._networks[op].is_valid(): - return self._networks[op] - return None - - def get_network_ops(self): - ret = [] - for net in self._networks.values(): - if net.is_valid(): - ret.append(net.get_op()) - return ret - - def get_mesh_step(self): - if self._type != DEVICE_TYPE_802_11_MESH_OLPC: - raise RuntimeError("Only valid for mesh devices") - try: - step = self.dev.getMeshStep(timeout=3) - except dbus.DBusException, e: - step = 0 - return step - - def get_frequency(self): - freq = 0.0 - try: - freq = self.dev.getFrequency(timeout=3) - except dbus.DBusException, e: - pass - # Hz -> GHz - self._freq = freq / 1000000000.0 - return self._freq - - def get_strength(self): - return self._strength - - def set_strength(self, strength): - if strength == self._strength: - return False - - if strength >= 0 and strength <= 100: - self._strength = strength - else: - self._strength = 0 - - if self._valid: - self.emit('strength-changed') - - def network_appeared(self, network): - if self._networks.has_key(network): - return - net = Network(self._client, network) - self._networks[network] = net - net.connect('initialized', lambda *args: self._net_initialized_cb(None, *args)) - - def network_disappeared(self, network): - if not self._networks.has_key(network): - return - - if self._valid: - self.emit('network-disappeared', self._networks[network]) - - del self._networks[network] - - def set_active_network(self, network): - if self._active_network == network: - return - - # Make sure the old one doesn't get a stuck state - if self._active_network: - self._active_network.set_state(NETWORK_STATE_NOTCONNECTED) - self._active_network.disconnect(self._active_net_sigid) - - self._active_network = network - - if self._active_network: - self._active_net_sigid = self._active_network.connect("initialized", - self._active_net_initialized); - - # don't emit ssid-changed for networks that are not yet valid - if self._valid: - if self._active_network and self._active_network.is_valid(): - self.emit('ssid-changed') - elif not self._active_network: - self.emit('ssid-changed') - - def _active_net_initialized(self, net, user_data=None): - if self._active_network and self._active_network.is_valid(): - self.emit('ssid-changed') - - def _get_active_net_cb(self, state, net_op): - if not self._networks.has_key(net_op): - self.set_active_network(None) - return - - self.set_active_network(self._networks[net_op]) - - _device_to_network_state = { - DEVICE_STATE_ACTIVATING : NETWORK_STATE_CONNECTING, - DEVICE_STATE_ACTIVATED : NETWORK_STATE_CONNECTED, - DEVICE_STATE_INACTIVE : NETWORK_STATE_NOTCONNECTED - } - - network_state = _device_to_network_state[state] - self._active_network.set_state(network_state) - - def _get_active_net_error_cb(self, err): - logging.debug("Couldn't get active network: %s" % err) - self.set_active_network(None) - - def get_state(self): - return self._state - - def set_state(self, state): - if state == self._state: - return - - if state == DEVICE_STATE_INACTIVE: - self._act_stage = 0 - - self._state = state - if self._valid: - self.emit('state-changed') - - if self._type == DEVICE_TYPE_802_11_WIRELESS: - if state == DEVICE_STATE_INACTIVE: - self.set_active_network(None) - else: - self.dev.getActiveNetwork(reply_handler=lambda *args: self._get_active_net_cb(state, *args), - error_handler=self._get_active_net_error_cb) - - def set_activation_stage(self, stage): - if stage == self._act_stage: - return - self._act_stage = stage - if self._valid: - self.emit('activation-stage-changed') - - def get_activation_stage(self): - return self._act_stage - - def get_ssid(self): - if self._active_network and self._active_network.is_valid(): - return self._active_network.get_ssid() - elif not self._active_network: - return None - - def get_active_network(self): - return self._active_network - - def get_type(self): - return self._type - - def is_valid(self): - return self._valid - - def set_carrier(self, on): - self._link = on - - def get_capabilities(self): - return self._caps - -class NMClient(gobject.GObject): - __gsignals__ = { - 'device-added' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'device-activated' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'device-activating': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'device-removed' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self.nminfo = None - self._nm_present = False - self._update_timer = 0 - self._devices = {} - - try: - self.nminfo = nminfo.NMInfo(self) - except RuntimeError: - pass - self._setup_dbus() - if self._nm_present: - self._get_initial_devices() - - def get_devices(self): - return self._devices.values() - - def _get_initial_devices_reply_cb(self, ops): - for op in ops: - self._add_device(op) - - def _dev_initialized_cb(self, dev): - self.emit('device-added', dev) - - def _dev_init_failed_cb(self, dev): - # Device failed to initialize, likely due to dbus errors or something - op = dev.get_op() - self._remove_device(op) - - def _get_initial_devices_error_cb(self, err): - logging.debug("Error updating devices (%s)" % err) - - def _get_initial_devices(self): - self._nm_obj.getDevices(reply_handler=self._get_initial_devices_reply_cb, \ - error_handler=self._get_initial_devices_error_cb) - - def _add_device(self, dev_op): - if self._devices.has_key(dev_op): - return - dev = Device(self, dev_op) - self._devices[dev_op] = dev - dev.connect('init-failed', self._dev_init_failed_cb) - dev.connect('initialized', self._dev_initialized_cb) - dev.connect('state-changed', self._dev_state_changed_cb) - - def _remove_device(self, dev_op): - if not self._devices.has_key(dev_op): - return - dev = self._devices[dev_op] - if dev.is_valid(): - self.emit('device-removed', dev) - del self._devices[dev_op] - - def _dev_state_changed_cb(self, dev): - op = dev.get_op() - if not self._devices.has_key(op) or not dev.is_valid(): - return - if dev.get_state() == DEVICE_STATE_ACTIVATING: - self.emit('device-activating', dev) - elif dev.get_state() == DEVICE_STATE_ACTIVATED: - self.emit('device-activated', dev) - - def get_device(self, dev_op): - if not self._devices.has_key(dev_op): - return None - return self._devices[dev_op] - - def _setup_dbus(self): - self._sig_handlers = { - 'StateChange': self.state_changed_sig_handler, - 'DeviceAdded': self.device_added_sig_handler, - 'DeviceRemoved': self.device_removed_sig_handler, - 'DeviceActivationStage': self.device_activation_stage_sig_handler, - 'DeviceActivating': self.device_activating_sig_handler, - 'DeviceNowActive': self.device_now_active_sig_handler, - 'DeviceNoLongerActive': self.device_no_longer_active_sig_handler, - 'DeviceActivationFailed': self.device_activation_failed_sig_handler, - 'DeviceCarrierOn': self.device_carrier_on_sig_handler, - 'DeviceCarrierOff': self.device_carrier_off_sig_handler, - 'DeviceStrengthChanged': self.wireless_device_strength_changed_sig_handler, - 'WirelessNetworkAppeared': self.wireless_network_appeared_sig_handler, - 'WirelessNetworkDisappeared': self.wireless_network_disappeared_sig_handler, - 'WirelessNetworkStrengthChanged': self.wireless_network_strength_changed_sig_handler - } - - try: - self._nm_proxy = sys_bus.get_object(NM_SERVICE, NM_PATH) - self._nm_obj = dbus.Interface(self._nm_proxy, NM_IFACE) - except dbus.DBusException, e: - logging.debug("Could not connect to NetworkManager!") - self._nm_present = False - return - - sys_bus.add_signal_receiver(self.name_owner_changed_sig_handler, - signal_name="NameOwnerChanged", - dbus_interface="org.freedesktop.DBus") - - for (signal, handler) in self._sig_handlers.items(): - sys_bus.add_signal_receiver(handler, signal_name=signal, dbus_interface=NM_IFACE) - - # Find out whether or not NMI is running - try: - bus_object = sys_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - name = bus_object.GetNameOwner("org.freedesktop.NetworkManagerInfo", \ - dbus_interface='org.freedesktop.DBus') - if name: - self._nm_present = True - except dbus.DBusException: - pass - - def set_active_device(self, device, network=None, mesh_freq=None, mesh_start=None): - ssid = "" - if network: - ssid = network.get_ssid() - if device.get_type() == DEVICE_TYPE_802_11_MESH_OLPC: - if mesh_freq or mesh_start: - if mesh_freq and not mesh_start: - self._nm_obj.setActiveDevice(device.get_op(), dbus.Double(mesh_freq)) - elif mesh_start and not mesh_freq: - self._nm_obj.setActiveDevice(device.get_op(), dbus.Double(0.0), dbus.UInt32(mesh_start)) - else: - self._nm_obj.setActiveDevice(device.get_op(), dbus.Double(mesh_freq), dbus.UInt32(mesh_start)) - else: - self._nm_obj.setActiveDevice(device.get_op()) - else: - self._nm_obj.setActiveDevice(device.get_op(), ssid) - - def state_changed_sig_handler(self, new_state): - logging.debug('NM State Changed to %d' % new_state) - - def device_activation_stage_sig_handler(self, device, stage): - logging.debug('Device Activation Stage "%s" for device %s' % (NM_DEVICE_STAGE_STRINGS[stage], device)) - if not self._devices.has_key(device): - logging.debug('DeviceActivationStage, device %s does not exist' % (device)) - return - self._devices[device].set_activation_stage(stage) - - def device_activating_sig_handler(self, device): - logging.debug('DeviceActivating for %s' % (device)) - if not self._devices.has_key(device): - logging.debug('DeviceActivating, device %s does not exist' % (device)) - return - self._devices[device].set_state(DEVICE_STATE_ACTIVATING) - - def device_now_active_sig_handler(self, device, ssid=None): - logging.debug('DeviceNowActive for %s' % (device)) - if not self._devices.has_key(device): - logging.debug('DeviceNowActive, device %s does not exist' % (device)) - return - self._devices[device].set_state(DEVICE_STATE_ACTIVATED) - - def device_no_longer_active_sig_handler(self, device): - logging.debug('DeviceNoLongerActive for %s' % (device)) - if not self._devices.has_key(device): - logging.debug('DeviceNoLongerActive, device %s does not exist' % (device)) - return - self._devices[device].set_state(DEVICE_STATE_INACTIVE) - - def device_activation_failed_sig_handler(self, device, ssid=None): - logging.debug('DeviceActivationFailed for %s' % (device)) - if not self._devices.has_key(device): - logging.debug('DeviceActivationFailed, device %s does not exist' % (device)) - return - self._devices[device].set_state(DEVICE_STATE_INACTIVE) - - def name_owner_changed_sig_handler(self, name, old, new): - if name != NM_SERVICE: - return - if (old and len(old)) and (not new and not len(new)): - # NM went away - self._nm_present = False - devs = self._devices.keys() - for op in devs: - self._remove_device(op) - self._devices = {} - elif (not old and not len(old)) and (new and len(new)): - # NM started up - self._nm_present = True - self._get_initial_devices() - - def device_added_sig_handler(self, device): - logging.debug('DeviceAdded for %s' % (device)) - self._add_device(device) - - def device_removed_sig_handler(self, device): - logging.debug('DeviceRemoved for %s' % (device)) - self._remove_device(device) - - def wireless_network_appeared_sig_handler(self, device, network): - if not self._devices.has_key(device): - return - self._devices[device].network_appeared(network) - - def wireless_network_disappeared_sig_handler(self, device, network): - if not self._devices.has_key(device): - return - self._devices[device].network_disappeared(network) - - def wireless_device_strength_changed_sig_handler(self, device, strength): - if not self._devices.has_key(device): - return - self._devices[device].set_strength(strength) - - def wireless_network_strength_changed_sig_handler(self, device, network, strength): - if not self._devices.has_key(device): - return - net = self._devices[device].get_network(network) - if net: - net.set_strength(strength) - - def device_carrier_on_sig_handler(self, device): - if not self._devices.has_key(device): - return - self._devices[device].set_carrier(True) - - def device_carrier_off_sig_handler(self, device): - if not self._devices.has_key(device): - return - self._devices[device].set_carrier(False) diff --git a/shell/hardware/nminfo.py b/shell/hardware/nminfo.py deleted file mode 100644 index 3a93120..0000000 --- a/shell/hardware/nminfo.py +++ /dev/null @@ -1,525 +0,0 @@ -# vi: ts=4 ai noet -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import dbus -import dbus.service -import time -import os -import binascii -import ConfigParser -import logging - -import nmclient -import keydialog -import gtk -from sugar import env - -IW_AUTH_KEY_MGMT_802_1X = 0x1 -IW_AUTH_KEY_MGMT_PSK = 0x2 - -IW_AUTH_WPA_VERSION_DISABLED = 0x00000001 -IW_AUTH_WPA_VERSION_WPA = 0x00000002 -IW_AUTH_WPA_VERSION_WPA2 = 0x00000004 - -NM_AUTH_TYPE_WPA_PSK_AUTO = 0x00000000 -IW_AUTH_CIPHER_NONE = 0x00000001 -IW_AUTH_CIPHER_WEP40 = 0x00000002 -IW_AUTH_CIPHER_TKIP = 0x00000004 -IW_AUTH_CIPHER_CCMP = 0x00000008 -IW_AUTH_CIPHER_WEP104 = 0x00000010 - -IW_AUTH_ALG_OPEN_SYSTEM = 0x00000001 -IW_AUTH_ALG_SHARED_KEY = 0x00000002 - -NM_INFO_IFACE='org.freedesktop.NetworkManagerInfo' -NM_INFO_PATH='/org/freedesktop/NetworkManagerInfo' - - -class NoNetworks(dbus.DBusException): - def __init__(self): - dbus.DBusException.__init__(self) - self._dbus_error_name = NM_INFO_IFACE + '.NoNetworks' - -class CanceledKeyRequestError(dbus.DBusException): - def __init__(self): - dbus.DBusException.__init__(self) - self._dbus_error_name = NM_INFO_IFACE + '.CanceledError' - - -class NetworkInvalidError(Exception): - pass - - -class NMConfig(ConfigParser.ConfigParser): - def get_bool(self, section, name): - opt = self.get(section, name) - if type(opt) == type(""): - if opt.lower() == 'yes' or opt.lower() == 'true': - return True - elif opt.lower() == 'no' or opt.lower() == 'false': - return False - raise ValueError("Invalid format for %s/%s. Should be one of [yes, no, true, false]." % (section, name)) - - def get_list(self, section, name): - opt = self.get(section, name) - if type(opt) == type(""): - if not len(opt): - return [] - try: - return opt.split() - except Exception: - pass - raise ValueError("Invalid format for %s/%s. Should be a space-separate list." % (section, name)) - - def get_int(self, section, name): - opt = self.get(section, name) - try: - return int(opt) - except Exception: - pass - raise ValueError("Invalid format for %s/%s. Should be a valid integer." % (section, name)) - - def get_float(self, section, name): - opt = self.get(section, name) - try: - return float(opt) - except Exception: - pass - raise ValueError("Invalid format for %s/%s. Should be a valid float." % (section, name)) - - -NETWORK_TYPE_UNKNOWN = 0 -NETWORK_TYPE_ALLOWED = 1 -NETWORK_TYPE_INVALID = 2 - - -class Security(object): - def __init__(self, we_cipher): - self._we_cipher = we_cipher - - def read_from_config(self, cfg, name): - pass - - def read_from_args(self, args): - pass - - def new_from_config(cfg, name): - security = None - we_cipher = cfg.get_int(name, "we_cipher") - if we_cipher == IW_AUTH_CIPHER_NONE: - security = Security(we_cipher) - elif we_cipher == IW_AUTH_CIPHER_WEP40 or we_cipher == IW_AUTH_CIPHER_WEP104: - security = WEPSecurity(we_cipher) - elif we_cipher == NM_AUTH_TYPE_WPA_PSK_AUTO or we_cipher == IW_AUTH_CIPHER_CCMP or we_cipher == IW_AUTH_CIPHER_TKIP: - security = WPASecurity(we_cipher) - else: - raise ValueError("Unsupported security combo") - security.read_from_config(cfg, name) - return security - new_from_config = staticmethod(new_from_config) - - def new_from_args(we_cipher, args): - security = None - try: - if we_cipher == IW_AUTH_CIPHER_NONE: - security = Security(we_cipher) - elif we_cipher == IW_AUTH_CIPHER_WEP40 or we_cipher == IW_AUTH_CIPHER_WEP104: - security = WEPSecurity(we_cipher) - elif we_cipher == NM_AUTH_TYPE_WPA_PSK_AUTO or we_cipher == IW_AUTH_CIPHER_CCMP or we_cipher == IW_AUTH_CIPHER_TKIP: - security = WPASecurity(we_cipher) - else: - raise ValueError("Unsupported security combo") - security.read_from_args(args) - except ValueError, e: - logging.debug("Error reading security information: %s" % e) - del security - return None - return security - new_from_args = staticmethod(new_from_args) - - def get_properties(self): - return [dbus.Int32(self._we_cipher)] - - def write_to_config(self, section, config): - config.set(section, "we_cipher", self._we_cipher) - - -class WEPSecurity(Security): - def read_from_args(self, args): - if len(args) != 2: - raise ValueError("not enough arguments") - key = args[0] - auth_alg = args[1] - if isinstance(key, unicode): - key = key.encode() - if not isinstance(key, str): - raise ValueError("wrong argument type for key") - if not isinstance(auth_alg, int): - raise ValueError("wrong argument type for auth_alg") - self._key = key - self._auth_alg = auth_alg - - def read_from_config(self, cfg, name): - # Key should be a hex encoded string - self._key = cfg.get(name, "key") - if self._we_cipher == IW_AUTH_CIPHER_WEP40 and len(self._key) != 10: - raise ValueError("Key length not right for 40-bit WEP") - if self._we_cipher == IW_AUTH_CIPHER_WEP104 and len(self._key) != 26: - raise ValueError("Key length not right for 104-bit WEP") - - try: - a = binascii.a2b_hex(self._key) - except TypeError: - raise ValueError("Key was not a hexadecimal string.") - - self._auth_alg = cfg.get_int(name, "auth_alg") - if self._auth_alg != IW_AUTH_ALG_OPEN_SYSTEM and self._auth_alg != IW_AUTH_ALG_SHARED_KEY: - raise ValueError("Invalid authentication algorithm %d" % self._auth_alg) - - def get_properties(self): - args = Security.get_properties(self) - args.append(dbus.String(self._key)) - args.append(dbus.Int32(self._auth_alg)) - return args - - def write_to_config(self, section, config): - Security.write_to_config(self, section, config) - config.set(section, "key", self._key) - config.set(section, "auth_alg", self._auth_alg) - -class WPASecurity(Security): - def read_from_args(self, args): - if len(args) != 3: - raise ValueError("not enough arguments") - key = args[0] - if isinstance(key, unicode): - key = key.encode() - if not isinstance(key, str): - raise ValueError("wrong argument type for key") - - wpa_ver = args[1] - if not isinstance(wpa_ver, int): - raise ValueError("wrong argument type for WPA version") - - key_mgmt = args[2] - if not isinstance(key_mgmt, int): - raise ValueError("wrong argument type for WPA key management") - if not key_mgmt & IW_AUTH_KEY_MGMT_PSK: - raise ValueError("Key management types other than PSK are not supported") - - self._key = key - self._wpa_ver = wpa_ver - self._key_mgmt = key_mgmt - - def read_from_config(self, cfg, name): - # Key should be a hex encoded string - self._key = cfg.get(name, "key") - if len(self._key) != 64: - raise ValueError("Key length not right for WPA-PSK") - - try: - a = binascii.a2b_hex(self._key) - except TypeError: - raise ValueError("Key was not a hexadecimal string.") - - self._wpa_ver = cfg.get_int(name, "wpa_ver") - if self._wpa_ver != IW_AUTH_WPA_VERSION_WPA and self._wpa_ver != IW_AUTH_WPA_VERSION_WPA2: - raise ValueError("Invalid WPA version %d" % self._wpa_ver) - - self._key_mgmt = cfg.get_int(name, "key_mgmt") - if not self._key_mgmt & IW_AUTH_KEY_MGMT_PSK: - raise ValueError("Invalid WPA key management option %d" % self._key_mgmt) - - def get_properties(self): - args = Security.get_properties(self) - args.append(dbus.String(self._key)) - args.append(dbus.Int32(self._wpa_ver)) - args.append(dbus.Int32(self._key_mgmt)) - return args - - def write_to_config(self, section, config): - Security.write_to_config(self, section, config) - config.set(section, "key", self._key) - config.set(section, "wpa_ver", self._wpa_ver) - config.set(section, "key_mgmt", self._key_mgmt) - - -class Network: - def __init__(self, ssid): - self.ssid = ssid - self.timestamp = int(time.time()) - self.bssids = [] - self.we_cipher = 0 - self._security = None - - def get_properties(self): - bssid_list = dbus.Array([], signature="s") - for item in self.bssids: - bssid_list.append(dbus.String(item)) - args = [dbus.String(self.ssid), dbus.Int32(self.timestamp), dbus.Boolean(True), bssid_list] - args += self._security.get_properties() - return tuple(args) - - def get_security(self): - return self._security.get_properties() - - def set_security(self, security): - self._security = security - - def read_from_args(self, auto, bssid, we_cipher, args): - if auto == False: - self.timestamp = int(time.time()) - if not bssid in self.bssids: - self.bssids.append(bssid) - - self._security = Security.new_from_args(we_cipher, args) - if not self._security: - raise NetworkInvalidError("Invalid security information") - - def read_from_config(self, config): - try: - self.timestamp = config.get_int(self.ssid, "timestamp") - except (ConfigParser.NoOptionError, ValueError), e: - raise NetworkInvalidError(e) - - try: - self._security = Security.new_from_config(config, self.ssid) - except Exception, e: - raise NetworkInvalidError(e) - - # The following don't need to be present - try: - self.bssids = config.get_list(self.ssid, "bssids") - except (ConfigParser.NoOptionError, ValueError), e: - pass - - def write_to_config(self, config): - try: - config.add_section(self.ssid) - config.set(self.ssid, "timestamp", self.timestamp) - if len(self.bssids) > 0: - opt = " " - opt.join(self.bssids) - config.set(self.ssid, "bssids", opt) - self._security.write_to_config(self.ssid, config) - except Exception, e: - logging.debug("Error writing '%s': %s" % (self.ssid, e)) - - -class NotFoundError(dbus.DBusException): - pass -class UnsupportedError(dbus.DBusException): - pass - -class NMInfoDBusServiceHelper(dbus.service.Object): - def __init__(self, parent): - self._parent = parent - bus = dbus.SystemBus() - - # If NMI is already around, don't grab the NMI service - bus_object = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - name = None - try: - name = bus_object.GetNameOwner("org.freedesktop.NetworkManagerInfo", \ - dbus_interface='org.freedesktop.DBus') - except dbus.DBusException: - pass - if name: - logging.debug("NMI service already owned by %s, won't claim it." % name) - raise RuntimeError - - bus_name = dbus.service.BusName(NM_INFO_IFACE, bus=bus) - dbus.service.Object.__init__(self, bus_name, NM_INFO_PATH) - - @dbus.service.method(NM_INFO_IFACE, in_signature='i', out_signature='as') - def getNetworks(self, net_type): - ssids = self._parent.get_networks(net_type) - if len(ssids) > 0: - return dbus.Array(ssids) - - raise NoNetworks() - - @dbus.service.method(NM_INFO_IFACE, in_signature='si', async_callbacks=('async_cb', 'async_err_cb')) - def getNetworkProperties(self, ssid, net_type, async_cb, async_err_cb): - self._parent.get_network_properties(ssid, net_type, async_cb, async_err_cb) - - @dbus.service.method(NM_INFO_IFACE) - def updateNetworkInfo(self, ssid, bauto, bssid, cipher, *args): - self._parent.update_network_info(ssid, bauto, bssid, cipher, args) - - @dbus.service.method(NM_INFO_IFACE, async_callbacks=('async_cb', 'async_err_cb')) - def getKeyForNetwork(self, dev_path, net_path, ssid, attempt, new_key, async_cb, async_err_cb): - self._parent.get_key_for_network(dev_path, net_path, ssid, - attempt, new_key, async_cb, async_err_cb) - - @dbus.service.method(NM_INFO_IFACE) - def cancelGetKeyForNetwork(self): - self._parent.cancel_get_key_for_network() - -class NMInfo(object): - def __init__(self, client): - profile_path = env.get_profile_path() - self._cfg_file = os.path.join(profile_path, "nm", "networks.cfg") - self._nmclient = client - self._allowed_networks = self._read_config() - self._dbus_helper = NMInfoDBusServiceHelper(self) - self._key_dialog = None - - def save_config(self): - self._write_config(self._allowed_networks) - - def _read_config(self): - if not os.path.exists(os.path.dirname(self._cfg_file)): - os.makedirs(os.path.dirname(self._cfg_file), 0755) - if not os.path.exists(self._cfg_file): - self._write_config({}) - return {} - - config = NMConfig() - config.read(self._cfg_file) - networks = {} - for name in config.sections(): - try: - net = Network(name) - net.read_from_config(config) - networks[name] = net - except Exception, e: - logging.error("Error when processing config for the network %s: %r" % (name, e)) - - del config - return networks - - def _write_config(self, networks): - fp = open(self._cfg_file, 'w') - config = NMConfig() - for net in networks.values(): - net.write_to_config(config) - config.write(fp) - fp.close() - del config - - def get_networks(self, net_type): - if net_type != NETWORK_TYPE_ALLOWED: - raise ValueError("Bad network type") - nets = [] - for net in self._allowed_networks.values(): - nets.append(net.ssid) - logging.debug("Returning networks: %s" % nets) - return nets - - def get_network_properties(self, ssid, net_type, async_cb, async_err_cb): - if not isinstance(ssid, unicode): - async_err_cb(ValueError("Invalid arguments; ssid must be unicode.")) - if net_type != NETWORK_TYPE_ALLOWED: - async_err_cb(ValueError("Bad network type")) - if not self._allowed_networks.has_key(ssid): - async_err_cb(NotFoundError("Network '%s' not found." % ssid)) - network = self._allowed_networks[ssid] - props = network.get_properties() - - # DBus workaround: the normal method return handler wraps - # the returned arguments in a tuple and then converts that to a - # struct, but NetworkManager expects a plain list of arguments. - # It turns out that the async callback method return code _doesn't_ - # wrap the returned arguments in a tuple, so as a workaround use - # the async callback stuff here even though we're not doing it - # asynchronously. - async_cb(*props) - - def update_network_info(self, ssid, auto, bssid, we_cipher, args): - if not isinstance(ssid, unicode): - raise ValueError("Invalid arguments; ssid must be unicode.") - if self._allowed_networks.has_key(ssid): - del self._allowed_networks[ssid] - net = Network(ssid) - try: - net.read_from_args(auto, bssid, we_cipher, args) - logging.debug("Updated network information for '%s'." % ssid) - self._allowed_networks[ssid] = net - self.save_config() - except NetworkInvalidError, e: - logging.debug("Error updating network information: %s" % e) - del net - - def get_key_for_network(self, dev_op, net_op, ssid, attempt, new_key, async_cb, async_err_cb): - if not isinstance(ssid, unicode): - raise ValueError("Invalid arguments; ssid must be unicode.") - if self._allowed_networks.has_key(ssid) and not new_key: - # We've got the info already - net = self._allowed_networks[ssid] - async_cb(tuple(net.get_security())) - return - - # Otherwise, ask the user for it - net = None - dev = self._nmclient.get_device(dev_op) - if not dev: - async_err_cb(NotFoundError("Device was unknown.")) - return - - if dev.get_type() == nmclient.DEVICE_TYPE_802_3_ETHERNET: - # We don't support wired 802.1x yet... - async_err_cb(UnsupportedError("Device type is unsupported by NMI.")) - return - - net = dev.get_network(net_op) - if not net: - async_err_cb(NotFoundError("Network was unknown.")) - return - - self._key_dialog = keydialog.new_key_dialog(net, async_cb, async_err_cb) - self._key_dialog.connect("response", self._key_dialog_response_cb) - self._key_dialog.connect("destroy", self._key_dialog_destroy_cb) - self._key_dialog.show_all() - - def _key_dialog_destroy_cb(self, widget, foo=None): - if widget != self._key_dialog: - return - self._key_dialog_response_cb(widget, gtk.RESPONSE_CANCEL) - - def _key_dialog_response_cb(self, widget, response_id): - if widget != self._key_dialog: - return - - (async_cb, async_err_cb) = self._key_dialog.get_callbacks() - net = self._key_dialog.get_network() - security = None - if response_id == gtk.RESPONSE_OK: - security = self._key_dialog.create_security() - self._key_dialog = None - widget.destroy() - - if response_id in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NONE]: - # key dialog dialog was canceled; send the error back to NM - async_err_cb(CanceledKeyRequestError()) - elif response_id == gtk.RESPONSE_OK: - if not security: - raise RuntimeError("Invalid security arguments.") - props = security.get_properties() - a = tuple(props) - async_cb(*a) - else: - raise RuntimeError("Unhandled key dialog response %d" % response_id) - - def cancel_get_key_for_network(self): - # Close the wireless key dialog and just have it return - # with the 'canceled' argument set to true - if not self._key_dialog: - return - self._key_dialog_destroy_cb(self._key_dialog) - diff --git a/shell/hardware/schoolserver.py b/shell/hardware/schoolserver.py deleted file mode 100644 index 68d14f7..0000000 --- a/shell/hardware/schoolserver.py +++ /dev/null @@ -1,45 +0,0 @@ -from sugar.profile import get_profile -from xmlrpclib import ServerProxy, Error -import sys -import os - -REGISTER_URL = 'http://schoolserver:8080/' - -def register_laptop(url=REGISTER_URL): - if not have_ofw_tree(): - return False - - sn = read_ofw('mfg-data/SN') - uuid = read_ofw('mfg-data/U#') - sn = sn or 'SHF00000000' - uuid = uuid or '00000000-0000-0000-0000-000000000000' - - profile = get_profile() - - try: - server = ServerProxy(url) - data = server.register(sn, profile.nick_name, uuid, profile.pubkey) - if data['success'] != 'OK': - print >> sys.stderr, "Error registering laptop: " + data['error'] - return False - - profile.jabber_server = data['jabberserver'] - profile.backup1 = data['backupurl'] - profile.save() - except Error, e: - print >> sys.stderr, "Error registering laptop: " + str(e) - return False - - return True - -def have_ofw_tree(): - return os.path.exists('/ofw') - -def read_ofw(path): - path = os.path.join('/ofw', path) - if not os.path.exists(path): - return None - fh = open(path, 'r') - data = fh.read().rstrip('\0\n') - fh.close() - return data diff --git a/shell/intro/Makefile.am b/shell/intro/Makefile.am deleted file mode 100644 index 3b92ea0..0000000 --- a/shell/intro/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -imagedir = $(pkgdatadir)/shell/intro -image_DATA = default-picture.png - -EXTRA_DIST = $(conf_DATA) $(image_DATA) -sugardir = $(pkgdatadir)/shell/intro -sugar_PYTHON = \ - __init__.py \ - colorpicker.py \ - intro.py \ - glive.py diff --git a/shell/intro/__init__.py b/shell/intro/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/shell/intro/__init__.py +++ /dev/null diff --git a/shell/intro/colorpicker.py b/shell/intro/colorpicker.py deleted file mode 100644 index 90dbc26..0000000 --- a/shell/intro/colorpicker.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo - -from sugar.graphics.icon import CanvasIcon -from sugar.graphics import style -from sugar.graphics.xocolor import XoColor - -class ColorPicker(hippo.CanvasBox, hippo.CanvasItem): - def __init__(self, **kwargs): - hippo.CanvasBox.__init__(self, **kwargs) - self.props.orientation = hippo.ORIENTATION_HORIZONTAL - - self._xo = CanvasIcon(size=style.XLARGE_ICON_SIZE, - icon_name='computer-xo') - self._set_random_colors() - self._xo.connect('activated', self._xo_activated_cb) - self.append(self._xo) - - def _xo_activated_cb(self, item): - self._set_random_colors() - - def get_color(self): - return self._xo_color - - def _set_random_colors(self): - self._xo_color = XoColor() - self._xo.props.xo_color = self._xo_color diff --git a/shell/intro/default-picture.png b/shell/intro/default-picture.png deleted file mode 100644 index e26b9b0..0000000 --- a/shell/intro/default-picture.png +++ /dev/null Binary files differ diff --git a/shell/intro/glive.py b/shell/intro/glive.py deleted file mode 100644 index a875e48..0000000 --- a/shell/intro/glive.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- Mode: Python -*- -# vi:si:et:sw=4:sts=4:ts=4 - -import gtk -import pygtk -pygtk.require('2.0') -import sys - -import pygst -pygst.require('0.10') -import gst -import gst.interfaces - -import gobject -gobject.threads_init() - -class Glive(gobject.GObject): - __gsignals__ = { - 'new-picture': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'sink': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self, parent, width, height): - gobject.GObject.__init__(self) - self._parent = parent - - #check out the halfpipe, d00d. - self.pipeline = gst.Pipeline() - - self.v4l2src = gst.element_factory_make("v4l2src", "v4l2src") - self.t = gst.element_factory_make("tee", "tee") - self.t_src_pad = self.t.get_request_pad( "src%d" ) - self.vscale = gst.element_factory_make("videoscale", "videoscale") - self.ximagesink = gst.element_factory_make("ximagesink", "ximagesink") - - self.pipeline.add(self.v4l2src) - self.pipeline.add(self.t) - self.pipeline.add(self.vscale) - self.pipeline.add(self.ximagesink) - - self.v4l2src.link(self.t) - - videoscale_structure = gst.Structure("video/x-raw-rgb") - videoscale_structure['width'] = width - videoscale_structure['height'] = height - videoscale_structure['bpp'] = 16 - videoscale_structure['depth'] = 16 - videoscale_caps = gst.Caps(videoscale_structure) - self.t_src_pad.link(self.vscale.get_pad("sink")) - self.vscale.link(self.ximagesink, videoscale_caps) - #self.vscale.link(self.ximagesink) - - self.queue = gst.element_factory_make("queue", "queue") - self.queue.set_property("leaky", True) - self.queue.set_property("max-size-buffers", 1) - self.qsrc = self.queue.get_pad( "src" ) - self.qsink = self.queue.get_pad("sink") - self.ffmpeg = gst.element_factory_make("ffmpegcolorspace", "ffmpegcolorspace") - self.jpgenc = gst.element_factory_make("jpegenc", "jpegenc") - self.filesink = gst.element_factory_make("fakesink", "fakesink") - self.filesink.connect( "handoff", self.copyframe ) - self.filesink.set_property("signal-handoffs", True) - self.pipeline.add(self.queue, self.ffmpeg, self.jpgenc, self.filesink) - - #only link at snapshot time - #self.t.link(self.queue) - self.queue.link(self.ffmpeg) - self.ffmpeg.link(self.jpgenc) - self.jpgenc.link(self.filesink) - self.exposureOpen = False - - self._bus = self.pipeline.get_bus() - self._CONNECT_SYNC = -1 - self._CONNECT_MSG = -1 - self.doPostBusStuff() - - def copyframe(self, fsink, buffer, pad, user_data=None): - #for some reason, we get two back to back buffers, even though we - #ask for only one. - if (self.exposureOpen): - self.exposureOpen = False - piccy = gtk.gdk.pixbuf_loader_new_with_mime_type("image/jpeg") - piccy.write( buffer ) - piccy.close() - pixbuf = piccy.get_pixbuf() - del piccy - - self.t.unlink(self.queue) - self.queue.set_property("leaky", True) - - gobject.idle_add(self.loadPic, pixbuf) - - def loadPic( self, pixbuf ): - self.emit('new-picture', pixbuf) - - def takeSnapshot( self ): - if (self.exposureOpen): - return - else: - self.exposureOpen = True - self.t.link(self.queue) - - def doPostBusStuff(self): - self._bus.enable_sync_message_emission() - self._bus.add_signal_watch() - self._CONNECT_SYNC = self._bus.connect('sync-message::element', self.on_sync_message) - self._CONNECT_MSG = self._bus.connect('message', self.on_message) - - def on_sync_message(self, bus, message): - if message.structure is None: - return - if message.structure.get_name() == 'prepare-xwindow-id': - self.emit('sink', message.src) - message.src.set_property('force-aspect-ratio', True) - - def on_message(self, bus, message): - t = message.type - if (t == gst.MESSAGE_ERROR): - err, debug = message.parse_error() - if (self.on_eos): - self.on_eos() - self._playing = False - elif (t == gst.MESSAGE_EOS): - if (self.on_eos): - self.on_eos() - self._playing = False - - def on_eos( self ): - pass - - def stop(self): - self.pipeline.set_state(gst.STATE_NULL) - - def play(self): - self.pipeline.set_state(gst.STATE_PLAYING) - - def pause(self): - self.pipeline.set_state(gst.STATE_PAUSED) - - -class LiveVideoSlot(gtk.EventBox): - __gsignals__ = { - 'pixbuf': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - } - - def __init__(self, width, height): - gtk.EventBox.__init__(self) - - self.imagesink = None - self.playa = None - self._width = width - self._height = height - - self.unset_flags(gtk.DOUBLE_BUFFERED) - self.connect('focus-in-event', self.focus_in) - self.connect('focus-out-event', self.focus_out) - self.connect("button-press-event", self._button_press_event_cb) - self.connect("expose-event", self._expose_event_cb) - - def _expose_event_cb(self, widget, event): - if not self.playa: - self.playa = Glive(self, self._width, self._height) - self.playa.connect('new-picture', self._new_picture_cb) - self.playa.connect('sink', self._new_sink_cb) - - def _new_picture_cb(self, playa, pixbuf): - self.emit('pixbuf', pixbuf) - - def _new_sink_cb(self, playa, sink): - if (self.imagesink != None): - assert self.window.xid - self.imagesink = None - del self.imagesink - self.imagesink = sink - self.imagesink.set_xwindow_id(self.window.xid) - - def _button_press_event_cb(self, widget, event): - self.takeSnapshot() - - def focus_in(self, widget, event, args=None): - self.play() - - def focus_out(self, widget, event, args=None): - self.stop() - - def play( self ): - self.playa.play() - - def pause( self ): - self.playa.pause() - - def stop( self ): - self.playa.stop() - - def takeSnapshot( self ): - self.playa.takeSnapshot() diff --git a/shell/intro/intro.py b/shell/intro/intro.py deleted file mode 100644 index 1bd46c7..0000000 --- a/shell/intro/intro.py +++ /dev/null @@ -1,267 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -from ConfigParser import ConfigParser -from gettext import gettext as _ - -import gtk -import gobject -import dbus -import hippo -import logging - -from sugar import env -from sugar.graphics import style -from sugar.graphics.icon import Icon -from sugar.graphics.entry import CanvasEntry -from sugar.profile import get_profile - -import colorpicker - -_BACKGROUND_COLOR = style.COLOR_PANEL_GREY - -class _Page(hippo.CanvasBox): - __gproperties__ = { - 'valid' : (bool, None, None, False, - gobject.PARAM_READABLE) - } - - def __init__(self, **kwargs): - hippo.CanvasBox.__init__(self, **kwargs) - self.valid = False - - def set_valid(self, valid): - self.valid = valid - self.notify('valid') - - def do_get_property(self, pspec): - if pspec.name == 'valid': - return self.valid - - def activate(self): - pass - -class _NamePage(_Page): - def __init__(self, intro): - _Page.__init__(self, xalign=hippo.ALIGNMENT_CENTER, - background_color=_BACKGROUND_COLOR.get_int(), - spacing=style.DEFAULT_SPACING, - orientation=hippo.ORIENTATION_HORIZONTAL,) - - self._intro = intro - - label = hippo.CanvasText(text=_("Name:")) - self.append(label) - - self._entry = CanvasEntry(box_width=style.zoom(300)) - self._entry.set_background(_BACKGROUND_COLOR.get_html()) - self._entry.connect('notify::text', self._text_changed_cb) - - widget = self._entry.props.widget - widget.set_max_length(45) - - self.append(self._entry) - - def _text_changed_cb(self, entry, pspec): - valid = len(entry.props.text.strip()) > 0 - self.set_valid(valid) - - def get_name(self): - return self._entry.props.text - - def activate(self): - self._entry.props.widget.grab_focus() - -class _ColorPage(_Page): - def __init__(self, **kwargs): - _Page.__init__(self, xalign=hippo.ALIGNMENT_CENTER, - background_color=_BACKGROUND_COLOR.get_int(), - spacing=style.DEFAULT_SPACING, - yalign=hippo.ALIGNMENT_CENTER, **kwargs) - - self._label = hippo.CanvasText(text=_("Click to change color:"), - xalign=hippo.ALIGNMENT_CENTER) - self.append(self._label) - - self._cp = colorpicker.ColorPicker(xalign=hippo.ALIGNMENT_CENTER) - self.append(self._cp) - - self._color = self._cp.get_color() - self.set_valid(True) - - def get_color(self): - return self._cp.get_color() - -class _IntroBox(hippo.CanvasBox): - __gsignals__ = { - 'done': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, - gobject.TYPE_PYOBJECT])) - } - - PAGE_NAME = 0 - PAGE_COLOR = 1 - - PAGE_FIRST = PAGE_NAME - PAGE_LAST = PAGE_COLOR - - def __init__(self): - hippo.CanvasBox.__init__(self, padding=style.zoom(30), - background_color=_BACKGROUND_COLOR.get_int()) - - self._page = self.PAGE_NAME - self._name_page = _NamePage(self) - self._color_page = _ColorPage() - self._current_page = None - - self._setup_page() - - def _setup_page(self): - self.remove_all() - - if self._page == self.PAGE_NAME: - self._current_page = self._name_page - elif self._page == self.PAGE_COLOR: - self._current_page = self._color_page - - self.append(self._current_page, hippo.PACK_EXPAND) - - button_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL) - - if self._page != self.PAGE_FIRST: - back_button = hippo.CanvasButton(text=_('Back')) - image = Icon(icon_name='go-left') - back_button.props.widget.set_image(image) - back_button.connect('activated', self._back_activated_cb) - button_box.append(back_button) - - spacer = hippo.CanvasBox() - button_box.append(spacer, hippo.PACK_EXPAND) - - self._next_button = hippo.CanvasButton() - image = Icon(icon_name='go-right') - self._next_button.props.widget.set_image(image) - - if self._page == self.PAGE_LAST: - self._next_button.props.text = _('Done') - self._next_button.connect('activated', self._done_activated_cb) - else: - self._next_button.props.text = _('Next') - self._next_button.connect('activated', self._next_activated_cb) - - self._current_page.activate() - - self._update_next_button() - button_box.append(self._next_button) - - self._current_page.connect('notify::valid', - self._page_valid_changed_cb) - self.append(button_box) - - def _update_next_button(self): - widget = self._next_button.props.widget - widget.props.sensitive = self._current_page.props.valid - - def _page_valid_changed_cb(self, page, pspec): - self._update_next_button() - - def _back_activated_cb(self, item): - self.back() - - def back(self): - if self._page != self.PAGE_FIRST: - self._page -= 1 - self._setup_page() - - def _next_activated_cb(self, item): - self.next() - - def next(self): - if self._page == self.PAGE_LAST: - self.done() - if self._current_page.props.valid: - self._page += 1 - self._setup_page() - - def _done_activated_cb(self, item): - self.done() - - def done(self): - path = os.path.join(os.path.dirname(__file__), 'default-picture.png') - pixbuf = gtk.gdk.pixbuf_new_from_file(path) - name = self._name_page.get_name() - color = self._color_page.get_color() - - self.emit('done', pixbuf, name, color) - - def _key_press_cb(self, widget, event): - if gtk.gdk.keyval_name(event.keyval) == "Return": - self.next() - return True - elif gtk.gdk.keyval_name(event.keyval) == "Escape": - self.back() - return True - return False - -class IntroWindow(gtk.Window): - def __init__(self): - gtk.Window.__init__(self) - - self._canvas = hippo.Canvas() - self._intro_box = _IntroBox() - self._intro_box.connect('done', self._done_cb) - self._canvas.set_root(self._intro_box) - - self.add(self._canvas) - self._canvas.show() - self.connect('key-press-event', self._intro_box._key_press_cb) - - def _done_cb(self, box, pixbuf, name, color): - self.hide() - gobject.idle_add(self._create_profile, pixbuf, name, color) - - def _create_profile(self, pixbuf, name, color): - # Save the buddy icon - icon_path = os.path.join(env.get_profile_path(), "buddy-icon.jpg") - scaled = pixbuf.scale_simple(200, 200, gtk.gdk.INTERP_BILINEAR) - pixbuf.save(icon_path, "jpeg", {"quality":"85"}) - - profile = get_profile() - profile.nick_name = name - profile.color = color - profile.save() - - # Generate keypair - import commands - keypath = os.path.join(env.get_profile_path(), "owner.key") - if not os.path.isfile(keypath): - cmd = "ssh-keygen -q -t dsa -f %s -C '' -N ''" % keypath - (s, o) = commands.getstatusoutput(cmd) - if s != 0: - logging.error("Could not generate key pair: %d" % s) - else: - logging.error("Keypair exists, skip generation.") - - gtk.main_quit() - return False - - -if __name__ == "__main__": - w = IntroWindow() - w.show() - w.connect('destroy', gtk.main_quit) - gtk.main() diff --git a/shell/logsmanager.py b/shell/logsmanager.py deleted file mode 100644 index caa50d2..0000000 --- a/shell/logsmanager.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (C) 2007 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import os -import time - -from sugar import env - -_MAX_BACKUP_DIRS = 3 - -def setup(): - logs_dir = env.get_logs_path() - if not os.path.isdir(logs_dir): - os.makedirs(logs_dir) - - backup_logs = [] - backup_dirs = [] - for f in os.listdir(logs_dir): - path = os.path.join(logs_dir, f) - if os.path.isfile(path): - backup_logs.append(f) - elif os.path.isdir(path): - backup_dirs.append(path) - - if len(backup_dirs) > _MAX_BACKUP_DIRS: - backup_dirs.sort() - root = backup_dirs[0] - for f in os.listdir(root): - os.remove(os.path.join(root, f)) - os.rmdir(root) - - if len(backup_logs) > 0: - name = str(int(time.time())) - backup_dir = os.path.join(logs_dir, name) - os.mkdir(backup_dir) - for log in backup_logs: - source_path = os.path.join(logs_dir, log) - dest_path = os.path.join(backup_dir, log) - os.rename(source_path, dest_path) - diff --git a/shell/main.py b/shell/main.py deleted file mode 100644 index f2f1a51..0000000 --- a/shell/main.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright (C) 2006, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os -from ConfigParser import ConfigParser -import gettext - -# HACK we need to import numpy before gtk otherwise we traceback in -# some locales. See http://dev.laptop.org/ticket/5559. -import numpy - -import pygtk -pygtk.require('2.0') -import gtk -import gobject - -from sugar import env -from sugar import logger -from sugar.profile import get_profile - -from view.Shell import Shell -from model.shellmodel import ShellModel -from shellservice import ShellService -from hardware import hardwaremanager -from intro import intro -import logsmanager -import config - -def _start_matchbox(): - cmd = ['matchbox-window-manager'] - - cmd.extend(['-use_titlebar', 'no']) - cmd.extend(['-theme', 'sugar']) - cmd.extend(['-kbdconfig', os.path.join(config.data_path, 'kbdconfig')]) - - gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH) - -def _save_session_info(): - # Save our DBus Session Bus address somewhere it can be found - # - # WARNING!!! this is going away at some near future point, do not rely on it - # - session_info_file = os.path.join(env.get_profile_path(), "session.info") - f = open(session_info_file, "w") - - cp = ConfigParser() - cp.add_section('Session') - cp.set('Session', 'dbus_address', os.environ['DBUS_SESSION_BUS_ADDRESS']) - cp.set('Session', 'display', gtk.gdk.display_get_default().get_name()) - cp.write(f) - - f.close() - -def _setup_translations(): - locale_path = os.path.join(config.prefix, 'share', 'locale') - domain = 'sugar' - - gettext.bindtextdomain(domain, locale_path) - gettext.textdomain(domain) - -def check_cm(bus_name): - try: - import dbus - bus = dbus.SessionBus() - bus_object = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - name = bus_object.GetNameOwner(bus_name, dbus_interface='org.freedesktop.DBus') - if name: - return True - except dbus.DBusException: - pass - return False - -def _shell_started_cb(): - # Unfreeze the display - hw_manager = hardwaremanager.get_manager() - hw_manager.set_dcon_freeze(0) - -def main(): - gobject.idle_add(_shell_started_cb) - - logsmanager.setup() - logger.start('shell') - - _save_session_info() - _start_matchbox() - _setup_translations() - - hw_manager = hardwaremanager.get_manager() - hw_manager.startup() - - icons_path = env.get_data_path('icons') - gtk.icon_theme_get_default().append_search_path(icons_path) - - # Do initial setup if needed - if not get_profile().is_valid(): - win = intro.IntroWindow() - win.show_all() - gtk.main() - - if os.environ.has_key("SUGAR_TP_DEBUG"): - # Allow the user time to start up telepathy connection managers - # using the Sugar DBus bus address - import time - from telepathy.client import ManagerRegistry - - registry = ManagerRegistry() - registry.LoadManagers() - - debug_flags = os.environ["SUGAR_TP_DEBUG"].split(',') - for cm_name in debug_flags: - if cm_name not in ["gabble", "salut"]: - continue - - try: - cm = registry.services[cm_name] - except KeyError: - print RuntimeError("%s connection manager not found!" % cm_name) - - while not check_cm(cm['busname']): - print "Waiting for %s on: DBUS_SESSION_BUS_ADDRESS=%s" % \ - (cm_name, os.environ["DBUS_SESSION_BUS_ADDRESS"]) - try: - time.sleep(5) - except KeyboardInterrupt: - print "Got Ctrl+C, continuing..." - break - - model = ShellModel() - shell = Shell(model) - service = ShellService(shell) - - try: - gtk.main() - except KeyboardInterrupt: - print 'Ctrl+C pressed, exiting...' - - session_info_file = os.path.join(env.get_profile_path(), "session.info") - os.remove(session_info_file) - diff --git a/shell/model/BuddyModel.py b/shell/model/BuddyModel.py deleted file mode 100644 index 11c6567..0000000 --- a/shell/model/BuddyModel.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging - -from sugar.presence import presenceservice -from sugar.graphics.xocolor import XoColor -import gobject - -_NOT_PRESENT_COLOR = "#888888,#BBBBBB" - -class BuddyModel(gobject.GObject): - __gsignals__ = { - 'appeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'disappeared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'nick-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'color-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'icon-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([])), - 'current-activity-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self, key=None, buddy=None, nick=None): - if (key and buddy) or (not key and not buddy): - raise RuntimeError("Must specify only _one_ of key or buddy.") - - gobject.GObject.__init__(self) - - self._ba_handler = None - self._pc_handler = None - self._dis_handler = None - self._bic_handler = None - self._cac_handler = None - - self._pservice = presenceservice.get_instance() - - self._buddy = None - - if not buddy: - self._key = key - # connect to the PS's buddy-appeared signal and - # wait for the buddy to appear - self._ba_handler = self._pservice.connect('buddy-appeared', - self._buddy_appeared_cb) - # Set color to 'inactive'/'disconnected' - self._set_color_from_string(_NOT_PRESENT_COLOR) - self._nick = nick - - self._pservice.get_buddies_async(reply_handler=self._get_buddies_cb) - else: - self._update_buddy(buddy) - - def _get_buddies_cb(self, list): - buddy = None - for iter_buddy in list: - if iter_buddy.props.key == self._key: - buddy = iter_buddy - break - - if buddy: - if self._ba_handler: - # Once we have the buddy, we no longer need to - # monitor buddy-appeared events - self._pservice.disconnect(self._ba_handler) - self._ba_handler = None - - self._update_buddy(buddy) - - def _set_color_from_string(self, color_string): - self._color = XoColor(color_string) - - def get_key(self): - return self._key - - def get_nick(self): - return self._nick - - def get_color(self): - return self._color - - def get_buddy(self): - return self._buddy - - def is_owner(self): - if not self._buddy: - return False - return self._buddy.props.owner - - def is_present(self): - if self._buddy: - return True - return False - - def get_current_activity(self): - if self._buddy: - return self._buddy.props.current_activity - return None - - def _update_buddy(self, buddy): - if not buddy: - raise ValueError("Buddy cannot be None.") - - self._buddy = buddy - self._key = self._buddy.props.key - self._nick = self._buddy.props.nick - self._set_color_from_string(self._buddy.props.color) - - self._pc_handler = self._buddy.connect('property-changed', self._buddy_property_changed_cb) - self._bic_handler = self._buddy.connect('icon-changed', self._buddy_icon_changed_cb) - - def _buddy_appeared_cb(self, pservice, buddy): - if self._buddy or buddy.props.key != self._key: - return - - if self._ba_handler: - # Once we have the buddy, we no longer need to - # monitor buddy-appeared events - self._pservice.disconnect(self._ba_handler) - self._ba_handler = None - - self._update_buddy(buddy) - self.emit('appeared') - - def _buddy_property_changed_cb(self, buddy, keys): - if not self._buddy: - return - if 'color' in keys: - self._set_color_from_string(self._buddy.props.color) - self.emit('color-changed', self.get_color()) - if 'current-activity' in keys: - self.emit('current-activity-changed', buddy.props.current_activity) - if 'nick' in keys: - self._nick = self._buddy.props.nick - self.emit('nick-changed', self.get_nick()) - - def _buddy_disappeared_cb(self, buddy): - if buddy != self._buddy: - return - self._buddy.disconnect(self._pc_handler) - self._buddy.disconnect(self._dis_handler) - self._buddy.disconnect(self._bic_handler) - self._buddy.disconnect(self._cac_handler) - self._set_color_from_string(_NOT_PRESENT_COLOR) - self.emit('disappeared') - self._buddy = None - - def _buddy_icon_changed_cb(self, buddy): - self.emit('icon-changed') diff --git a/shell/model/Friends.py b/shell/model/Friends.py deleted file mode 100644 index 6fc3e97..0000000 --- a/shell/model/Friends.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import dbus -import os -from ConfigParser import ConfigParser - -import gobject - -from model.BuddyModel import BuddyModel -from sugar import env -import logging - -class Friends(gobject.GObject): - __gsignals__ = { - 'friend-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - 'friend-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([str])), - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._friends = {} - self._path = os.path.join(env.get_profile_path(), 'friends') - - self.load() - - def has_buddy(self, buddy): - return self._friends.has_key(buddy.get_key()) - - def add_friend(self, buddy_info): - self._friends[buddy_info.get_key()] = buddy_info - self.emit('friend-added', buddy_info) - - def make_friend(self, buddy): - if not self.has_buddy(buddy): - self.add_friend(buddy) - self.save() - - def remove(self, buddy_info): - del self._friends[buddy_info.get_key()] - self.save() - self.emit('friend-removed', buddy_info.get_key()) - - def __iter__(self): - return self._friends.values().__iter__() - - def load(self): - cp = ConfigParser() - - try: - success = cp.read([self._path]) - if success: - for key in cp.sections(): - # HACK: don't screw up on old friends files - if len(key) < 20: - continue - buddy = BuddyModel(key=key, nick=cp.get(key, 'nick')) - self.add_friend(buddy) - except Exception, exc: - logging.error("Error parsing friends file: %s" % exc) - - def save(self): - cp = ConfigParser() - - for friend in self: - section = friend.get_key() - cp.add_section(section) - cp.set(section, 'nick', friend.get_nick()) - cp.set(section, 'color', friend.get_color().to_string()) - - fileobject = open(self._path, 'w') - cp.write(fileobject) - fileobject.close() - - self._sync_friends() - - def _sync_friends(self): - # XXX: temporary hack - # remove this when the shell service has a D-Bus API for buddies - - def friends_synced(): - pass - - def friends_synced_error(e): - logging.error("Error asking presence service to sync friends: %s" - % e) - - keys = [] - for friend in self: - keys.append(friend.get_key()) - - bus = dbus.SessionBus() - ps = bus.get_object('org.laptop.Sugar.Presence', - '/org/laptop/Sugar/Presence') - psi = dbus.Interface(ps, 'org.laptop.Sugar.Presence') - psi.SyncFriends(keys, - reply_handler=friends_synced, - error_handler=friends_synced_error) diff --git a/shell/model/Invites.py b/shell/model/Invites.py deleted file mode 100644 index 9ffab44..0000000 --- a/shell/model/Invites.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject -from sugar.presence import presenceservice - -class Invite: - def __init__(self, issuer, bundle_id, activity_id): - self._issuer = issuer - self._activity_id = activity_id - self._bundle_id = bundle_id - - def get_activity_id(self): - return self._activity_id - - def get_bundle_id(self): - return self._bundle_id - -class Invites(gobject.GObject): - __gsignals__ = { - 'invite-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - 'invite-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([object])), - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._dict = {} - - ps = presenceservice.get_instance() - owner = ps.get_owner() - owner.connect('joined-activity', self._owner_joined_cb) - - def add_invite(self, issuer, bundle_id, activity_id): - if activity_id in self._dict: - # there is no point to add more than one time - # an invite for the same activity - return - - invite = Invite(issuer, bundle_id, activity_id) - self._dict[activity_id] = invite - self.emit('invite-added', invite) - - def remove_invite(self, invite): - self._dict.pop(invite.get_activity_id()) - self.emit('invite-removed', invite) - - def remove_activity(self, activity_id): - invite = self._dict.get(activity_id) - if invite is not None: - self.remove_invite(invite) - - def _owner_joined_cb(self, owner, activity): - self.remove_activity(activity.props.id) - - def __iter__(self): - return self._dict.values().__iter__() diff --git a/shell/model/Makefile.am b/shell/model/Makefile.am deleted file mode 100644 index 0b7d14c..0000000 --- a/shell/model/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -SUBDIRS = devices - -sugardir = $(pkgdatadir)/shell/model -sugar_PYTHON = \ - __init__.py \ - accesspointmodel.py \ - BuddyModel.py \ - Friends.py \ - Invites.py \ - Owner.py \ - MeshModel.py \ - shellmodel.py \ - homeactivity.py \ - homemodel.py diff --git a/shell/model/MeshModel.py b/shell/model/MeshModel.py deleted file mode 100644 index da5b3c2..0000000 --- a/shell/model/MeshModel.py +++ /dev/null @@ -1,235 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject - -from sugar.graphics.xocolor import XoColor -from sugar.presence import presenceservice -from sugar import activity - -from model.BuddyModel import BuddyModel -from model.accesspointmodel import AccessPointModel -from hardware import hardwaremanager -from hardware import nmclient - -class ActivityModel: - def __init__(self, activity, bundle): - self.activity = activity - self.bundle = bundle - - def get_id(self): - return self.activity.props.id - - def get_icon_name(self): - return self.bundle.icon - - def get_color(self): - return XoColor(self.activity.props.color) - - def get_bundle_id(self): - return self.bundle.bundle_id - -class MeshModel(gobject.GObject): - __gsignals__ = { - 'activity-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'activity-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'buddy-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'buddy-moved': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT, - gobject.TYPE_PYOBJECT])), - 'buddy-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'access-point-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'access-point-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'mesh-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), - 'mesh-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._activities = {} - self._buddies = {} - self._access_points = {} - self._mesh = None - - self._pservice = presenceservice.get_instance() - self._pservice.connect("activity-appeared", - self._activity_appeared_cb) - self._pservice.connect('activity-disappeared', - self._activity_disappeared_cb) - self._pservice.connect("buddy-appeared", - self._buddy_appeared_cb) - self._pservice.connect("buddy-disappeared", - self._buddy_disappeared_cb) - - # Add any buddies the PS knows about already - self._pservice.get_buddies_async(reply_handler=self._get_buddies_cb) - - self._pservice.get_activities_async(reply_handler=self._get_activities_cb) - - network_manager = hardwaremanager.get_network_manager() - if network_manager: - for nm_device in network_manager.get_devices(): - self._add_network_device(nm_device) - network_manager.connect('device-added', - self._nm_device_added_cb) - network_manager.connect('device-removed', - self._nm_device_removed_cb) - - def _get_buddies_cb(self, list): - for buddy in list: - self._buddy_appeared_cb(self._pservice, buddy) - - def _get_activities_cb(self, list): - for activity in list: - self._check_activity(activity) - - def _nm_device_added_cb(self, manager, nm_device): - self._add_network_device(nm_device) - - def _nm_device_removed_cb(self, manager, nm_device): - self._remove_network_device(nm_device) - - def _nm_network_appeared_cb(self, nm_device, nm_network): - self._add_access_point(nm_device, nm_network) - - def _nm_network_disappeared_cb(self, nm_device, nm_network): - if self._access_points.has_key(nm_network.get_op()): - ap = self._access_points[nm_network.get_op()] - self._remove_access_point(ap) - - def _add_network_device(self, nm_device): - dtype = nm_device.get_type() - if dtype == nmclient.DEVICE_TYPE_802_11_WIRELESS: - for nm_network in nm_device.get_networks(): - self._add_access_point(nm_device, nm_network) - - nm_device.connect('network-appeared', - self._nm_network_appeared_cb) - nm_device.connect('network-disappeared', - self._nm_network_disappeared_cb) - elif dtype == nmclient.DEVICE_TYPE_802_11_MESH_OLPC: - self._mesh = nm_device - self.emit('mesh-added', self._mesh) - - def _remove_network_device(self, nm_device): - if nm_device == self._mesh: - self._mesh = None - self.emit('mesh-removed') - elif nm_device.get_type() == nmclient.DEVICE_TYPE_802_11_WIRELESS: - aplist = self._access_points.values() - for ap in aplist: - if ap.get_nm_device() == nm_device: - self._remove_access_point(ap) - - def _add_access_point(self, nm_device, nm_network): - model = AccessPointModel(nm_device, nm_network) - self._access_points[model.get_id()] = model - self.emit('access-point-added', model) - - def _remove_access_point(self, ap): - if not self._access_points.has_key(ap.get_id()): - return - self.emit('access-point-removed', ap) - del self._access_points[ap.get_id()] - - def get_mesh(self): - return self._mesh - - def get_access_points(self): - return self._access_points.values() - - def get_activities(self): - return self._activities.values() - - def get_buddies(self): - return self._buddies.values() - - def _buddy_activity_changed_cb(self, model, cur_activity): - if not self._buddies.has_key(model.get_key()): - return - if cur_activity and self._activities.has_key(cur_activity.props.id): - activity_model = self._activities[cur_activity.props.id] - self.emit('buddy-moved', model, activity_model) - else: - self.emit('buddy-moved', model, None) - - def _buddy_appeared_cb(self, pservice, buddy): - if self._buddies.has_key(buddy.props.key): - return - - model = BuddyModel(buddy=buddy) - model.connect('current-activity-changed', - self._buddy_activity_changed_cb) - self._buddies[buddy.props.key] = model - self.emit('buddy-added', model) - - cur_activity = buddy.props.current_activity - if cur_activity: - self._buddy_activity_changed_cb(model, cur_activity) - - def _buddy_disappeared_cb(self, pservice, buddy): - if not self._buddies.has_key(buddy.props.key): - return - self.emit('buddy-removed', self._buddies[buddy.props.key]) - del self._buddies[buddy.props.key] - - def _activity_appeared_cb(self, pservice, activity): - self._check_activity(activity) - - def _check_activity(self, presence_activity): - registry = activity.get_registry() - bundle = registry.get_activity(presence_activity.props.type) - if not bundle: - return - if self.has_activity(presence_activity.props.id): - return - self.add_activity(bundle, presence_activity) - - def has_activity(self, activity_id): - return self._activities.has_key(activity_id) - - def get_activity(self, activity_id): - if self.has_activity(activity_id): - return self._activities[activity_id] - else: - return None - - def add_activity(self, bundle, activity): - model = ActivityModel(activity, bundle) - self._activities[model.get_id()] = model - self.emit('activity-added', model) - - for buddy in self._pservice.get_buddies(): - cur_activity = buddy.props.current_activity - key = buddy.props.key - if cur_activity == activity and self._buddies.has_key(key): - buddy_model = self._buddies[key] - self.emit('buddy-moved', buddy_model, model) - - def _activity_disappeared_cb(self, pservice, activity): - if self._activities.has_key(activity.props.id): - activity_model = self._activities[activity.props.id] - self.emit('activity-removed', activity_model) - del self._activities[activity.props.id] diff --git a/shell/model/Owner.py b/shell/model/Owner.py deleted file mode 100644 index b06b391..0000000 --- a/shell/model/Owner.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject -import os -import random -import base64 -import time -import logging -import dbus - -from sugar import env -from sugar import profile -from sugar.presence import presenceservice -from sugar import util -from model.Invites import Invites - -class ShellOwner(gobject.GObject): - __gtype_name__ = "ShellOwner" - - __gsignals__ = { - 'nick-changed' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_STRING])), - 'color-changed' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'icon-changed' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - """Class representing the owner of this machine/instance. This class - runs in the shell and serves up the buddy icon and other stuff. It's the - server portion of the Owner, paired with the client portion in Buddy.py.""" - def __init__(self): - gobject.GObject.__init__(self) - - self._nick = profile.get_nick_name() - - self._icon = None - self._icon_hash = "" - icon = os.path.join(env.get_profile_path(), "buddy-icon.jpg") - if not os.path.exists(icon): - raise RuntimeError("missing buddy icon") - - fd = open(icon, "r") - self._icon = fd.read() - fd.close() - if not self._icon: - raise RuntimeError("invalid buddy icon") - - # Get the icon's hash - import md5 - digest = md5.new(self._icon).digest() - self._icon_hash = util.printable_hash(digest) - - self._pservice = presenceservice.get_instance() - self._pservice.connect('activity-invitation', - self._activity_invitation_cb) - self._pservice.connect('activity-disappeared', - self._activity_disappeared_cb) - - self._invites = Invites() - - def get_invites(self): - return self._invites - - def get_nick(self): - return self._nick - - def _activity_invitation_cb(self, pservice, activity, buddy, message): - self._invites.add_invite(buddy, activity.props.type, - activity.props.id) - - def _activity_disappeared_cb(self, pservice, activity): - self._invites.remove_activity(activity.props.id) diff --git a/shell/model/__init__.py b/shell/model/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/model/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/model/accesspointmodel.py b/shell/model/accesspointmodel.py deleted file mode 100644 index 1d4d6cb..0000000 --- a/shell/model/accesspointmodel.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject -import sys - -from hardware import nmclient - -STATE_CONNECTING = 0 -STATE_CONNECTED = 1 -STATE_NOTCONNECTED = 2 - -_nm_state_to_state = { - nmclient.NETWORK_STATE_CONNECTED : STATE_CONNECTED, - nmclient.NETWORK_STATE_CONNECTING : STATE_CONNECTING, - nmclient.NETWORK_STATE_NOTCONNECTED : STATE_NOTCONNECTED -} - -class AccessPointModel(gobject.GObject): - __gproperties__ = { - 'name' : (str, None, None, None, - gobject.PARAM_READABLE), - 'strength' : (int, None, None, 0, 100, 0, - gobject.PARAM_READABLE), - 'state' : (int, None, None, STATE_CONNECTING, - STATE_NOTCONNECTED, 0, gobject.PARAM_READABLE), - 'capabilities' : (int, None, None, 0, 0x7FFFFFFF, 0, - gobject.PARAM_READABLE), - 'mode' : (int, None, None, 0, 6, 0, gobject.PARAM_READABLE) - } - - def __init__(self, nm_device, nm_network): - gobject.GObject.__init__(self) - self._nm_network = nm_network - self._nm_device = nm_device - - self._nm_network.connect('strength-changed', - self._strength_changed_cb) - self._nm_network.connect('state-changed', - self._state_changed_cb) - - def _strength_changed_cb(self, nm_network): - self.notify('strength') - - def _state_changed_cb(self, nm_network): - self.notify('state') - - def get_id(self): - return self._nm_network.get_op() - - def get_nm_device(self): - return self._nm_device - - def get_nm_network(self): - return self._nm_network - - def do_get_property(self, pspec): - if pspec.name == 'strength': - return self._nm_network.get_strength() - elif pspec.name == 'name': - return self._nm_network.get_ssid() - elif pspec.name == 'state': - nm_state = self._nm_network.get_state() - return _nm_state_to_state[nm_state] - elif pspec.name == 'capabilities': - return self._nm_network.get_caps() - elif pspec.name == 'mode': - return self._nm_network.get_mode() diff --git a/shell/model/devices/Makefile.am b/shell/model/devices/Makefile.am deleted file mode 100644 index 5440eeb..0000000 --- a/shell/model/devices/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -SUBDIRS = network - -sugardir = $(pkgdatadir)/shell/model/devices -sugar_PYTHON = \ - __init__.py \ - device.py \ - devicesmodel.py \ - battery.py diff --git a/shell/model/devices/__init__.py b/shell/model/devices/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/model/devices/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/model/devices/battery.py b/shell/model/devices/battery.py deleted file mode 100644 index 853d00e..0000000 --- a/shell/model/devices/battery.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging - -import gobject -import dbus - -from model.devices import device - -_LEVEL_PROP = 'battery.charge_level.percentage' -_CHARGING_PROP = 'battery.rechargeable.is_charging' -_DISCHARGING_PROP = 'battery.rechargeable.is_discharging' - -class Device(device.Device): - __gproperties__ = { - 'level' : (int, None, None, 0, 100, 0, - gobject.PARAM_READABLE), - 'charging' : (bool, None, None, False, - gobject.PARAM_READABLE), - 'discharging' : (bool, None, None, False, - gobject.PARAM_READABLE) - } - - def __init__(self, udi): - device.Device.__init__(self, udi) - - bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) - proxy = bus.get_object('org.freedesktop.Hal', udi) - self._battery = dbus.Interface(proxy, 'org.freedesktop.Hal.Device') - bus.add_signal_receiver(self._battery_changed, - 'PropertyModified', - 'org.freedesktop.Hal.Device', - 'org.freedesktop.Hal', - udi) - - self._level = self._get_level() - self._charging = self._get_charging() - self._discharging = self._get_discharging() - - def _get_level(self): - try: - return self._battery.GetProperty(_LEVEL_PROP) - except dbus.DBusException: - logging.error('Cannot access %s' % _LEVEL_PROP) - return 0 - - def _get_charging(self): - try: - return self._battery.GetProperty(_CHARGING_PROP) - except dbus.DBusException: - logging.error('Cannot access %s' % _CHARGING_PROP) - return False - - def _get_discharging(self): - try: - return self._battery.GetProperty(_DISCHARGING_PROP) - except dbus.DBusException: - logging.error('Cannot access %s' % _DISCHARGING_PROP) - return False - - def do_get_property(self, pspec): - if pspec.name == 'level': - return self._level - if pspec.name == 'charging': - return self._charging - if pspec.name == 'discharging': - return self._discharging - - def get_type(self): - return 'battery' - - def _battery_changed(self, num_changes, changes_list): - for change in changes_list: - if change[0] == _LEVEL_PROP: - self._level = self._get_level() - self.notify('level') - elif change[0] == _CHARGING_PROP: - self._charging = self._get_charging() - self.notify('charging') - elif change[0] == _DISCHARGING_PROP: - self._discharging = self._get_discharging() - self.notify('discharging') diff --git a/shell/model/devices/device.py b/shell/model/devices/device.py deleted file mode 100644 index d7105b5..0000000 --- a/shell/model/devices/device.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject -from hardware import nmclient - -from sugar import util - -STATE_ACTIVATING = 0 -STATE_ACTIVATED = 1 -STATE_INACTIVE = 2 - -_nm_state_to_state = { - nmclient.DEVICE_STATE_ACTIVATING : STATE_ACTIVATING, - nmclient.DEVICE_STATE_ACTIVATED : STATE_ACTIVATED, - nmclient.DEVICE_STATE_INACTIVE : STATE_INACTIVE -} - -class Device(gobject.GObject): - def __init__(self, device_id=None): - gobject.GObject.__init__(self) - if device_id: - self._id = device_id - else: - self._id = util.unique_id() - - def get_type(self): - return 'unknown' - - def get_id(self): - return self._id diff --git a/shell/model/devices/devicesmodel.py b/shell/model/devices/devicesmodel.py deleted file mode 100644 index fab9fa4..0000000 --- a/shell/model/devices/devicesmodel.py +++ /dev/null @@ -1,136 +0,0 @@ -# -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging -import gobject -import dbus - -from model.devices import device -from model.devices.network import wired -from model.devices.network import wireless -from model.devices.network import mesh -from model.devices import battery -from hardware import hardwaremanager -from hardware import nmclient - -class DevicesModel(gobject.GObject): - __gsignals__ = { - 'device-appeared' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'device-disappeared': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._devices = {} - self._sigids = {} - - self._observe_hal_manager() - self._observe_network_manager() - - def _observe_hal_manager(self): - bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) - proxy = bus.get_object('org.freedesktop.Hal', - '/org/freedesktop/Hal/Manager') - hal_manager = dbus.Interface(proxy, 'org.freedesktop.Hal.Manager') - - for udi in hal_manager.FindDeviceByCapability('battery'): - self.add_device(battery.Device(udi)) - - def _observe_network_manager(self): - network_manager = hardwaremanager.get_network_manager() - if not network_manager: - return - - for device in network_manager.get_devices(): - self._check_network_device(device) - - network_manager.connect('device-added', - self._network_device_added_cb) - network_manager.connect('device-activating', - self._network_device_activating_cb) - network_manager.connect('device-activated', - self._network_device_activated_cb) - network_manager.connect('device-removed', - self._network_device_removed_cb) - - def _network_device_added_cb(self, network_manager, nm_device): - state = nm_device.get_state() - if state == nmclient.DEVICE_STATE_ACTIVATING \ - or state == nmclient.DEVICE_STATE_ACTIVATED: - self._check_network_device(nm_device) - - def _network_device_activating_cb(self, network_manager, nm_device): - self._check_network_device(nm_device) - - def _network_device_activated_cb(self, network_manager, nm_device): - pass - - def _network_device_removed_cb(self, network_manager, nm_device): - if self._devices.has_key(str(nm_device.get_op())): - self.remove_device(self._get_network_device(nm_device)) - - def _check_network_device(self, nm_device): - if not nm_device.is_valid(): - logging.debug("Device %s not valid" % nm_device.get_op()) - return - - dtype = nm_device.get_type() - if dtype == nmclient.DEVICE_TYPE_802_11_WIRELESS \ - or dtype == nmclient.DEVICE_TYPE_802_11_MESH_OLPC: - self._add_network_device(nm_device) - - def _get_network_device(self, nm_device): - return self._devices[str(nm_device.get_op())] - - def _network_device_state_changed_cb(self, dev, param): - if dev.props.state == device.STATE_INACTIVE: - self.remove_device(dev) - - def _add_network_device(self, nm_device): - if self._devices.has_key(str(nm_device.get_op())): - logging.debug("Tried to add device %s twice" % nm_device.get_op()) - return - - dtype = nm_device.get_type() - if dtype == nmclient.DEVICE_TYPE_802_11_WIRELESS: - dev = wireless.Device(nm_device) - self.add_device(dev) - sigid = dev.connect('notify::state', self._network_device_state_changed_cb) - self._sigids[dev] = sigid - if dtype == nmclient.DEVICE_TYPE_802_11_MESH_OLPC: - dev = mesh.Device(nm_device) - self.add_device(dev) - sigid = dev.connect('notify::state', self._network_device_state_changed_cb) - self._sigids[dev] = sigid - - def __iter__(self): - return iter(self._devices.values()) - - def add_device(self, device): - self._devices[device.get_id()] = device - self.emit('device-appeared', device) - - def remove_device(self, device): - self.emit('device-disappeared', self._devices[device.get_id()]) - device.disconnect(self._sigids[device]) - del self._sigids[device] - del self._devices[device.get_id()] diff --git a/shell/model/devices/network/Makefile.am b/shell/model/devices/network/Makefile.am deleted file mode 100644 index 04074e5..0000000 --- a/shell/model/devices/network/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -sugardir = $(pkgdatadir)/shell/model/devices/network -sugar_PYTHON = \ - __init__.py \ - mesh.py \ - wired.py \ - wireless.py diff --git a/shell/model/devices/network/__init__.py b/shell/model/devices/network/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/model/devices/network/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/model/devices/network/mesh.py b/shell/model/devices/network/mesh.py deleted file mode 100644 index 0152d8a..0000000 --- a/shell/model/devices/network/mesh.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject - -from model.devices import device -from hardware import nmclient - -class Device(device.Device): - __gproperties__ = { - 'strength' : (int, None, None, 0, 100, 0, - gobject.PARAM_READABLE), - 'state' : (int, None, None, device.STATE_ACTIVATING, - device.STATE_INACTIVE, 0, gobject.PARAM_READABLE), - 'activation-stage': (int, None, None, 0, 7, 0, gobject.PARAM_READABLE), - 'frequency': (float, None, None, 0, 2.72, 0, gobject.PARAM_READABLE), - 'mesh-step': (int, None, None, 0, 4, 0, gobject.PARAM_READABLE), - } - - def __init__(self, nm_device): - device.Device.__init__(self) - self._nm_device = nm_device - - self._nm_device.connect('strength-changed', - self._strength_changed_cb) - self._nm_device.connect('state-changed', - self._state_changed_cb) - self._nm_device.connect('activation-stage-changed', - self._activation_stage_changed_cb) - - def _strength_changed_cb(self, nm_device): - self.notify('strength') - - def _state_changed_cb(self, nm_device): - self.notify('state') - - def _activation_stage_changed_cb(self, nm_device): - self.notify('activation-stage') - - def do_get_property(self, pspec): - if pspec.name == 'strength': - return self._nm_device.get_strength() - elif pspec.name == 'state': - nm_state = self._nm_device.get_state() - return device._nm_state_to_state[nm_state] - elif pspec.name == 'activation-stage': - return self._nm_device.get_activation_stage() - elif pspec.name == 'frequency': - return self._nm_device.get_frequency() - elif pspec.name == 'mesh-step': - return self._nm_device.get_mesh_step() - - def get_type(self): - return 'network.mesh' - - def get_id(self): - return str(self._nm_device.get_op()) - - def get_nm_device(self): - return self._nm_device - diff --git a/shell/model/devices/network/wired.py b/shell/model/devices/network/wired.py deleted file mode 100644 index 66c5206..0000000 --- a/shell/model/devices/network/wired.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from model.devices import device - -class Device(device.Device): - def __init__(self, nm_device): - device.Device.__init__(self) - self._nm_device = device - - def get_id(self): - return str(self._nm_device.get_op()) - - def get_type(self): - return 'network.wired' diff --git a/shell/model/devices/network/wireless.py b/shell/model/devices/network/wireless.py deleted file mode 100644 index c45a08e..0000000 --- a/shell/model/devices/network/wireless.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject - -from model.devices import device -from hardware import nmclient - -def freq_to_channel(freq): - ftoc = { 2.412: 1, 2.417: 2, 2.422: 3, 2.427: 4, - 2.432: 5, 2.437: 6, 2.442: 7, 2.447: 8, - 2.452: 9, 2.457: 10, 2.462: 11, 2.467: 12, - 2.472: 13 - } - return ftoc[freq] - -def channel_to_freq(channel): - ctof = { 1: 2.412, 2: 2.417, 3: 2.422, 4: 2.427, - 5: 2.432, 6: 2.437, 7: 2.442, 8: 2.447, - 9: 2.452, 10: 2.457, 11: 2.462, 12: 2.467, - 13: 2.472 - } - return ctof[channel] - - -class Device(device.Device): - __gproperties__ = { - 'name' : (str, None, None, None, - gobject.PARAM_READABLE), - 'strength' : (int, None, None, 0, 100, 0, - gobject.PARAM_READABLE), - 'state' : (int, None, None, device.STATE_ACTIVATING, - device.STATE_INACTIVE, 0, gobject.PARAM_READABLE), - 'frequency': (float, None, None, 0.0, 9999.99, 0.0, - gobject.PARAM_READABLE) - } - - def __init__(self, nm_device): - device.Device.__init__(self) - self._nm_device = nm_device - - self._nm_device.connect('strength-changed', - self._strength_changed_cb) - self._nm_device.connect('ssid-changed', - self._ssid_changed_cb) - self._nm_device.connect('state-changed', - self._state_changed_cb) - - def _strength_changed_cb(self, nm_device): - self.notify('strength') - - def _ssid_changed_cb(self, nm_device): - self.notify('name') - - def _state_changed_cb(self, nm_device): - self.notify('state') - - def do_get_property(self, pspec): - if pspec.name == 'strength': - return self._nm_device.get_strength() - elif pspec.name == 'name': - import logging - logging.debug('wireless.Device.props.name: %s' % self._nm_device.get_ssid()) - return self._nm_device.get_ssid() - elif pspec.name == 'state': - nm_state = self._nm_device.get_state() - return device._nm_state_to_state[nm_state] - elif pspec.name == 'frequency': - return self._nm_device.get_frequency() - - def get_type(self): - return 'network.wireless' - - def get_id(self): - return str(self._nm_device.get_op()) - - def get_active_network_colors(self): - net = self._nm_device.get_active_network() - if not net: - return (None, None) - return net.get_colors() - diff --git a/shell/model/homeactivity.py b/shell/model/homeactivity.py deleted file mode 100644 index 7365271..0000000 --- a/shell/model/homeactivity.py +++ /dev/null @@ -1,215 +0,0 @@ -# Copyright (C) 2006-2007 Owen Williams. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import time -import logging - -import gobject -import dbus - -from sugar.graphics.xocolor import XoColor -from sugar.presence import presenceservice -from sugar import profile - -_SERVICE_NAME = "org.laptop.Activity" -_SERVICE_PATH = "/org/laptop/Activity" -_SERVICE_INTERFACE = "org.laptop.Activity" - -class HomeActivity(gobject.GObject): - """Activity which appears in the "Home View" of the Sugar shell - - This class stores the Sugar Shell's metadata regarding a - given activity/application in the system. It interacts with - the sugar.activity.* modules extensively in order to - accomplish its tasks. - """ - - __gtype_name__ = 'SugarHomeActivity' - - __gproperties__ = { - 'launching' : (bool, None, None, False, - gobject.PARAM_READWRITE), - } - - def __init__(self, activity_info, activity_id): - """Initialise the HomeActivity - - activity_info -- sugar.activity.registry.ActivityInfo instance, - provides the information required to actually - create the new instance. This is, in effect, - the "type" of activity being created. - activity_id -- unique identifier for this instance - of the activity type - """ - gobject.GObject.__init__(self) - - self._window = None - self._xid = None - self._pid = None - self._service = None - self._activity_id = activity_id - self._activity_info = activity_info - self._launch_time = time.time() - self._launching = False - - self._retrieve_service() - - if not self._service: - bus = dbus.SessionBus() - bus.add_signal_receiver(self._name_owner_changed_cb, - signal_name="NameOwnerChanged", - dbus_interface="org.freedesktop.DBus") - - def set_window(self, window): - """An activity is 'launched' once we get its window.""" - if self._window or self._xid: - raise RuntimeError("Activity is already launched!") - if not window: - raise ValueError("window must be valid") - - self._window = window - self._xid = window.get_xid() - self._pid = window.get_pid() - - def get_service(self): - """Get the activity service - - Note that non-native Sugar applications will not have - such a service, so the return value will be None in - those cases. - """ - - return self._service - - def get_title(self): - """Retrieve the application's root window's suggested title""" - if self._window: - return self._window.get_name() - else: - return '' - - def get_icon_path(self): - """Retrieve the activity's icon (file) name""" - if self._activity_info: - return self._activity_info.icon - else: - return None - - def get_icon_color(self): - """Retrieve the appropriate icon colour for this activity - - Uses activity_id to index into the PresenceService's - set of activity colours, if the PresenceService does not - have an entry (implying that this is not a Sugar-shared application) - uses the local user's profile.get_color() to determine the - colour for the icon. - """ - pservice = presenceservice.get_instance() - - # HACK to suppress warning in logs when activity isn't found - # (if it's locally launched and not shared yet) - activity = None - for act in pservice.get_activities(): - if self._activity_id == act.props.id: - activity = act - break - - if activity != None: - return XoColor(activity.props.color) - else: - return profile.get_color() - - def get_activity_id(self): - """Retrieve the "activity_id" passed in to our constructor - - This is a "globally likely unique" identifier generated by - sugar.util.unique_id - """ - return self._activity_id - - def get_xid(self): - """Retrieve the X-windows ID of our root window""" - return self._xid - - def get_window(self): - """Retrieve the X-windows root window of this application - - This was stored by the set_window method, which was - called by HomeModel._add_activity, which was called - via a callback that looks for all 'window-opened' - events. - - HomeModel currently uses a dbus service query on the - activity to determine to which HomeActivity the newly - launched window belongs. - """ - return self._window - - def get_type(self): - """Retrieve the activity bundle id for future reference""" - if self._activity_info: - return self._activity_info.bundle_id - else: - return None - - def get_launch_time(self): - """Return the time at which the activity was first launched - - Format is floating-point time.time() value - (seconds since the epoch) - """ - return self._launch_time - - def get_pid(self): - """Returns the activity's PID""" - return self._pid - - def equals(self, activity): - if self._activity_id and activity.get_activity_id(): - return self._activity_id == activity.get_activity_id() - if self._xid and activity.get_xid(): - return self._xid == activity.get_xid() - return False - - def do_set_property(self, pspec, value): - if pspec.name == 'launching': - self._launching = value - - def do_get_property(self, pspec): - if pspec.name == 'launching': - return self._launching - - def _get_service_name(self): - if self._activity_id: - return _SERVICE_NAME + self._activity_id - else: - return None - - def _retrieve_service(self): - if not self._activity_id: - return - - try: - bus = dbus.SessionBus() - proxy = bus.get_object(self._get_service_name(), - _SERVICE_PATH + "/" + self._activity_id) - self._service = dbus.Interface(proxy, _SERVICE_INTERFACE) - except dbus.DBusException: - self._service = None - - def _name_owner_changed_cb(self, name, old, new): - if name == self._get_service_name(): - self._retrieve_service() diff --git a/shell/model/homemodel.py b/shell/model/homemodel.py deleted file mode 100644 index 44d5417..0000000 --- a/shell/model/homemodel.py +++ /dev/null @@ -1,283 +0,0 @@ -# Copyright (C) 2006-2007 Owen Williams. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging - -import gobject -import wnck -import dbus - -from sugar import wm -from sugar import activity - -from model.homeactivity import HomeActivity - -class HomeModel(gobject.GObject): - """Model of the "Home" view (activity management) - - The HomeModel is basically the point of registration - for all running activities within Sugar. It traps - events that tell the system there is a new activity - being created (generated by the activity factories), - or removed, as well as those which tell us that the - currently focussed activity has changed. - - The HomeModel tracks a set of HomeActivity instances, - which are tracking the window to activity mappings - the activity factories have set up. - """ - __gsignals__ = { - 'activity-added': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'activity-started': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'activity-removed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'active-activity-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])), - 'pending-activity-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._activities = [] - self._active_activity = None - self._pending_activity = None - - screen = wnck.screen_get_default() - screen.connect('window-opened', self._window_opened_cb) - screen.connect('window-closed', self._window_closed_cb) - screen.connect('active-window-changed', - self._active_window_changed_cb) - - def _get_activities_with_window(self): - ret = [] - for i in self._activities: - if i.get_window() is not None: - ret.append(i) - return ret - - def get_previous_activity(self): - activities = self._get_activities_with_window() - i = activities.index(self._pending_activity) - if len(activities) == 0: - return None - elif i - 1 >= 0: - return activities[i - 1] - else: - return activities[len(activities) - 1] - - def get_next_activity(self): - activities = self._get_activities_with_window() - i = activities.index(self._pending_activity) - if len(activities) == 0: - return None - elif i + 1 < len(activities): - return activities[i + 1] - else: - return activities[0] - - def get_pending_activity(self): - """Returns the activity that would be seen in the Activity zoom level - - In the Home (or Neighborhood or Groups) zoom level, this - indicates the activity that would become active if the user - switched to the Activity zoom level. (In the Activity zoom - level, this just returns the currently-active activity.) - Unlike get_active_activity(), this never returns None as long - as there is any activity running. - """ - return self._pending_activity - - def _set_pending_activity(self, home_activity): - if self._pending_activity == home_activity: - return - - self._pending_activity = home_activity - self.emit('pending-activity-changed', self._pending_activity) - - def get_active_activity(self): - """Returns the activity that the user is currently working in - - In the Activity zoom level, this returns the currently-active - activity. In the other zoom levels, it returns the activity - that was most-recently active in the Activity zoom level, or - None if the most-recently-active activity is no longer - running. - """ - return self._active_activity - - def _set_active_activity(self, home_activity): - if self._active_activity == home_activity: - return - - if self._active_activity: - service = self._active_activity.get_service() - if service: - service.SetActive(False, - reply_handler=self._set_active_success, - error_handler=self._set_active_error) - if home_activity: - service = home_activity.get_service() - if service: - service.SetActive(True, - reply_handler=self._set_active_success, - error_handler=self._set_active_error) - - self._active_activity = home_activity - self.emit('active-activity-changed', self._active_activity) - - def __iter__(self): - return iter(self._activities) - - def __len__(self): - return len(self._activities) - - def __getitem__(self, i): - return self._activities[i] - - def index(self, obj): - return self._activities.index(obj) - - def _window_opened_cb(self, screen, window): - if window.get_window_type() == wnck.WINDOW_NORMAL: - home_activity = None - - activity_id = wm.get_activity_id(window) - - service_name = wm.get_bundle_id(window) - if service_name: - registry = activity.get_registry() - activity_info = registry.get_activity(service_name) - else: - activity_info = None - - if activity_id: - home_activity = self._get_activity_by_id(activity_id) - - if not home_activity: - home_activity = HomeActivity(activity_info, activity_id) - self._add_activity(home_activity) - - home_activity.set_window(window) - - home_activity.props.launching = False - self.emit('activity-started', home_activity) - - if self._pending_activity is None: - self._set_pending_activity(home_activity) - - def _window_closed_cb(self, screen, window): - if window.get_window_type() == wnck.WINDOW_NORMAL: - self._remove_activity_by_xid(window.get_xid()) - - def _get_activity_by_xid(self, xid): - for home_activity in self._activities: - if home_activity.get_xid() == xid: - return home_activity - return None - - def _get_activity_by_id(self, activity_id): - for home_activity in self._activities: - if home_activity.get_activity_id() == activity_id: - return home_activity - return None - - def _set_active_success(self): - pass - - def _set_active_error(self, err): - logging.error("set_active() failed: %s" % err) - - def _active_window_changed_cb(self, screen, previous_window=None): - window = screen.get_active_window() - if window is None: - return - - if window.get_window_type() != wnck.WINDOW_DIALOG: - while window.get_transient() is not None: - window = window.get_transient() - - activity = self._get_activity_by_xid(window.get_xid()) - if activity is not None: - self._set_pending_activity(activity) - self._set_active_activity(activity) - - def _add_activity(self, home_activity): - self._activities.append(home_activity) - self.emit('activity-added', home_activity) - - def _remove_activity(self, home_activity): - if home_activity == self._active_activity: - self._set_active_activity(None) - - if home_activity == self._pending_activity: - # Figure out the new _pending_activity - windows = wnck.screen_get_default().get_windows_stacked() - windows.reverse() - for window in windows: - new_activity = self._get_activity_by_xid(window.get_xid()) - if new_activity is not None: - self._set_pending_activity(new_activity) - break - else: - logging.error('No activities are running') - self._set_pending_activity(None) - - self.emit('activity-removed', home_activity) - self._activities.remove(home_activity) - - def _remove_activity_by_xid(self, xid): - home_activity = self._get_activity_by_xid(xid) - if home_activity: - self._remove_activity(home_activity) - else: - logging.error('Model for window %d does not exist.' % xid) - - def notify_activity_launch(self, activity_id, service_name): - registry = activity.get_registry() - activity_info = registry.get_activity(service_name) - if not activity_info: - raise ValueError("Activity service name '%s' was not found in the bundle registry." % service_name) - home_activity = HomeActivity(activity_info, activity_id) - home_activity.props.launching = True - self._add_activity(home_activity) - - # FIXME: better learn about finishing processes by receiving a signal. - # Now just check whether an activity has a window after ~90sec - gobject.timeout_add(90000, self._check_activity_launched, activity_id) - - def notify_activity_launch_failed(self, activity_id): - home_activity = self._get_activity_by_id(activity_id) - if home_activity: - logging.debug("Activity %s (%s) launch failed" % (activity_id, home_activity.get_type())) - self._remove_activity(home_activity) - else: - logging.error('Model for activity id %s does not exist.' % activity_id) - - def _check_activity_launched(self, activity_id): - home_activity = self._get_activity_by_id(activity_id) - if home_activity and home_activity.props.launching: - logging.debug('Activity %s still launching, assuming it failed...', activity_id) - self.notify_activity_launch_failed(activity_id) - return False diff --git a/shell/model/shellmodel.py b/shell/model/shellmodel.py deleted file mode 100644 index 5462e27..0000000 --- a/shell/model/shellmodel.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os - -import wnck -import gobject - -from sugar.presence import presenceservice -from model.Friends import Friends -from model.MeshModel import MeshModel -from model.homemodel import HomeModel -from model.Owner import ShellOwner -from model.devices.devicesmodel import DevicesModel -from sugar import env - -class ShellModel(gobject.GObject): - STATE_STARTUP = 0 - STATE_RUNNING = 1 - STATE_SHUTDOWN = 2 - - ZOOM_MESH = 0 - ZOOM_FRIENDS = 1 - ZOOM_HOME = 2 - ZOOM_ACTIVITY = 3 - - __gproperties__ = { - 'state' : (int, None, None, - 0, 2, STATE_RUNNING, - gobject.PARAM_READWRITE), - 'zoom-level' : (int, None, None, - 0, 3, ZOOM_HOME, - gobject.PARAM_READABLE) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._current_activity = None - self._state = self.STATE_RUNNING - self._zoom_level = self.ZOOM_HOME - self._showing_desktop = True - - self._pservice = presenceservice.get_instance() - - self._owner = ShellOwner() - - self._friends = Friends() - self._mesh = MeshModel() - self._home = HomeModel() - self._devices = DevicesModel() - - self._screen = wnck.screen_get_default() - self._screen.connect('showing-desktop-changed', - self._showing_desktop_changed_cb) - - def set_zoom_level(self, level): - self._zoom_level = level - self.notify('zoom-level') - - def get_zoom_level(self): - if self._screen.get_showing_desktop(): - return self._zoom_level - else: - return self.ZOOM_ACTIVITY - - def do_set_property(self, pspec, value): - if pspec.name == 'state': - self._state = value - - def do_get_property(self, pspec): - if pspec.name == 'state': - return self._state - elif pspec.name == 'zoom-level': - return self.get_zoom_level() - - def get_mesh(self): - return self._mesh - - def get_friends(self): - return self._friends - - def get_invites(self): - return self._owner.get_invites() - - def get_home(self): - return self._home - - def get_owner(self): - return self._owner - - def get_devices(self): - return self._devices - - def _showing_desktop_changed_cb(self, screen): - showing_desktop = self._screen.get_showing_desktop() - if self._showing_desktop != showing_desktop: - self._showing_desktop = showing_desktop - self.notify('zoom-level') diff --git a/shell/shellservice.py b/shell/shellservice.py deleted file mode 100644 index 458f941..0000000 --- a/shell/shellservice.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -"""D-bus service providing access to the shell's functionality""" -import dbus -import os - -_DBUS_SERVICE = "org.laptop.Shell" -_DBUS_SHELL_IFACE = "org.laptop.Shell" -_DBUS_OWNER_IFACE = "org.laptop.Shell.Owner" -_DBUS_PATH = "/org/laptop/Shell" - -_DBUS_RAINBOW_IFACE = "org.laptop.security.Rainbow" - -class ShellService(dbus.service.Object): - """Provides d-bus service to script the shell's operations - - Uses a shell_model object to observe events such as changes to: - - * nickname - * colour - * icon - * currently active activity - - and pass the event off to the methods in the dbus signature. - - Key method here at the moment is add_bundle, which is used to - do a run-time registration of a bundle using it's application path. - - XXX At the moment the d-bus service methods do not appear to do - anything other than add_bundle - """ - - _rainbow = None - - def __init__(self, shell): - self._shell = shell - self._shell_model = shell.get_model() - - self._owner = self._shell_model.get_owner() - self._owner.connect('nick-changed', self._owner_nick_changed_cb) - self._owner.connect('icon-changed', self._owner_icon_changed_cb) - self._owner.connect('color-changed', self._owner_color_changed_cb) - - self._home_model = self._shell_model.get_home() - self._home_model.connect('active-activity-changed', - self._cur_activity_changed_cb) - - bus = dbus.SessionBus() - bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus) - dbus.service.Object.__init__(self, bus_name, _DBUS_PATH) - - @dbus.service.method(_DBUS_SHELL_IFACE, - in_signature="s", out_signature="b") - def ActivateActivity(self, activity_id): - host = self._shell.get_activity(activity_id) - if host: - host.present() - return True - - return False - - @dbus.service.method(_DBUS_SHELL_IFACE, - in_signature="ss", out_signature="") - def NotifyLaunch(self, bundle_id, activity_id): - self._shell.notify_launch(bundle_id, activity_id) - - @dbus.service.method(_DBUS_SHELL_IFACE, - in_signature="s", out_signature="") - def NotifyLaunchFailure(self, activity_id): - self._shell.notify_launch_failure(activity_id) - - @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") - def ColorChanged(self, color): - pass - - def _owner_color_changed_cb(self, new_color): - self.ColorChanged(new_color.to_string()) - - @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") - def NickChanged(self, nick): - pass - - def _owner_nick_changed_cb(self, new_nick): - self.NickChanged(new_nick) - - @dbus.service.signal(_DBUS_OWNER_IFACE, signature="ay") - def IconChanged(self, icon_data): - pass - - def _owner_icon_changed_cb(self, new_icon): - self.IconChanged(dbus.ByteArray(new_icon)) - - def _get_rainbow_service(self): - """Lazily initializes an interface to the Rainbow security daemon.""" - if self._rainbow is None: - system_bus = dbus.SystemBus() - object = system_bus.get_object(_DBUS_RAINBOW_IFACE, '/', - follow_name_owner_changes=True) - self._rainbow = dbus.Interface(object, - dbus_interface=_DBUS_RAINBOW_IFACE) - return self._rainbow - - @dbus.service.signal(_DBUS_OWNER_IFACE, signature="s") - def CurrentActivityChanged(self, activity_id): - if os.path.exists('/etc/olpc-security'): - self._get_rainbow_service().ChangeActivity( - activity_id, - dbus_interface=_DBUS_RAINBOW_IFACE) - - def _cur_activity_changed_cb(self, owner, new_activity): - new_id = "" - if new_activity: - new_id = new_activity.get_activity_id() - if new_id: - self.CurrentActivityChanged(new_id) - diff --git a/shell/view/ActivityHost.py b/shell/view/ActivityHost.py deleted file mode 100644 index 4332372..0000000 --- a/shell/view/ActivityHost.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import dbus -import logging - -from sugar.presence import presenceservice - -import OverlayWindow - -class ActivityChatWindow(gtk.Window): - def __init__(self, gdk_window, chat_widget): - gtk.Window.__init__(self) - - self.realize() - self.set_decorated(False) - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) - self.window.set_accept_focus(True) - self.window.set_transient_for(gdk_window) - self.set_position(gtk.WIN_POS_CENTER_ALWAYS) - self.set_default_size(600, 450) - - self.add(chat_widget) - -class ActivityHost: - def __init__(self, model): - self._model = model - self._window = model.get_window() - self._gdk_window = gtk.gdk.window_foreign_new(self.get_xid()) - - try: - self._overlay_window = OverlayWindow.OverlayWindow(self._gdk_window) - win = self._overlay_window.window - except RuntimeError: - self._overlay_window = None - win = self._gdk_window - - #self._chat_widget = ActivityChat.ActivityChat(self) - self._chat_widget = gtk.HBox() - self._chat_window = ActivityChatWindow(win, self._chat_widget) - - self._frame_was_visible = False - - def get_id(self): - return self._model.get_activity_id() - - def get_xid(self): - return self._window.get_xid() - - def get_model(self): - return self._model - - def invite(self, buddy_model): - service = self._model.get_service() - if service: - buddy = buddy_model.get_buddy() - service.Invite(buddy.props.key) - else: - logging.error('Invite failed, activity service not ') - - def toggle_fullscreen(self): - fullscreen = not self._window.is_fullscreen() - self._window.set_fullscreen(fullscreen) - - def present(self): - # wnck.Window.activate() expects a timestamp, but we don't - # always have one, and libwnck will complain if we pass "0", - # and matchbox doesn't look at the timestamp anyway. So we - # just always pass "1". - self._window.activate(1) - - def close(self): - # The "1" is a fake timestamp as with present() - self._window.close(1) - - def show_dialog(self, dialog): - dialog.show() - dialog.window.set_transient_for(self._gdk_window) - - def chat_show(self, frame_was_visible): - if self._overlay_window: - self._overlay_window.appear() - self._chat_window.show_all() - self._frame_was_visible = frame_was_visible - - def chat_hide(self): - self._chat_window.hide() - if self._overlay_window: - self._overlay_window.disappear() - wasvis = self._frame_was_visible - self._frame_was_visible = False - return wasvis - - def is_chat_visible(self): - return self._chat_window.get_property('visible') - - def set_active(self, active): - if not active: - self.chat_hide() - self._frame_was_visible = False - - def destroy(self): - self._chat_window.destroy() - self._frame_was_visible = False diff --git a/shell/view/BuddyIcon.py b/shell/view/BuddyIcon.py deleted file mode 100644 index 3734001..0000000 --- a/shell/view/BuddyIcon.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from sugar.graphics.icon import CanvasIcon -from sugar.graphics.palette import Palette -from sugar.graphics import style - -from view.BuddyMenu import BuddyMenu - -class BuddyIcon(CanvasIcon): - def __init__(self, shell, buddy, size=style.STANDARD_ICON_SIZE): - CanvasIcon.__init__(self, icon_name='computer-xo', size=size) - - self._greyed_out = False - self._shell = shell - self._buddy = buddy - self._buddy.connect('appeared', self._buddy_presence_change_cb) - self._buddy.connect('disappeared', self._buddy_presence_change_cb) - self._buddy.connect('color-changed', self._buddy_presence_change_cb) - - palette = BuddyMenu(shell, buddy) - self.set_palette(palette) - - self._update_color() - - def _buddy_presence_change_cb(self, buddy, color=None): - # Update the icon's color when the buddy comes and goes - self._update_color() - - def _update_color(self): - if self._greyed_out: - self.props.stroke_color = '#D5D5D5' - self.props.fill_color = '#E5E5E5' - else: - self.props.xo_color = self._buddy.get_color() - - def set_filter(self, query): - self._greyed_out = (self._buddy.get_nick().lower().find(query) == -1) \ - and not self._buddy.is_owner() - self._update_color() - diff --git a/shell/view/BuddyMenu.py b/shell/view/BuddyMenu.py deleted file mode 100644 index e7e12ca..0000000 --- a/shell/view/BuddyMenu.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from gettext import gettext as _ -import logging - -import gobject -import hippo - -from sugar.graphics.palette import Palette -from sugar.graphics.menuitem import MenuItem -from sugar.graphics.icon import Icon -from sugar.presence import presenceservice - -class BuddyMenu(Palette): - def __init__(self, shell, buddy): - self._buddy = buddy - self._shell = shell - - Palette.__init__(self, buddy.get_nick()) - self._active_activity_changed_hid = None - self.connect('destroy', self.__destroy_cb) - - self._buddy.connect('icon-changed', self._buddy_icon_changed_cb) - self._buddy.connect('nick-changed', self._buddy_nick_changed_cb) - - owner = self._get_shell_model().get_owner() - if not buddy.is_owner(): - self._add_items() - - def _get_shell_model(self): - return self._shell.get_model() - - def _get_home_model(self): - return self._get_shell_model().get_home() - - def __destroy_cb(self, menu): - if self._active_activity_changed_hid is not None: - home_model = self._get_home_model() - home_model.disconnect(self._active_activity_changed_hid) - - def _add_items(self): - pservice = presenceservice.get_instance() - - friends = self._get_shell_model().get_friends() - if friends.has_buddy(self._buddy): - menu_item = MenuItem(_('Remove friend'), 'list-remove') - menu_item.connect('activate', self._remove_friend_cb) - else: - menu_item = MenuItem(_('Make friend'), 'list-add') - menu_item.connect('activate', self._make_friend_cb) - - self.menu.append(menu_item) - menu_item.show() - - self._invite_menu = MenuItem('') - self._invite_menu.connect('activate', self._invite_friend_cb) - self.menu.append(self._invite_menu) - - home_model = self._get_home_model() - self._active_activity_changed_hid = home_model.connect( - 'active-activity-changed', self._cur_activity_changed_cb) - activity = home_model.get_active_activity() - self._update_invite_menu(activity) - - def _update_invite_menu(self, activity): - if activity is None: - self._invite_menu.hide() - else: - title = activity.get_title() - label = self._invite_menu.get_children()[0] - label.set_text(_('Invite to %s') % title) - - icon = Icon(file=activity.get_icon_path()) - icon.props.xo_color = activity.get_icon_color() - self._invite_menu.set_image(icon) - icon.show() - - self._invite_menu.show() - - def _cur_activity_changed_cb(self, home_model, activity_model): - self._update_invite_menu(activity_model) - - def _buddy_icon_changed_cb(self, buddy): - pass - - def _buddy_nick_changed_cb(self, buddy, nick): - self.set_primary_text(nick) - - def _make_friend_cb(self, menuitem): - friends = self._get_shell_model().get_friends() - friends.make_friend(self._buddy) - - def _remove_friend_cb(self, menuitem): - friends = self._get_shell_model().get_friends() - friends.remove(self._buddy) - - def _invite_friend_cb(self, menuitem): - activity = self._shell.get_current_activity() - activity.invite(self._buddy) - diff --git a/shell/view/Makefile.am b/shell/view/Makefile.am deleted file mode 100644 index abbb230..0000000 --- a/shell/view/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -SUBDIRS = devices frame home - -sugardir = $(pkgdatadir)/shell/view -sugar_PYTHON = \ - __init__.py \ - ActivityHost.py \ - BuddyIcon.py \ - BuddyMenu.py \ - clipboardicon.py \ - clipboardmenu.py \ - keyhandler.py \ - pulsingicon.py \ - OverlayWindow.py \ - Shell.py diff --git a/shell/view/OverlayWindow.py b/shell/view/OverlayWindow.py deleted file mode 100644 index 376ca2f..0000000 --- a/shell/view/OverlayWindow.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import cairo - -def _grab_pixbuf(window=None): - if not window: - screen = gtk.gdk.screen_get_default() - window = screen.get_root_window() - color_map = gtk.gdk.colormap_get_system() - (x, y, w, h, bpp) = window.get_geometry() - return gtk.gdk.pixbuf_get_from_drawable(None, window, color_map, x, y, 0, 0, w, h) - -class OverlayWindow(gtk.Window): - def __init__(self, lower_window): - gtk.Window.__init__(self) - self._lower_window = lower_window - - self._img = gtk.Image() - self.add(self._img) - - self.realize() - - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) - self.window.set_accept_focus(False) - self.window.set_transient_for(lower_window) - - self.set_decorated(False) - self.set_position(gtk.WIN_POS_CENTER_ALWAYS) - self.set_default_size(gtk.gdk.screen_width(), gtk.gdk.screen_height()) - self.set_app_paintable(True) - -# self.connect('expose-event', self._expose_cb) - - def appear(self): - pbuf = _grab_pixbuf(self._lower_window) - #pbuf.saturate_and_pixelate(pbuf, 0.5, False) - w = pbuf.get_width() - h = pbuf.get_height() - pbuf2 = pbuf.composite_color_simple(w, h, gtk.gdk.INTERP_NEAREST, 100, 1024, 0, 0) - self._img.set_from_pixbuf(pbuf2) - self.show_all() - - def disappear(self): - self._img.set_from_pixbuf(None) - self.hide() - - def _expose_cb(self, widget, event): - cr = widget.window.cairo_create() - cr.set_source_rgba(0.0, 0.0, 0.0, 0.4) # Transparent - cr.set_operator(cairo.OPERATOR_SOURCE) - cr.paint() - return False - diff --git a/shell/view/Shell.py b/shell/view/Shell.py deleted file mode 100644 index 72aa3b1..0000000 --- a/shell/view/Shell.py +++ /dev/null @@ -1,298 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ -from sets import Set -import logging -import tempfile -import os -import time -import shutil - -import gobject -import gtk -import wnck -import dbus - -from sugar.activity.activityhandle import ActivityHandle -from sugar import activity -from sugar.activity import activityfactory -from sugar.datastore import datastore -from sugar import profile -from sugar import env - -from view.ActivityHost import ActivityHost -from view.frame.frame import Frame -from view.keyhandler import KeyHandler -from view.home.HomeWindow import HomeWindow -from model.shellmodel import ShellModel - -# #3903 - this constant can be removed and assumed to be 1 when dbus-python -# 0.82.3 is the only version used -if dbus.version >= (0, 82, 3): - DBUS_PYTHON_TIMEOUT_UNITS_PER_SECOND = 1 -else: - DBUS_PYTHON_TIMEOUT_UNITS_PER_SECOND = 1000 - -class Shell(gobject.GObject): - def __init__(self, model): - gobject.GObject.__init__(self) - - self._activities_starting = Set() - self._model = model - self._hosts = {} - self._screen = wnck.screen_get_default() - self._current_host = None - self._pending_host = None - self._screen_rotation = 0 - self._zoom_level = ShellModel.ZOOM_HOME - - self._key_handler = KeyHandler(self) - - self._frame = Frame(self) - - self._home_window = HomeWindow(self) - self._home_window.show() - - home_model = self._model.get_home() - home_model.connect('activity-started', self._activity_started_cb) - home_model.connect('activity-removed', self._activity_removed_cb) - home_model.connect('active-activity-changed', - self._active_activity_changed_cb) - home_model.connect('pending-activity-changed', - self._pending_activity_changed_cb) - - self._model.connect('notify::zoom-level', self._zoom_level_changed_cb) - - gobject.idle_add(self._start_journal_idle) - - def _start_journal_idle(self): - # Mount the datastore in internal flash - ds_path = env.get_profile_path('datastore') - try: - datastore.mount(ds_path, [], timeout=120 * \ - DBUS_PYTHON_TIMEOUT_UNITS_PER_SECOND) - except: - # Don't explode if there's corruption; move the data out of the way - # and attempt to create a store from scratch. - shutil.move(ds_path, os.path.abspath(ds_path) + str(time.time())) - datastore.mount(ds_path, [], timeout=120 * \ - DBUS_PYTHON_TIMEOUT_UNITS_PER_SECOND) - - # Checking for the bundle existence will also ensure - # that the shell service is started up. - registry = activity.get_registry() - if registry.get_activity('org.laptop.JournalActivity'): - self.start_activity('org.laptop.JournalActivity') - - def _activity_started_cb(self, home_model, home_activity): - activity_host = ActivityHost(home_activity) - self._hosts[activity_host.get_xid()] = activity_host - if home_activity.get_type() in self._activities_starting: - self._activities_starting.remove(home_activity.get_type()) - - def _activity_removed_cb(self, home_model, home_activity): - if home_activity.get_type() in self._activities_starting: - self._activities_starting.remove(home_activity.get_type()) - xid = home_activity.get_xid() - if self._hosts.has_key(xid): - self._hosts[xid].destroy() - del self._hosts[xid] - - def _active_activity_changed_cb(self, home_model, home_activity): - if home_activity: - host = self._hosts[home_activity.get_xid()] - else: - host = None - - if self._current_host: - self._current_host.set_active(False) - - self._current_host = host - - def _pending_activity_changed_cb(self, home_model, home_activity): - if home_activity: - self._pending_host = self._hosts[home_activity.get_xid()] - else: - self._pending_host = None - - def get_model(self): - return self._model - - def get_frame(self): - return self._frame - - def join_activity(self, bundle_id, activity_id): - activity_host = self.get_activity(activity_id) - if activity_host: - activity_host.present() - return - - # Get the service name for this activity, if - # we have a bundle on the system capable of handling - # this activity type - registry = activity.get_registry() - bundle = registry.get_activity(bundle_id) - if not bundle: - logging.error("Couldn't find activity for type %s" % bundle_id) - return - - handle = ActivityHandle(activity_id) - activityfactory.create(bundle_id, handle) - - def notify_launch(self, bundle_id, activity_id): - # Zoom to Home for launch feedback - self.set_zoom_level(ShellModel.ZOOM_HOME) - - home_model = self._model.get_home() - home_model.notify_activity_launch(activity_id, bundle_id) - - def notify_launch_failure(self, activity_id): - home_model = self._model.get_home() - home_model.notify_activity_launch_failed(activity_id) - - def start_activity(self, activity_type): - if activity_type in self._activities_starting: - logging.debug("This activity is still launching.") - return - - self._activities_starting.add(activity_type) - activityfactory.create(activity_type) - - def take_activity_screenshot(self): - if self._model.get_zoom_level() != ShellModel.ZOOM_ACTIVITY: - return - if self.get_frame().visible: - return - - home_model = self._model.get_home() - activity = home_model.get_active_activity() - if activity is not None: - service = activity.get_service() - if service is not None: - try: - service.TakeScreenshot(timeout=2.0) - except dbus.DBusException, e: - logging.debug('Error raised by TakeScreenshot(): %s', e) - - def set_zoom_level(self, level): - if level == self._zoom_level: - return - - self.take_activity_screenshot() - - if level == ShellModel.ZOOM_ACTIVITY: - if self._pending_host is not None: - self._pending_host.present() - self._screen.toggle_showing_desktop(False) - else: - self._model.set_zoom_level(level) - self._screen.toggle_showing_desktop(True) - self._home_window.set_zoom_level(level) - - def _zoom_level_changed_cb(self, model, pspec): - new_level = model.props.zoom_level - - if new_level == ShellModel.ZOOM_HOME: - self._frame.show(Frame.MODE_NON_INTERACTIVE) - - if self._zoom_level == ShellModel.ZOOM_HOME: - self._frame.hide() - - self._zoom_level = new_level - - def toggle_activity_fullscreen(self): - if self._model.get_zoom_level() == ShellModel.ZOOM_ACTIVITY: - self.get_current_activity().toggle_fullscreen() - - def activate_previous_activity(self): - home_model = self._model.get_home() - activity = home_model.get_previous_activity() - if activity: - self.take_activity_screenshot() - activity.get_window().activate(1) - - def activate_next_activity(self): - home_model = self._model.get_home() - activity = home_model.get_next_activity() - if activity: - self.take_activity_screenshot() - activity.get_window().activate(1) - - def close_current_activity(self): - if self._model.get_zoom_level() != ShellModel.ZOOM_ACTIVITY: - return - - home_model = self._model.get_home() - activity = home_model.get_active_activity() - if activity.get_type() == 'org.laptop.JournalActivity': - return - - self.take_activity_screenshot() - self.get_current_activity().close() - - def get_current_activity(self): - return self._current_host - - def get_activity(self, activity_id): - for host in self._hosts.values(): - if host.get_id() == activity_id: - return host - return None - - def toggle_chat_visibility(self): - act = self.get_current_activity() - if not act: - return - is_visible = self._frame.is_visible() - if act.is_chat_visible(): - frame_was_visible = act.chat_hide() - if not frame_was_visible: - self._frame.do_slide_out() - else: - if not is_visible: - self._frame.do_slide_in() - act.chat_show(is_visible) - - def take_screenshot(self): - file_path = os.path.join(tempfile.gettempdir(), '%i' % time.time()) - - window = gtk.gdk.get_default_root_window() - width, height = window.get_size() - x_orig, y_orig = window.get_origin() - - screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False, - bits_per_sample=8, width=width, height=height) - screenshot.get_from_drawable(window, window.get_colormap(), x_orig, y_orig, 0, 0, - width, height) - screenshot.save(file_path, "png") - try: - jobject = datastore.create() - try: - jobject.metadata['title'] = _('Screenshot') - jobject.metadata['keep'] = '0' - jobject.metadata['buddies'] = '' - jobject.metadata['preview'] = '' - jobject.metadata['icon-color'] = profile.get_color().to_string() - jobject.metadata['mime_type'] = 'image/png' - jobject.file_path = file_path - datastore.write(jobject) - finally: - jobject.destroy() - del jobject - finally: - os.remove(file_path) - diff --git a/shell/view/__init__.py b/shell/view/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/view/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/view/clipboardicon.py b/shell/view/clipboardicon.py deleted file mode 100644 index 4b36395..0000000 --- a/shell/view/clipboardicon.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# Copyright (C) 2007, One Laptop Per Child -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging -from gettext import gettext as _ - -import gobject -import gtk - -from sugar.graphics.radiotoolbutton import RadioToolButton -from sugar.graphics.xocolor import XoColor -from sugar.graphics.icon import Icon -from sugar.graphics import style -from sugar.clipboard import clipboardservice -from sugar.bundle.activitybundle import ActivityBundle -from sugar import util -from sugar import profile - -from view.clipboardmenu import ClipboardMenu -from view.frame.frameinvoker import FrameWidgetInvoker - -class ClipboardIcon(RadioToolButton): - __gtype_name__ = 'SugarClipboardIcon' - - def __init__(self, object_id, name, group): - RadioToolButton.__init__(self, group=group) - self._object_id = object_id - self._name = name - self._percent = 0 - self._preview = None - self._activity = None - self.owns_clipboard = False - self.props.sensitive = False - self.props.active = False - - self._icon = Icon() - self._icon.props.xo_color = profile.get_color() - self.set_icon_widget(self._icon) - self._icon.show() - - cb_service = clipboardservice.get_instance() - cb_service.connect('object-state-changed', self._object_state_changed_cb) - obj = cb_service.get_object(self._object_id) - - self.palette = ClipboardMenu(self._object_id, self._name, self._percent, - self._preview, self._activity, - self._is_bundle(obj['FORMATS'])) - self.palette.props.invoker = FrameWidgetInvoker(self) - - self.child.connect('drag_data_get', self._drag_data_get_cb) - self.connect('notify::active', self._notify_active_cb) - - def _is_bundle(self, formats): - # A bundle will have only one format. - return formats and formats[0] in [ActivityBundle.MIME_TYPE, - ActivityBundle.DEPRECATED_MIME_TYPE] - - def get_object_id(self): - return self._object_id - - def _drag_data_get_cb(self, widget, context, selection, targetType, eventTime): - logging.debug('_drag_data_get_cb: requested target ' + selection.target) - - cb_service = clipboardservice.get_instance() - data = cb_service.get_object_data(self._object_id, selection.target)['DATA'] - - selection.set(selection.target, 8, data) - - def _put_in_clipboard(self): - logging.debug('ClipboardIcon._put_in_clipboard') - - if self._percent < 100: - raise ValueError('Object is not complete, cannot be put into the clipboard.') - - targets = self._get_targets() - if targets: - clipboard = gtk.Clipboard() - if not clipboard.set_with_data(targets, - self._clipboard_data_get_cb, - self._clipboard_clear_cb, - targets): - logging.error('GtkClipboard.set_with_data failed!') - else: - self.owns_clipboard = True - - def _clipboard_data_get_cb(self, clipboard, selection, info, targets): - if not selection.target in [target[0] for target in targets]: - logging.warning('ClipboardIcon._clipboard_data_get_cb: asked %s but' \ - ' only have %r.' % (selection.target, targets)) - return - cb_service = clipboardservice.get_instance() - data = cb_service.get_object_data(self._object_id, selection.target)['DATA'] - - selection.set(selection.target, 8, data) - - def _clipboard_clear_cb(self, clipboard, targets): - logging.debug('ClipboardIcon._clipboard_clear_cb') - self.owns_clipboard = False - - def _object_state_changed_cb(self, cb_service, object_id, name, percent, - icon_name, preview, activity): - - if object_id != self._object_id: - return - - cb_service = clipboardservice.get_instance() - obj = cb_service.get_object(self._object_id) - - if icon_name: - self._icon.props.icon_name = icon_name - else: - self._icon.props.icon_name = 'application-octet-stream' - - self.child.drag_source_set(gtk.gdk.BUTTON1_MASK, - self._get_targets(), - gtk.gdk.ACTION_COPY) - self.child.drag_source_set_icon_name(self._icon.props.icon_name) - - self._name = name - self._preview = preview - self._activity = activity - self.palette.set_state(name, percent, preview, activity, - self._is_bundle(obj['FORMATS'])) - - old_percent = self._percent - self._percent = percent - if self._percent == 100: - self.props.sensitive = True - - # Clipboard object became complete. Make it the active one. - if old_percent < 100 and self._percent == 100: - self.props.active = True - - def _notify_active_cb(self, widget, pspec): - if self.props.active: - self._put_in_clipboard() - else: - self.owns_clipboard = False - - def _get_targets(self): - cb_service = clipboardservice.get_instance() - - attrs = cb_service.get_object(self._object_id) - format_types = attrs[clipboardservice.FORMATS_KEY] - - targets = [] - for format_type in format_types: - targets.append((format_type, 0, 0)) - - return targets - diff --git a/shell/view/clipboardmenu.py b/shell/view/clipboardmenu.py deleted file mode 100644 index b847828..0000000 --- a/shell/view/clipboardmenu.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ -import tempfile -import urlparse -import os -import logging - -import gtk -import hippo - -from sugar.graphics.palette import Palette -from sugar.graphics.menuitem import MenuItem -from sugar.graphics import style -from sugar.clipboard import clipboardservice -from sugar.datastore import datastore -from sugar import mime -from sugar import profile -from sugar import activity - -class ClipboardMenu(Palette): - - def __init__(self, object_id, name, percent, preview, activities, installable): - Palette.__init__(self, name) - - self._object_id = object_id - self._percent = percent - self._activities = activities - - self.set_group_id('frame') - - self._progress_bar = None - - """ - if preview: - self._preview_text = hippo.CanvasText(text=preview, - size_mode=hippo.CANVAS_SIZE_WRAP_WORD) - self._preview_text.props.color = color.LABEL_TEXT.get_int() - self._preview_text.props.font_desc = \ - style.FONT_NORMAL.get_pango_desc() - self.append(self._preview_text) - """ - - self._remove_item = MenuItem(_('Remove'), 'list-remove') - self._remove_item.connect('activate', self._remove_item_activate_cb) - self.menu.append(self._remove_item) - self._remove_item.show() - - self._open_item = MenuItem(_('Open')) - self._open_item.connect('activate', self._open_item_activate_cb) - self.menu.append(self._open_item) - self._open_item.show() - - #self._stop_item = MenuItem(_('Stop download'), 'stock-close') - # TODO: Implement stopping downloads - #self._stop_item.connect('activate', self._stop_item_activate_cb) - #self.append_menu_item(self._stop_item) - - self._journal_item = MenuItem(_('Add to journal'), 'document-save') - self._journal_item.connect('activate', self._journal_item_activate_cb) - self.menu.append(self._journal_item) - self._journal_item.show() - - self._update_items_visibility(installable) - self._update_open_submenu() - - def _update_open_submenu(self): - logging.debug('_update_open_submenu: %r' % self._activities) - if self._activities is None or len(self._activities) <= 1: - if self._open_item.get_submenu() is not None: - self._open_item.remove_submenu() - return - - submenu = self._open_item.get_submenu() - if submenu is None: - submenu = gtk.Menu() - self._open_item.set_submenu(submenu) - submenu.show() - else: - for item in submenu.get_children(): - submenu.remove(item) - - for service_name in self._activities: - registry = activity.get_registry() - activity_info = registry.get_activity(service_name) - - if not activity_info: - logging.warning('Activity %s is unknown.' % service_name) - - item = gtk.MenuItem(activity_info.name) - item.connect('activate', self._open_submenu_item_activate_cb, service_name) - submenu.append(item) - item.show() - - def _update_items_visibility(self, installable): - if self._percent == 100 and (self._activities or installable): - self._remove_item.props.sensitive = True - self._open_item.props.sensitive = True - #self._stop_item.props.sensitive = False - self._journal_item.props.sensitive = True - elif self._percent == 100 and (not self._activities and not installable): - self._remove_item.props.sensitive = True - self._open_item.props.sensitive = False - #self._stop_item.props.sensitive = False - self._journal_item.props.sensitive = True - else: - self._remove_item.props.sensitive = True - self._open_item.props.sensitive = False - # TODO: reenable the stop item when we implement stoping downloads. - #self._stop_item.props.sensitive = True - self._journal_item.props.sensitive = False - - self._update_progress_bar() - - def _update_progress_bar(self): - if self._percent == 100.0: - if self._progress_bar: - self._progress_bar = None - self.set_content(None) - else: - if self._progress_bar is None: - self._progress_bar = gtk.ProgressBar() - self._progress_bar.show() - self.set_content(self._progress_bar) - - self._progress_bar.props.fraction = self._percent / 100.0 - self._progress_bar.props.text = '%.2f %%' % self._percent - - def set_state(self, name, percent, preview, activities, installable): - self.set_primary_text(name) - self._percent = percent - self._activities = activities - self._update_progress_bar() - self._update_items_visibility(installable) - self._update_open_submenu() - - def _open_item_activate_cb(self, menu_item): - logging.debug('_open_item_activate_cb') - if self._percent < 100 or menu_item.get_submenu() is not None: - return - jobject = self._copy_to_journal() - jobject.resume(self._activities[0]) - jobject.destroy() - - def _open_submenu_item_activate_cb(self, menu_item, service_name): - logging.debug('_open_submenu_item_activate_cb') - if self._percent < 100: - return - jobject = self._copy_to_journal() - jobject.resume(service_name) - jobject.destroy() - - def _remove_item_activate_cb(self, menu_item): - cb_service = clipboardservice.get_instance() - cb_service.delete_object(self._object_id) - - def _journal_item_activate_cb(self, menu_item): - logging.debug('_journal_item_activate_cb') - jobject = self._copy_to_journal() - jobject.destroy() - - def _write_to_temp_file(self, data): - f, file_path = tempfile.mkstemp() - try: - os.write(f, data) - finally: - os.close(f) - return file_path - - def _copy_to_journal(self): - cb_service = clipboardservice.get_instance() - obj = cb_service.get_object(self._object_id) - - format = mime.choose_most_significant(obj['FORMATS']) - data = cb_service.get_object_data(self._object_id, format) - - transfer_ownership = False - if format == 'text/uri-list': - uris = mime.split_uri_list(data['DATA']) - if len(uris) == 1 and uris[0].startswith('file://'): - file_path = urlparse.urlparse(uris[0]).path - transfer_ownership = False - mime_type = mime.get_for_file(file_path) - else: - file_path = self._write_to_temp_file(data['DATA']) - transfer_ownership = True - mime_type = 'text/uri-list' - else: - if data['ON_DISK']: - file_path = urlparse.urlparse(data['DATA']).path - transfer_ownership = False - mime_type = mime.get_for_file(file_path) - else: - file_path = self._write_to_temp_file(data['DATA']) - transfer_ownership = True - mime_type = mime.get_for_file(file_path) - - jobject = datastore.create() - jobject.metadata['title'] = _('Clipboard object: %s.') % obj['NAME'] - jobject.metadata['keep'] = '0' - jobject.metadata['buddies'] = '' - jobject.metadata['preview'] = '' - jobject.metadata['icon-color'] = profile.get_color().to_string() - jobject.metadata['mime_type'] = mime_type - jobject.file_path = file_path - datastore.write(jobject, transfer_ownership=transfer_ownership) - - return jobject - diff --git a/shell/view/devices/Makefile.am b/shell/view/devices/Makefile.am deleted file mode 100644 index c040beb..0000000 --- a/shell/view/devices/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -SUBDIRS = network - -sugardir = $(pkgdatadir)/shell/view/devices -sugar_PYTHON = \ - __init__.py \ - battery.py \ - deviceview.py diff --git a/shell/view/devices/__init__.py b/shell/view/devices/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/view/devices/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/view/devices/battery.py b/shell/view/devices/battery.py deleted file mode 100644 index 09c69df..0000000 --- a/shell/view/devices/battery.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ - -import gtk - -from sugar import profile -from sugar.graphics.icon import CanvasIcon -from sugar.graphics.icon import get_icon_state -from sugar.graphics import style -from sugar.graphics.palette import Palette - -_ICON_NAME = 'battery' - -_STATUS_CHARGING = 0 -_STATUS_DISCHARGING = 1 -_STATUS_FULLY_CHARGED = 2 - -class DeviceView(CanvasIcon): - def __init__(self, model): - CanvasIcon.__init__(self, size=style.MEDIUM_ICON_SIZE, - xo_color=profile.get_color()) - self._model = model - self._palette = BatteryPalette(_('My Battery life')) - self.set_palette(self._palette) - - model.connect('notify::level', self._battery_status_changed_cb) - model.connect('notify::charging', self._battery_status_changed_cb) - model.connect('notify::discharging', self._battery_status_changed_cb) - self._update_info() - - def _update_info(self): - name = get_icon_state(_ICON_NAME, self._model.props.level) - self.props.icon_name = name - - # Update palette - if self._model.props.charging: - status = _STATUS_CHARGING - self.props.badge_name = 'emblem-charging' - elif self._model.props.discharging: - status = _STATUS_DISCHARGING - self.props.badge_name = None - else: - status = _STATUS_FULLY_CHARGED - self.props.badge_name = None - - self._palette.set_level(self._model.props.level) - self._palette.set_status(status) - - def _battery_status_changed_cb(self, pspec, param): - self._update_info() - -class BatteryPalette(Palette): - - def __init__(self, primary_text): - Palette.__init__(self, primary_text) - - self._level = 0 - self._progress_bar = gtk.ProgressBar() - self._progress_bar.show() - self._status_label = gtk.Label() - self._status_label.show() - - vbox = gtk.VBox() - vbox.pack_start(self._progress_bar) - vbox.pack_start(self._status_label) - vbox.show() - - self.set_content(vbox) - - def set_level(self, percent): - self._level = percent - fraction = percent/100.0 - self._progress_bar.set_fraction(fraction) - - def set_status(self, status): - percent_string = ' (%s%%)' % self._level - - if status == _STATUS_CHARGING: - charge_text = _('Battery charging') + percent_string - elif status == _STATUS_DISCHARGING: - charge_text = _('Battery discharging') + percent_string - elif status == _STATUS_FULLY_CHARGED: - charge_text = _('Battery fully charged') - - self._status_label.set_text(charge_text) diff --git a/shell/view/devices/deviceview.py b/shell/view/devices/deviceview.py deleted file mode 100644 index f58da02..0000000 --- a/shell/view/devices/deviceview.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from sugar.graphics.icon import CanvasIcon - -def create(model): - name = 'view.devices.' + model.get_type() - - mod = __import__(name) - components = name.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - - return mod.DeviceView(model) diff --git a/shell/view/devices/network/Makefile.am b/shell/view/devices/network/Makefile.am deleted file mode 100644 index 0d215f0..0000000 --- a/shell/view/devices/network/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -sugardir = $(pkgdatadir)/shell/view/devices/network -sugar_PYTHON = \ - __init__.py \ - mesh.py \ - wired.py \ - wireless.py diff --git a/shell/view/devices/network/__init__.py b/shell/view/devices/network/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/view/devices/network/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/view/devices/network/mesh.py b/shell/view/devices/network/mesh.py deleted file mode 100644 index 2543957..0000000 --- a/shell/view/devices/network/mesh.py +++ /dev/null @@ -1,125 +0,0 @@ -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ - -import gtk - -from sugar import profile -from sugar.graphics.icon import CanvasIcon -from sugar.graphics import style -from model.devices import device - -from sugar.graphics.palette import Palette -from model.devices.network import wireless - -from hardware import hardwaremanager - -class DeviceView(CanvasIcon): - def __init__(self, model): - CanvasIcon.__init__(self, size=style.MEDIUM_ICON_SIZE, - icon_name='network-mesh') - self._model = model - self._palette = MeshPalette(_("Mesh Network"), model) - self.set_palette(self._palette) - - model.connect('notify::state', self._state_changed_cb) - model.connect('notify::activation-stage', self._state_changed_cb) - self._update_state() - - def _state_changed_cb(self, model, pspec): - self._update_state() - - def _update_state(self): - # FIXME Change icon colors once we have real icons - state = self._model.props.state - self._palette.update_state(state) - - if state == device.STATE_ACTIVATING: - self.props.fill_color = style.COLOR_INACTIVE_FILL.get_svg() - self.props.stroke_color = style.COLOR_INACTIVE_STROKE.get_svg() - elif state == device.STATE_ACTIVATED: - self.props.xo_color = profile.get_color() - elif state == device.STATE_INACTIVE: - self.props.fill_color = style.COLOR_INACTIVE_FILL.get_svg() - self.props.stroke_color = style.COLOR_INACTIVE_STROKE.get_svg() - - if state == device.STATE_INACTIVE: - self._palette.set_primary_text(_("Mesh Network")) - else: - chan = wireless.freq_to_channel(self._model.props.frequency) - if chan > 0: - self._palette.set_primary_text(_("Mesh Network") + " %d" % chan) - self._palette.set_mesh_step(self._model.props.mesh_step, state) - -class MeshPalette(Palette): - def __init__(self, primary_text, model): - Palette.__init__(self, primary_text, menu_after_content=True) - self._model = model - - self._step_label = gtk.Label() - self._step_label.show() - - vbox = gtk.VBox() - vbox.pack_start(self._step_label) - vbox.show() - - self.set_content(vbox) - - self._disconnect_item = gtk.MenuItem(_('Disconnect...')) - self._disconnect_item.connect('activate', self._disconnect_activate_cb) - self.menu.append(self._disconnect_item) - - def update_state(self, state): - if state == device.STATE_ACTIVATED: - self._disconnect_item.show() - else: - self._disconnect_item.hide() - - def _disconnect_activate_cb(self, menuitem): - # Disconnection for an mesh means activating the default mesh device - # again without a channel - network_manager = hardwaremanager.get_network_manager() - nm_device = self._model.get_nm_device() - if network_manager and nm_device: - network_manager.set_active_device(nm_device) - - def set_mesh_step(self, step, state): - label = "" - if step == 1: - if state == device.STATE_ACTIVATED: - label = _("Connected to a School Mesh Portal") - elif state == device.STATE_ACTIVATING: - label = _("Looking for a School Mesh Portal...") - elif step == 3: - if state == device.STATE_ACTIVATED: - label = _("Connected to an XO Mesh Portal") - elif state == device.STATE_ACTIVATING: - label = _("Looking for an XO Mesh Portal...") - elif step == 4: - if state == device.STATE_ACTIVATED: - label = _("Connected to a Simple Mesh") - elif state == device.STATE_ACTIVATING: - label = _("Starting a Simple Mesh") - - if len(label): - self._step_label.set_text(label) - else: - import logging - logging.debug("Unhandled mesh step %d" % step) - self._step_label.set_text(_("Unknown Mesh")) - diff --git a/shell/view/devices/network/wired.py b/shell/view/devices/network/wired.py deleted file mode 100644 index dc83a08..0000000 --- a/shell/view/devices/network/wired.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from view.devices import deviceview - -class DeviceView(deviceview.DeviceView): - def __init__(self, model): - deviceview.DeviceView.__init__(self, model) - self.props.icon_name = 'network-wired' diff --git a/shell/view/devices/network/wireless.py b/shell/view/devices/network/wireless.py deleted file mode 100644 index f4f8869..0000000 --- a/shell/view/devices/network/wireless.py +++ /dev/null @@ -1,132 +0,0 @@ -# -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ - -import gtk - -from sugar.graphics.icon import get_icon_state -from sugar.graphics.icon import CanvasIcon -from sugar.graphics import style -from sugar.graphics.palette import Palette - -from model.devices.network import wireless -from model.devices import device - -from hardware import hardwaremanager -from hardware import nmclient - -_ICON_NAME = 'network-wireless' - -class DeviceView(CanvasIcon): - def __init__(self, model): - CanvasIcon.__init__(self, size=style.MEDIUM_ICON_SIZE) - self._model = model - - meshdev = None - network_manager = hardwaremanager.get_network_manager() - for device in network_manager.get_devices(): - if device.get_type() == nmclient.DEVICE_TYPE_802_11_MESH_OLPC: - meshdev = device - break - - self._palette = WirelessPalette(self._get_palette_primary_text(), meshdev) - self.set_palette(self._palette) - self._counter = 0 - self._palette.set_frequency(self._model.props.frequency) - - model.connect('notify::name', self._name_changed_cb) - model.connect('notify::strength', self._strength_changed_cb) - model.connect('notify::state', self._state_changed_cb) - - self._update_icon() - self._update_state() - - def _get_palette_primary_text(self): - if self._model.props.state == device.STATE_INACTIVE: - return _("Disconnected") - return self._model.props.name - - def _strength_changed_cb(self, model, pspec): - self._update_icon() - # Only update frequency periodically - if self._counter % 4 == 0: - self._palette.set_frequency(self._model.props.frequency) - self._counter += 1 - - def _name_changed_cb(self, model, pspec): - self.palette.set_primary_text(self._get_palette_primary_text()) - - def _state_changed_cb(self, model, pspec): - self._update_state() - self.palette.set_primary_text(self._get_palette_primary_text()) - - def _update_icon(self): - strength = self._model.props.strength - if self._model.props.state == device.STATE_INACTIVE: - strength = 0 - icon_name = get_icon_state(_ICON_NAME, strength) - if icon_name: - self.props.icon_name = icon_name - - def _update_state(self): - # FIXME Change icon colors once we have real icons - state = self._model.props.state - if state == device.STATE_ACTIVATING: - self.props.fill_color = style.COLOR_INACTIVE_FILL.get_svg() - self.props.stroke_color = style.COLOR_INACTIVE_STROKE.get_svg() - elif state == device.STATE_ACTIVATED: - (stroke, fill) = self._model.get_active_network_colors() - self.props.stroke_color = stroke - self.props.fill_color = fill - elif state == device.STATE_INACTIVE: - self.props.fill_color = style.COLOR_INACTIVE_FILL.get_svg() - self.props.stroke_color = style.COLOR_INACTIVE_STROKE.get_svg() - -class WirelessPalette(Palette): - def __init__(self, primary_text, meshdev): - Palette.__init__(self, primary_text, menu_after_content=True) - self._meshdev = meshdev - - self._chan_label = gtk.Label() - self._chan_label.show() - - vbox = gtk.VBox() - vbox.pack_start(self._chan_label) - vbox.show() - - if meshdev: - disconnect_item = gtk.MenuItem(_('Disconnect...')) - disconnect_item.connect('activate', self._disconnect_activate_cb) - self.menu.append(disconnect_item) - disconnect_item.show() - - self.set_content(vbox) - - def _disconnect_activate_cb(self, menuitem): - # Disconnection for an AP means activating the default mesh device - network_manager = hardwaremanager.get_network_manager() - if network_manager and self._meshdev: - network_manager.set_active_device(self._meshdev) - - def set_frequency(self, freq): - try: - chan = wireless.freq_to_channel(freq) - except KeyError: - chan = 0 - self._chan_label.set_text("%s: %d" % (_("Channel"), chan)) - diff --git a/shell/view/frame/Makefile.am b/shell/view/frame/Makefile.am deleted file mode 100644 index 02951b9..0000000 --- a/shell/view/frame/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -sugardir = $(pkgdatadir)/shell/view/frame -sugar_PYTHON = \ - __init__.py \ - activitiestray.py \ - activitybutton.py \ - clipboardbox.py \ - clipboardpanelwindow.py \ - frameinvoker.py \ - friendstray.py \ - eventarea.py \ - frame.py \ - overlaybox.py \ - framewindow.py \ - zoomtoolbar.py diff --git a/shell/view/frame/__init__.py b/shell/view/frame/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/view/frame/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/view/frame/activitiestray.py b/shell/view/frame/activitiestray.py deleted file mode 100644 index 3dbf955..0000000 --- a/shell/view/frame/activitiestray.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo -import logging - -from sugar.graphics.tray import TrayButton -from sugar.graphics.tray import HTray -from sugar.graphics.icon import Icon -from sugar.graphics import style -from sugar import profile -from sugar import activity -from sugar import env - -from activitybutton import ActivityButton - -class InviteButton(TrayButton): - def __init__(self, activity_model, invite): - TrayButton.__init__(self) - - icon = Icon(file=activity_model.get_icon_name(), - xo_color=activity_model.get_color()) - self.set_icon_widget(icon) - icon.show() - - self._invite = invite - - def get_activity_id(self): - return self._invite.get_activity_id() - - def get_bundle_id(self): - return self._invite.get_bundle_id() - - def get_invite(self): - return self._invite - -class ActivitiesTray(hippo.CanvasBox): - def __init__(self, shell): - hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL) - - self._shell = shell - self._shell_model = self._shell.get_model() - self._invite_to_item = {} - self._invites = self._shell_model.get_invites() - self._config = self._load_config() - - self._tray = HTray() - self.append(hippo.CanvasWidget(widget=self._tray), hippo.PACK_EXPAND) - self._tray.show() - - registry = activity.get_registry() - registry.get_activities_async(reply_handler=self._get_activities_cb) - - registry.connect('activity-added', self._activity_added_cb) - registry.connect('activity-removed', self._activity_removed_cb) - - for invite in self._invites: - self.add_invite(invite) - self._invites.connect('invite-added', self._invite_added_cb) - self._invites.connect('invite-removed', self._invite_removed_cb) - - def _load_config(self): - config = [] - - f = open(env.get_data_path('activities.defaults'), 'r') - for line in f.readlines(): - line = line.strip() - if line and not line.startswith('#'): - config.append(line) - f.close() - - return config - - def _get_activities_cb(self, activity_list): - known_activities = [] - unknown_activities = [] - name_to_activity = {} - - while activity_list: - info = activity_list.pop() - name_to_activity[info.bundle_id] = info - - if info.bundle_id in self._config: - known_activities.append(info) - else: - unknown_activities.append(info) - - sorted_activities = [] - for name in self._config: - if name in name_to_activity: - sorted_activities.append(name_to_activity[name]) - - for info in sorted_activities + unknown_activities: - if info.show_launcher: - self.add_activity(info) - - def _activity_clicked_cb(self, icon): - self._shell.start_activity(icon.get_bundle_id()) - - def _invite_clicked_cb(self, icon): - self._invites.remove_invite(icon.get_invite()) - self._shell.join_activity(icon.get_bundle_id(), - icon.get_activity_id()) - - def _invite_added_cb(self, invites, invite): - self.add_invite(invite) - - def _invite_removed_cb(self, invites, invite): - self.remove_invite(invite) - - def _remove_activity_cb(self, item): - self._tray.remove_item(item) - - def _activity_added_cb(self, activity_registry, activity_info): - self.add_activity(activity_info) - - def _activity_removed_cb(self, activity_registry, activity_info): - for item in self._tray.get_children(): - if item.get_bundle_id() == activity_info.bundle_id: - self._tray.remove_item(item) - return - - def add_activity(self, activity_info): - item = ActivityButton(activity_info) - item.connect('clicked', self._activity_clicked_cb) - item.connect('remove_activity', self._remove_activity_cb) - self._tray.add_item(item, -1) - item.show() - - def add_invite(self, invite): - mesh = self._shell_model.get_mesh() - activity_model = mesh.get_activity(invite.get_activity_id()) - if activity: - item = InviteButton(activity_model, invite) - item.connect('clicked', self._invite_clicked_cb) - self._tray.add_item(item, 0) - item.show() - - self._invite_to_item[invite] = item - - def remove_invite(self, invite): - self._tray.remove_item(self._invite_to_item[invite]) - del self._invite_to_item[invite] diff --git a/shell/view/frame/activitybutton.py b/shell/view/frame/activitybutton.py deleted file mode 100644 index 0c7c7fb..0000000 --- a/shell/view/frame/activitybutton.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gtk -import os -import gobject -from gettext import gettext as _ - -from sugar.graphics.palette import Palette -from sugar.graphics.tray import TrayButton -from sugar.graphics.icon import Icon -from sugar.graphics import style - -from view.frame.frameinvoker import FrameWidgetInvoker - -class ActivityButton(TrayButton, gobject.GObject): - __gtype_name__ = 'SugarActivityButton' - __gsignals__ = { - 'remove_activity': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) - } - - def __init__(self, activity_info): - TrayButton.__init__(self) - - icon = Icon(file=activity_info.icon, - stroke_color=style.COLOR_WHITE.get_svg(), - fill_color=style.COLOR_TRANSPARENT.get_svg()) - self.set_icon_widget(icon) - icon.show() - - self._activity_info = activity_info - self.setup_rollover_options() - - def get_bundle_id(self): - return self._activity_info.bundle_id - - def setup_rollover_options(self): - palette = Palette(self._activity_info.name) - self.set_palette(palette) - palette.props.invoker = FrameWidgetInvoker(self) - -#TODO: Disabled this until later, see #4967 -# if os.path.dirname(self._activity_info.path) == os.path.expanduser('~/Activities'): -# menu_item = gtk.MenuItem(_('Remove')) -# menu_item.connect('activate', self.item_remove_cb) -# palette.menu.append(menu_item) -# menu_item.show() - - def item_remove_cb(self, widget): - self.emit('remove_activity') diff --git a/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py deleted file mode 100644 index 7702759..0000000 --- a/shell/view/frame/clipboardbox.py +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -import logging -import tempfile - -import hippo -import gtk - -from sugar import util -from sugar.clipboard import clipboardservice -from sugar.graphics.tray import VTray -from sugar.graphics import style - -from view.clipboardicon import ClipboardIcon - -class _ContextMap: - """Maps a drag context to the clipboard object involved in the dragging.""" - def __init__(self): - self._context_map = {} - - def add_context(self, context, object_id, data_types): - """Establishes the mapping. data_types will serve us for reference- - counting this mapping. - """ - self._context_map[context] = [object_id, data_types] - - def get_object_id(self, context): - """Retrieves the object_id associated with context. - Will release the association when this function was called as many times - as the number of data_types that this clipboard object contains. - """ - [object_id, data_types_left] = self._context_map[context] - - data_types_left = data_types_left - 1 - if data_types_left == 0: - del self._context_map[context] - else: - self._context_map[context] = [object_id, data_types_left] - - return object_id - - def has_context(self, context): - return context in self._context_map - -class ClipboardBox(hippo.CanvasBox): - - MAX_ITEMS = gtk.gdk.screen_height() / style.GRID_CELL_SIZE - 2 - - def __init__(self): - hippo.CanvasBox.__init__(self) - self._icons = {} - self._context_map = _ContextMap() - - self._tray = VTray() - self.append(hippo.CanvasWidget(widget=self._tray), hippo.PACK_EXPAND) - self._tray.show() - - cb_service = clipboardservice.get_instance() - cb_service.connect('object-added', self._object_added_cb) - cb_service.connect('object-deleted', self._object_deleted_cb) - - def owns_clipboard(self): - for icon in self._icons.values(): - if icon.owns_clipboard: - return True - return False - - def _add_selection(self, object_id, selection): - if not selection.data: - return - - logging.debug('ClipboardBox: adding type ' + selection.type) - - cb_service = clipboardservice.get_instance() - if selection.type == 'text/uri-list': - uris = selection.data.split('\n') - if len(uris) > 1: - raise NotImplementedError('Multiple uris in text/uri-list still not supported.') - - cb_service.add_object_format(object_id, - selection.type, - uris[0], - on_disk=True) - else: - cb_service.add_object_format(object_id, - selection.type, - selection.data, - on_disk=False) - - def _object_added_cb(self, cb_service, object_id, name): - if self._icons: - group = self._icons.values()[0] - else: - group = None - - icon = ClipboardIcon(object_id, name, group) - self._tray.add_item(icon, 0) - icon.show() - self._icons[object_id] = icon - - objects_to_delete = self._tray.get_children()[ClipboardBox.MAX_ITEMS:] - for icon in objects_to_delete: - logging.debug('ClipboardBox: deleting surplus object') - cb_service = clipboardservice.get_instance() - cb_service.delete_object(icon.get_object_id()) - - logging.debug('ClipboardBox: ' + object_id + ' was added.') - - def _object_deleted_cb(self, cb_service, object_id): - icon = self._icons[object_id] - self._tray.remove_item(icon) - del self._icons[object_id] - logging.debug('ClipboardBox: ' + object_id + ' was deleted.') - - def drag_motion_cb(self, widget, context, x, y, time): - logging.debug('ClipboardBox._drag_motion_cb') - context.drag_status(gtk.gdk.ACTION_COPY, time) - return True; - - def drag_drop_cb(self, widget, context, x, y, time): - logging.debug('ClipboardBox._drag_drop_cb') - cb_service = clipboardservice.get_instance() - object_id = cb_service.add_object(name="") - - self._context_map.add_context(context, object_id, len(context.targets)) - - if 'XdndDirectSave0' in context.targets: - window = context.source_window - prop_type, format, filename = \ - window.property_get('XdndDirectSave0','text/plain') - - # FIXME query the clipboard service for a filename? - base_dir = tempfile.gettempdir() - dest_filename = util.unique_id() - - name, dot, extension = filename.rpartition('.') - dest_filename += dot + extension - - dest_uri = 'file://' + os.path.join(base_dir, dest_filename) - - window.property_change('XdndDirectSave0', prop_type, format, - gtk.gdk.PROP_MODE_REPLACE, dest_uri) - - widget.drag_get_data(context, 'XdndDirectSave0', time) - else: - for target in context.targets: - if str(target) not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE'): - widget.drag_get_data(context, target, time) - - cb_service.set_object_percent(object_id, percent=100) - - return True - - def drag_data_received_cb(self, widget, context, x, y, selection, targetType, time): - logging.debug('ClipboardBox: got data for target %r' % selection.target) - - object_id = self._context_map.get_object_id(context) - try: - if selection is None: - logging.warn('ClipboardBox: empty selection for target ' + selection.target) - elif selection.target == 'XdndDirectSave0': - if selection.data == 'S': - window = context.source_window - - prop_type, format, dest = \ - window.property_get('XdndDirectSave0','text/plain') - - clipboard = clipboardservice.get_instance() - clipboard.add_object_format( - object_id, 'XdndDirectSave0', dest, on_disk=True) - else: - self._add_selection(object_id, selection) - - finally: - # If it's the last target to be processed, finish the dnd transaction - if not self._context_map.has_context(context): - context.drop_finish(True, gtk.get_current_event_time()) - diff --git a/shell/view/frame/clipboardpanelwindow.py b/shell/view/frame/clipboardpanelwindow.py deleted file mode 100644 index e579b8c..0000000 --- a/shell/view/frame/clipboardpanelwindow.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (C) 2007, One Laptop Per Child -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging -import urlparse - -import gtk -import hippo - -from view.frame.framewindow import FrameWindow -from view.frame.clipboardbox import ClipboardBox -from sugar.clipboard import clipboardservice -from sugar import util - -class ClipboardPanelWindow(FrameWindow): - def __init__(self, frame, orientation): - FrameWindow.__init__(self, orientation) - - self._frame = frame - - # Listening for new clipboard objects - # NOTE: we need to keep a reference to gtk.Clipboard in order to keep - # listening to it. - self._clipboard = gtk.Clipboard() - self._clipboard.connect("owner-change", self._owner_change_cb) - - self._clipboard_box = ClipboardBox() - self.append(self._clipboard_box, hippo.PACK_EXPAND) - - # Receiving dnd drops - self.drag_dest_set(0, [], 0) - self.connect("drag_motion", self._clipboard_box.drag_motion_cb) - self.connect("drag_drop", self._clipboard_box.drag_drop_cb) - self.connect("drag_data_received", - self._clipboard_box.drag_data_received_cb) - - def _owner_change_cb(self, clipboard, event): - logging.debug("owner_change_cb") - - if self._clipboard_box.owns_clipboard(): - return - - cb_service = clipboardservice.get_instance() - key = cb_service.add_object(name="") - cb_service.set_object_percent(key, percent=0) - - targets = clipboard.wait_for_targets() - for target in targets: - if target not in ('TIMESTAMP', 'TARGETS', 'MULTIPLE', 'SAVE_TARGETS'): - logging.debug('Asking for target %s.' % target) - selection = clipboard.wait_for_contents(target) - if not selection: - logging.warning('no data for selection target %s.' % target) - continue - self._add_selection(key, selection) - - cb_service.set_object_percent(key, percent=100) - - def _add_selection(self, key, selection): - if not selection.data: - logging.warning('no data for selection target %s.' % selection.type) - return - - logging.debug('adding type ' + selection.type + '.') - - cb_service = clipboardservice.get_instance() - if selection.type == 'text/uri-list': - uris = selection.get_uris() - - if len(uris) > 1: - raise NotImplementedError('Multiple uris in text/uri-list still not supported.') - uri = uris[0] - - scheme, netloc, path, parameters, query, fragment = urlparse.urlparse(uri) - on_disk = (scheme == 'file') - - cb_service.add_object_format(key, - selection.type, - uri, - on_disk) - else: - cb_service.add_object_format(key, - selection.type, - selection.data, - on_disk=False) - diff --git a/shell/view/frame/eventarea.py b/shell/view/frame/eventarea.py deleted file mode 100644 index 69bb759..0000000 --- a/shell/view/frame/eventarea.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import gobject -import wnck - -class EventArea(gobject.GObject): - __gsignals__ = { - 'enter': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'leave': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) - } - - def __init__(self): - gobject.GObject.__init__(self) - - self._windows = [] - self._hover = False - - right = gtk.gdk.screen_width() - 1 - bottom = gtk.gdk.screen_height() -1 - - invisible = self._create_invisible(0, 0, 1, 1) - self._windows.append(invisible) - - invisible = self._create_invisible(right, 0, 1, 1) - self._windows.append(invisible) - - invisible = self._create_invisible(0, bottom, 1, 1) - self._windows.append(invisible) - - invisible = self._create_invisible(right, bottom, 1, 1) - self._windows.append(invisible) - - screen = wnck.screen_get_default() - screen.connect('window-stacking-changed', - self._window_stacking_changed_cb) - - def _create_invisible(self, x, y, width, height): - invisible = gtk.Invisible() - invisible.connect('enter-notify-event', self._enter_notify_cb) - invisible.connect('leave-notify-event', self._leave_notify_cb) - - invisible.drag_dest_set(0, [], 0) - invisible.connect('drag_motion', self._drag_motion_cb) - invisible.connect('drag_leave', self._drag_leave_cb) - - invisible.realize() - invisible.window.set_events(gtk.gdk.POINTER_MOTION_MASK | - gtk.gdk.ENTER_NOTIFY_MASK | - gtk.gdk.LEAVE_NOTIFY_MASK) - invisible.window.move_resize(x, y, width, height) - - return invisible - - def _notify_enter(self): - if not self._hover: - self._hover = True - self.emit('enter') - - def _notify_leave(self): - if self._hover: - self._hover = False - self.emit('leave') - - def _enter_notify_cb(self, widget, event): - self._notify_enter() - - def _leave_notify_cb(self, widget, event): - self._notify_leave() - - def _drag_motion_cb(self, widget, drag_context, x, y, timestamp): - drag_context.drag_status(0, timestamp); - self._notify_enter() - return True - - def _drag_leave_cb(self, widget, drag_context, timestamp): - self._notify_leave() - return True - - def show(self): - for window in self._windows: - window.show() - - def hide(self): - for window in self._windows: - window.hide() - - def _window_stacking_changed_cb(self, screen): - for window in self._windows: - window.window.raise_() diff --git a/shell/view/frame/frame.py b/shell/view/frame/frame.py deleted file mode 100644 index e8f8fa4..0000000 --- a/shell/view/frame/frame.py +++ /dev/null @@ -1,272 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import logging - -import gtk -import gobject -import hippo - -from sugar.graphics import animator -from sugar.graphics import style -from sugar.graphics import palettegroup -from sugar.clipboard import clipboardservice - -from view.frame.eventarea import EventArea -from view.frame.activitiestray import ActivitiesTray -from view.frame.zoomtoolbar import ZoomToolbar -from view.frame.friendstray import FriendsTray -from view.frame.framewindow import FrameWindow -from view.frame.clipboardpanelwindow import ClipboardPanelWindow -from model.shellmodel import ShellModel - -_FRAME_HIDING_DELAY = 500 - -class _Animation(animator.Animation): - def __init__(self, frame, end): - start = frame.current_position - animator.Animation.__init__(self, start, end) - self._frame = frame - - def next_frame(self, current): - self._frame.move(current) - -class _MouseListener(object): - def __init__(self, frame): - self._frame = frame - self._hide_sid = 0 - - def mouse_enter(self): - self._show_frame() - - def mouse_leave(self): - if self._frame.mode == Frame.MODE_MOUSE: - self._hide_frame() - - def _show_frame(self): - if self._hide_sid != 0: - gobject.source_remove(self._hide_sid) - self._frame.show(Frame.MODE_MOUSE) - - def _hide_frame_timeout_cb(self): - self._frame.hide() - return False - - def _hide_frame(self): - if self._hide_sid != 0: - gobject.source_remove(self._hide_sid) - self._hide_sid = gobject.timeout_add( - _FRAME_HIDING_DELAY, self._hide_frame_timeout_cb) - -class _KeyListener(object): - def __init__(self, frame): - self._frame = frame - - def key_press(self): - if self._frame.visible: - if self._frame.mode == Frame.MODE_KEYBOARD: - self._frame.hide() - else: - self._frame.show(Frame.MODE_KEYBOARD) - -class Frame(object): - MODE_MOUSE = 0 - MODE_KEYBOARD = 1 - MODE_NON_INTERACTIVE = 2 - - def __init__(self, shell): - self.mode = None - - self._palette_group = palettegroup.get_group('frame') - self._palette_group.connect('popdown', self._palette_group_popdown_cb) - - self._left_panel = None - self._right_panel = None - self._top_panel = None - self._bottom_panel = None - - self._shell = shell - self.current_position = 0.0 - self._animator = None - - self._event_area = EventArea() - self._event_area.connect('enter', self._enter_corner_cb) - self._event_area.show() - - self._top_panel = self._create_top_panel() - self._bottom_panel = self._create_bottom_panel() - self._left_panel = self._create_left_panel() - self._right_panel = self._create_right_panel() - - screen = gtk.gdk.screen_get_default() - screen.connect('size-changed', self._size_changed_cb) - - cb_service = clipboardservice.get_instance() - cb_service.connect_after('object-added', self._clipboard_object_added_cb) - - self._key_listener = _KeyListener(self) - self._mouse_listener = _MouseListener(self) - - self.move(1.0) - - def is_visible(self): - return self.current_position != 0.0 - - def hide(self): - if self._animator: - self._animator.stop() - - self._animator = animator.Animator(0.5) - self._animator.add(_Animation(self, 0.0)) - self._animator.start() - - self._event_area.show() - - self.mode = None - - def show(self, mode): - if self.visible: - return - if self._animator: - self._animator.stop() - - self._shell.take_activity_screenshot() - - self.mode = mode - - self._animator = animator.Animator(0.5) - self._animator.add(_Animation(self, 1.0)) - self._animator.start() - - self._event_area.hide() - - def move(self, pos): - self.current_position = pos - self._update_position() - - def _is_hover(self): - return (self._top_panel.hover or \ - self._bottom_panel.hover or \ - self._left_panel.hover or \ - self._right_panel.hover) - - def _create_top_panel(self): - panel = self._create_panel(gtk.POS_TOP) - - toolbar = ZoomToolbar(self._shell) - panel.append(hippo.CanvasWidget(widget=toolbar)) - toolbar.show() - - return panel - - def _create_bottom_panel(self): - panel = self._create_panel(gtk.POS_BOTTOM) - - box = ActivitiesTray(self._shell) - panel.append(box, hippo.PACK_EXPAND) - - return panel - - def _create_right_panel(self): - panel = self._create_panel(gtk.POS_RIGHT) - - tray = FriendsTray(self._shell) - panel.append(hippo.CanvasWidget(widget=tray), hippo.PACK_EXPAND) - tray.show() - - return panel - - def _create_left_panel(self): - panel = ClipboardPanelWindow(self, gtk.POS_LEFT) - - self._connect_to_panel(panel) - panel.connect('drag-motion', self._drag_motion_cb) - panel.connect('drag-leave', self._drag_leave_cb) - - return panel - - def _create_panel(self, orientation): - panel = FrameWindow(orientation) - self._connect_to_panel(panel) - - return panel - - def _move_panel(self, panel, pos, x1, y1, x2, y2): - x = (x2 - x1) * pos + x1 - y = (y2 - y1) * pos + y1 - - panel.move(int(x), int(y)) - - # FIXME we should hide and show as necessary to free memory - if not panel.props.visible: - panel.show() - - def _connect_to_panel(self, panel): - panel.connect('enter-notify-event', self._enter_notify_cb) - panel.connect('leave-notify-event', self._leave_notify_cb) - - def _update_position(self): - screen_h = gtk.gdk.screen_height() - screen_w = gtk.gdk.screen_width() - - self._move_panel(self._top_panel, self.current_position, - 0, - self._top_panel.size, 0, 0) - - self._move_panel(self._bottom_panel, self.current_position, - 0, screen_h, 0, screen_h - self._bottom_panel.size) - - self._move_panel(self._left_panel, self.current_position, - - self._left_panel.size, 0, 0, 0) - - self._move_panel(self._right_panel, self.current_position, - screen_w, 0, screen_w - self._right_panel.size, 0) - - def _size_changed_cb(self, screen): - self._update_position() - - def _clipboard_object_added_cb(self, cb_service, object_id, name): - if not self.visible: - self.show(self.MODE_NON_INTERACTIVE) - gobject.timeout_add(2000, lambda: self.hide()) - - def _enter_notify_cb(self, window, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR: - self._mouse_listener.mouse_enter() - - def _leave_notify_cb(self, window, event): - if event.detail == gtk.gdk.NOTIFY_INFERIOR: - return - - if not self._is_hover() and not self._palette_group.is_up(): - self._mouse_listener.mouse_leave() - - def _palette_group_popdown_cb(self, group): - if not self._is_hover(): - self._mouse_listener.mouse_leave() - - def _drag_motion_cb(self, window, context, x, y, time): - self._mouse_listener.mouse_enter() - - def _drag_leave_cb(self, window, drag_context, timestamp): - self._mouse_listener.mouse_leave() - - def _enter_corner_cb(self, event_area): - self._mouse_listener.mouse_enter() - - def notify_key_press(self): - self._key_listener.key_press() - - visible = property(is_visible, None) diff --git a/shell/view/frame/frameinvoker.py b/shell/view/frame/frameinvoker.py deleted file mode 100644 index 07dc9d8..0000000 --- a/shell/view/frame/frameinvoker.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2007, Eduardo Silva -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gtk - -from sugar.graphics import style -from sugar.graphics.palette import Palette -from sugar.graphics.palette import CanvasInvoker -from sugar.graphics.palette import WidgetInvoker - -def _get_screen_area(): - frame_thickness = style.GRID_CELL_SIZE - - x = y = frame_thickness - width = gtk.gdk.screen_width() - frame_thickness - height = gtk.gdk.screen_height() - frame_thickness - - return gtk.gdk.Rectangle(x, y, width, height) - -class FrameWidgetInvoker(WidgetInvoker): - def __init__(self, widget): - WidgetInvoker.__init__(self, widget.child) - - self._position_hint = self.ANCHORED - self._screen_area = _get_screen_area() diff --git a/shell/view/frame/framewindow.py b/shell/view/frame/framewindow.py deleted file mode 100644 index 623d162..0000000 --- a/shell/view/frame/framewindow.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import hippo - -from sugar.graphics import style - -class FrameWindow(gtk.Window): - __gtype_name__ = 'SugarFrameWindow' - - def __init__(self, position): - gtk.Window.__init__(self) - self.hover = False - self.size = style.GRID_CELL_SIZE + style.LINE_WIDTH - - self._position = position - - self.set_decorated(False) - self.connect('realize', self._realize_cb) - self.connect('enter-notify-event', self._enter_notify_cb) - self.connect('leave-notify-event', self._leave_notify_cb) - - self._canvas = hippo.Canvas() - self.add(self._canvas) - self._canvas.show() - - box = hippo.CanvasBox() - self._canvas.set_root(box) - - padding = style.GRID_CELL_SIZE - if self._position == gtk.POS_TOP or self._position == gtk.POS_BOTTOM: - box.props.orientation = hippo.ORIENTATION_HORIZONTAL - box.props.padding_left = padding - box.props.padding_right = padding - box.props.padding_top = 0 - box.props.padding_bottom = 0 - else: - box.props.orientation = hippo.ORIENTATION_VERTICAL - box.props.padding_left = 0 - box.props.padding_right = 0 - box.props.padding_top = padding - box.props.padding_bottom = padding - - self._bg = hippo.CanvasBox( - border_color=style.COLOR_BUTTON_GREY.get_int()) - - border = style.LINE_WIDTH - if position == gtk.POS_TOP: - self._bg.props.orientation = hippo.ORIENTATION_HORIZONTAL - self._bg.props.border_bottom = border - elif position == gtk.POS_BOTTOM: - self._bg.props.orientation = hippo.ORIENTATION_HORIZONTAL - self._bg.props.border_top = border - elif position == gtk.POS_LEFT: - self._bg.props.orientation = hippo.ORIENTATION_VERTICAL - self._bg.props.border_right = border - elif position == gtk.POS_RIGHT: - self._bg.props.orientation = hippo.ORIENTATION_VERTICAL - self._bg.props.border_left = border - - box.append(self._bg, hippo.PACK_EXPAND) - - self._update_size() - - screen = gtk.gdk.screen_get_default() - screen.connect('size-changed', self._size_changed_cb) - - def append(self, child, flags=0): - self._bg.append(child, flags) - - def _update_size(self): - if self._position == gtk.POS_TOP or self._position == gtk.POS_BOTTOM: - self.resize(gtk.gdk.screen_width(), self.size) - else: - self.resize(self.size, gtk.gdk.screen_height()) - - def _realize_cb(self, widget): - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) - self.window.set_accept_focus(False) - - def _enter_notify_cb(self, window, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR: - self.hover = True - - def _leave_notify_cb(self, window, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR: - self.hover = False - - def _size_changed_cb(self, screen): - self._update_size() diff --git a/shell/view/frame/friendstray.py b/shell/view/frame/friendstray.py deleted file mode 100644 index b34f357..0000000 --- a/shell/view/frame/friendstray.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo - -from sugar.presence import presenceservice -from sugar.graphics.tray import VTray, TrayIcon - -from view.BuddyMenu import BuddyMenu -from view.frame.frameinvoker import FrameWidgetInvoker -from model.BuddyModel import BuddyModel - -class FriendIcon(TrayIcon): - def __init__(self, shell, buddy): - TrayIcon.__init__(self, icon_name='computer-xo', - xo_color=buddy.get_color()) - - palette = BuddyMenu(shell, buddy) - self.set_palette(palette) - palette.set_group_id('frame') - palette.props.invoker = FrameWidgetInvoker(self) - -class FriendsTray(VTray): - def __init__(self, shell): - VTray.__init__(self) - - self._shell = shell - self._activity_ps = None - self._joined_hid = -1 - self._left_hid = -1 - self._buddies = {} - - self._pservice = presenceservice.get_instance() - self._pservice.connect('activity-appeared', - self.__activity_appeared_cb) - - self._owner = self._pservice.get_owner() - - # Add initial activities the PS knows about - self._pservice.get_activities_async(reply_handler=self._get_activities_cb) - - home_model = shell.get_model().get_home() - home_model.connect('pending-activity-changed', - self._pending_activity_changed_cb) - - def _get_activities_cb(self, list): - for activity in list: - self.__activity_appeared_cb(self._pservice, activity) - - def add_buddy(self, buddy): - if self._buddies.has_key(buddy.props.key): - return - - model = BuddyModel(buddy=buddy) - - icon = FriendIcon(self._shell, model) - self.add_item(icon) - icon.show() - - self._buddies[buddy.props.key] = icon - - def remove_buddy(self, buddy): - if not self._buddies.has_key(buddy.props.key): - return - - self.remove_item(self._buddies[buddy.props.key]) - del self._buddies[buddy.props.key] - - def clear(self): - for item in self.get_children(): - self.remove_item(item) - self._buddies = {} - - def __activity_appeared_cb(self, pservice, activity_ps): - activity = self._shell.get_current_activity() - if activity and activity_ps.props.id == activity.get_id(): - self._set_activity_ps(activity_ps, True) - - def _set_activity_ps(self, activity_ps, shared_activity): - if self._activity_ps == activity_ps: - return - - if self._joined_hid > 0: - self._activity_ps.disconnect(self._joined_hid) - self._joined_hid = -1 - if self._left_hid > 0: - self._activity_ps.disconnect(self._left_hid) - self._left_hid = -1 - - self._activity_ps = activity_ps - - self.clear() - - if shared_activity is True: - for buddy in activity_ps.get_joined_buddies(): - self.add_buddy(buddy) - - self._joined_hid = activity_ps.connect( - 'buddy-joined', self.__buddy_joined_cb) - self._left_hid = activity_ps.connect( - 'buddy-left', self.__buddy_left_cb) - else: - # only display myself if not shared - self.add_buddy(self._owner) - - def _pending_activity_changed_cb(self, home_model, home_activity): - if home_activity is None: - return - - activity_id = home_activity.get_activity_id() - if activity_id is None: - return - - # check if activity is shared - activity = None - for act in self._pservice.get_activities(): - if activity_id == act.props.id: - activity = act - break - if activity: - self._set_activity_ps(activity, True) - else: - self._set_activity_ps(home_activity, False) - - def __buddy_joined_cb(self, activity, buddy): - self.add_buddy(buddy) - - def __buddy_left_cb(self, activity, buddy): - self.remove_buddy(buddy) diff --git a/shell/view/frame/overlaybox.py b/shell/view/frame/overlaybox.py deleted file mode 100644 index bb74f18..0000000 --- a/shell/view/frame/overlaybox.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo - -from sugar.graphics.iconbutton import IconButton - -class OverlayBox(hippo.CanvasBox): - def __init__(self, shell): - hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL) - - self._shell = shell - - icon = IconButton(icon_name='stock-chat') - icon.connect('activated', self._overlay_clicked_cb) - self.append(icon) - - def _overlay_clicked_cb(self, item): - self._shell.toggle_chat_visibility() diff --git a/shell/view/frame/zoomtoolbar.py b/shell/view/frame/zoomtoolbar.py deleted file mode 100644 index 48e63de..0000000 --- a/shell/view/frame/zoomtoolbar.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from gettext import gettext as _ - -import gtk - -from sugar.graphics.palette import Palette -from sugar.graphics.toolbutton import ToolButton - -from view.frame.frameinvoker import FrameWidgetInvoker -from model.shellmodel import ShellModel - -class ZoomToolbar(gtk.Toolbar): - def __init__(self, shell): - gtk.Toolbar.__init__(self) - - self._shell = shell - - self.set_show_arrow(False) - - button = ToolButton(icon_name='zoom-neighborhood') - button.connect('clicked', - self._level_clicked_cb, - ShellModel.ZOOM_MESH) - self.insert(button, -1) - button.show() - - palette = Palette(_('Neighborhood')) - palette.props.invoker = FrameWidgetInvoker(button) - palette.set_group_id('frame') - button.set_palette(palette) - - button = ToolButton(icon_name='zoom-groups') - button.connect('clicked', - self._level_clicked_cb, - ShellModel.ZOOM_FRIENDS) - self.insert(button, -1) - button.show() - - palette = Palette(_('Group')) - palette.props.invoker = FrameWidgetInvoker(button) - palette.set_group_id('frame') - button.set_palette(palette) - - button = ToolButton(icon_name='zoom-home') - button.connect('clicked', - self._level_clicked_cb, - ShellModel.ZOOM_HOME) - self.insert(button, -1) - button.show() - - palette = Palette(_('Home')) - palette.props.invoker = FrameWidgetInvoker(button) - palette.set_group_id('frame') - button.set_palette(palette) - - button = ToolButton(icon_name='zoom-activity') - button.connect('clicked', - self._level_clicked_cb, - ShellModel.ZOOM_ACTIVITY) - self.insert(button, -1) - button.show() - - palette = Palette(_('Activity')) - palette.props.invoker = FrameWidgetInvoker(button) - palette.set_group_id('frame') - button.set_palette(palette) - - def _level_clicked_cb(self, button, level): - self._shell.set_zoom_level(level) diff --git a/shell/view/home/FriendView.py b/shell/view/home/FriendView.py deleted file mode 100644 index 786589f..0000000 --- a/shell/view/home/FriendView.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo -import gobject - -from sugar.graphics.icon import CanvasIcon -from sugar.graphics import style -from sugar.presence import presenceservice -from sugar import activity - -from view.BuddyIcon import BuddyIcon - -class FriendView(hippo.CanvasBox): - def __init__(self, shell, buddy, **kwargs): - hippo.CanvasBox.__init__(self, **kwargs) - - self._pservice = presenceservice.get_instance() - - self._buddy = buddy - self._buddy_icon = BuddyIcon(shell, buddy) - self._buddy_icon.props.size = style.LARGE_ICON_SIZE - self.append(self._buddy_icon) - - self._activity_icon = CanvasIcon(size=style.LARGE_ICON_SIZE) - self._activity_icon_visible = False - - if self._buddy.is_present(): - self._buddy_appeared_cb(buddy) - - self._buddy.connect('current-activity-changed', self._buddy_activity_changed_cb) - self._buddy.connect('appeared', self._buddy_appeared_cb) - self._buddy.connect('disappeared', self._buddy_disappeared_cb) - self._buddy.connect('color-changed', self._buddy_color_changed_cb) - - def _get_new_icon_name(self, ps_activity): - registry = activity.get_registry() - activity_info = registry.get_activity(ps_activity.props.type) - if activity_info: - return activity_info.icon - return None - - def _remove_activity_icon(self): - if self._activity_icon_visible: - self.remove(self._activity_icon) - self._activity_icon_visible = False - - def _buddy_activity_changed_cb(self, buddy, ps_activity=None): - if not ps_activity: - self._remove_activity_icon() - return - - # FIXME: use some sort of "unknown activity" icon rather - # than hiding the icon? - name = self._get_new_icon_name(ps_activity) - if name: - self._activity_icon.props.file_name = name - self._activity_icon.props.xo_color = buddy.get_color() - if not self._activity_icon_visible: - self.append(self._activity_icon, hippo.PACK_EXPAND) - self._activity_icon_visible = True - else: - self._remove_activity_icon() - - def _buddy_appeared_cb(self, buddy): - home_activity = self._buddy.get_current_activity() - self._buddy_activity_changed_cb(buddy, home_activity) - - def _buddy_disappeared_cb(self, buddy): - self._buddy_activity_changed_cb(buddy, None) - - def _buddy_color_changed_cb(self, buddy, color): - self._activity_icon.props.xo_color = buddy.get_color() diff --git a/shell/view/home/FriendsBox.py b/shell/view/home/FriendsBox.py deleted file mode 100644 index e9efc57..0000000 --- a/shell/view/home/FriendsBox.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import random - -import hippo -import gobject - -from sugar import profile -from sugar.graphics import style -from sugar.graphics.icon import CanvasIcon -from sugar.graphics.palette import Palette - -from view.home.FriendView import FriendView -from view.home.spreadlayout import SpreadLayout - -class FriendsBox(hippo.CanvasBox): - __gtype_name__ = 'SugarFriendsBox' - def __init__(self, shell): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff) - - self._shell = shell - self._friends = {} - - self._layout = SpreadLayout() - self.set_layout(self._layout) - - self._owner_icon = CanvasIcon(icon_name='computer-xo', cache=True, - xo_color=profile.get_color()) - self._owner_icon.props.size = style.LARGE_ICON_SIZE - palette = Palette(profile.get_nick_name()) - self._owner_icon.set_palette(palette) - self._layout.add_center(self._owner_icon) - - friends = self._shell.get_model().get_friends() - - for friend in friends: - self.add_friend(friend) - - friends.connect('friend-added', self._friend_added_cb) - friends.connect('friend-removed', self._friend_removed_cb) - - def add_friend(self, buddy_info): - icon = FriendView(self._shell, buddy_info) - self._layout.add(icon) - - self._friends[buddy_info.get_key()] = icon - - def _friend_added_cb(self, data_model, buddy_info): - self.add_friend(buddy_info) - - def _friend_removed_cb(self, data_model, key): - self._layout.remove(self._friends[key]) - del self._friends[key] diff --git a/shell/view/home/HomeBox.py b/shell/view/home/HomeBox.py deleted file mode 100644 index 8764887..0000000 --- a/shell/view/home/HomeBox.py +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -import logging -import signal -from gettext import gettext as _ -import re - -import gobject -import gtk -import hippo -import dbus - -from hardware import hardwaremanager -from sugar.graphics import style -from sugar.graphics.palette import Palette -from sugar.profile import get_profile -from sugar import env - -from view.home.activitiesdonut import ActivitiesDonut -from view.devices import deviceview -from view.home.MyIcon import MyIcon -from model.shellmodel import ShellModel -from hardware import schoolserver - -_logger = logging.getLogger('HomeBox') - -class HomeBox(hippo.CanvasBox, hippo.CanvasItem): - __gtype_name__ = 'SugarHomeBox' - - def __init__(self, shell): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff) - - self._redraw_id = None - - shell_model = shell.get_model() - - top_box = hippo.CanvasBox(box_height=style.GRID_CELL_SIZE * 2.5) - self.append(top_box) - - center_box = hippo.CanvasBox(yalign=hippo.ALIGNMENT_CENTER) - self.append(center_box, hippo.PACK_EXPAND) - - bottom_box = hippo.CanvasBox(box_height=style.GRID_CELL_SIZE * 2.5) - self.append(bottom_box) - - self._donut = ActivitiesDonut(shell) - center_box.append(self._donut) - - self._my_icon = _MyIcon(shell, style.XLARGE_ICON_SIZE) - self.append(self._my_icon, hippo.PACK_FIXED) - - self._devices_box = _DevicesBox(shell_model.get_devices()) - bottom_box.append(self._devices_box) - - shell_model.connect('notify::state', - self._shell_state_changed_cb) - - def _shell_state_changed_cb(self, model, pspec): - # FIXME implement this - if model.props.state == ShellModel.STATE_SHUTDOWN: - pass - - def do_allocate(self, width, height, origin_changed): - hippo.CanvasBox.do_allocate(self, width, height, origin_changed) - - [icon_width, icon_height] = self._my_icon.get_allocation() - self.set_position(self._my_icon, (width - icon_width) / 2, - (height - icon_height) / 2) - - _REDRAW_TIMEOUT = 5 * 60 * 1000 # 5 minutes - - def resume(self): - if self._redraw_id is None: - self._redraw_id = gobject.timeout_add(self._REDRAW_TIMEOUT, - self._redraw_activity_ring) - self._redraw_activity_ring() - - def suspend(self): - if self._redraw_id is not None: - gobject.source_remove(self._redraw_id) - self._redraw_id = None - - def _redraw_activity_ring(self): - self._donut.redraw() - return True - - def has_activities(self): - return self._donut.has_activities() - - def enable_xo_palette(self): - self._my_icon.enable_palette() - - def grab_and_rotate(self): - pass - - def rotate(self): - pass - - def release(self): - pass - -class _DevicesBox(hippo.CanvasBox): - def __init__(self, devices_model): - gobject.GObject.__init__(self, - orientation=hippo.ORIENTATION_HORIZONTAL, - xalign=hippo.ALIGNMENT_CENTER) - - self._device_icons = {} - - for device in devices_model: - self._add_device(device) - - devices_model.connect('device-appeared', - self._device_appeared_cb) - devices_model.connect('device-disappeared', - self._device_disappeared_cb) - - def _add_device(self, device): - view = deviceview.create(device) - self.append(view) - self._device_icons[device.get_id()] = view - - def _remove_device(self, device): - self.remove(self._device_icons[device.get_id()]) - del self._device_icons[device.get_id()] - - def _device_appeared_cb(self, model, device): - self._add_device(device) - - def _device_disappeared_cb(self, model, device): - self._remove_device(device) - -class _MyIcon(MyIcon): - def __init__(self, shell, scale): - MyIcon.__init__(self, scale) - - self._power_manager = None - self._shell = shell - self._profile = get_profile() - - def enable_palette(self): - palette = Palette(self._profile.nick_name) - - item = gtk.MenuItem(_('Reboot')) - item.connect('activate', self._reboot_activate_cb) - palette.menu.append(item) - item.show() - - item = gtk.MenuItem(_('Shutdown')) - item.connect('activate', self._shutdown_activate_cb) - palette.menu.append(item) - item.show() - - if not self._profile.is_registered(): - item = gtk.MenuItem(_('Register')) - item.connect('activate', self._register_activate_cb) - palette.menu.append(item) - item.show() - - item = gtk.MenuItem(_('About this XO')) - item.connect('activate', self._about_activate_cb) - palette.menu.append(item) - item.show() - - self.set_palette(palette) - - def _reboot_activate_cb(self, menuitem): - model = self._shell.get_model() - model.props.state = ShellModel.STATE_SHUTDOWN - - pm = self._get_power_manager() - - hw_manager = hardwaremanager.get_manager() - hw_manager.shutdown() - - if env.is_emulator(): - self._close_emulator() - else: - pm.Reboot() - - def _shutdown_activate_cb(self, menuitem): - model = self._shell.get_model() - model.props.state = ShellModel.STATE_SHUTDOWN - - pm = self._get_power_manager() - - hw_manager = hardwaremanager.get_manager() - hw_manager.shutdown() - - if env.is_emulator(): - self._close_emulator() - else: - pm.Shutdown() - - def _register_activate_cb(self, menuitem): - schoolserver.register_laptop() - if self._profile.is_registered(): - self.get_palette().menu.remove(menuitem) - - def _about_activate_cb(self, menuitem): - dialog = gtk.Dialog(_('About this XO'), - self.palette, - gtk.DIALOG_MODAL | - gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_OK, gtk.RESPONSE_OK)) - - not_available = _('Not available') - build = self._read_file('/boot/olpc_build') - if build is None: - build = not_available - label_build = gtk.Label('Build: %s' % build) - label_build.set_alignment(0, 0.5) - label_build.show() - dialog.vbox.pack_start(label_build) - - firmware = self._read_file('/ofw/openprom/model') - if firmware is None: - firmware = not_available - else: - firmware = re.split(" +", firmware) - if len(firmware) == 3: - firmware = firmware[1] - label_firmware = gtk.Label('Firmware: %s' % firmware) - label_firmware.set_alignment(0, 0.5) - label_firmware.show() - dialog.vbox.pack_start(label_firmware) - - serial = self._read_file('/ofw/serial-number') - if serial is None: - serial = not_available - label_serial = gtk.Label('Serial Number: %s' % serial) - label_serial.set_alignment(0, 0.5) - label_serial.show() - dialog.vbox.pack_start(label_serial) - - dialog.set_default_response(gtk.RESPONSE_OK) - dialog.connect('response', self._response_cb) - dialog.show() - - def _read_file(self, path): - if os.access(path, os.R_OK) == 0: - _logger.error('read_file() No such file or directory: %s', path) - return None - - fd = open(path, 'r') - value = fd.read() - fd.close() - if value: - value = value.strip('\n') - return value - else: - _logger.error('read_file() No information in file or directory: %s', path) - return None - - def _response_cb(self, widget, response_id): - if response_id == gtk.RESPONSE_OK: - widget.destroy() - - def _close_emulator(self): - if os.environ.has_key('SUGAR_EMULATOR_PID'): - pid = int(os.environ['SUGAR_EMULATOR_PID']) - os.kill(pid, signal.SIGTERM) - - def _get_power_manager(self): - if self._power_manager is None: - bus = dbus.SystemBus() - proxy = bus.get_object('org.freedesktop.Hal', - '/org/freedesktop/Hal/devices/computer') - self._power_manager = dbus.Interface(proxy, \ - 'org.freedesktop.Hal.Device.SystemPowerManagement') - - return self._power_manager diff --git a/shell/view/home/HomeWindow.py b/shell/view/home/HomeWindow.py deleted file mode 100644 index f1f46e9..0000000 --- a/shell/view/home/HomeWindow.py +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import hippo -import cairo - -from sugar.graphics import style - -from view.home.MeshBox import MeshBox -from view.home.HomeBox import HomeBox -from view.home.FriendsBox import FriendsBox -from view.home.transitionbox import TransitionBox -from model.shellmodel import ShellModel - -_HOME_PAGE = 0 -_FRIENDS_PAGE = 1 -_MESH_PAGE = 2 -_TRANSITION_PAGE = 3 - -class HomeWindow(gtk.Window): - def __init__(self, shell): - gtk.Window.__init__(self) - - self._shell = shell - self._active = False - self._level = ShellModel.ZOOM_HOME - - self._canvas = hippo.Canvas() - self.add(self._canvas) - self._canvas.show() - - self.set_default_size(gtk.gdk.screen_width(), - gtk.gdk.screen_height()) - - self.realize() - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP) - self.connect("key-release-event", self._key_release_cb) - self.connect('focus-in-event', self._focus_in_cb) - self.connect('focus-out-event', self._focus_out_cb) - - self._enter_sid = self.connect('enter-notify-event', - self._enter_notify_event_cb) - self._leave_sid = self.connect('leave-notify-event', - self._leave_notify_event_cb) - self._motion_sid = self.connect('motion-notify-event', - self._motion_notify_event_cb) - - self._home_box = HomeBox(shell) - self._friends_box = FriendsBox(shell) - self._mesh_box = MeshBox(shell) - self._transition_box = TransitionBox() - - self._activate_view() - self._canvas.set_root(self._home_box) - - self._transition_box.connect('completed', - self._transition_completed_cb) - - def _enter_notify_event_cb(self, window, event): - if event.x != gtk.gdk.screen_width() / 2 or \ - event.y != gtk.gdk.screen_height() / 2: - self._mouse_moved() - - def _leave_notify_event_cb(self, window, event): - self._mouse_moved() - - def _motion_notify_event_cb(self, window, event): - self._mouse_moved() - - # We want to enable the XO palette only when the user - # moved away from the default mouse position (screen center). - def _mouse_moved(self): - self._home_box.enable_xo_palette() - self.disconnect(self._leave_sid) - self.disconnect(self._motion_sid) - self.disconnect(self._enter_sid) - - def _key_release_cb(self, widget, event): - keyname = gtk.gdk.keyval_name(event.keyval) - if keyname == "Alt_L": - self._home_box.release() - - def _deactivate_view(self): - if self._level == ShellModel.ZOOM_HOME: - self._home_box.suspend() - elif self._level == ShellModel.ZOOM_MESH: - self._mesh_box.suspend() - - def _activate_view(self): - if self._level == ShellModel.ZOOM_HOME: - self._home_box.resume() - elif self._level == ShellModel.ZOOM_MESH: - self._mesh_box.resume() - - def _focus_in_cb(self, widget, event): - self._activate_view() - - def _focus_out_cb(self, widget, event): - self._deactivate_view() - - def set_zoom_level(self, level): - self._deactivate_view() - self._level = level - self._activate_view() - - self._canvas.set_root(self._transition_box) - - if level == ShellModel.ZOOM_HOME: - size = style.XLARGE_ICON_SIZE - elif level == ShellModel.ZOOM_FRIENDS: - size = style.LARGE_ICON_SIZE - elif level == ShellModel.ZOOM_MESH: - size = style.STANDARD_ICON_SIZE - - self._transition_box.set_size(size) - - def _transition_completed_cb(self, transition_box): - if self._level == ShellModel.ZOOM_HOME: - self._canvas.set_root(self._home_box) - elif self._level == ShellModel.ZOOM_FRIENDS: - self._canvas.set_root(self._friends_box) - elif self._level == ShellModel.ZOOM_MESH: - self._canvas.set_root(self._mesh_box) - self._mesh_box.focus_search_entry() - - def get_home_box(self): - return self._home_box diff --git a/shell/view/home/Makefile.am b/shell/view/home/Makefile.am deleted file mode 100644 index 6916806..0000000 --- a/shell/view/home/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -sugardir = $(pkgdatadir)/shell/view/home -sugar_PYTHON = \ - __init__.py \ - activitiesdonut.py \ - FriendView.py \ - FriendsBox.py \ - HomeBox.py \ - HomeWindow.py \ - MeshBox.py \ - MyIcon.py \ - proc_smaps.py \ - snowflakelayout.py \ - spreadlayout.py \ - transitionbox.py diff --git a/shell/view/home/MeshBox.py b/shell/view/home/MeshBox.py deleted file mode 100644 index 3b7c4a7..0000000 --- a/shell/view/home/MeshBox.py +++ /dev/null @@ -1,615 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import random -from gettext import gettext as _ -import logging - -import hippo -import gobject -import gtk - -from sugar.graphics.icon import CanvasIcon -from sugar.graphics import style -from sugar.graphics.icon import get_icon_state -from sugar.graphics import style -from sugar.graphics import palette -from sugar.graphics import iconentry -from sugar.graphics.menuitem import MenuItem -from sugar import profile - -from model import accesspointmodel -from model.devices.network import mesh -from model.devices.network import wireless -from hardware import hardwaremanager -from hardware import nmclient -from view.BuddyIcon import BuddyIcon -from view.pulsingicon import PulsingIcon -from view.home.snowflakelayout import SnowflakeLayout -from view.home.spreadlayout import SpreadLayout - -from hardware.nmclient import NM_802_11_CAP_PROTO_WEP, NM_802_11_CAP_PROTO_WPA, NM_802_11_CAP_PROTO_WPA2 - - -_ICON_NAME = 'network-wireless' - -class AccessPointView(PulsingIcon): - def __init__(self, model, mesh_device=None): - PulsingIcon.__init__(self, size=style.STANDARD_ICON_SIZE, cache=True) - self._model = model - self._meshdev = mesh_device - self._disconnect_item = None - self._greyed_out = False - - self.connect('activated', self._activate_cb) - - model.connect('notify::strength', self._strength_changed_cb) - model.connect('notify::name', self._name_changed_cb) - model.connect('notify::state', self._state_changed_cb) - - (stroke, fill) = model.get_nm_network().get_colors() - self._device_stroke = stroke - self._device_fill = fill - - self._palette = self._create_palette() - self.set_palette(self._palette) - - self._update_icon() - self._update_name() - self._update_state() - - # Update badge - caps = model.props.capabilities - if model.get_nm_network().is_favorite(): - self.props.badge_name = "emblem-favorite" - elif (caps & NM_802_11_CAP_PROTO_WEP) or (caps & NM_802_11_CAP_PROTO_WPA) or (caps & NM_802_11_CAP_PROTO_WPA2): - self.props.badge_name = "emblem-locked" - - def _create_palette(self): - p = palette.Palette(self._model.props.name, menu_after_content=True) - if not self._meshdev: - return p - - # Only show disconnect when there's a mesh device, because mesh takes - # priority over the normal wireless device. NM doesn't have a "disconnect" - # method for a device either (for various reasons) so this doesn't - # have a good mapping - self._disconnect_item = gtk.MenuItem(_('Disconnect...')) - self._disconnect_item.connect('activate', self._disconnect_activate_cb) - p.menu.append(self._disconnect_item) - if self._model.props.state == accesspointmodel.STATE_CONNECTED: - self._disconnect_item.show() - return p - - def _disconnect_activate_cb(self, menuitem): - # Disconnection for an AP means activating the default mesh device - network_manager = hardwaremanager.get_network_manager() - if network_manager and self._meshdev: - network_manager.set_active_device(self._meshdev) - - def _strength_changed_cb(self, model, pspec): - self._update_icon() - - def _name_changed_cb(self, model, pspec): - self._update_name() - - def _state_changed_cb(self, model, pspec): - self._update_state() - - def _activate_cb(self, icon): - network_manager = hardwaremanager.get_network_manager() - if network_manager: - device = self._model.get_nm_device() - network = self._model.get_nm_network() - network_manager.set_active_device(device, network) - - def _update_name(self): - self._palette.set_primary_text(self._model.props.name) - - def _update_icon(self): - icon_name = get_icon_state(_ICON_NAME, self._model.props.strength) - if icon_name: - self.props.icon_name = icon_name - - def _update_state(self): - if self._model.props.state == accesspointmodel.STATE_CONNECTING: - if self._disconnect_item: - self._disconnect_item.hide() - self.props.pulse_time = 1.0 - self.props.colors = [ - [ style.Color(self._device_stroke).get_svg(), - style.Color(self._device_fill).get_svg() ], - [ style.Color(self._device_stroke).get_svg(), - '#e2e2e2' ] - ] - elif self._model.props.state == accesspointmodel.STATE_CONNECTED: - if self._disconnect_item: - self._disconnect_item.show() - self.props.pulse_time = 0.0 - self.props.colors = [ - [ '#ffffff', - style.Color(self._device_fill).get_svg() ], - [ '#ffffff', - style.Color(self._device_fill).get_svg() ] - ] - elif self._model.props.state == accesspointmodel.STATE_NOTCONNECTED: - if self._disconnect_item: - self._disconnect_item.hide() - self.props.pulse_time = 0.0 - self.props.colors = [ - [ style.Color(self._device_stroke).get_svg(), - style.Color(self._device_fill).get_svg() ] - ] - - if self._greyed_out: - self.props.pulse_time = 0.0 - self.props.colors = [['#D5D5D5', '#D5D5D5']] - - def set_filter(self, query): - self._greyed_out = self._model.props.name.lower().find(query) == -1 - self._update_state() - -_MESH_ICON_NAME = 'network-mesh' - -class MeshDeviceView(PulsingIcon): - def __init__(self, nm_device, channel): - if not channel in [1, 6, 11]: - raise ValueError("Invalid channel %d" % channel) - - PulsingIcon.__init__(self, size=style.STANDARD_ICON_SIZE, - icon_name=_MESH_ICON_NAME, cache=True) - - self._nm_device = nm_device - self.channel = channel - self.props.badge_name = "badge-channel-%d" % self.channel - self._greyed_out = False - - self._disconnect_item = None - self._palette = self._create_palette() - self.set_palette(self._palette) - - mycolor = profile.get_color() - self._device_fill = mycolor.get_fill_color() - self._device_stroke = mycolor.get_stroke_color() - - self.connect('activated', self._activate_cb) - - self._nm_device.connect('state-changed', self._state_changed_cb) - self._nm_device.connect('activation-stage-changed', self._state_changed_cb) - self._update_state() - - def _create_palette(self): - p = palette.Palette(_("Mesh Network") + " " + str(self.channel), menu_after_content=True) - - self._disconnect_item = gtk.MenuItem(_('Disconnect...')) - self._disconnect_item.connect('activate', self._disconnect_activate_cb) - p.menu.append(self._disconnect_item) - - state = self._nm_device.get_state() - chan = wireless.freq_to_channel(self._nm_device.get_frequency()) - if state == nmclient.DEVICE_STATE_ACTIVATED and chan == self.channel: - self._disconnect_item.show() - return p - - def _disconnect_activate_cb(self, menuitem): - network_manager = hardwaremanager.get_network_manager() - if network_manager: - network_manager.set_active_device(self._nm_device) - - def _activate_cb(self, icon): - network_manager = hardwaremanager.get_network_manager() - if network_manager: - freq = wireless.channel_to_freq(self.channel) - network_manager.set_active_device(self._nm_device, mesh_freq=freq) - - def _state_changed_cb(self, model): - self._update_state() - - def _update_state(self): - state = self._nm_device.get_state() - chan = wireless.freq_to_channel(self._nm_device.get_frequency()) - if self._greyed_out: - self.props.colors = [['#D5D5D5', '#D5D5D5']] - elif state == nmclient.DEVICE_STATE_ACTIVATING and chan == self.channel: - self._disconnect_item.hide() - self.props.pulse_time = 0.75 - self.props.colors = [ - [ style.Color(self._device_stroke).get_svg(), - style.Color(self._device_fill).get_svg() ], - [ style.Color(self._device_stroke).get_svg(), - '#e2e2e2' ] - ] - elif state == nmclient.DEVICE_STATE_ACTIVATED and chan == self.channel: - self._disconnect_item.show() - self.props.pulse_time = 0.0 - self.props.colors = [ - [ '#ffffff', - style.Color(self._device_fill).get_svg() ], - [ '#ffffff', - style.Color(self._device_fill).get_svg() ] - ] - elif state == nmclient.DEVICE_STATE_INACTIVE or chan != self.channel: - self._disconnect_item.hide() - self.props.pulse_time = 0.0 - self.props.colors = [ - [ style.Color(self._device_stroke).get_svg(), - style.Color(self._device_fill).get_svg() ] - ] - else: - raise RuntimeError("Shouldn't get here") - - def set_filter(self, query): - self._greyed_out = (query != '') - self._update_state() - -class ActivityView(hippo.CanvasBox): - def __init__(self, shell, model): - hippo.CanvasBox.__init__(self) - - self._shell = shell - self._model = model - self._icons = {} - - self._layout = SnowflakeLayout() - self.set_layout(self._layout) - - self._icon = self._create_icon() - self._layout.add(self._icon, center=True) - - self._update_palette() - - activity = self._model.activity - activity.connect('notify::name', self._name_changed_cb) - activity.connect('notify::color', self._color_changed_cb) - activity.connect('notify::private', self._private_changed_cb) - activity.connect('joined', self._joined_changed_cb) - #FIXME: 'joined' signal not working, see #5032 - - def _create_icon(self): - icon = CanvasIcon(file_name=self._model.get_icon_name(), - xo_color=self._model.get_color(), cache=True, - size=style.STANDARD_ICON_SIZE) - icon.connect('activated', self._clicked_cb) - return icon - - def _create_palette(self): - p = palette.Palette(self._model.activity.props.name) - - private = self._model.activity.props.private - joined = self._model.activity.props.joined - - if joined: - item = MenuItem(_('Resume'), 'activity-start') - item.connect('activate', self._clicked_cb) - item.show() - p.menu.append(item) - elif not private: - item = MenuItem(_('Join'), 'activity-start') - item.connect('activate', self._clicked_cb) - item.show() - p.menu.append(item) - - return p - - def _update_palette(self): - self._palette = self._create_palette() - self._icon.set_palette(self._palette) - - def has_buddy_icon(self, key): - return self._icons.has_key(key) - - def add_buddy_icon(self, key, icon): - self._icons[key] = icon - self._layout.add(icon) - - def remove_buddy_icon(self, key): - icon = self._icons[key] - del self._icons[key] - icon.destroy() - - def _clicked_cb(self, item): - bundle_id = self._model.get_bundle_id() - self._shell.join_activity(bundle_id, self._model.get_id()) - - def set_filter(self, query): - text_to_check = self._model.activity.props.name.lower() + \ - self._model.activity.props.type.lower() - if text_to_check.find(query) == -1: - self._icon.props.stroke_color = '#D5D5D5' - self._icon.props.fill_color = '#E5E5E5' - else: - self._icon.props.xo_color = self._model.get_color() - - for key, icon in self._icons.iteritems(): - if hasattr(icon, 'set_filter'): - icon.set_filter(query) - - def _name_changed_cb(self, activity, pspec): - self._update_palette() - - def _color_changed_cb(self, activity, pspec): - self._layout.remove(self._icon) - self._icon = self._create_icon() - self._layout.add(self._icon, center=True) - self._icon.set_palette(self._palette) - - def _private_changed_cb(self, activity, pspec): - self._update_palette() - - def _joined_changed_cb(self, widget, event): - logging.debug('ActivityView._joined_changed_cb: AAAA!!!!') - -_AUTOSEARCH_TIMEOUT = 1000 - -class MeshToolbar(gtk.Toolbar): - __gtype_name__ = 'MeshToolbar' - - __gsignals__ = { - 'query-changed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([str])) - } - - def __init__(self): - gtk.Toolbar.__init__(self) - - self._query = None - self._autosearch_timer = None - - self._add_separator() - - tool_item = gtk.ToolItem() - tool_item.set_expand(True) - self.insert(tool_item, -1) - tool_item.show() - - self._search_entry = iconentry.IconEntry() - self._search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'system-search') - self._search_entry.add_clear_button() - self._search_entry.connect('activate', self._entry_activated_cb) - self._search_entry.connect('changed', self._entry_changed_cb) - tool_item.add(self._search_entry) - self._search_entry.show() - - self._add_separator() - - def _add_separator(self): - separator = gtk.SeparatorToolItem() - separator.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE) - separator.props.draw = False - self.insert(separator, -1) - separator.show() - - def _entry_activated_cb(self, entry): - if self._autosearch_timer: - gobject.source_remove(self._autosearch_timer) - new_query = entry.props.text - if self._query != new_query: - self._query = new_query - self.emit('query-changed', self._query) - - def _entry_changed_cb(self, entry): - if not entry.props.text: - entry.activate() - return - - if self._autosearch_timer: - gobject.source_remove(self._autosearch_timer) - self._autosearch_timer = gobject.timeout_add(_AUTOSEARCH_TIMEOUT, - self._autosearch_timer_cb) - - def _autosearch_timer_cb(self): - logging.debug('_autosearch_timer_cb') - self._autosearch_timer = None - self._search_entry.activate() - return False - -class MeshBox(hippo.CanvasBox): - def __init__(self, shell): - hippo.CanvasBox.__init__(self) - - self._shell = shell - self._model = shell.get_model().get_mesh() - self._buddies = {} - self._activities = {} - self._access_points = {} - self._mesh = {} - self._buddy_to_activity = {} - self._suspended = True - self._query = '' - - self._toolbar = MeshToolbar() - self._toolbar.connect('query-changed', self._toolbar_query_changed_cb) - self.append(hippo.CanvasWidget(widget=self._toolbar)) - - self._layout_box = hippo.CanvasBox(background_color=0xe2e2e2ff) - self.append(self._layout_box, hippo.PACK_EXPAND) - - self._layout = SpreadLayout() - self._layout_box.set_layout(self._layout) - - for buddy_model in self._model.get_buddies(): - self._add_alone_buddy(buddy_model) - - self._model.connect('buddy-added', self._buddy_added_cb) - self._model.connect('buddy-removed', self._buddy_removed_cb) - self._model.connect('buddy-moved', self._buddy_moved_cb) - - for activity_model in self._model.get_activities(): - self._add_activity(activity_model) - - self._model.connect('activity-added', self._activity_added_cb) - self._model.connect('activity-removed', self._activity_removed_cb) - - for ap_model in self._model.get_access_points(): - self._add_access_point(ap_model) - - self._model.connect('access-point-added', - self._access_point_added_cb) - self._model.connect('access-point-removed', - self._access_point_removed_cb) - - if self._model.get_mesh(): - self._mesh_added_cb(self._model, self._model.get_mesh()) - - self._model.connect('mesh-added', - self._mesh_added_cb) - self._model.connect('mesh-removed', - self._mesh_removed_cb) - - def _mesh_added_cb(self, model, meshdev): - self._add_mesh_icon(meshdev, 1) - self._add_mesh_icon(meshdev, 6) - self._add_mesh_icon(meshdev, 11) - - def _mesh_removed_cb(self, model): - self._remove_mesh_icon(1) - self._remove_mesh_icon(6) - self._remove_mesh_icon(11) - - def _buddy_added_cb(self, model, buddy_model): - self._add_alone_buddy(buddy_model) - - def _buddy_removed_cb(self, model, buddy_model): - self._remove_buddy(buddy_model) - - def _buddy_moved_cb(self, model, buddy_model, activity_model): - # Owner doesn't move from the center - if buddy_model.is_owner(): - return - self._move_buddy(buddy_model, activity_model) - - def _activity_added_cb(self, model, activity_model): - self._add_activity(activity_model) - - def _activity_removed_cb(self, model, activity_model): - self._remove_activity(activity_model) - - def _access_point_added_cb(self, model, ap_model): - self._add_access_point(ap_model) - - def _access_point_removed_cb(self, model, ap_model): - self._remove_access_point(ap_model) - - def _add_mesh_icon(self, meshdev, channel): - if self._mesh.has_key(channel): - self._remove_mesh_icon(channel) - if not meshdev: - return - self._mesh[channel] = MeshDeviceView(meshdev, channel) - self._layout.add(self._mesh[channel]) - - def _remove_mesh_icon(self, channel): - if not self._mesh.has_key(channel): - return - self._layout.remove(self._mesh[channel]) - del self._mesh[channel] - - def _add_alone_buddy(self, buddy_model): - icon = BuddyIcon(self._shell, buddy_model) - if buddy_model.is_owner(): - vertical_offset = - style.GRID_CELL_SIZE - self._layout.add_center(icon, vertical_offset) - else: - self._layout.add(icon) - - if hasattr(icon, 'set_filter'): - icon.set_filter(self._query) - - self._buddies[buddy_model.get_key()] = icon - - def _remove_alone_buddy(self, buddy_model): - icon = self._buddies[buddy_model.get_key()] - self._layout.remove(icon) - del self._buddies[buddy_model.get_key()] - icon.destroy() - - def _remove_buddy(self, buddy_model): - key = buddy_model.get_key() - if self._buddies.has_key(key): - self._remove_alone_buddy(buddy_model) - else: - for activity in self._activities.values(): - if activity.has_buddy_icon(key): - activity.remove_buddy_icon(key) - - def _move_buddy(self, buddy_model, activity_model): - key = buddy_model.get_key() - - self._remove_buddy(buddy_model) - - if activity_model == None: - self._add_alone_buddy(buddy_model) - elif activity_model.get_id() in self._activities: - activity = self._activities[activity_model.get_id()] - - icon = BuddyIcon(self._shell, buddy_model, - style.SMALL_ICON_SIZE) - activity.add_buddy_icon(buddy_model.get_key(), icon) - - if hasattr(icon, 'set_filter'): - icon.set_filter(self._query) - - def _add_activity(self, activity_model): - icon = ActivityView(self._shell, activity_model) - self._layout.add(icon) - - if hasattr(icon, 'set_filter'): - icon.set_filter(self._query) - - self._activities[activity_model.get_id()] = icon - - def _remove_activity(self, activity_model): - icon = self._activities[activity_model.get_id()] - self._layout.remove(icon) - del self._activities[activity_model.get_id()] - icon.destroy() - - def _add_access_point(self, ap_model): - meshdev = self._model.get_mesh() - icon = AccessPointView(ap_model, meshdev) - self._layout.add(icon) - - if hasattr(icon, 'set_filter'): - icon.set_filter(self._query) - - self._access_points[ap_model.get_id()] = icon - - def _remove_access_point(self, ap_model): - icon = self._access_points[ap_model.get_id()] - self._layout.remove(icon) - del self._access_points[ap_model.get_id()] - - def suspend(self): - if not self._suspended: - self._suspended = True - for ap in self._access_points.values(): - ap.props.paused = True - - def resume(self): - if self._suspended: - self._suspended = False - for ap in self._access_points.values(): - ap.props.paused = False - - def _toolbar_query_changed_cb(self, toolbar, query): - self._query = query.lower() - for icon in self._layout_box.get_children(): - if hasattr(icon, 'set_filter'): - icon.set_filter(self._query) - - def focus_search_entry(self): - self._toolbar._search_entry.grab_focus() diff --git a/shell/view/home/MyIcon.py b/shell/view/home/MyIcon.py deleted file mode 100644 index af0f6ce..0000000 --- a/shell/view/home/MyIcon.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -from sugar.graphics.icon import CanvasIcon -from sugar import profile - -class MyIcon(CanvasIcon): - def __init__(self, size): - CanvasIcon.__init__(self, size=size, - icon_name='computer-xo', - xo_color=profile.get_color()) diff --git a/shell/view/home/__init__.py b/shell/view/home/__init__.py deleted file mode 100644 index a9dd95a..0000000 --- a/shell/view/home/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - diff --git a/shell/view/home/activitiesdonut.py b/shell/view/home/activitiesdonut.py deleted file mode 100755 index 8e09006..0000000 --- a/shell/view/home/activitiesdonut.py +++ /dev/null @@ -1,556 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import colorsys -from gettext import gettext as _ -import logging -import math -import os - -import hippo -import gobject -import gtk - -from sugar.graphics.icon import CanvasIcon -from sugar.graphics.menuitem import MenuItem -from sugar.graphics.palette import Palette -from sugar.graphics import style -from sugar.graphics import xocolor -from sugar import profile -import proc_smaps - -_MAX_ACTIVITIES = 6 -_MIN_WEDGE_SIZE = 1.0 / _MAX_ACTIVITIES -_DONUT_SIZE = style.zoom(450) - -# TODO: rgb_to_html and html_to_rgb are useful elsewhere -# we should put this in a common module -def rgb_to_html(r, g, b): - """ (r, g, b) tuple (in float format) -> #RRGGBB """ - return '#%02x%02x%02x' % (int(r * 255), int(g * 255), int(b * 255)) - -def html_to_rgb(html_color): - """ #RRGGBB -> (r, g, b) tuple (in float format) """ - html_color = html_color.strip() - if html_color[0] == '#': - html_color = html_color[1:] - if len(html_color) != 6: - raise ValueError, "input #%s is not in #RRGGBB format" % html_color - r, g, b = html_color[:2], html_color[2:4], html_color[4:] - r, g, b = [int(n, 16) for n in (r, g, b)] - r, g, b = (r / 255.0, g / 255.0, b / 255.0) - return (r, g, b) - -class ActivityIcon(CanvasIcon): - _INTERVAL = 200 - - __gsignals__ = { - 'resume': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])), - 'stop': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) - } - - def __init__(self, activity): - self._orig_color = activity.get_icon_color() - self._icon_colors = self._compute_icon_colors() - - self._direction = 0 - self._level_max = len(self._icon_colors) - 1 - self._level = self._level_max - color = self._icon_colors[self._level] - - CanvasIcon.__init__(self, xo_color=color, cache=True, - size=style.MEDIUM_ICON_SIZE) - - icon_path = activity.get_icon_path() - if icon_path: - self.props.file_name = icon_path - else: - self.props.icon_name = 'image-missing' - - self._activity = activity - self._pulse_id = 0 - - self.size = _MIN_WEDGE_SIZE - - palette = Palette(_('Starting...')) - self.set_palette(palette) - - if activity.props.launching: - self._start_pulsing() - activity.connect('notify::launching', self._launching_changed_cb) - else: - self._setup_palette() - - def _setup_palette(self): - palette = self.get_palette() - - palette.set_primary_text(self._activity.get_title()) - - resume_menu_item = MenuItem(_('Resume'), 'activity-start') - resume_menu_item.connect('activate', self._resume_activate_cb) - palette.menu.append(resume_menu_item) - resume_menu_item.show() - - # FIXME: kludge - if self._activity.get_type() != "org.laptop.JournalActivity": - stop_menu_item = MenuItem(_('Stop'), 'activity-stop') - stop_menu_item.connect('activate', self._stop_activate_cb) - palette.menu.append(stop_menu_item) - stop_menu_item.show() - - def _launching_changed_cb(self, activity, pspec): - if not activity.props.launching: - self._stop_pulsing() - self._setup_palette() - - def __del__(self): - self._cleanup() - - def _cleanup(self): - if self._pulse_id: - gobject.source_remove(self._pulse_id) - self._pulse_id = 0 - - def _compute_icon_colors(self): - _LEVEL_MAX = 1.6 - _LEVEL_STEP = 0.16 - _LEVEL_MIN = 0.0 - icon_colors = {} - level = _LEVEL_MIN - for i in range(0, int(_LEVEL_MAX / _LEVEL_STEP)): - icon_colors[i] = self._get_icon_color_for_level(level) - level += _LEVEL_STEP - return icon_colors - - def _get_icon_color_for_level(self, level): - factor = math.sin(level) - h, s, v = colorsys.rgb_to_hsv(*html_to_rgb(self._orig_color.get_fill_color())) - new_fill = rgb_to_html(*colorsys.hsv_to_rgb(h, s * factor, v)) - h, s, v = colorsys.rgb_to_hsv(*html_to_rgb(self._orig_color.get_stroke_color())) - new_stroke = rgb_to_html(*colorsys.hsv_to_rgb(h, s * factor, v)) - return xocolor.XoColor("%s,%s" % (new_stroke, new_fill)) - - def _pulse_cb(self): - if self._direction == 1: - self._level += 1 - if self._level > self._level_max: - self._direction = 0 - self._level = self._level_max - elif self._direction == 0: - self._level -= 1 - if self._level <= 0: - self._direction = 1 - self._level = 0 - - self.props.xo_color = self._icon_colors[self._level] - self.emit_paint_needed(0, 0, -1, -1) - return True - - def _start_pulsing(self): - if self._pulse_id: - return - - self._pulse_id = gobject.timeout_add(self._INTERVAL, self._pulse_cb) - - def _stop_pulsing(self): - if not self._pulse_id: - return - - self._cleanup() - self._level = 100.0 - self.props.xo_color = self._orig_color - - def _resume_activate_cb(self, menuitem): - self.emit('resume') - - def _stop_activate_cb(self, menuitem): - self.emit('stop') - - def get_activity(self): - return self._activity - -class ActivitiesDonut(hippo.CanvasBox, hippo.CanvasItem): - __gtype_name__ = 'SugarActivitiesDonut' - def __init__(self, shell, **kwargs): - hippo.CanvasBox.__init__(self, **kwargs) - - self._activities = [] - self._shell = shell - self._angles = [] - self._shell_mappings = proc_smaps.get_shared_mapping_names(os.getpid()) - - self._layout = _Layout() - self.set_layout(self._layout) - - self._model = shell.get_model().get_home() - self._model.connect('activity-added', self._activity_added_cb) - self._model.connect('activity-removed', self._activity_removed_cb) - self._model.connect('pending-activity-changed', self._activity_changed_cb) - - self.connect('button-release-event', self._button_release_event_cb) - - def _get_icon_from_activity(self, activity): - for icon in self._activities: - if icon.get_activity().equals(activity): - return icon - - def _activity_added_cb(self, model, activity): - self._add_activity(activity) - - def _activity_removed_cb(self, model, activity): - self._remove_activity(activity) - - def _activity_changed_cb(self, model, activity): - self.emit_paint_needed(0, 0, -1, -1) - - def _remove_activity(self, activity): - icon = self._get_icon_from_activity(activity) - if icon: - self.remove(icon) - icon._cleanup() - self._activities.remove(icon) - self._compute_angles() - - def _add_activity(self, activity): - icon = ActivityIcon(activity) - icon.connect('resume', self._activity_icon_resumed_cb) - icon.connect('stop', self._activity_icon_stop_cb) - self.append(icon, hippo.PACK_FIXED) - - self._activities.append(icon) - self._compute_angles() - - def _activity_icon_resumed_cb(self, icon): - activity = icon.get_activity() - activity_host = self._shell.get_activity(activity.get_activity_id()) - if activity_host: - activity_host.present() - else: - logging.error("Could not find ActivityHost for activity %s" % - activity.get_activity_id()) - - def _activity_icon_stop_cb(self, icon): - activity = icon.get_activity() - activity_host = self._shell.get_activity(activity.get_activity_id()) - if activity_host: - activity_host.close() - else: - logging.error("Could not find ActivityHost for activity %s" % - activity.get_activity_id()) - - def _get_activity(self, x, y): - # Compute the distance from the center. - [width, height] = self.get_allocation() - x -= width / 2 - y -= height / 2 - r = math.hypot(x, y) - - # Ignore the click if it's not inside the donut - if r < self._get_inner_radius() or r > self._get_radius(): - return None - - # Now figure out where in the donut the click was. - angle = math.atan2(-y, -x) + math.pi - - # Unfortunately, _get_angles() doesn't count from 0 to 2pi, it - # counts from roughly pi/2 to roughly 5pi/2. So we have to - # compare its return values against both angle and angle+2pi - high_angle = angle + 2 * math.pi - - for index, activity in enumerate(self._model): - [angle_start, angle_end] = self._get_angles(index) - if angle_start < angle and angle_end > angle: - return activity - elif angle_start < high_angle and angle_end > high_angle: - return activity - - return None - - def _button_release_event_cb(self, item, event): - activity = self._get_activity(event.x, event.y) - if activity is None: - return False - - activity_host = self._shell.get_activity(activity.get_activity_id()) - if activity_host: - activity_host.present() - return True - - def _set_fixed_arc_size(self): - """Set fixed arc size""" - - n = len(self._activities) - if n > _MAX_ACTIVITIES: - size = 1.0 / n - else: - size = 1.0 / _MAX_ACTIVITIES - - for act in self._activities: - act.size = size - - def _update_activity_sizes(self): - """Currently the size of an activity on the donut does not - represent it's memory usage. This is disabled because it was - either not working perfectly or a little confusing. See #3605""" - self._set_fixed_arc_size() - return - - # Get the memory mappings of each process that hosts an - # activity, and count how many activity instances each - # activity process hosts, and how many processes are mapping - # each shared library, etc - process_mappings = {} - num_activities = {} - num_mappings = {} - unknown_size_activities = 0 - for activity in self._model: - pid = activity.get_pid() - if not pid: - # Still starting up, hasn't opened a window yet - unknown_size_activities += 1 - continue - - if num_activities.has_key(pid): - num_activities[pid] += 1 - continue - - try: - mappings = proc_smaps.get_mappings(pid, self._shell_mappings) - for mapping in mappings: - if mapping.shared > 0: - if num_mappings.has_key(mapping.name): - num_mappings[mapping.name] += 1 - else: - num_mappings[mapping.name] = 1 - process_mappings[pid] = mappings - num_activities[pid] = 1 - except Exception, e: - logging.warn('ActivitiesDonut: could not read /proc/%s/smaps: %r' - % (pid, e)) - - # Compute total memory used per process - process_size = {} - total_activity_size = 0 - for activity in self._model: - pid = activity.get_pid() - if not process_mappings.has_key(pid): - continue - - mappings = process_mappings[pid] - size = 0 - for mapping in mappings: - size += mapping.private - if mapping.shared > 0: - num = num_mappings[mapping.name] - size += mapping.shared / num - process_size[pid] = size - total_activity_size += size / num_activities[pid] - - # Now, see how much free memory is left. - free_memory = 0 - try: - meminfo = open('/proc/meminfo') - for line in meminfo.readlines(): - if line.startswith('MemFree:') or line.startswith('SwapFree:'): - free_memory += int(line[9:-3]) - meminfo.close() - except IOError: - logging.warn('ActivitiesDonut: could not read /proc/meminfo') - except (IndexError, ValueError): - logging.warn('ActivitiesDonut: /proc/meminfo was not in ' + - 'expected format') - - total_memory = float(total_activity_size + free_memory) - - # Each activity has an ideal size of: - # process_size[pid] / num_activities[pid] / total_memory - # (And the free memory wedge is ideally free_memory / - # total_memory) However, no activity wedge is allowed to be - # smaller than _MIN_WEDGE_SIZE. This means the small - # activities will use up extra space, which would make the - # ring overflow. We fix that by reducing the large activities - # and the free space proportionately. If there are activities - # of unknown size, they are simply carved out of the free - # space. - - free_percent = free_memory / total_memory - activity_sizes = [] - overflow = 0.0 - reducible = free_percent - for icon in self._activities: - pid = icon.get_activity().get_pid() - if process_size.has_key(pid): - icon.size = (process_size[pid] / num_activities[pid] / - total_memory) - if icon.size < _MIN_WEDGE_SIZE: - overflow += _MIN_WEDGE_SIZE - icon.size - icon.size = _MIN_WEDGE_SIZE - else: - reducible += icon.size - _MIN_WEDGE_SIZE - else: - icon.size = _MIN_WEDGE_SIZE - - if reducible > 0.0: - reduction = overflow / reducible - if unknown_size_activities > 0: - unknown_percent = _MIN_WEDGE_SIZE * unknown_size_activities - if (free_percent * (1 - reduction) < unknown_percent): - # The free wedge won't be large enough to fit the - # unknown-size activities. So adjust things - overflow += unknown_percent - free_percent - reducible -= free_percent - reduction = overflow / reducible - - if reduction > 0.0: - for icon in self._activities: - if icon.size > _MIN_WEDGE_SIZE: - icon.size -= (icon.size - _MIN_WEDGE_SIZE) * reduction - - def _compute_angles(self): - self._angles = [] - if len(self._activities) == 0: - return - - # Normally we don't _update_activity_sizes() when launching a - # new activity; but if the new wedge would overflow the ring - # then we have no choice. - total = reduce(lambda s1,s2: s1 + s2, - [icon.size for icon in self._activities]) - if total > 1.0: - self._update_activity_sizes() - - # The first wedge (Journal) should be centered at 6 o'clock - size = self._activities[0].size or _MIN_WEDGE_SIZE - angle = (math.pi - size * 2 * math.pi) / 2 - self._angles.append(angle) - - for icon in self._activities: - size = icon.size or _MIN_WEDGE_SIZE - self._angles.append(self._angles[-1] + size * 2 * math.pi) - - def redraw(self): - self._update_activity_sizes() - self._compute_angles() - self.emit_request_changed() - - def _get_angles(self, index): - return [self._angles[index], - self._angles[(index + 1) % len(self._angles)]] - - def _get_radius(self): - [width, height] = self.get_allocation() - return min(width, height) / 2 - - def _get_inner_radius(self): - return self._get_radius() * 0.5 - - def do_paint_below_children(self, cr, damaged_box): - [width, height] = self.get_allocation() - - cr.translate(width / 2, height / 2) - - radius = self._get_radius() - - # Outer Ring - cr.set_source_rgb(0xf1 / 255.0, 0xf1 / 255.0, 0xf1 / 255.0) - cr.arc(0, 0, radius, 0, 2 * math.pi) - cr.fill() - - # Selected Wedge - current_activity = self._model.get_pending_activity() - if current_activity is not None: - selected_index = self._model.index(current_activity) - [angle_start, angle_end] = self._get_angles(selected_index) - - cr.new_path() - cr.move_to(0, 0) - cr.line_to(radius * math.cos(angle_start), - radius * math.sin(angle_start)) - cr.arc(0, 0, radius, angle_start, angle_end) - cr.line_to(0, 0) - cr.set_source_rgb(1, 1, 1) - cr.fill() - - # Edges - if len(self._model): - n_edges = len(self._model) + 1 - else: - n_edges = 0 - - for i in range(0, n_edges): - cr.new_path() - cr.move_to(0, 0) - [angle, unused_angle] = self._get_angles(i) - cr.line_to(radius * math.cos(angle), - radius * math.sin(angle)) - - cr.set_source_rgb(0xe2 / 255.0, 0xe2 / 255.0, 0xe2 / 255.0) - cr.set_line_width(4) - cr.stroke_preserve() - - # Inner Ring - cr.new_path() - cr.arc(0, 0, self._get_inner_radius(), 0, 2 * math.pi) - cr.set_source_rgb(0xe2 / 255.0, 0xe2 / 255.0, 0xe2 / 255.0) - cr.fill() - - def do_allocate(self, width, height, origin_changed): - hippo.CanvasBox.do_allocate(self, width, height, origin_changed) - - radius = (self._get_inner_radius() + self._get_radius()) / 2 - - for i, icon in enumerate(self._activities): - [angle_start, angle_end] = self._get_angles(i) - angle = angle_start + (angle_end - angle_start) / 2 - - [icon_width, icon_height] = icon.get_allocation() - - x = int(radius * math.cos(angle)) - icon_width / 2 - y = int(radius * math.sin(angle)) - icon_height / 2 - - self.set_position(icon, x + width / 2, y + height / 2) - -class _Layout(gobject.GObject,hippo.CanvasLayout): - __gtype_name__ = 'SugarDonutLayout' - def __init__(self): - gobject.GObject.__init__(self) - - def do_set_box(self, box): - self._box = box - - def do_get_height_request(self, for_width): - return _DONUT_SIZE, _DONUT_SIZE - - def do_get_width_request(self): - return _DONUT_SIZE, _DONUT_SIZE - - def do_allocate(self, x, y, width, height, - req_width, req_height, origin_changed): - for child in self._box.get_layout_children(): - min_width, child_width = child.get_width_request() - min_height, child_height = child.get_height_request(child_width) - - [angle_start, angle_end] = self._box._get_angles(i) - angle = angle_start + (angle_end - angle_start) / 2 - - x = int(radius * math.cos(angle)) - icon_width / 2 - y = int(radius * math.sin(angle)) - icon_height / 2 - - child.allocate(x + (width - child_width) / 2, - y + (height - child_height) / 2, - icon_width, icon_height, origin_changed) diff --git a/shell/view/home/proc_smaps.py b/shell/view/home/proc_smaps.py deleted file mode 100755 index 6e1680f..0000000 --- a/shell/view/home/proc_smaps.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (C) 2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 -# USA - -import os - -# /proc/PID/maps consists of a number of lines like this: -# 00400000-004b1000 r-xp 00000000 fd:00 5767206 /bin/bash -# 006b1000-006bb000 rw-p 000b1000 fd:00 5767206 /bin/bash -# 006bb000-006c0000 rw-p 006bb000 00:00 0 -# ... -# The fields are: address, permissions, offset, device, inode, and -# (for non-anonymous mappings) pathname. -# -# /proc/PID/smaps gives additional information for each mapping: -# 00400000-004b1000 r-xp 00000000 fd:00 5767206 /bin/bash -# Size: 708 kB -# Rss: 476 kB -# Shared_Clean: 468 kB -# Shared_Dirty: 0 kB -# Private_Clean: 8 kB -# Private_Dirty: 0 kB -# Referenced: 0 kb -# -# The "Referenced" line only appears in kernel 2.6.22 and later. - -def get_shared_mapping_names(pid): - """Returns a set of the files for which PID has a shared mapping""" - - mappings = set() - infile = open("/proc/%s/maps" % pid, "r") - for line in infile: - # sharable mappings are non-anonymous and either read-only - # (permissions "r-..") or writable but explicitly marked - # shared ("rw.s") - fields = line.split() - if len(fields) < 6 or not fields[5].startswith('/'): - continue - if fields[1][0] != 'r' or (fields[1][1] == 'w' and fields[1][3] != 's'): - continue - mappings.add(fields[5]) - infile.close() - return mappings - -_smaps_lines_per_entry = None - -def get_mappings(pid, ignored_shared_mappings): - """Returns a list of (name, private, shared) tuples describing the - memory mappings of PID. Shared mappings named in - ignored_shared_mappings are ignored - """ - - global _smaps_lines_per_entry - if _smaps_lines_per_entry is None: - if os.path.isfile('/proc/%s/clear_refs' % os.getpid()): - _smaps_lines_per_entry = 8 - else: - _smaps_lines_per_entry = 7 - - mappings = [] - - smapfile = "/proc/%s/smaps" % pid - infile = open(smapfile, "r") - input = infile.read() - infile.close() - lines = input.splitlines() - - for line_idx in range(0, len(lines), _smaps_lines_per_entry): - name_idx = lines[line_idx].find('/') - if name_idx == -1: - name = None - else: - name = lines[line_idx][name_idx:] - - private_clean = int(lines[line_idx + 5][14:-3]) - private_dirty = int(lines[line_idx + 6][14:-3]) - if name in ignored_shared_mappings: - shared_clean = 0 - shared_dirty = 0 - else: - shared_clean = int(lines[line_idx + 3][14:-3]) - shared_dirty = int(lines[line_idx + 4][14:-3]) - - mapping = Mapping(name, private_clean + private_dirty, - shared_clean + shared_dirty) - mappings.append (mapping) - - return mappings - -class Mapping: - def __init__ (self, name, private, shared): - self.name = name - self.private = private - self.shared = shared diff --git a/shell/view/home/snowflakelayout.py b/shell/view/home/snowflakelayout.py deleted file mode 100644 index 1eb58cf..0000000 --- a/shell/view/home/snowflakelayout.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import math - -import gobject -import hippo - -from sugar.graphics import style - -_BASE_DISTANCE = style.zoom(15) -_CHILDREN_FACTOR = style.zoom(3) - -class SnowflakeLayout(gobject.GObject,hippo.CanvasLayout): - __gtype_name__ = 'SugarSnowflakeLayout' - def __init__(self): - gobject.GObject.__init__(self) - self._nflakes = 0 - - def add(self, child, center=False): - if not center: - self._nflakes += 1 - - self._box.append(child) - - box_child = self._box.find_box_child(child) - box_child.is_center = center - - def remove(self, child): - box_child = self._box.find_box_child(child) - if not box_child.is_center: - self._nflakes -= 1 - - self._box.remove(child) - - def do_set_box(self, box): - self._box = box - - def do_get_height_request(self, for_width): - size = self._calculate_size() - return (size, size) - - def do_get_width_request(self): - size = self._calculate_size() - return (size, size) - - def do_allocate(self, x, y, width, height, - req_width, req_height, origin_changed): - r = self._get_radius() - index = 0 - - for child in self._box.get_layout_children(): - cx = x + width / 2 - cy = x + height / 2 - - min_width, child_width = child.get_width_request() - min_height, child_height = child.get_height_request(child_width) - - if child.is_center: - child.allocate(x + (width - child_width) / 2, - y + (height - child_height) / 2, - child_width, child_height, origin_changed) - else: - angle = 2 * math.pi * index / self._nflakes - - dx = math.cos(angle) * r - dy = math.sin(angle) * r - - child_x = int(x + (width - child_width) / 2 + dx) - child_y = int(y + (height - child_height) / 2 + dy) - - child.allocate(child_x, child_y, child_width, - child_height, origin_changed) - - index += 1 - - def _get_radius(self): - radius = int(_BASE_DISTANCE + _CHILDREN_FACTOR * self._nflakes) - for child in self._box.get_layout_children(): - if child.is_center: - [min_w, child_w] = child.get_width_request() - [min_h, child_h] = child.get_height_request(child_w) - radius += max(child_w, child_h) / 2 - - return radius - - def _calculate_size(self): - thickness = 0 - for child in self._box.get_layout_children(): - [min_width, child_width] = child.get_width_request() - [min_height, child_height] = child.get_height_request(child_width) - thickness = max(thickness, max(child_width, child_height)) - - return self._get_radius() * 2 + thickness diff --git a/shell/view/home/spreadlayout.py b/shell/view/home/spreadlayout.py deleted file mode 100644 index 3463169..0000000 --- a/shell/view/home/spreadlayout.py +++ /dev/null @@ -1,246 +0,0 @@ -# Copyright (C) 2007 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -from numpy import array -from random import random - -import hippo -import gobject -import gtk - -from sugar.graphics import style - -_PLACE_TRIALS = 20 -_MAX_WEIGHT = 255 -_CELL_SIZE = 4 - -class _Grid(gobject.GObject): - __gsignals__ = { - 'child-changed' : (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, - ([gobject.TYPE_PYOBJECT])) - } - def __init__(self, width, height): - gobject.GObject.__init__(self) - - self.width = width - self.height = height - self._children = [] - self._collisions = [] - self._collisions_sid = 0 - - self._array = array([0], dtype='b') - self._array.resize(width * height) - - def add(self, child, width, height): - trials = _PLACE_TRIALS - weight = _MAX_WEIGHT - while trials > 0 and weight: - x = int(random() * (self.width - width)) - y = int(random() * (self.height - height)) - - rect = gtk.gdk.Rectangle(x, y, width, height) - new_weight = self._compute_weight(rect) - if weight > new_weight: - weight = new_weight - - trials -= 1 - - child.grid_rect = rect - child.locked = False - - self._add_child(child) - - if weight > 0: - self._detect_collisions(child) - - def remove(self, child): - self._children.remove(child) - self._remove_weight(child.grid_rect) - child.grid_rect = None - - def _add_child(self, child): - self._children.append(child) - self.add_weight(child.grid_rect) - - def _move_child(self, child, new_rect): - self._remove_weight(child.grid_rect) - self.add_weight(new_rect) - - child.grid_rect = new_rect - - self.emit('child-changed', child) - - def _shift_child(self, child): - rect = child.grid_rect - weight = self._compute_weight(rect) - new_rects = [] - - if (rect.x + rect.width < self.width - 1): - new_rects.append(gtk.gdk.Rectangle(rect.x + 1, rect.y, - rect.width, rect.height)) - - if (rect.x - 1 > 0): - new_rects.append(gtk.gdk.Rectangle(rect.x - 1, rect.y, - rect.width, rect.height)) - - if (rect.y + rect.height < self.height - 1): - new_rects.append(gtk.gdk.Rectangle(rect.x, rect.y + 1, - rect.width, rect.height)) - - if (rect.y - 1 > 0): - new_rects.append(gtk.gdk.Rectangle(rect.x, rect.y - 1, - rect.width, rect.height)) - - best_rect = None - for new_rect in new_rects: - new_weight = self._compute_weight(new_rect) - if new_weight < weight: - best_rect = new_rect - weight = new_weight - - if best_rect: - self._move_child(child, best_rect) - - return weight - - - def _solve_collisions(self): - for collision in self._collisions[:]: - weight = self._shift_child(collision) - if not weight: - self._collisions.remove(collision) - - return (len(self._collisions) > 0) - - def _detect_collisions(self, child): - collision_found = False - for c in self._children: - intersection = child.grid_rect.intersect(c.grid_rect) - if c != child and intersection.width > 0: - if c not in self._collisions: - collision_found = True - self._collisions.append(c) - - if collision_found: - if child not in self._collisions: - self._collisions.append(child) - -# if len(self._collisions) and not self._collisions_sid: -# self._collisions_sid = gobject.idle_add(self._solve_collisions) - - def add_weight(self, rect): - for i in range(rect.x, rect.x + rect.width): - for j in range(rect.y, rect.y + rect.height): - self[j, i] += 1 - - def _remove_weight(self, rect): - for i in range(rect.x, rect.x + rect.width): - for j in range(rect.y, rect.y + rect.height): - self[j, i] -= 1 - - def _compute_weight(self, rect): - weight = 0 - - for i in range(rect.x, rect.x + rect.width): - for j in range(rect.y, rect.y + rect.height): - weight += self[j, i] - - return weight - - def __getitem__(self, (row, col)): - return self._array[col + row * self.width] - - def __setitem__(self, (row, col), value): - self._array[col + row * self.width] = value - - -class SpreadLayout(gobject.GObject, hippo.CanvasLayout): - __gtype_name__ = 'SugarSpreadLayout' - def __init__(self): - gobject.GObject.__init__(self) - - min_width, width = self.do_get_width_request() - min_height, height = self.do_get_height_request(width) - - self._grid = _Grid(width / _CELL_SIZE, height / _CELL_SIZE) - self._grid.connect('child-changed', self._grid_child_changed_cb) - - def add_center(self, child, vertical_offset=0): - self._box.append(child) - - width, height = self._get_child_grid_size(child) - rect = gtk.gdk.Rectangle(int((self._grid.width - width) / 2), - int((self._grid.height - height) / 2), - width + 1, height + 1) - self._grid.add_weight(rect) - - box_child = self._box.find_box_child(child) - box_child.grid_rect = None - box_child.vertical_offset = vertical_offset - - def add(self, child): - self._box.append(child) - - width, height = self._get_child_grid_size(child) - box_child = self._box.find_box_child(child) - self._grid.add(box_child, width, height) - - def remove(self, child): - box_child = self._box.find_box_child(child) - self._grid.remove(box_child) - - self._box.remove(child) - - def do_set_box(self, box): - self._box = box - - def do_get_height_request(self, for_width): - return 0, gtk.gdk.screen_height() - style.GRID_CELL_SIZE - - def do_get_width_request(self): - return 0, gtk.gdk.screen_width() - - def do_allocate(self, x, y, width, height, - req_width, req_height, origin_changed): - for child in self._box.get_layout_children(): - # We need to always get requests to not confuse hippo - min_w, child_width = child.get_width_request() - min_h, child_height = child.get_height_request(child_width) - - rect = child.grid_rect - if child.grid_rect: - child.allocate(rect.x * _CELL_SIZE, - rect.y * _CELL_SIZE, - rect.width * _CELL_SIZE, - rect.height * _CELL_SIZE, - origin_changed) - else: - vertical_offset = child.vertical_offset - child_x = x + (width - child_width) / 2 - child_y = y + (height - child_height + vertical_offset) / 2 - child.allocate(child_x, child_y, child_width, child_height, - origin_changed) - - def _get_child_grid_size(self, child): - min_width, width = child.get_width_request() - min_height, height = child.get_height_request(width) - - return int(width / _CELL_SIZE), int(height / _CELL_SIZE) - - def _grid_child_changed_cb(self, grid, box_child): - box_child.item.emit_request_changed() diff --git a/shell/view/home/transitionbox.py b/shell/view/home/transitionbox.py deleted file mode 100644 index f1ba4fb..0000000 --- a/shell/view/home/transitionbox.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import hippo -import gobject - -from sugar.graphics import style -from sugar.graphics import animator - -from view.home.MyIcon import MyIcon -from view.home.spreadlayout import SpreadLayout - -class _Animation(animator.Animation): - def __init__(self, icon, start_size, end_size): - animator.Animation.__init__(self, 0.0, 1.0) - - self._icon = icon - self.start_size = start_size - self.end_size = end_size - - def next_frame(self, current): - d = (self.end_size - self.start_size) * current - self._icon.props.size = self.start_size + d - -class _Layout(gobject.GObject,hippo.CanvasLayout): - __gtype_name__ = 'SugarTransitionBoxLayout' - def __init__(self): - gobject.GObject.__init__(self) - - def do_set_box(self, box): - self._box = box - - def do_get_height_request(self, for_width): - return 0, 0 - - def do_get_width_request(self): - return 0, 0 - - def do_allocate(self, x, y, width, height, - req_width, req_height, origin_changed): - for child in self._box.get_layout_children(): - min_width, child_width = child.get_width_request() - min_height, child_height = child.get_height_request(child_width) - - child.allocate(x + (width - child_width) / 2, - y + (height - child_height) / 2, - child_width, child_height, origin_changed) - -class TransitionBox(hippo.CanvasBox): - __gtype_name__ = 'SugarTransitionBox' - - __gsignals__ = { - 'completed': (gobject.SIGNAL_RUN_FIRST, - gobject.TYPE_NONE, ([])) - } - - def __init__(self): - hippo.CanvasBox.__init__(self, background_color=0xe2e2e2ff) - - self._size = style.XLARGE_ICON_SIZE - - self._layout = _Layout() - self.set_layout(self._layout) - - self._my_icon = MyIcon(self._size) - self.append(self._my_icon) - - self._animator = animator.Animator(0.3) - self._animator.connect('completed', self._animation_completed_cb) - - def _animation_completed_cb(self, anim): - self.emit('completed') - - def set_size(self, size): - self._animator.remove_all() - self._animator.add(_Animation(self._my_icon, self._size, size)) - self._animator.start() - - self._size = size - diff --git a/shell/view/keyhandler.py b/shell/view/keyhandler.py deleted file mode 100644 index b07f46c..0000000 --- a/shell/view/keyhandler.py +++ /dev/null @@ -1,237 +0,0 @@ -# Copyright (C) 2006-2007, Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -import signal -import logging -import subprocess - -import dbus -import gtk - -from hardware import hardwaremanager -from model.shellmodel import ShellModel -from sugar._sugarext import KeyGrabber - -_BRIGHTNESS_STEP = 2 -_VOLUME_STEP = 10 -_BRIGHTNESS_MAX = 15 -_VOLUME_MAX = 100 - -_actions_table = { - 'F1' : 'zoom_mesh', - 'F2' : 'zoom_friends', - 'F3' : 'zoom_home', - 'F4' : 'zoom_activity', - 'F9' : 'brightness_down', - 'F10' : 'brightness_up', - 'F9' : 'brightness_min', - 'F10' : 'brightness_max', - 'F11' : 'volume_down', - 'F12' : 'volume_up', - 'F11' : 'volume_min', - 'F12' : 'volume_max', - '1' : 'screenshot', - 'f' : 'frame', - '0x93' : 'frame', - 'o' : 'overlay', - '0xE0' : 'overlay', - '0xEB' : 'rotate', - 'r' : 'rotate', - 'q' : 'quit_emulator', - 'Tab' : 'next_window', - 'n' : 'next_window', - 'Tab' : 'previous_window', - 'p' : 'previous_window', - 'Escape' : 'close_window', - 'q' : 'close_window', - '0xDC' : 'open_search', - 'o' : 'open_search', - 's' : 'say_text' -} - -J_DBUS_SERVICE = 'org.laptop.Journal' -J_DBUS_PATH = '/org/laptop/Journal' -J_DBUS_INTERFACE = 'org.laptop.Journal' - -SPEECH_DBUS_SERVICE = 'org.laptop.Speech' -SPEECH_DBUS_PATH = '/org/laptop/Speech' -SPEECH_DBUS_INTERFACE = 'org.laptop.Speech' - -class KeyHandler(object): - def __init__(self, shell): - self._shell = shell - self._screen_rotation = 0 - self._key_pressed = None - self._keycode_pressed = 0 - self._keystate_pressed = 0 - self._speech_proxy = None - - self._key_grabber = KeyGrabber() - self._key_grabber.connect('key-pressed', - self._key_pressed_cb) - - for key in _actions_table.keys(): - self._key_grabber.grab(key) - - def _change_volume(self, step=None, value=None): - hw_manager = hardwaremanager.get_manager() - - if step is not None: - volume = hw_manager.get_volume() + step - elif value is not None: - volume = value - - volume = min(max(0, volume), _VOLUME_MAX) - - hw_manager.set_volume(volume) - hw_manager.set_mute(volume == 0) - - def _change_brightness(self, step=None, value=None): - hw_manager = hardwaremanager.get_manager() - - if step is not None: - level = hw_manager.get_display_brightness() + step - elif value is not None: - level = value - - level = min(max(0, level), _BRIGHTNESS_MAX) - - hw_manager.set_display_brightness(level) - if level == 0: - hw_manager.set_display_mode(hardwaremanager.B_AND_W_MODE) - else: - hw_manager.set_display_mode(hardwaremanager.COLOR_MODE) - - def _get_speech_proxy(self): - if self._speech_proxy is None: - bus = dbus.SessionBus() - speech_obj = bus.get_object(SPEECH_DBUS_SERVICE, SPEECH_DBUS_PATH) - self._speech_proxy = dbus.Interface(speech_obj, SPEECH_DBUS_INTERFACE) - return self._speech_proxy - - def _on_speech_err(self, ex): - logging.error("An error occurred with the ESpeak service: %r" % (ex, )) - - def _primary_selection_cb(self, clipboard, text, user_data): - logging.debug('KeyHandler._primary_selection_cb: %r' % text) - if text: - self._get_speech_proxy().SayText(text, reply_handler=lambda: None, \ - error_handler=self._on_speech_err) - - def handle_say_text(self): - clipboard = gtk.clipboard_get(selection="PRIMARY") - clipboard.request_text(self._primary_selection_cb) - - def handle_previous_window(self): - self._shell.activate_previous_activity() - - def handle_next_window(self): - self._shell.activate_next_activity() - - def handle_close_window(self): - self._shell.close_current_activity() - - def handle_zoom_mesh(self): - self._shell.set_zoom_level(ShellModel.ZOOM_MESH) - - def handle_zoom_friends(self): - self._shell.set_zoom_level(ShellModel.ZOOM_FRIENDS) - - def handle_zoom_home(self): - self._shell.set_zoom_level(ShellModel.ZOOM_HOME) - - def handle_zoom_activity(self): - self._shell.set_zoom_level(ShellModel.ZOOM_ACTIVITY) - - def handle_brightness_max(self): - self._change_brightness(value=_BRIGHTNESS_MAX) - - def handle_brightness_min(self): - self._change_brightness(value=0) - - def handle_volume_max(self): - self._change_volume(value=_VOLUME_MAX) - - def handle_volume_min(self): - self._change_volume(value=0) - - def handle_brightness_up(self): - self._change_brightness(step=_BRIGHTNESS_STEP) - - def handle_brightness_down(self): - self._change_brightness(step=-_BRIGHTNESS_STEP) - - def handle_volume_up(self): - self._change_volume(step=_VOLUME_STEP) - - def handle_volume_down(self): - self._change_volume(step=-_VOLUME_STEP) - - def handle_screenshot(self): - self._shell.take_screenshot() - - def handle_frame(self): - self._shell.get_frame().notify_key_press() - - def handle_overlay(self): - self._shell.toggle_chat_visibility() - - def handle_rotate(self): - states = [ 'normal', 'left', 'inverted', 'right'] - - self._screen_rotation += 1 - if self._screen_rotation == len(states): - self._screen_rotation = 0 - - subprocess.Popen(['xrandr', '-o', states[self._screen_rotation]]) - - def handle_quit_emulator(self): - if os.environ.has_key('SUGAR_EMULATOR_PID'): - pid = int(os.environ['SUGAR_EMULATOR_PID']) - os.kill(pid, signal.SIGTERM) - - def focus_journal_search(self): - bus = dbus.SessionBus() - obj = bus.get_object(J_DBUS_SERVICE, J_DBUS_PATH) - journal = dbus.Interface(obj, J_DBUS_INTERFACE) - journal.FocusSearch({}) - - def handle_open_search(self): - self.focus_journal_search() - - def _key_pressed_cb(self, grabber, keycode, state): - key = grabber.get_key(keycode, state) - logging.debug('_key_pressed_cb: %i %i %s' % (keycode, state, key)) - if key: - self._key_pressed = key - self._keycode_pressed = keycode - self._keystate_pressed = state - - """ - status = gtk.gdk.keyboard_grab(gtk.gdk.get_default_root_window(), - owner_events=False, time=0L) - if status != gtk.gdk.GRAB_SUCCESS: - logging.error("KeyHandler._key_pressed_cb(): keyboard grab failed: " + status) - """ - - action = _actions_table[key] - method = getattr(self, 'handle_' + action) - method() - - return True - - return False diff --git a/shell/view/pulsingicon.py b/shell/view/pulsingicon.py deleted file mode 100644 index 9e7b3d9..0000000 --- a/shell/view/pulsingicon.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (C) 2006-2007 Red Hat, Inc. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gobject - -from sugar.graphics.icon import CanvasIcon - -class PulsingIcon(CanvasIcon): - __gproperties__ = { - 'paused' : (bool, None, None, False, - gobject.PARAM_READWRITE), - 'colors' : (object, None, None, - gobject.PARAM_READWRITE), - 'pulse-time' : (float, None, None, - 0.0, 500.0, 0.0, - gobject.PARAM_READWRITE), - } - - def __init__(self, **kwargs): - self._paused = False - self._pulse_time = 0.0 - self._colors = None - self._pulse_sid = 0 - self._pos = 0 - - CanvasIcon.__init__(self, **kwargs) - - def do_set_property(self, pspec, value): - CanvasIcon.do_set_property(self, pspec, value) - - if pspec.name == 'pulse-time': - self._pulse_time = value - self._stop() - if not self._paused and self._pulse_time > 0.0: - self._start() - elif pspec.name == 'colors': - self._colors = value - self._pos = 0 - self._update_colors() - elif pspec.name == 'paused': - self._paused = value - if not self._paused and self._pulse_time > 0.0: - self._start() - else: - self._stop() - - def do_get_property(self, pspec): - CanvasIcon.do_get_property(self, pspec) - - if pspec.name == 'pulse-time': - return self._pulse_time - elif pspec.name == 'colors': - return self._colors - - def _update_colors(self): - self.props.stroke_color = self._colors[self._pos][0] - self.props.fill_color = self._colors[self._pos][1] - - def _pulse_timeout(self): - if self._colors: - self._update_colors() - - self._pos += 1 - if self._pos == len(self._colors): - self._pos = 0 - - return True - - def _start(self): - if self._pulse_sid == 0: - self._pulse_sid = gobject.timeout_add( - int(self._pulse_time * 1000), self._pulse_timeout) - - def _stop(self): - if self._pulse_sid: - gobject.source_remove(self._pulse_sid) - self._pulse_sid = 0 -- cgit v0.9.1