PERFORCE change 119989 for review

Ivan Voras ivoras at FreeBSD.org
Fri May 18 12:25:57 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=119989

Change 119989 by ivoras at ivoras_beastie on 2007/05/18 12:25:03

	* Implement almost all of the remaining GTK infrastructure (the "next" /
	"previous" wizard),
	* Add add a new tile: ndisks (novice disks choser), which is not yet
	functional.     
	* Add logging infrasructure

Affected files ...

.. //depot/projects/soc2007/ivoras_finstall/installer/finstall.py#5 edit
.. //depot/projects/soc2007/ivoras_finstall/installer/glade/mainwin.glade#4 edit
.. //depot/projects/soc2007/ivoras_finstall/installer/glade/ndisks.glade#1 add
.. //depot/projects/soc2007/ivoras_finstall/installer/text/intro.txt#3 edit
.. //depot/projects/soc2007/ivoras_finstall/installer/text/ndisks.txt#1 add

Differences ...

==== //depot/projects/soc2007/ivoras_finstall/installer/finstall.py#5 (text+ko) ====

@@ -1,22 +1,42 @@
+import logging
 from types import MethodType
 import gtk, gtk.gdk, gtk.glade
 
 
 class MainWin:
+
+	# Configured tracks
+	Steps_Novice = [
+		{ "tile" : "intro" },
+		{ "tile" : "ndisks" }
+	]
+
+
 	def __init__(self):
+		self.tile_xml = None	# will be used for tiles
 		self.xml = gtk.glade.XML("glade/mainwin.glade")
 		self.window = self.xml.get_widget("mainwin")
-		self.xml.signal_autoconnect(self._get_event_handlers())
+		self.xml.signal_autoconnect(self._get_event_handlers(None))
 		self["img_logo"].set_from_file("img/logo.jpg")
 		# img_logo stretches the window vertically, so calling window.set_position() has no affect
-		self._center_window(self.window) 
-		self["label2"].set_text(self._load_label("intro.txt"))
-		self["label2"].set_use_markup(True)
+		self._center_window(self.window)
+		self.step_current = 0
+		self.step_track = MainWin.Steps_Novice
+		self._load_tile_nr(self.step_current)
 
 
-	def __getitem__(self,key):
-		"""Make convenient shortcut to window widgets."""
-		return self.xml.get_widget(key)
+	def __getitem__(self, key):
+		"""Make convenient shortcut to window widgets. This is actually not
+		easy as it seems, since we use different Glade XML files for different
+		tiles of the wizard dialog."""
+		if self.tile_xml:
+			w = self.tile_xml.get_widget(key)
+			if w == None:
+				return self.xml.get_widget(key)
+			else:
+				return w
+		else:
+			return self.xml.get_widget(key)
 
 
 	def _center_window(self, window):
@@ -25,29 +45,126 @@
 		window.move((gtk.gdk.screen_width() - ws[0]) / 2, (gtk.gdk.screen_height() - ws[1]) / 2)
 
 
-	def _get_event_handlers(self):
+	def _get_event_handlers(self, prefix):
 		"""Returns a dictionary of form {'on_method' : self.on_method} for all
 		methods of self begining with "on_". This is useful for binding signal
 		handlers."""
 		dict = {}
+		if prefix != None:
+			prefix2 = "%s_on_" % prefix
+		else:
+			prefix2 = "on_"
 		for name in dir(self):
-			if not name.startswith("on_"):
+			if not name.startswith(prefix2):
 				continue
 			attr = getattr(self, name)
 			if isinstance(attr, MethodType):
-				dict[name] = attr
+				dict[name[len(prefix2)-3:]] = attr
 		return dict
 
+
 	def _load_label(self, file_name):
+		"""Returns the content of a text/* file with formatting replacements
+		so it looks decent when Pango renders it"""
 		return file("text/%s" % file_name).read().replace("\n", " ").replace("<br>", "\n").replace("\n ", "\n")
 
