From cdabf58cbcc32c8ded7c8a955d638ba6ddd94068 Mon Sep 17 00:00:00 2001 From: Pootle Translation Date: Thu, 7 Aug 2008 17:12:10 -0400 Subject: [PATCH 01/15] Commit from One Laptop Per Child: Translation System by user khaled. 28 of 28 messages translated (0 fuzzy). --- po/ar.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/po/ar.po b/po/ar.po index 25645f8d..f4e9b3ef 100644 --- a/po/ar.po +++ b/po/ar.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: sugar\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-06-24 00:07+0530\n" -"PO-Revision-Date: 2008-08-07 09:05-0400\n" +"PO-Revision-Date: 2008-08-07 17:03-0400\n" "Last-Translator: Khaled Hosny \n" "Language-Team: Arabic \n" "MIME-Version: 1.0\n" @@ -133,8 +133,8 @@ msgstr[5] "%d سنة" msgid "%d month" msgid_plural "%d months" msgstr[0] "%d شهر" -msgstr[1] "%.sشهر" -msgstr[2] "%.sشهرين" +msgstr[1] "%.0sشهر" +msgstr[2] "%.0sشهرين" msgstr[3] "%d شهور" msgstr[4] "%d شهرا" msgstr[5] "%d شهر" @@ -144,8 +144,8 @@ msgstr[5] "%d شهر" msgid "%d week" msgid_plural "%d weeks" msgstr[0] "%d أسبوع" -msgstr[1] "%.sأسبوع" -msgstr[2] "%.sأسبوعين" +msgstr[1] "%.0sأسبوع" +msgstr[2] "%.0sأسبوعين" msgstr[3] "%d أسابيع" msgstr[4] "%d أسبوعا" msgstr[5] "%d أسبوع" @@ -155,8 +155,8 @@ msgstr[5] "%d أسبوع" msgid "%d day" msgid_plural "%d days" msgstr[0] "%d يوم" -msgstr[1] "%.sيوم" -msgstr[2] "%.sيومين" +msgstr[1] "%.0sيوم" +msgstr[2] "%.0sيومين" msgstr[3] "%d أيام" msgstr[4] "%d يوما" msgstr[5] "%d يوم" @@ -166,8 +166,8 @@ msgstr[5] "%d يوم" msgid "%d hour" msgid_plural "%d hours" msgstr[0] "%d ساعة" -msgstr[1] "%.sساعة" -msgstr[2] "%.sساعتين" +msgstr[1] "%.0sساعة" +msgstr[2] "%.0sساعتين" msgstr[3] "%d ساعات" msgstr[4] "%d ساعة" msgstr[5] "%d ساعة" @@ -177,8 +177,8 @@ msgstr[5] "%d ساعة" msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d دقيقة" -msgstr[1] "%.sدقيقة" -msgstr[2] "%.sدقيقتين" +msgstr[1] "%.0sدقيقة" +msgstr[2] "%.0sدقيقتين" msgstr[3] "%d دقائق" msgstr[4] "%d دقيقة" msgstr[5] "%d دقيقة" From 1878c9f36973e1c25a19d9e02f4eed60eab35905 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 00:00:55 +0200 Subject: [PATCH 02/15] Pylint cleanups. --- src/sugar/util.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sugar/util.py b/src/sugar/util.py index 8f81210c..a713cb0e 100644 --- a/src/sugar/util.py +++ b/src/sugar/util.py @@ -20,10 +20,10 @@ import time import sha import random import binascii -import string -from gettext import gettext as _ import gettext +_ = gettext.gettext + def printable_hash(in_hash): """Convert binary hash data into printable characters.""" printable = "" @@ -58,7 +58,12 @@ def unique_id(data = ''): ACTIVITY_ID_LEN = 40 def is_hex(s): - return s.strip(string.hexdigits) == '' + try: + int(s, 16) + except ValueError: + return False + + return True def validate_activity_id(actid): """Validate an activity ID.""" @@ -106,6 +111,7 @@ class LRU: http://pype.sourceforge.net Copyright 2003 Josiah Carlson. """ + # pylint: disable-msg=W0102,W0612 def __init__(self, count, pairs=[]): self.count = max(count, 1) self.d = {} From 04750e69d3f1a0ed224399f1be412b4dbbc82916 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 00:18:04 +0200 Subject: [PATCH 03/15] Drop broken, unused code --- src/sugar/network.py | 116 ------------------------------------------- 1 file changed, 116 deletions(-) diff --git a/src/sugar/network.py b/src/sugar/network.py index 66327619..8bcf8c07 100644 --- a/src/sugar/network.py +++ b/src/sugar/network.py @@ -474,119 +474,3 @@ class _Method: return _Method(self.__send, "%s.%s" % (self.__name, name)) def __call__(self, *args, **kwargs): return self.__send(self.__name, *args, **kwargs) - - -class GlibServerProxy(xmlrpclib.ServerProxy): - """Subclass xmlrpclib.ServerProxy so we can run the XML-RPC request - in two parts, integrated with the glib mainloop, such that we don't - block anywhere. - - Using this object is somewhat special; it requires more arguments to each - XML-RPC request call than the normal xmlrpclib.ServerProxy object: - - client = GlibServerProxy("http://127.0.0.1:8888") - user_data = "bar" - xmlrpc_arg1 = "test" - xmlrpc_arg2 = "foo" - client.test(xmlrpc_test_cb, user_data, xmlrpc_arg1, xmlrpc_arg2) - - Here, 'xmlrpc_test_cb' is the callback function, which has the following - signature: - - def xmlrpc_test_cb(result_status, response, user_data=None): - ... - """ - def __init__(self, uri, encoding=None, verbose=0, allow_none=0): - self._transport = GlibXMLRPCTransport() - self._encoding = encoding - self._verbose = verbose - self._allow_none = allow_none - xmlrpclib.ServerProxy.__init__(self, uri, self._transport, - encoding, verbose, allow_none) - - # get the url - urltype, uri = urllib.splittype(uri) - if urltype not in ("http", "https"): - raise IOError, "unsupported XML-RPC protocol" - self._host, self._handler = urllib.splithost(uri) - if not self._handler: - self._handler = "/RPC2" - - def __request(self, methodname, *args, **kwargs): - """Call the method on the remote server. We just start the request here - and the transport itself takes care of scheduling the response callback - when the remote server returns the response. - We don't want to block anywhere.""" - - request = xmlrpclib.dumps(args, methodname, encoding=self._encoding, - allow_none=self._allow_none) - - reply_hdl = kwargs.get("reply_handler") - err_hdl = kwargs.get("error_handler") - udata = kwargs.get("user_data") - try: - response = self._transport.start_request( - self._host, - self._handler, - request, - verbose=self._verbose, - reply_handler=reply_hdl, - error_handler=err_hdl, - user_data=udata - ) - except socket.error, exc: - if err_hdl: - gobject.idle_add(err_hdl, exc, udata) - - def __getattr__(self, name): - # magic method dispatcher - return _Method(self.__request, name) - - -class Test(object): - def test(self, arg1, arg2): - print "Request got %s, %s" % (arg1, arg2) - return "success", "bork" - -def xmlrpc_success_cb(response, resp2, loop): - print "Response was %s %s" % (response, resp2) - loop.quit() - -def xmlrpc_error_cb(err, loop): - print "Error: %s" % err - loop.quit() - -def xmlrpc_test(loop): - client = GlibServerProxy("http://127.0.0.1:8888") - client.test("bar", "baz", - reply_handler=xmlrpc_success_cb, - error_handler=xmlrpc_error_cb, - user_data=loop) - -def start_xmlrpc(): - server = GlibXMLRPCServer(("", 8888)) - inst = Test() - server.register_instance(inst) - gobject.idle_add(xmlrpc_test, loop) - -class TestReqHandler(ChunkedGlibHTTPRequestHandler): - def translate_path(self, path): - return "/tmp/foo" - -def start_http(): - server = GlibTCPServer(("", 8890), TestReqHandler) - -def main(): - loop = gobject.MainLoop() -# start_xmlrpc() - start_http() - try: - loop.run() - except KeyboardInterrupt: - print 'Ctrl+C pressed, exiting...' - print "Done." - -if __name__ == "__main__": - main() - - From 4c35d778549477d0865b69761b2d87eef94cad18 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 00:22:17 +0200 Subject: [PATCH 04/15] Drop more obsolete xmlrpc code --- src/sugar/network.py | 181 ------------------------------------------- 1 file changed, 181 deletions(-) diff --git a/src/sugar/network.py b/src/sugar/network.py index 8bcf8c07..aad817aa 100644 --- a/src/sugar/network.py +++ b/src/sugar/network.py @@ -15,19 +15,13 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import socket import os import threading -import traceback -import xmlrpclib -import sys -import httplib import urllib import fcntl import tempfile import gobject -import SimpleXMLRPCServer import SimpleHTTPServer import SocketServer @@ -299,178 +293,3 @@ class GlibURLDownloader(gobject.GObject): if remove: os.remove(self._fname) self._outf = None - - -class GlibXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - """ GlibXMLRPCRequestHandler - - The stock SimpleXMLRPCRequestHandler and server don't allow any way to pass - the client's address and/or SSL certificate into the function that actually - _processes_ the request. So we have to store it in a thread-indexed dict. - """ - - def do_POST(self): - _add_authinfo(self.client_address) - try: - SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self) - except socket.timeout: - pass - except socket.error, e: - print "Error (%s): socket error - '%s'" % (self.client_address, e) - except: - print "Error while processing POST:" - traceback.print_exc() - _del_authinfo() - -class GlibXMLRPCServer(GlibTCPServer, - SimpleXMLRPCServer.SimpleXMLRPCDispatcher): - """GlibXMLRPCServer - - Use nonblocking sockets and handle the accept via glib rather than - blocking on accept(). - """ - - def __init__(self, addr, requestHandler=GlibXMLRPCRequestHandler, - logRequests=0, allow_none=False): - self.logRequests = logRequests - if sys.version_info[:3] >= (2, 5, 0): - SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__( - self, allow_none, encoding="utf-8") - else: - SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) - GlibTCPServer.__init__(self, addr, requestHandler) - - def _marshaled_dispatch(self, data, dispatch_method = None): - """Dispatches an XML-RPC method from marshalled (XML) data. - - XML-RPC methods are dispatched from the marshalled (XML) data - using the _dispatch method and the result is returned as - marshalled data. For backwards compatibility, a dispatch - function can be provided as an argument (see comment in - SimpleXMLRPCRequestHandler.do_POST) but overriding the - existing method through subclassing is the prefered means - of changing method dispatch behavior. - """ - - params, method = xmlrpclib.loads(data) - - # generate response - try: - if dispatch_method is not None: - response = dispatch_method(method, params) - else: - response = self._dispatch(method, params) - # wrap response in a singleton tuple - response = (response,) - response = xmlrpclib.dumps(response, methodresponse=1) - except xmlrpclib.Fault, fault: - response = xmlrpclib.dumps(fault) - except: - print "Exception while processing request:" - traceback.print_exc() - - # report exception back to server - response = xmlrpclib.dumps( - xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)) - ) - - return response - - -class GlibHTTP(httplib.HTTP): - """Subclass HTTP so we can return it's connection class' socket.""" - def connect(self, host=None, port=None): - httplib.HTTP.connect(self, host, port) - self._conn.sock.setblocking(0) - -class GlibXMLRPCTransport(xmlrpclib.Transport): - """Integrate the request with the glib mainloop rather than blocking.""" - ## - # Connect to server. - # - # @param host Target host. - # @return A connection handle. - - def __init__(self, use_datetime=0): - self.verbose = None - if sys.version_info[:3] >= (2, 5, 0): - xmlrpclib.Transport.__init__(self, use_datetime) - - def make_connection(self, host): - """Use our own connection object so we can get its socket.""" - # create a HTTP connection object from a host descriptor - host, extra_headers_, x509_ = self.get_host_info(host) - return GlibHTTP(host) - - ## - # Send a complete request, and parse the response. - # - # @param host Target host. - # @param handler Target PRC handler. - # @param request_body XML-RPC request body. - # @param verbose Debugging flag. - # @return Parsed response. - - def start_request(self, host, handler, request_body, verbose=0, - reply_handler=None, error_handler=None, user_data=None): - """Do the first half of the request by sending data to the remote - server. The bottom half bits get run when the remote server's response - actually comes back.""" - # issue XML-RPC request - - h = self.make_connection(host) - if verbose: - h.set_debuglevel(1) - - self.send_request(h, handler, request_body) - self.send_host(h, host) - self.send_user_agent(h) - self.send_content(h, request_body) - - # Schedule a GIOWatch so we don't block waiting for the response - gobject.io_add_watch(h._conn.sock, gobject.IO_IN, self._finish_request, - h, host, handler, verbose, reply_handler, error_handler, user_data) - - def _finish_request(self, source, condition, h, host, handler, verbose, - reply_handler=None, error_handler=None, user_data=None): - """Parse and return response when the - remote server actually returns it.""" - if not (condition & gobject.IO_IN): - return True - - try: - errcode, errmsg, headers = h.getreply() - except socket.error, err: - if err[0] != 104: - raise socket.error(err) - else: - if error_handler: - gobject.idle_add(error_handler, err, user_data) - return False - - if errcode != 200: - raise xmlrpclib.ProtocolError(host + handler, errcode, - errmsg, headers) - self.verbose = verbose - response = self._parse_response(h.getfile(), h._conn.sock) - if reply_handler: - # Coerce to a list so we can append user data - response = response[0] - if not isinstance(response, list): - response = [response] - response.append(user_data) - gobject.idle_add(reply_handler, *response) - return False - -class _Method: - """Right, so python people thought it would be funny to make this - class private to xmlrpclib.py...""" - # some magic to bind an XML-RPC method to an RPC server. - # supports "nested" methods (e.g. examples.getStateName) - def __init__(self, send, name): - self.__send = send - self.__name = name - def __getattr__(self, name): - return _Method(self.__send, "%s.%s" % (self.__name, name)) - def __call__(self, *args, **kwargs): - return self.__send(self.__name, *args, **kwargs) From 80190bf944977de1315df5f0d35438de29bac010 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 00:50:29 +0200 Subject: [PATCH 05/15] Several pylint fixes. --- src/sugar/bundle/activitybundle.py | 2 +- src/sugar/bundle/contentbundle.py | 1 + src/sugar/presence/activity.py | 6 +++--- src/sugar/presence/presenceservice.py | 15 ++++++++++----- src/sugar/presence/sugartubeconn.py | 4 ++-- src/sugar/profile.py | 2 +- src/sugar/util.py | 4 ++-- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/sugar/bundle/activitybundle.py b/src/sugar/bundle/activitybundle.py index 2c235d88..5f29a698 100644 --- a/src/sugar/bundle/activitybundle.py +++ b/src/sugar/bundle/activitybundle.py @@ -291,7 +291,7 @@ class ActivityBundle(Bundle): # List installed files manifestfiles = self.get_files(self._raw_manifest()) paths = [] - for root, dirs, files in os.walk(install_path): + for root, dirs_, files in os.walk(install_path): rel_path = root[len(install_path) + 1:] for f in files: paths.append(os.path.join(rel_path, f)) diff --git a/src/sugar/bundle/contentbundle.py b/src/sugar/bundle/contentbundle.py index 32f38e30..f99c13a1 100644 --- a/src/sugar/bundle/contentbundle.py +++ b/src/sugar/bundle/contentbundle.py @@ -49,6 +49,7 @@ class ContentBundle(Bundle): self._category_icon = None self._library_version = None self._bundle_class = None + self._activity_start = None info_file = self.get_file('library/library.info') if info_file is None: diff --git a/src/sugar/presence/activity.py b/src/sugar/presence/activity.py index ab3cffff..bd41cecd 100644 --- a/src/sugar/presence/activity.py +++ b/src/sugar/presence/activity.py @@ -281,8 +281,8 @@ class Activity(gobject.GObject): def tubes_ready(): if self.telepathy_text_chan is None or \ - self.telepathy_tubes_chan is None: - return + self.telepathy_tubes_chan is None: + return _logger.debug('%r: finished setting up tubes', self) reply_handler() @@ -303,7 +303,7 @@ class Activity(gobject.GObject): found_text_channel = False found_tubes_channel = False - for chan_path, chan_iface, handle_type, handle in chans: + for chan_path, chan_iface, handle_type, handle_ in chans: if handle_type != telepathy.HANDLE_TYPE_ROOM: return diff --git a/src/sugar/presence/presenceservice.py b/src/sugar/presence/presenceservice.py index fb59a42b..50f0f7fd 100644 --- a/src/sugar/presence/presenceservice.py +++ b/src/sugar/presence/presenceservice.py @@ -178,7 +178,7 @@ class PresenceService(gobject.GObject): self._del_object, object_path) try: # Pre-fill the activity's ID - foo = obj.props.id + activity_id = obj.props.id except dbus.exceptions.DBusException: logging.debug('Cannot get the activity ID') else: @@ -239,9 +239,11 @@ class PresenceService(gobject.GObject): gobject.idle_add(self._emit_activity_invitation_signal, activity_path, buddy_path, message) - def _emit_private_invitation_signal(self, bus_name, connection, channel, chan_type): + def _emit_private_invitation_signal(self, bus_name, connection, + channel, chan_type): """Emit GObject event with bus_name, connection and channel""" - self.emit('private-invitation', bus_name, connection, channel, chan_type) + self.emit('private-invitation', bus_name, connection, + channel, chan_type) return False def _private_invitation_cb(self, bus_name, connection, channel, chan_type): @@ -469,7 +471,7 @@ class PresenceService(gobject.GObject): (activity.get_id(), err)) self.emit("activity-shared", False, None, err) - def share_activity(self, activity, properties={}, private=True): + def share_activity(self, activity, properties=None, private=True): """Ask presence service to ask the activity to share itself publicly. Uses the AdvertiseActivity method on the service to ask for the @@ -484,6 +486,9 @@ class PresenceService(gobject.GObject): """ actid = activity.get_id() + if properties is None: + properties = {} + # Ensure the activity is not already shared/joined for obj in self._objcache.values(): if not isinstance(object, Activity): @@ -584,7 +589,7 @@ class _MockPresenceService(gobject.GObject): def get_owner(self): return None - def share_activity(self, activity, properties={}): + def share_activity(self, activity, properties=None): return None _ps = None diff --git a/src/sugar/presence/sugartubeconn.py b/src/sugar/presence/sugartubeconn.py index 34776119..18113fe1 100644 --- a/src/sugar/presence/sugartubeconn.py +++ b/src/sugar/presence/sugartubeconn.py @@ -19,8 +19,8 @@ from telepathy.constants import ( CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES) -from tubeconn import TubeConnection -import presenceservice +from sugar.presence.tubeconn import TubeConnection +from sugar.presence import presenceservice class SugarTubeConnection(TubeConnection): diff --git a/src/sugar/profile.py b/src/sugar/profile.py index 25b957ef..db360a1a 100644 --- a/src/sugar/profile.py +++ b/src/sugar/profile.py @@ -215,7 +215,7 @@ class Profile(object): return None # hash it - key_hash = util._sha_data(key) + key_hash = util.sha_data(key) return util.printable_hash(key_hash) def _get_privkey_hash(self): diff --git a/src/sugar/util.py b/src/sugar/util.py index a713cb0e..2706b5d6 100644 --- a/src/sugar/util.py +++ b/src/sugar/util.py @@ -31,7 +31,7 @@ def printable_hash(in_hash): printable = printable + binascii.b2a_hex(char) return printable -def _sha_data(data): +def sha_data(data): """sha1 hash some bytes.""" sha_hash = sha.new() sha_hash.update(data) @@ -52,7 +52,7 @@ def unique_id(data = ''): perfectly unique values. """ data_string = "%s%s%s" % (time.time(), random.randint(10000, 100000), data) - return printable_hash(_sha_data(data_string)) + return printable_hash(sha_data(data_string)) ACTIVITY_ID_LEN = 40 From 204e4f233a1ded5fb8eef3a3123a9d5bfde48276 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 01:10:02 +0200 Subject: [PATCH 06/15] Port a few widgets to use new style properties. --- src/sugar/activity/activity.py | 44 +++++++++---------- src/sugar/graphics/combobox.py | 20 ++++----- src/sugar/graphics/icon.py | 78 +++++++++++++++++----------------- 3 files changed, 67 insertions(+), 75 deletions(-) diff --git a/src/sugar/activity/activity.py b/src/sugar/activity/activity.py index 9784b28e..f46d3193 100644 --- a/src/sugar/activity/activity.py +++ b/src/sugar/activity/activity.py @@ -425,13 +425,6 @@ class Activity(Window, gtk.Container): 'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) } - __gproperties__ = { - 'active' : (bool, None, None, False, - gobject.PARAM_READWRITE), - 'max-participants': (int, None, None, 0, 1000, 0, - gobject.PARAM_READWRITE) - } - def __init__(self, handle, create_jobject=True): """Initialise the Activity @@ -570,24 +563,27 @@ class Activity(Window, gtk.Container): # https://dev.laptop.org/ticket/3071 datastore.write(self._jobject) - def do_set_property(self, pspec, value): - if pspec.name == 'active': - if self._active != value: - self._active = value - if not self._active and self._jobject: - self.save() - elif pspec.name == 'max-participants': - self._max_participants = value - else: - Window.do_set_property(self, pspec, value) + def get_active(self): + return self._active - def do_get_property(self, pspec): - if pspec.name == 'active': - return self._active - elif pspec.name == 'max-participants': - return self._max_participants - else: - return Window.do_get_property(self, pspec) + def set_active(self, active): + if self._active != active: + self._active = active + if not self._active and self._jobject: + self.save() + + active = gobject.property( + type=bool, default=False, getter=get_active, setter=set_active) + + def get_max_participants(self): + return self._max_participants + + def set_max_participants(self, participants): + self._max_participants = participants + + max_participants = gobject.property( + type=int, default=0, getter=get_max_participants, + setter=set_max_participants) def get_id(self): """Returns the activity id of the current instance of your activity. diff --git a/src/sugar/graphics/combobox.py b/src/sugar/graphics/combobox.py index 2924fb35..68a71062 100644 --- a/src/sugar/graphics/combobox.py +++ b/src/sugar/graphics/combobox.py @@ -21,10 +21,6 @@ import gtk class ComboBox(gtk.ComboBox): __gtype_name__ = 'SugarComboBox' - __gproperties__ = { - 'value' : (object, None, None, - gobject.PARAM_READABLE) - } def __init__(self): gtk.ComboBox.__init__(self) @@ -39,14 +35,14 @@ class ComboBox(gtk.ComboBox): self.set_row_separator_func(self._is_separator) - def do_get_property(self, pspec): - if pspec.name == 'value': - row = self.get_active_item() - if not row: - return None - return row[0] - else: - return gtk.ComboBox.do_get_property(self, pspec) + def get_value(self): + row = self.get_active_item() + if not row: + return None + return row[0] + + value = gobject.property( + type=object, getter=get_value, setter=None) def _get_real_name_from_theme(self, name, size): icon_theme = gtk.icon_theme_get_default() diff --git a/src/sugar/graphics/icon.py b/src/sugar/graphics/icon.py index f99eadee..0dc82bba 100644 --- a/src/sugar/graphics/icon.py +++ b/src/sugar/graphics/icon.py @@ -293,17 +293,6 @@ class _IconBuffer(object): class Icon(gtk.Image): __gtype_name__ = 'SugarIcon' - __gproperties__ = { - 'xo-color' : (object, None, None, - gobject.PARAM_WRITABLE), - 'fill-color' : (object, None, None, - gobject.PARAM_READWRITE), - 'stroke-color' : (object, None, None, - gobject.PARAM_READWRITE), - 'badge-name' : (str, None, None, None, - gobject.PARAM_READWRITE) - } - def __init__(self, **kwargs): self._buffer = _IconBuffer() @@ -368,35 +357,46 @@ class Icon(gtk.Image): cr.set_source_surface(surface, x, y) cr.paint() - def do_set_property(self, pspec, value): - if pspec.name == 'xo-color': - if self._buffer.xo_color != value: - self._buffer.xo_color = value - self.queue_draw() - elif pspec.name == 'fill-color': - if self._buffer.fill_color != value: - self._buffer.fill_color = value - self.queue_draw() - elif pspec.name == 'stroke-color': - if self._buffer.stroke_color != value: - self._buffer.stroke_color = value - self.queue_draw() - elif pspec.name == 'badge-name': - if self._buffer.badge_name != value: - self._buffer.badge_name = value - self.queue_resize() - else: - gtk.Image.do_set_property(self, pspec, value) + def set_xo_color(self, value): + if self._buffer.xo_color != value: + self._buffer.xo_color = value + self.queue_draw() - def do_get_property(self, pspec): - if pspec.name == 'fill-color': - return self._buffer.fill_color - elif pspec.name == 'stroke-color': - return self._buffer.stroke_color - elif pspec.name == 'badge-name': - return self._buffer.badge_name - else: - return gtk.Image.do_get_property(self, pspec) + xo_color = gobject.property( + type=object, getter=None, setter=set_xo_color) + + def set_fill_color(self, value): + if self._buffer.fill_color != value: + self._buffer.fill_color = value + self.queue_draw() + + def get_fill_color(self): + return self._buffer.fill_color + + fill_color = gobject.property( + type=object, getter=get_fill_color, setter=set_fill_color) + + def set_stroke_color(self, value): + if self._buffer.stroke_color != value: + self._buffer.stroke_color = value + self.queue_draw() + + def get_stroke_color(self): + return self._buffer.stroke_color + + stroke_color = gobject.property( + type=object, getter=get_stroke_color, setter=set_stroke_color) + + def set_badge_name(self, value): + if self._buffer.badge_name != value: + self._buffer.badge_name = value + self.queue_resize() + + def get_badge_name(self): + return self._buffer.badge_name + + badge_name = gobject.property( + type=str, getter=get_badge_name, setter=set_badge_name) class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'CanvasIcon' From c563543dea7078a7bdc26d9beca31b35ae6635cc Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 01:20:08 +0200 Subject: [PATCH 07/15] More pylint fixes --- src/sugar/datastore/datastore.py | 5 ++++- src/sugar/graphics/palette.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sugar/datastore/datastore.py b/src/sugar/datastore/datastore.py index b88a8775..1917b19f 100644 --- a/src/sugar/datastore/datastore.py +++ b/src/sugar/datastore/datastore.py @@ -278,11 +278,14 @@ def delete(object_id): logging.debug('datastore.delete') dbus_helpers.delete(object_id) -def find(query, sorting=None, limit=None, offset=None, properties=[], +def find(query, sorting=None, limit=None, offset=None, properties=None, reply_handler=None, error_handler=None): query = query.copy() + if properties is None: + properties = [] + if sorting: query['order_by'] = sorting if limit: diff --git a/src/sugar/graphics/palette.py b/src/sugar/graphics/palette.py index 2c073892..1268726b 100644 --- a/src/sugar/graphics/palette.py +++ b/src/sugar/graphics/palette.py @@ -1032,6 +1032,7 @@ class CanvasInvoker(Invoker): self._position_hint = self.AT_CURSOR self._motion_hid = None self._release_hid = None + self._item = None if parent: self.attach(parent) @@ -1093,7 +1094,7 @@ class ToolInvoker(WidgetInvoker): def _get_alignments(self): parent = self._widget.get_parent() if parent is None: - return WidgetInvoker.get_alignments() + return WidgetInvoker._get_alignments() if parent.get_orientation() is gtk.ORIENTATION_HORIZONTAL: return self.BOTTOM + self.TOP From 4114ef699d4f9fa009d5ee77eb56e9ae26ccbc3e Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Mon, 11 Aug 2008 20:14:37 +0530 Subject: [PATCH 08/15] Fix gettext invocation, and set text domain (fixes #7800) --- src/sugar/util.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sugar/util.py b/src/sugar/util.py index 2706b5d6..67653d91 100644 --- a/src/sugar/util.py +++ b/src/sugar/util.py @@ -22,7 +22,9 @@ import random import binascii import gettext -_ = gettext.gettext +_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) +_ngettext = lambda msg1, msg2, n: gettext.dngettext('sugar-toolkit', msg1, msg2, n) + def printable_hash(in_hash): """Convert binary hash data into printable characters.""" @@ -228,8 +230,8 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2): if levels > 0: time_period += COMMA - time_period += gettext.ngettext(name_singular, name_plural, - elapsed_units) % elapsed_units + time_period += _ngettext(name_singular, name_plural, + elapsed_units) % elapsed_units elapsed_seconds -= elapsed_units * factor From 8afa8c77d214c8ac1c21bf3b792e494606f33753 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 11 Aug 2008 18:35:34 +0200 Subject: [PATCH 09/15] Add missing get_type declaration --- src/sugar/gsm-session.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sugar/gsm-session.h b/src/sugar/gsm-session.h index 94577c9a..d4880a9b 100644 --- a/src/sugar/gsm-session.h +++ b/src/sugar/gsm-session.h @@ -73,6 +73,8 @@ typedef enum { GSM_SESSION_LOGOUT_MODE_FORCE } GsmSessionLogoutMode; +GType gsm_session_get_type (void) G_GNUC_CONST; + void gsm_session_set_name (GsmSession *session, const char *name); From 9a827ead86311933802bbd4c919b8cbd5de62a88 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Tue, 12 Aug 2008 01:53:28 +0200 Subject: [PATCH 10/15] Enable maximum warnings. A bunch of compile fixes. --- configure.ac | 2 + m4/gnome-compiler-flags.m4 | 141 ++++++++++++++++++++++++++++++++ src/sugar/Makefile.am | 1 + src/sugar/_sugarext.override | 2 +- src/sugar/eggsmclient-private.h | 2 + src/sugar/gsm-session.c | 53 ------------ src/sugar/sugar-menu.h | 1 + src/sugar/sugar-preview.c | 5 +- 8 files changed, 150 insertions(+), 57 deletions(-) create mode 100644 m4/gnome-compiler-flags.m4 diff --git a/configure.ac b/configure.ac index 1c234d30..66c275cd 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,8 @@ AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip]) AC_DISABLE_STATIC AC_PROG_LIBTOOL +GNOME_COMPILE_WARNINGS(maximum) + AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) AM_PATH_PYTHON diff --git a/m4/gnome-compiler-flags.m4 b/m4/gnome-compiler-flags.m4 new file mode 100644 index 00000000..b9db2fd7 --- /dev/null +++ b/m4/gnome-compiler-flags.m4 @@ -0,0 +1,141 @@ +dnl GNOME_COMPILE_WARNINGS +dnl Turn on many useful compiler warnings +dnl For now, only works on GCC +AC_DEFUN([GNOME_COMPILE_WARNINGS],[ + dnl ****************************** + dnl More compiler warnings + dnl ****************************** + + AC_ARG_ENABLE(compile-warnings, + AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@], + [Turn on compiler warnings]),, + [enable_compile_warnings="m4_default([$1],[yes])"]) + + warnCFLAGS= + if test "x$GCC" != xyes; then + enable_compile_warnings=no + fi + + warning_flags= + realsave_CFLAGS="$CFLAGS" + + case "$enable_compile_warnings" in + no) + warning_flags= + ;; + minimum) + warning_flags="-Wall" + ;; + yes) + warning_flags="-Wall -Wmissing-prototypes" + ;; + maximum|error) + warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith" + CFLAGS="$warning_flags $CFLAGS" + for option in -Wno-sign-compare; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $option" + AC_MSG_CHECKING([whether gcc understands $option]) + AC_TRY_COMPILE([], [], + has_option=yes, + has_option=no,) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT($has_option) + if test $has_option = yes; then + warning_flags="$warning_flags $option" + fi + unset has_option + unset SAVE_CFLAGS + done + unset option + if test "$enable_compile_warnings" = "error" ; then + warning_flags="$warning_flags -Werror" + fi + ;; + *) + AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings) + ;; + esac + CFLAGS="$realsave_CFLAGS" + AC_MSG_CHECKING(what warning flags to pass to the C compiler) + AC_MSG_RESULT($warning_flags) + + AC_ARG_ENABLE(iso-c, + AC_HELP_STRING([--enable-iso-c], + [Try to warn if code is not ISO C ]),, + [enable_iso_c=no]) + + AC_MSG_CHECKING(what language compliance flags to pass to the C compiler) + complCFLAGS= + if test "x$enable_iso_c" != "xno"; then + if test "x$GCC" = "xyes"; then + case " $CFLAGS " in + *[\ \ ]-ansi[\ \ ]*) ;; + *) complCFLAGS="$complCFLAGS -ansi" ;; + esac + case " $CFLAGS " in + *[\ \ ]-pedantic[\ \ ]*) ;; + *) complCFLAGS="$complCFLAGS -pedantic" ;; + esac + fi + fi + AC_MSG_RESULT($complCFLAGS) + + WARN_CFLAGS="$warning_flags $complCFLAGS" + AC_SUBST(WARN_CFLAGS) +]) + +dnl For C++, do basically the same thing. + +AC_DEFUN([GNOME_CXX_WARNINGS],[ + AC_ARG_ENABLE(cxx-warnings, + AC_HELP_STRING([--enable-cxx-warnings=@<:@no/minimum/yes@:>@] + [Turn on compiler warnings.]),, + [enable_cxx_warnings="m4_default([$1],[minimum])"]) + + AC_MSG_CHECKING(what warning flags to pass to the C++ compiler) + warnCXXFLAGS= + if test "x$GXX" != xyes; then + enable_cxx_warnings=no + fi + if test "x$enable_cxx_warnings" != "xno"; then + if test "x$GXX" = "xyes"; then + case " $CXXFLAGS " in + *[\ \ ]-Wall[\ \ ]*) ;; + *) warnCXXFLAGS="-Wall -Wno-unused" ;; + esac + + ## -W is not all that useful. And it cannot be controlled + ## with individual -Wno-xxx flags, unlike -Wall + if test "x$enable_cxx_warnings" = "xyes"; then + warnCXXFLAGS="$warnCXXFLAGS -Wshadow -Woverloaded-virtual" + fi + fi + fi + AC_MSG_RESULT($warnCXXFLAGS) + + AC_ARG_ENABLE(iso-cxx, + AC_HELP_STRING([--enable-iso-cxx], + [Try to warn if code is not ISO C++ ]),, + [enable_iso_cxx=no]) + + AC_MSG_CHECKING(what language compliance flags to pass to the C++ compiler) + complCXXFLAGS= + if test "x$enable_iso_cxx" != "xno"; then + if test "x$GXX" = "xyes"; then + case " $CXXFLAGS " in + *[\ \ ]-ansi[\ \ ]*) ;; + *) complCXXFLAGS="$complCXXFLAGS -ansi" ;; + esac + + case " $CXXFLAGS " in + *[\ \ ]-pedantic[\ \ ]*) ;; + *) complCXXFLAGS="$complCXXFLAGS -pedantic" ;; + esac + fi + fi + AC_MSG_RESULT($complCXXFLAGS) + + WARN_CXXFLAGS="$CXXFLAGS $warnCXXFLAGS $complCXXFLAGS" + AC_SUBST(WARN_CXXFLAGS) +]) diff --git a/src/sugar/Makefile.am b/src/sugar/Makefile.am index ef91efe9..5cc58d1f 100644 --- a/src/sugar/Makefile.am +++ b/src/sugar/Makefile.am @@ -14,6 +14,7 @@ pkgpyexecdir = $(pythondir)/sugar pkgpyexec_LTLIBRARIES = _sugarext.la _sugarext_la_CFLAGS = \ + $(WARN_CFLAGS) \ $(EXT_CFLAGS) \ $(PYTHON_INCLUDES) diff --git a/src/sugar/_sugarext.override b/src/sugar/_sugarext.override index db49e274..dc54de02 100644 --- a/src/sugar/_sugarext.override +++ b/src/sugar/_sugarext.override @@ -10,8 +10,8 @@ headers #include "sugar-preview.h" #include "sexy-icon-entry.h" #include "gsm-session.h" +#include "gsm-xsmp.h" -#define EGG_SM_CLIENT_BACKEND_XSMP #include "eggsmclient.h" #include "eggsmclient-private.h" diff --git a/src/sugar/eggsmclient-private.h b/src/sugar/eggsmclient-private.h index 0b4ec408..d2958c9b 100644 --- a/src/sugar/eggsmclient-private.h +++ b/src/sugar/eggsmclient-private.h @@ -25,6 +25,8 @@ G_BEGIN_DECLS +#define EGG_SM_CLIENT_BACKEND_XSMP + GKeyFile *egg_sm_client_save_state (EggSMClient *client); void egg_sm_client_quit_requested (EggSMClient *client); void egg_sm_client_quit_cancelled (EggSMClient *client); diff --git a/src/sugar/gsm-session.c b/src/sugar/gsm-session.c index 95dd7cbe..3f0714c7 100644 --- a/src/sugar/gsm-session.c +++ b/src/sugar/gsm-session.c @@ -150,53 +150,6 @@ end_phase (GsmSession *session) start_phase (session); } -static void -app_condition_changed (GsmApp *app, gboolean condition, gpointer data) -{ - GsmSession *session; - GsmClient *client = NULL; - GSList *cl = NULL; - - g_return_if_fail (data != NULL); - - session = (GsmSession *) data; - - /* Check for an existing session client for this app */ - for (cl = session->clients; cl; cl = cl->next) - { - GsmClient *c = GSM_CLIENT (cl->data); - - if (!strcmp (app->client_id, gsm_client_get_client_id (c))) - client = c; - } - - if (condition) - { - GError *error = NULL; - - if (app->pid <= 0 && client == NULL) - gsm_app_launch (app, &error); - - if (error != NULL) - { - g_warning ("Not able to launch autostart app from its condition: %s", - error->message); - - g_error_free (error); - } - } - else - { - /* Kill client in case condition if false and make sure it won't - * be automatically restarted by adding the client to - * condition_clients */ - session->condition_clients = - g_slist_prepend (session->condition_clients, client); - gsm_client_die (client); - app->pid = -1; - } -} - static void app_registered (GsmApp *app, gpointer data) { @@ -241,10 +194,6 @@ phase_timeout (gpointer data) static void start_phase (GsmSession *session) { - GsmApp *app; - GSList *a; - GError *err = NULL; - g_debug ("starting phase %d\n", session->phase); g_slist_free (session->pending_apps); @@ -359,8 +308,6 @@ client_saved_state (GsmClient *client, gpointer data) void gsm_session_initiate_shutdown (GsmSession *session) { - gboolean logout_prompt; - if (session->phase == GSM_SESSION_PHASE_SHUTDOWN) { /* Already shutting down, nothing more to do */ diff --git a/src/sugar/sugar-menu.h b/src/sugar/sugar-menu.h index 8773a316..74ce8916 100644 --- a/src/sugar/sugar-menu.h +++ b/src/sugar/sugar-menu.h @@ -50,6 +50,7 @@ void sugar_menu_set_active (SugarMenu *menu, gboolean active); void sugar_menu_embed (SugarMenu *menu, GtkContainer *parent); +void sugar_menu_unembed (SugarMenu *menu); G_END_DECLS diff --git a/src/sugar/sugar-preview.c b/src/sugar/sugar-preview.c index f54045bf..42fb9d31 100644 --- a/src/sugar/sugar-preview.c +++ b/src/sugar/sugar-preview.c @@ -19,6 +19,7 @@ #include #include +#include #include "sugar-preview.h" @@ -37,8 +38,6 @@ sugar_preview_set_size(SugarPreview *preview, int width, int height) GdkPixbuf * sugar_preview_get_pixbuf(SugarPreview *preview) { - GdkPixbuf *pixbuf; - if (preview->pixbuf != NULL) { return preview->pixbuf; } @@ -92,7 +91,7 @@ sugar_preview_take_screenshot(SugarPreview *preview, GdkDrawable *drawable) XShmGetImage(GDK_SCREEN_XDISPLAY(screen), GDK_DRAWABLE_XID(drawable), gdk_x11_image_get_ximage(preview->image), - 0, 0, AllPlanes, ZPixmap); + 0, 0, AllPlanes); } static void From 3ce887ce9002a6147c286f00ea95fe2d9eb2065a Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Wed, 13 Aug 2008 11:58:06 +0200 Subject: [PATCH 11/15] Add dep on libSM --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 66c275cd..7250e79d 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)]) AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no) -PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0) +PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0, sm) PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0` AC_SUBST(PYGTK_DEFSDIR) From e3861325f4ff8e785350ea9d5965f4c430b6e0e3 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Wed, 13 Aug 2008 13:12:06 +0200 Subject: [PATCH 12/15] Add dependency on libICE --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7250e79d..1f2c8972 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)]) AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no) -PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0, sm) +PKG_CHECK_MODULES(EXT, pygtk-2.0 gtk+-2.0, sm, ice) PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0` AC_SUBST(PYGTK_DEFSDIR) From 5cf5e91d69639ce09792b3aa24fd498a78eb5965 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Wed, 13 Aug 2008 14:28:40 +0200 Subject: [PATCH 13/15] pylint fix --- src/sugar/util.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sugar/util.py b/src/sugar/util.py index 67653d91..955f4c81 100644 --- a/src/sugar/util.py +++ b/src/sugar/util.py @@ -23,8 +23,7 @@ import binascii import gettext _ = lambda msg: gettext.dgettext('sugar-toolkit', msg) -_ngettext = lambda msg1, msg2, n: gettext.dngettext('sugar-toolkit', msg1, msg2, n) - +_ngettext = lambda m1, m2, n: gettext.dngettext('sugar-toolkit', m1, m2, n) def printable_hash(in_hash): """Convert binary hash data into printable characters.""" From bd264577e7a30565e9c27400633e440e6ce1f83d Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 14 Aug 2008 15:12:57 +0200 Subject: [PATCH 14/15] Make Palette handle changes of the invoker widget. Fix #7881 --- src/sugar/graphics/palette.py | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/sugar/graphics/palette.py b/src/sugar/graphics/palette.py index 1268726b..04f269fe 100644 --- a/src/sugar/graphics/palette.py +++ b/src/sugar/graphics/palette.py @@ -244,9 +244,7 @@ class Palette(gtk.Window): self._menu_box = None self._content = None self._palette_popup_sid = None - self._enter_invoker_hid = None - self._leave_invoker_hid = None - self._right_click_invoker_hid = None + self._invoker_hids = [] self.set_group_id("default") @@ -312,21 +310,27 @@ class Palette(gtk.Window): return gtk.gdk.Rectangle(x, y, width, height) def _set_invoker(self, invoker): - if self._invoker is not None: - self._invoker.disconnect(self._enter_invoker_hid) - self._invoker.disconnect(self._leave_invoker_hid) - self._invoker.disconnect(self._right_click_invoker_hid) + for hid in self._invoker_hids[:]: + self._invoker.disconnect(hid) + self._invoker_hids.remove(hid) self._invoker = invoker if invoker is not None: - self._enter_invoker_hid = self._invoker.connect( - 'mouse-enter', self._invoker_mouse_enter_cb) - self._leave_invoker_hid = self._invoker.connect( - 'mouse-leave', self._invoker_mouse_leave_cb) - self._right_click_invoker_hid = self._invoker.connect( - 'right-click', self._invoker_right_click_cb) + self._invoker_hids.append(self._invoker.connect( + 'mouse-enter', self._invoker_mouse_enter_cb)) + self._invoker_hids.append(self._invoker.connect( + 'mouse-leave', self._invoker_mouse_leave_cb)) + self._invoker_hids.append(self._invoker.connect( + 'right-click', self._invoker_right_click_cb)) if hasattr(invoker.props, 'widget'): - self._label.props.accel_widget = invoker.props.widget + self._update_accel_widget() + logging.debug(('Setup widget', invoker.props.widget)) + self._invoker_hids.append(self._invoker.connect( + 'notify::widget', self._invoker_widget_changed_cb)) + + def _update_accel_widget(self): + assert self.props.invoker is not None + self._label.props.accel_widget = self.props.invoker.props.widget def set_primary_text(self, label, accel_path=None): self._primary_text = label @@ -611,6 +615,9 @@ class Palette(gtk.Window): self.popup(immediate=immediate) + def _invoker_widget_changed_cb(self, invoker, spec): + self._update_accel_widget() + def _invoker_mouse_enter_cb(self, invoker): self._mouse_detector.start() @@ -939,6 +946,8 @@ class WidgetInvoker(Invoker): else: self._widget = parent + self.notify('widget') + self._enter_hid = self._widget.connect('enter-notify-event', self.__enter_notify_event_cb) self._leave_hid = self._widget.connect('leave-notify-event', From ba850d5787168f1d02fe9b38c971a9d18164b1c7 Mon Sep 17 00:00:00 2001 From: Simon Schampijer Date: Thu, 14 Aug 2008 21:31:42 +0200 Subject: [PATCH 15/15] Wrap message in alert needed for 7841 --- src/sugar/graphics/alert.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sugar/graphics/alert.py b/src/sugar/graphics/alert.py index fad90bb1..a4d2a5ac 100644 --- a/src/sugar/graphics/alert.py +++ b/src/sugar/graphics/alert.py @@ -85,7 +85,7 @@ class Alert(gtk.EventBox): self._buttons_box.set_spacing(style.DEFAULT_SPACING) self._hbox.pack_start(self._buttons_box) - gtk.EventBox.__init__(self, **kwargs) + gobject.GObject.__init__(self, **kwargs) self.set_visible_window(True) self.add(self._hbox) @@ -105,6 +105,10 @@ class Alert(gtk.EventBox): if self._msg != value: self._msg = value self._msg_label.set_markup(self._msg) + width, height_ = self._msg_label.size_request() + self._msg_label.set_size_request(width-style.DEFAULT_SPACING, + -1) + self._msg_label.set_line_wrap(True) elif pspec.name == 'icon': if self._icon != value: self._icon = value