| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | import sys | 
					
						
							|  |  |  | import imp | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import dbus | 
					
						
							|  |  |  | import dbus.service | 
					
						
							|  |  |  | import dbus.glib | 
					
						
							|  |  |  | import pygtk | 
					
						
							|  |  |  | pygtk.require('2.0') | 
					
						
							| 
									
										
										
										
											2006-06-14 21:06:25 +02:00
										 |  |  | import gtk, gobject | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-06 16:06:07 +02:00
										 |  |  | from sugar.LogWriter import LogWriter | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | SHELL_SERVICE_NAME = "com.redhat.Sugar.Shell" | 
					
						
							|  |  |  | SHELL_SERVICE_PATH = "/com/redhat/Sugar/Shell" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ACTIVITY_SERVICE_NAME = "com.redhat.Sugar.Activity" | 
					
						
							|  |  |  | ACTIVITY_SERVICE_PATH = "/com/redhat/Sugar/Activity" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | ON_CONNECTED_TO_SHELL_CB = "connected_to_shell" | 
					
						
							|  |  |  | ON_DISCONNECTED_FROM_SHELL_CB = "disconnected_from_shell" | 
					
						
							|  |  |  | ON_RECONNECTED_TO_SHELL_CB = "reconnected_to_shell" | 
					
						
							|  |  |  | ON_CLOSE_FROM_USER_CB = "close_from_user" | 
					
						
							|  |  |  | ON_LOST_FOCUS_CB = "lost_focus" | 
					
						
							|  |  |  | ON_GOT_FOCUS_CB = "got_focus" | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | ON_PUBLISH_CB = "publish" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | def get_path(activity_name): | 
					
						
							|  |  |  | 	"""Returns the activity path""" | 
					
						
							|  |  |  | 	return '/' + activity_name.replace('.', '/') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_factory(activity_name): | 
					
						
							|  |  |  | 	"""Returns the activity factory""" | 
					
						
							|  |  |  | 	return activity_name + '.Factory' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ActivityFactory(dbus.service.Object): | 
					
						
							|  |  |  | 	"""Dbus service that takes care of creating new instances of an activity""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def __init__(self, activity_name, activity_class): | 
					
						
							|  |  |  | 		splitted_module = activity_class.rsplit('.', 1) | 
					
						
							|  |  |  | 		module_name = splitted_module[0] | 
					
						
							|  |  |  | 		class_name = splitted_module[1] | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		(fp, pathname, description) = imp.find_module(module_name) | 
					
						
							|  |  |  | 		module = imp.load_module(module_name, fp, pathname, description) | 
					
						
							|  |  |  | 		self._class = getattr(module, class_name) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		bus = dbus.SessionBus() | 
					
						
							|  |  |  | 		factory = get_factory(activity_name) | 
					
						
							|  |  |  | 		bus_name = dbus.service.BusName(factory, bus = bus)  | 
					
						
							|  |  |  | 		dbus.service.Object.__init__(self, bus_name, get_path(factory)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@dbus.service.method("com.redhat.Sugar.ActivityFactory") | 
					
						
							|  |  |  | 	def create_with_service(self, serialized_service, args): | 
					
						
							|  |  |  | 		service = None | 
					
						
							|  |  |  | 		if serialized_service is not None: | 
					
						
							|  |  |  | 			service = Service.deserialize(serialized_service) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		activity = self._class(args) | 
					
						
							|  |  |  | 		gobject.idle_add(self._start_activity_cb, activity, service) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	@dbus.service.method("com.redhat.Sugar.ActivityFactory") | 
					
						
							|  |  |  | 	def create(self, args): | 
					
						
							|  |  |  | 		self.create_with_service(None, args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _start_activity_cb(self, activity, service): | 
					
						
							|  |  |  | 		activity.connect_to_shell(service) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create(activity_name, service = None, args = None): | 
					
						
							|  |  |  | 	"""Create a new activity from his name.""" | 
					
						
							|  |  |  | 	bus = dbus.SessionBus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	factory_name = get_factory(activity_name) | 
					
						
							|  |  |  | 	factory_path = get_path(factory_name)  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	proxy_obj = bus.get_object(factory_name, factory_path) | 
					
						
							|  |  |  | 	factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if service: | 
					
						
							|  |  |  | 		serialized_service = service.serialize(service) | 
					
						
							|  |  |  | 		factory.create_with_service(serialized_service, args) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		factory.create(args)		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(activity_name, activity_class): | 
					
						
							|  |  |  | 	"""Starts the activity main loop.""" | 
					
						
							| 
									
										
										
										
											2006-07-06 16:06:07 +02:00
										 |  |  | 	log_writer = LogWriter(activity_name) | 
					
						
							|  |  |  | 	log_writer.start() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | 	factory = ActivityFactory(activity_name, activity_class) | 
					
						
							| 
									
										
										
										
											2006-07-06 16:06:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | 	gtk.main() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | class ActivityDbusService(dbus.service.Object): | 
					
						
							|  |  |  | 	"""Base dbus service object that each Activity uses to export dbus methods.
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	The dbus service is separate from the actual Activity object so that we can | 
					
						
							|  |  |  | 	tightly control what stuff passes through the dbus python bindings."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	_ALLOWED_CALLBACKS = [ON_CONNECTED_TO_SHELL_CB, ON_DISCONNECTED_FROM_SHELL_CB, \ | 
					
						
							|  |  |  | 			ON_RECONNECTED_TO_SHELL_CB, ON_CLOSE_FROM_USER_CB, ON_LOST_FOCUS_CB, \ | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | 			ON_GOT_FOCUS_CB, ON_PUBLISH_CB] | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def __init__(self, activity): | 
					
						
							|  |  |  | 		self._activity = activity | 
					
						
							|  |  |  | 		self._activity_id = None | 
					
						
							|  |  |  | 		self._activity_object = None | 
					
						
							|  |  |  | 		self._service = None | 
					
						
							|  |  |  | 		self._bus = dbus.SessionBus() | 
					
						
							|  |  |  | 		self._bus.add_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._callbacks = {} | 
					
						
							|  |  |  | 		for cb in self._ALLOWED_CALLBACKS: | 
					
						
							|  |  |  | 			self._callbacks[cb] = None | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def __del__(self): | 
					
						
							|  |  |  | 		if self._activity_id: | 
					
						
							|  |  |  | 			del self._service | 
					
						
							|  |  |  | 			del self._activity_container | 
					
						
							|  |  |  | 			del self._activity_conainer_object | 
					
						
							|  |  |  | 			del self._activity_object | 
					
						
							|  |  |  | 		self._bus.remove_signal_receiver(self.name_owner_changed, dbus_interface="org.freedesktop.DBus", signal_name="NameOwnerChanged") | 
					
						
							|  |  |  | 		del self._bus | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	def register_callback(self, name, callback): | 
					
						
							|  |  |  | 		if name not in self._ALLOWED_CALLBACKS: | 
					
						
							|  |  |  | 			print "ActivityDbusService: bad callback registration request for '%s'" % name | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		self._callbacks[name] = callback | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-14 21:06:25 +02:00
										 |  |  | 	def _call_callback_cb(self, func, *args): | 
					
						
							|  |  |  | 		gobject.idle_add(func, *args) | 
					
						
							|  |  |  | 		return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	def _call_callback(self, name, *args): | 
					
						
							| 
									
										
										
										
											2006-06-14 21:06:25 +02:00
										 |  |  | 		"""Call our activity object back, but from an idle handler
 | 
					
						
							|  |  |  | 		to minimize the possibility of stupid activities deadlocking | 
					
						
							|  |  |  | 		in dbus callbacks."""
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		if name in self._ALLOWED_CALLBACKS and self._callbacks[name]: | 
					
						
							| 
									
										
										
										
											2006-06-14 21:06:25 +02:00
										 |  |  | 			gobject.idle_add(self._call_callback_cb, self._callbacks[name], *args) | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 	def connect_to_shell(self, service=None): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Register with the shell via dbus, getting an activity ID and
 | 
					
						
							|  |  |  | 		and XEMBED window ID in which to display the Activity."""
 | 
					
						
							|  |  |  | 		self._activity_container_object = self._bus.get_object(SHELL_SERVICE_NAME, \ | 
					
						
							|  |  |  | 															   SHELL_SERVICE_PATH + "/ActivityContainer") | 
					
						
							|  |  |  | 		self._activity_container = dbus.Interface(self._activity_container_object, \ | 
					
						
							|  |  |  | 												   SHELL_SERVICE_NAME + ".ActivityContainer") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 		if service is None: | 
					
						
							| 
									
										
										
										
											2006-06-17 05:10:30 +02:00
										 |  |  | 			self._activity_id = self._activity_container.add_activity("", self._activity.default_type()) | 
					
						
							| 
									
										
										
										
											2006-06-16 07:43:42 +02:00
										 |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2006-06-22 20:05:38 +02:00
										 |  |  | 			self._activity_id = service.get_activity_id() | 
					
						
							| 
									
										
										
										
											2006-06-19 15:47:28 +02:00
										 |  |  | 			self._activity_container.add_activity_with_id("", self._activity.default_type(), self._activity_id) | 
					
						
							| 
									
										
										
										
											2006-06-16 07:43:42 +02:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-06-13 19:32:49 +02:00
										 |  |  | 		self._object_path = SHELL_SERVICE_PATH + "/Activities/%s" % self._activity_id | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		print "ActivityDbusService: object path is '%s'" % self._object_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		self._activity_object = dbus.Interface(self._bus.get_object(SHELL_SERVICE_NAME, self._object_path), \ | 
					
						
							|  |  |  | 											  SHELL_SERVICE_NAME + ".ActivityHost") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		# Now let us register a peer service so the Shell can poke it | 
					
						
							| 
									
										
										
										
											2006-06-13 19:32:49 +02:00
										 |  |  | 		self._peer_service_name = ACTIVITY_SERVICE_NAME + "%s" % self._activity_id | 
					
						
							|  |  |  | 		self._peer_object_path = ACTIVITY_SERVICE_PATH + "/%s" % self._activity_id | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		self._service = dbus.service.BusName(self._peer_service_name, bus=self._bus) | 
					
						
							|  |  |  | 		dbus.service.Object.__init__(self, self._service, self._peer_object_path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		self._activity_object.set_peer_service_name(self._peer_service_name, self._peer_object_path) | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 		self._call_callback(ON_CONNECTED_TO_SHELL_CB, self._activity_object, self._activity_id, service) | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def _shutdown_reply_cb(self): | 
					
						
							|  |  |  | 		"""Shutdown was successful, tell the Activity that we're disconnected.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._call_callback(ON_DISCONNECTED_FROM_SHELL_CB) | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def _shutdown_error_cb(self, error): | 
					
						
							|  |  |  | 		print "ActivityDbusService: error during shutdown - '%s'" % error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def shutdown(self): | 
					
						
							|  |  |  | 		"""Notify the shell that we are shutting down.""" | 
					
						
							|  |  |  | 		self._activity_object.shutdown(reply_handler=self._shutdown_reply_cb, error_handler=self._shutdown_error_cb) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def name_owner_changed(self, service_name, old_service_name, new_service_name): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Handle dbus NameOwnerChanged signals.""" | 
					
						
							|  |  |  | 		if not self._activity_id: | 
					
						
							|  |  |  | 			# Do nothing if we're not connected yet | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if service_name == SHELL_SERVICE_NAME and not len(new_service_name): | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 			self._call_callback(ON_DISCONNECTED_FROM_SHELL_CB) | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		elif service_name == SHELL_SERVICE_NAME and not len(old_service_name): | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 			self._call_callback(ON_RECONNECTED_TO_SHELL_CB) | 
					
						
							| 
									
										
										
										
											2006-05-22 22:35:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	@dbus.service.method(ACTIVITY_SERVICE_NAME) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 	def lost_focus(self): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Called by the shell to notify us that we've lost focus.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._call_callback(ON_LOST_FOCUS_CB) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	@dbus.service.method(ACTIVITY_SERVICE_NAME) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 	def got_focus(self): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Called by the shell to notify us that the user gave us focus.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._call_callback(ON_GOT_FOCUS_CB) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	@dbus.service.method(ACTIVITY_SERVICE_NAME) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 	def close_from_user(self): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Called by the shell to notify us that the user closed us.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._call_callback(ON_CLOSE_FROM_USER_CB) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | 	@dbus.service.method(ACTIVITY_SERVICE_NAME) | 
					
						
							|  |  |  | 	def publish(self): | 
					
						
							|  |  |  | 		"""Called by the shell to request the activity to publish itself on the network.""" | 
					
						
							|  |  |  | 		self._call_callback(ON_PUBLISH_CB) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | 	@dbus.service.signal(ACTIVITY_SERVICE_NAME) | 
					
						
							| 
									
										
										
										
											2006-06-23 04:42:29 +02:00
										 |  |  | 	def ActivityShared(self): | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | class Activity(object): | 
					
						
							|  |  |  | 	"""Base Activity class that all other Activities derive from.""" | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 05:10:30 +02:00
										 |  |  | 	def __init__(self, default_type): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		self._dbus_service = self._get_new_dbus_service() | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._dbus_service.register_callback(ON_CONNECTED_TO_SHELL_CB, self._internal_on_connected_to_shell_cb) | 
					
						
							|  |  |  | 		self._dbus_service.register_callback(ON_DISCONNECTED_FROM_SHELL_CB, self._internal_on_disconnected_from_shell_cb) | 
					
						
							|  |  |  | 		self._dbus_service.register_callback(ON_RECONNECTED_TO_SHELL_CB, self._internal_on_reconnected_to_shell_cb) | 
					
						
							|  |  |  | 		self._dbus_service.register_callback(ON_CLOSE_FROM_USER_CB, self._internal_on_close_from_user_cb) | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | 		self._dbus_service.register_callback(ON_PUBLISH_CB, self._internal_on_publish_cb) | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._dbus_service.register_callback(ON_LOST_FOCUS_CB, self._internal_on_lost_focus_cb) | 
					
						
							|  |  |  | 		self._dbus_service.register_callback(ON_GOT_FOCUS_CB, self._internal_on_got_focus_cb) | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		self._has_focus = False | 
					
						
							|  |  |  | 		self._plug = None | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 		self._initial_service = None | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		self._activity_object = None | 
					
						
							| 
									
										
										
										
											2006-06-23 04:42:29 +02:00
										 |  |  | 		self._shared = False | 
					
						
							| 
									
										
										
										
											2006-06-17 05:10:30 +02:00
										 |  |  | 		if type(default_type) != type("") or not len(default_type): | 
					
						
							|  |  |  | 			raise ValueError("Default type must be a valid string.") | 
					
						
							|  |  |  | 		self._default_type = default_type | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def _cleanup(self): | 
					
						
							|  |  |  | 		if self._plug: | 
					
						
							|  |  |  | 			self._plug.destroy() | 
					
						
							|  |  |  | 			self._plug = None | 
					
						
							|  |  |  | 		if self._dbus_service: | 
					
						
							|  |  |  | 			del self._dbus_service | 
					
						
							|  |  |  | 			self._dbus_service = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def __del__(self): | 
					
						
							|  |  |  | 		self._cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _get_new_dbus_service(self): | 
					
						
							|  |  |  | 		"""Create and return a new dbus service object for this Activity.
 | 
					
						
							|  |  |  | 		Allows subclasses to use their own dbus service object if they choose."""
 | 
					
						
							|  |  |  | 		return ActivityDbusService(self) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-17 05:10:30 +02:00
										 |  |  | 	def default_type(self): | 
					
						
							|  |  |  | 		return self._default_type | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-23 04:42:29 +02:00
										 |  |  | 	def set_shared(self): | 
					
						
							|  |  |  | 		"""Mark the activity as 'shared'.""" | 
					
						
							|  |  |  | 		if not self._shared: | 
					
						
							|  |  |  | 			self._shared = True | 
					
						
							|  |  |  | 			self._dbus_service.ActivityShared() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def shared(self): | 
					
						
							|  |  |  | 		return self._shared | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def has_focus(self): | 
					
						
							|  |  |  | 		"""Return whether or not this Activity is visible to the user.""" | 
					
						
							|  |  |  | 		return self._has_focus | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 	def connect_to_shell(self, service = None): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		"""Called by our controller to tell us to initialize and connect
 | 
					
						
							|  |  |  | 		to the shell."""
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 		self._dbus_service.connect_to_shell(service) | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 	def _internal_on_connected_to_shell_cb(self, activity_object, activity_id, service=None): | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		"""Callback when the dbus service object has connected to the shell.""" | 
					
						
							|  |  |  | 		self._activity_object = activity_object | 
					
						
							|  |  |  | 		self._activity_id = activity_id | 
					
						
							|  |  |  | 		self._window_id = self._activity_object.get_host_xembed_id() | 
					
						
							| 
									
										
										
										
											2006-06-13 19:32:49 +02:00
										 |  |  | 		print "Activity: XEMBED window ID is %s" % self._window_id | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		self._plug = gtk.Plug(self._window_id) | 
					
						
							| 
									
										
										
										
											2006-06-18 07:31:55 +02:00
										 |  |  | 		self._initial_service = service | 
					
						
							| 
									
										
										
										
											2006-06-23 04:42:29 +02:00
										 |  |  | 		if service: | 
					
						
							| 
									
										
										
										
											2006-06-23 17:17:33 +02:00
										 |  |  | 			self.set_shared() | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		self.on_connected_to_shell() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	def _internal_on_disconnected_from_shell_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object has disconnected from the shell.""" | 
					
						
							|  |  |  | 		self._cleanup() | 
					
						
							|  |  |  | 		self.on_disconnected_from_shell() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _internal_on_reconnected_to_shell_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object has reconnected to the shell.""" | 
					
						
							|  |  |  | 		self.on_reconnected_to_shell() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _internal_on_close_from_user_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object tells us the user has closed our activity.""" | 
					
						
							|  |  |  | 		self.shutdown() | 
					
						
							|  |  |  | 		self.on_close_from_user() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | 	def _internal_on_publish_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object tells us the user has closed our activity.""" | 
					
						
							|  |  |  | 		self.publish() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	def _internal_on_lost_focus_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object tells us we have lost focus.""" | 
					
						
							|  |  |  | 		self._has_focus = False | 
					
						
							|  |  |  | 		self.on_lost_focus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _internal_on_got_focus_cb(self): | 
					
						
							|  |  |  | 		"""Callback when the dbus service object tells us we have gotten focus.""" | 
					
						
							|  |  |  | 		self._has_focus = True | 
					
						
							|  |  |  | 		self.set_has_changes(False) | 
					
						
							|  |  |  | 		self.on_got_focus() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def gtk_plug(self): | 
					
						
							|  |  |  | 		"""Return our GtkPlug widget.""" | 
					
						
							|  |  |  | 		return self._plug | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_ellipsize_tab(self, ellipsize): | 
					
						
							|  |  |  | 		"""Sets this Activity's tab text to be ellipsized or not.""" | 
					
						
							|  |  |  | 		self._activity_object.set_ellipsize_tab(ellipsize) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_tab_text(self, text): | 
					
						
							|  |  |  | 		"""Sets this Activity's tab text.""" | 
					
						
							|  |  |  | 		self._activity_object.set_tab_text(text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_can_close(self, can_close): | 
					
						
							|  |  |  | 		"""Sets whether or not this Activity can be closed by the user.""" | 
					
						
							|  |  |  | 		self._activity_object.set_can_close(can_close) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_show_tab_icon(self, show_icon): | 
					
						
							|  |  |  | 		"""Sets whether or not an icon is shown in this Activity's tab.""" | 
					
						
							|  |  |  | 		self._activity_object.set_tab_show_icon(show_icon) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_tab_icon(self, pixbuf=None, name=None): | 
					
						
							|  |  |  | 		"""Set the Activity's tab icon, either from pixbuf data
 | 
					
						
							|  |  |  | 		or by an icon theme icon name."""
 | 
					
						
							|  |  |  | 		if name: | 
					
						
							|  |  |  | 			icon_theme = gtk.icon_theme_get_default() | 
					
						
							|  |  |  | 			icon_info = icon_theme.lookup_icon(name, gtk.ICON_SIZE_MENU, 0) | 
					
						
							|  |  |  | 			if icon_info: | 
					
						
							|  |  |  | 				orig_pixbuf = icon_info.load_icon() | 
					
						
							|  |  |  | 				pixbuf = orig_pixbuf.scale_simple(16, 16, gtk.gdk.INTERP_BILINEAR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if pixbuf: | 
					
						
							|  |  |  | 			# Dump the pixel data into an array and shove it through dbus | 
					
						
							|  |  |  | 			pixarray = [] | 
					
						
							|  |  |  | 			pixstr = pixbuf.get_pixels(); | 
					
						
							|  |  |  | 			for c in pixstr: | 
					
						
							|  |  |  | 				pixarray.append(c) | 
					
						
							|  |  |  | 			self._activity_object.set_tab_icon(pixarray, \ | 
					
						
							|  |  |  | 												pixbuf.get_colorspace(), \ | 
					
						
							|  |  |  | 												pixbuf.get_has_alpha(),  \ | 
					
						
							|  |  |  | 												pixbuf.get_bits_per_sample(), \ | 
					
						
							|  |  |  | 												pixbuf.get_width(), \ | 
					
						
							|  |  |  | 												pixbuf.get_height(), \ | 
					
						
							|  |  |  | 												pixbuf.get_rowstride()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def set_has_changes(self, has_changes): | 
					
						
							|  |  |  | 		"""Marks this Activity as having changes.  This usually means
 | 
					
						
							|  |  |  | 		that this Activity's tab turns a red color or something else | 
					
						
							|  |  |  | 		to notify the user that this Activity needs attention."""
 | 
					
						
							| 
									
										
										
										
											2006-06-07 19:26:38 +02:00
										 |  |  | 		if not self.has_focus() and has_changes: | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 			self._activity_object.set_has_changes(True) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self._activity_object.set_has_changes(False) | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-15 17:29:00 +02:00
										 |  |  | 	def get_id(self): | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 		return self._activity_id | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def shutdown(self): | 
					
						
							|  |  |  | 		"""Disconnect from the shell and clean up.""" | 
					
						
							|  |  |  | 		self._dbus_service.shutdown() | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 	############################################################# | 
					
						
							|  |  |  | 	# Pure Virtual methods that subclasses may/may not implement | 
					
						
							|  |  |  | 	############################################################# | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-13 20:49:01 +02:00
										 |  |  | 	def publish(self): | 
					
						
							|  |  |  | 		"""Called to request the activity to publish itself on the network.""" | 
					
						
							|  |  |  | 		pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def on_lost_focus(self): | 
					
						
							|  |  |  | 		"""Triggered when this Activity loses focus.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-05-22 23:59:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def on_got_focus(self): | 
					
						
							|  |  |  | 		"""Triggered when this Activity gets focus.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def on_disconnected_from_shell(self): | 
					
						
							|  |  |  | 		"""Triggered when we disconnect from the shell.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-05-12 08:34:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def on_reconnected_to_shell(self): | 
					
						
							|  |  |  | 		"""Triggered when the shell's service comes back.""" | 
					
						
							|  |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-05-15 20:48:08 +02:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 	def on_connected_to_shell(self): | 
					
						
							|  |  |  | 		"""Triggered when this Activity has successfully connected to the shell.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-06-02 20:52:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def on_close_from_user(self): | 
					
						
							|  |  |  | 		"""Triggered when this Activity is closed by the user.""" | 
					
						
							| 
									
										
										
										
											2006-06-05 18:35:00 +02:00
										 |  |  | 		pass | 
					
						
							| 
									
										
										
										
											2006-07-06 15:59:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  | 	main(sys.argv[1], sys.argv[2]) |