-	def on_button_next_clicked(self, obj):
-		print "clicked!", obj
-		gtk.main_quit()
+
+	def _clear_container(self, cont):
+		for child in cont.get_children():
+			cont.remove(child)
+
+
+	def _load_tile(self, tile_name):
+		"""Loads a tile by it's name and integrates it in the wizard window"""
+		self._clear_container(self.xml.get_widget("vbox_container"))
+		self.tile_xml = gtk.glade.XML("glade/%s.glade" % tile_name)
+		self.tile_handlers = self._get_event_handlers(tile_name)
+		self.tile_xml.signal_autoconnect(self.tile_handlers)
+		w = self.tile_xml.get_widget("vbox_container").get_children()[0]
+		w.reparent(self.xml.get_widget("vbox_container"))
+		self.xml.get_widget("vbox_container").resize_children()
+		if "on_load" in self.tile_handlers:
+			try:
+				if not self.tile_handlers["on_load"]():
+					logging.error("On_Load refused by %s, but it's not implemented" % tile_name)
+			except:
+				logging.exception("Error executing on_load handler for %s" % tile_name)
+
+
+	def _load_tile_nr(self, tile_nr):
+		"""Loads a (numerated) tile from the current step_track"""
+		self._load_tile(self.step_track[tile_nr]["tile"])
+
 
+	# Handlers for the main window elements (the window itself, Next/Previous
+	# buttons, etc.
 	def on_mainwin_delete_event(self, obj, data):
 		gtk.main_quit()
 
+
+	def on_button_next_clicked(self, obj):
+		"""'Next' button clicked - tries to load the next tile in current 
+		step track"""
+		if "on_next" in self.tile_handlers:
+			try:
+				if not self.tile_handlers["on_next"]():
+					logging.debug("On_next denied for %s" % self.step_track[self.step_current]["tile"])
+					return
+			except:
+				logging.exception("Error executing on_next handler in %s" % self.step_track[self.step_current]["tile"])
+				return
+		self.step_current += 1
+		if self.step_current >= len(self.step_track):
+			self.step_current = 0	# XXX: Fix by disabling next/previous
+		self._load_tile_nr(self.step_current)
+
+
+	def on_button_previous_clicked(self, obj):
+		"""'Previous' button clicked - tries to load the previous tile
+		in current step track."""
+		if "on_previous" in self.tile_handlers:
+			try:
+				if not self.tile_handlers["on_previous"]():
+					logging.debug("On_previous denied for %s" % self.step_track[self.step_current]["tile"])
+					return
+			except:
+				logging.exception("Error executing on_previous in %s" % self.step_track[self.step_current]["tile"])
+				return
+		self.step_current -= 1
+		if self.step_current < 0:
+			self.step_current = len(self.step_track)-1	# XXX: fix by disabling next/previous
+		self._load_tile_nr(self.step_current)
+
+
+	# Handlers for "intro" tile
+	def intro_on_load(self):
+		self["label2"].set_text(self._load_label("intro.txt"))
+		self["label2"].set_use_markup(True)
+		return True
+
+
+	def intro_on_next(self):
+		if self["radio_novice"].get_active():
+			pass # The default track is already Novice
+		elif self["radio_standard"].get_active():
+			print "standard"
+		elif self["radio_expert"].get_active():
+			print "expert"
+		return True
+
+
+	# Handlers for "ndisks"
+	def ndisks_on_load(self):
+		self["label2"].set_text(self._load_label("ndisks.txt"))
+		self["label2"].set_use_markup(True)
+		return True
+
+
+	# Handlers for "win1"
+	def win1_on_button1_clicked(self, obj):
+		print "clicked"
+
+logging.basicConfig(level=logging.DEBUG)
 w = MainWin()
 gtk.main()
 

==== //depot/projects/soc2007/ivoras_finstall/installer/glade/mainwin.glade#4 (text+ko) ====

@@ -3,6 +3,7 @@
 <!--*- mode: xml -*-->
 <glade-interface>
   <widget class="GtkWindow" id="mainwin">
+    <property name="height_request">450</property>
     <property name="visible">True</property>
     <property name="border_width">1</property>
     <property name="title" translatable="yes">FreeBSD Installer</property>
@@ -173,6 +174,7 @@
                     <property name="can_default">True</property>
                     <property name="label">gtk-media-previous</property>
                     <property name="use_stock">True</property>
+                    <signal name="clicked" handler="on_button_previous_clicked"/>
                   </widget>
                   <packing>
                     <property name="position">1</property>

==== //depot/projects/soc2007/ivoras_finstall/installer/text/intro.txt#3 (text+ko) ====



More information about the p4-projects mailing list