Jid-multi almost works.
This commit is contained in:
		
							parent
							
								
									aed92d21b7
								
							
						
					
					
						commit
						db089f103d
					
				
					 5 changed files with 420 additions and 132 deletions
				
			
		|  | @ -286,11 +286,11 @@ | |||
| 	      <property name="spacing">0</property> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkLabel" id="instructions_label"> | ||||
| 		<widget class="GtkLabel" id="notes_label"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="label" translatable="yes"><b>Fill in the form</b></property> | ||||
| 		  <property name="label" translatable="yes">Please wait while the command is sending...</property> | ||||
| 		  <property name="use_underline">False</property> | ||||
| 		  <property name="use_markup">True</property> | ||||
| 		  <property name="use_markup">False</property> | ||||
| 		  <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 		  <property name="wrap">False</property> | ||||
| 		  <property name="selectable">False</property> | ||||
|  | @ -651,26 +651,39 @@ | |||
| 	  <property name="spacing">0</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkButton" id="cancel_button"> | ||||
| 	    <widget class="GtkHBox" id="hbox2958"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="can_focus">True</property> | ||||
| 	      <property name="label">gtk-cancel</property> | ||||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:06 GMT"/> | ||||
| 	      <property name="homogeneous">False</property> | ||||
| 	      <property name="spacing">0</property> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkButton" id="cancel_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="label">gtk-cancel</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		  <signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:32 GMT"/> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
| 		  <property name="padding">0</property> | ||||
| 		  <property name="expand">False</property> | ||||
| 		  <property name="fill">False</property> | ||||
| 		</packing> | ||||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<placeholder/> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">3</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">False</property> | ||||
| 	      <property name="expand">True</property> | ||||
| 	      <property name="fill">True</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <placeholder/> | ||||
| 	  </child> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkButton" id="back_button"> | ||||
| 	      <property name="visible">True</property> | ||||
|  | @ -679,10 +692,10 @@ | |||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <signal name="clicked" handler="on_back_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:13 GMT"/> | ||||
| 	      <signal name="clicked" handler="on_back_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:50 GMT"/> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">3</property> | ||||
| 	      <property name="padding">0</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">False</property> | ||||
| 	    </packing> | ||||
|  | @ -696,7 +709,7 @@ | |||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <signal name="clicked" handler="on_forward_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:18 GMT"/> | ||||
| 	      <signal name="clicked" handler="on_forward_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:47 GMT"/> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">3</property> | ||||
|  | @ -713,7 +726,23 @@ | |||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <signal name="clicked" handler="on_execute_button_clicked" last_modification_time="Thu, 22 Jun 2006 19:56:23 GMT"/> | ||||
| 	      <signal name="clicked" handler="on_execute_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:42 GMT"/> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">3</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">False</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkButton" id="close_button"> | ||||
| 	      <property name="can_focus">True</property> | ||||
| 	      <property name="label">gtk-close</property> | ||||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <signal name="clicked" handler="on_close_button_clicked" last_modification_time="Mon, 10 Jul 2006 16:24:38 GMT"/> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">3</property> | ||||
|  |  | |||
|  | @ -199,61 +199,214 @@ | |||
|   <property name="focus_on_map">True</property> | ||||
| 
 | ||||
|   <child> | ||||
|     <widget class="GtkScrolledWindow" id="data_form_scrolledwindow"> | ||||
|     <widget class="GtkVBox" id="vbox111"> | ||||
|       <property name="visible">True</property> | ||||
|       <property name="can_focus">True</property> | ||||
|       <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> | ||||
|       <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
|       <property name="shadow_type">GTK_SHADOW_NONE</property> | ||||
|       <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
|       <property name="homogeneous">False</property> | ||||
|       <property name="spacing">10</property> | ||||
| 
 | ||||
|       <child> | ||||
| 	<widget class="GtkVBox" id="container_vbox"> | ||||
| 	  <property name="border_width">5</property> | ||||
| 	<widget class="GtkScrolledWindow" id="data_form_scrolledwindow"> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="spacing">5</property> | ||||
| 	  <property name="can_focus">True</property> | ||||
| 	  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 	  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 	  <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
| 	  <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkLabel" id="form_instructions_label"> | ||||
| 	    <widget class="GtkViewport" id="viewport2"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="label" translatable="yes"></property> | ||||
| 	      <property name="use_underline">False</property> | ||||
| 	      <property name="use_markup">False</property> | ||||
| 	      <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 	      <property name="wrap">True</property> | ||||
| 	      <property name="selectable">False</property> | ||||
| 	      <property name="xalign">0</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
| 	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> | ||||
| 	      <property name="width_chars">-1</property> | ||||
| 	      <property name="single_line_mode">False</property> | ||||
| 	      <property name="angle">0</property> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">5</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">False</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 	      <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkHSeparator" id="hseparator16"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">5</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">True</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 	      <child> | ||||
| 		<widget class="GtkVBox" id="container_vbox"> | ||||
| 		  <property name="border_width">5</property> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="homogeneous">False</property> | ||||
| 		  <property name="spacing">5</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <placeholder/> | ||||
| 		  <child> | ||||
| 		    <widget class="GtkLabel" id="form_instructions_label"> | ||||
| 		      <property name="visible">True</property> | ||||
| 		      <property name="label" translatable="yes"></property> | ||||
| 		      <property name="use_underline">False</property> | ||||
| 		      <property name="use_markup">False</property> | ||||
| 		      <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 		      <property name="wrap">True</property> | ||||
| 		      <property name="selectable">False</property> | ||||
| 		      <property name="xalign">0</property> | ||||
| 		      <property name="yalign">0.5</property> | ||||
| 		      <property name="xpad">0</property> | ||||
| 		      <property name="ypad">0</property> | ||||
| 		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> | ||||
| 		      <property name="width_chars">-1</property> | ||||
| 		      <property name="single_line_mode">False</property> | ||||
| 		      <property name="angle">0</property> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">5</property> | ||||
| 		      <property name="expand">False</property> | ||||
| 		      <property name="fill">False</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 
 | ||||
| 		  <child> | ||||
| 		    <widget class="GtkHSeparator" id="form_instructions_hseparator"> | ||||
| 		      <property name="visible">True</property> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">5</property> | ||||
| 		      <property name="expand">False</property> | ||||
| 		      <property name="fill">True</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 
 | ||||
| 		  <child> | ||||
| 		    <placeholder/> | ||||
| 		  </child> | ||||
| 		</widget> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	  </child> | ||||
| 	</widget> | ||||
| 	<packing> | ||||
| 	  <property name="padding">0</property> | ||||
| 	  <property name="expand">True</property> | ||||
| 	  <property name="fill">True</property> | ||||
| 	</packing> | ||||
|       </child> | ||||
| 
 | ||||
|       <child> | ||||
| 	<widget class="GtkTable" id="item_list_table"> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="n_rows">1</property> | ||||
| 	  <property name="n_columns">2</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="row_spacing">0</property> | ||||
| 	  <property name="column_spacing">0</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkScrolledWindow" id="scrolledwindow36"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="can_focus">True</property> | ||||
| 	      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> | ||||
| 	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> | ||||
| 	      <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
| 	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkTreeView" id="item_treeview"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="headers_visible">False</property> | ||||
| 		  <property name="rules_hint">False</property> | ||||
| 		  <property name="reorderable">False</property> | ||||
| 		  <property name="enable_search">True</property> | ||||
| 		  <property name="fixed_height_mode">False</property> | ||||
| 		  <property name="hover_selection">False</property> | ||||
| 		  <property name="hover_expand">False</property> | ||||
| 		</widget> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="left_attach">0</property> | ||||
| 	      <property name="right_attach">1</property> | ||||
| 	      <property name="top_attach">0</property> | ||||
| 	      <property name="bottom_attach">1</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkVBox" id="vbox112"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="homogeneous">False</property> | ||||
| 	      <property name="spacing">0</property> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkButton" id="clear_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="label">gtk-clear</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
| 		  <property name="padding">0</property> | ||||
| 		  <property name="expand">False</property> | ||||
| 		  <property name="fill">True</property> | ||||
| 		  <property name="pack_type">GTK_PACK_END</property> | ||||
| 		</packing> | ||||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkButton" id="remove_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="label">gtk-remove</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
| 		  <property name="padding">0</property> | ||||
| 		  <property name="expand">False</property> | ||||
| 		  <property name="fill">True</property> | ||||
| 		  <property name="pack_type">GTK_PACK_END</property> | ||||
| 		</packing> | ||||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkButton" id="add_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="label">gtk-add</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
| 		  <property name="padding">0</property> | ||||
| 		  <property name="expand">False</property> | ||||
| 		  <property name="fill">True</property> | ||||
| 		</packing> | ||||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkButton" id="edit_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="label">gtk-edit</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
| 		  <property name="padding">0</property> | ||||
| 		  <property name="expand">False</property> | ||||
| 		  <property name="fill">False</property> | ||||
| 		</packing> | ||||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<placeholder/> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="left_attach">1</property> | ||||
| 	      <property name="right_attach">2</property> | ||||
| 	      <property name="top_attach">0</property> | ||||
| 	      <property name="bottom_attach">1</property> | ||||
| 	      <property name="x_options">fill</property> | ||||
| 	      <property name="y_options">fill</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 	</widget> | ||||
| 	<packing> | ||||
| 	  <property name="padding">0</property> | ||||
| 	  <property name="expand">True</property> | ||||
| 	  <property name="fill">True</property> | ||||
| 	</packing> | ||||
|       </child> | ||||
|     </widget> | ||||
|   </child> | ||||
|  |  | |||
|  | @ -61,11 +61,11 @@ class CommandWindow: | |||
| 		self.xml = gtkgui_helpers.get_glade('adhoc_commands_window.glade') | ||||
| 		self.window = self.xml.get_widget('adhoc_commands_window') | ||||
| 		for name in ('cancel_button', 'back_button', 'forward_button', | ||||
| 			'execute_button','stages_notebook', | ||||
| 			'execute_button','close_button','stages_notebook', | ||||
| 			'retrieving_commands_stage_vbox', | ||||
| 			'command_list_stage_vbox','command_list_vbox', | ||||
| 			'sending_form_stage_vbox','sending_form_progressbar', | ||||
| 			'no_commands_stage_vbox','error_stage_vbox', | ||||
| 			'notes_label','no_commands_stage_vbox','error_stage_vbox', | ||||
| 			'error_description_label'): | ||||
| 			self.__dict__[name] = self.xml.get_widget(name) | ||||
| 
 | ||||
|  | @ -75,6 +75,7 @@ class CommandWindow: | |||
| 		self.sending_form_stage_vbox.pack_start(self.data_form_widget) | ||||
| 
 | ||||
| 		# setting initial stage | ||||
| 		self.close_button.set_no_show_all(True) | ||||
| 		self.stage1() | ||||
| 
 | ||||
| 		# displaying the window | ||||
|  | @ -87,6 +88,7 @@ class CommandWindow: | |||
| 	def stage_back_button_clicked(self, *anything): assert False | ||||
| 	def stage_forward_button_clicked(self, *anything): assert False | ||||
| 	def stage_execute_button_clicked(self, *anything): assert False | ||||
| 	def stage_close_button_clicked(self, *anything): assert False | ||||
| 	def stage_adhoc_commands_window_delete_event(self, *anything): assert False | ||||
| 	def do_nothing(self, *anything): return False | ||||
| 
 | ||||
|  | @ -103,8 +105,11 @@ class CommandWindow: | |||
| 	def on_execute_button_clicked(self, *anything): | ||||
| 		return self.stage_execute_button_clicked(*anything) | ||||
| 
 | ||||
| 	def on_close_button_clicked(self, *anything): | ||||
| 		return self.stage_close_button_clicked(*anything) | ||||
| 
 | ||||
| 	def on_adhoc_commands_window_destroy(self, *anything): | ||||
| 		# do all actions that are needed to remove this object from memory... | ||||
| 		# TODO: do all actions that are needed to remove this object from memory... | ||||
| 		self.remove_pulsing() | ||||
| 
 | ||||
| 	def on_adhoc_commands_window_delete_event(self, *anything): | ||||
|  | @ -215,6 +220,8 @@ class CommandWindow: | |||
| 
 | ||||
| 		assert isinstance(self.commandnode, unicode) | ||||
| 
 | ||||
| 		self.form_status = None | ||||
| 
 | ||||
| 		self.stages_notebook.set_current_page( | ||||
| 			self.stages_notebook.page_num( | ||||
| 				self.sending_form_stage_vbox)) | ||||
|  | @ -231,6 +238,7 @@ class CommandWindow: | |||
| 		self.stage_back_button_clicked = self.stage3_back_button_clicked | ||||
| 		self.stage_forward_button_clicked = self.stage3_forward_button_clicked | ||||
| 		self.stage_execute_button_clicked = self.stage3_execute_button_clicked | ||||
| 		self.stage_close_button_clicked = self.stage3_close_button_clicked | ||||
| 		self.stage_adhoc_commands_window_delete_event = self.stage3_cancel_button_clicked | ||||
| 
 | ||||
| 	def stage3_finish(self): | ||||
|  | @ -255,6 +263,14 @@ class CommandWindow: | |||
| 			return False | ||||
| 		return True | ||||
| 
 | ||||
| 	def stage3_close_button_clicked(self, widget): | ||||
| 		# this works also as a handler for window_delete_event, so we have to return appropriate | ||||
| 		# values | ||||
| 		if widget==self.window: | ||||
| 			return False | ||||
| 		else: | ||||
| 			self.window.destroy() | ||||
| 
 | ||||
| 	def stage3_back_button_clicked(self, widget): | ||||
| 		self.stage3_submit_form('prev') | ||||
| 
 | ||||
|  | @ -287,23 +303,24 @@ class CommandWindow: | |||
| 		if self.sessionid is None: | ||||
| 			self.sessionid = command.getAttr('sessionid') | ||||
| 
 | ||||
| 		self.dataform = dataforms.DataForm(node=command.getTag('x')) | ||||
| 		self.form_status = command.getAttr('status') | ||||
| 
 | ||||
| 		self.data_form_widget.set_sensitive(True) | ||||
| 		try: | ||||
| 			self.data_form_widget.data_form=self.dataform | ||||
| 		except dataforms.BadDataFormNode: | ||||
| 			# TODO: translate | ||||
| 			self.stage5('Service sent malformed data', senderror=True) | ||||
| 		self.data_form_widget.show() | ||||
| 		if command.getTag('x') is not None: | ||||
| 			self.dataform = dataforms.DataForm(node=command.getTag('x')) | ||||
| 
 | ||||
| 			self.data_form_widget.set_sensitive(True) | ||||
| 			try: | ||||
| 				self.data_form_widget.data_form=self.dataform | ||||
| 			except dataforms.BadDataFormNode: | ||||
| 				# TODO: translate | ||||
| 				self.stage5('Service sent malformed data', senderror=True) | ||||
| 			self.data_form_widget.show() | ||||
| 		else: | ||||
| 			self.data_form_widget.hide() | ||||
| 
 | ||||
| 		action = command.getTag('action') | ||||
| 		if action is None: | ||||
| 			# no action tag? check if that's last stage... | ||||
| 			if command.getAttr('status')=='completed': | ||||
| 				self.cancel_button.set_sensitive(False) | ||||
| 			else: | ||||
| 				self.cancel_button.set_sensitive(True) | ||||
| 			self.cancel_button.set_sensitive(True) | ||||
| 			self.back_button.set_sensitive(False) | ||||
| 			self.forward_button.set_sensitive(False) | ||||
| 			self.execute_button.set_sensitive(True) | ||||
|  | @ -314,6 +331,25 @@ class CommandWindow: | |||
| 			self.forward_button.set_sensitive(action.getTag('next') is not None) | ||||
| 			self.execute_button.set_sensitive(True) | ||||
| 
 | ||||
| 		if self.form_status == 'completed': | ||||
| 			self.cancel_button.set_sensitive(False) | ||||
| 			self.back_button.set_sensitive(False) | ||||
| 			self.forward_button.set_sensitive(False) | ||||
| 			self.execute_button.set_no_show_all(True) | ||||
| 			self.execute_button.hide() | ||||
| 			self.close_button.set_no_show_all(False) | ||||
| 			self.close_button.show() | ||||
| 			self.stage_adhoc_commands_window_delete_event = self.stage3_close_button_clicked | ||||
| 
 | ||||
| 		note = command.getTag('note') | ||||
| 		if note is not None: | ||||
| 			self.notes_label.set_text(note.getData().decode('utf-8')) | ||||
| 			self.notes_label.set_no_show_all(False) | ||||
| 			self.notes_label.show() | ||||
| 		else: | ||||
| 			self.notes_label.set_no_show_all(True) | ||||
| 			self.notes_label.hide() | ||||
| 
 | ||||
| # stage 4: no commands are exposed | ||||
| 	def stage4(self): | ||||
| 		'''Display the message. Wait for user to close the window''' | ||||
|  |  | |||
|  | @ -249,7 +249,7 @@ class DataForm(xmpp.Node, object): | |||
| 				self.delChild('recorded') | ||||
| 			except ValueError: | ||||
| 				pass | ||||
| 			self.addChild('recorded', None, fields) | ||||
| 			self.addChild('recorded', {}, fields) | ||||
| 
 | ||||
| 	def del_fields(self): | ||||
| 		if self.mode is DATAFORM_SINGLE: | ||||
|  | @ -335,7 +335,10 @@ class DataField(xmpp.Node, object): | |||
| 		self.setAttr('var', var) | ||||
| 
 | ||||
| 	def del_var(self): | ||||
| 		self.delAttr('var') | ||||
| 		try: | ||||
| 			self.delAttr('var') | ||||
| 		except KeyError: | ||||
| 			pass | ||||
| 
 | ||||
| 	var = property(get_var, set_var, del_var, | ||||
| 		""" Field name. """) | ||||
|  | @ -347,7 +350,10 @@ class DataField(xmpp.Node, object): | |||
| 		self.setAttr('label', label) | ||||
| 
 | ||||
| 	def del_label(self): | ||||
| 		self.delAttr('label') | ||||
| 		try: | ||||
| 			self.delAttr('label') | ||||
| 		except KeyError: | ||||
| 			pass | ||||
| 
 | ||||
| 	label = property(get_label, set_label, del_label, | ||||
| 		""" Human-readable name for field. """) | ||||
|  | @ -384,6 +390,14 @@ class DataField(xmpp.Node, object): | |||
| 	required = property(get_required, set_required, None, | ||||
| 		""" If this is set to True, the field is required for form to be valid. """) | ||||
| 
 | ||||
| 	def iter_values(self): | ||||
| 		assert self.type in ('list-single', 'list-multi', 'jid-multi') | ||||
| 
 | ||||
| 		for element in self.getChildren(): | ||||
| 			if not isinstance(element, xmpp.Node): continue | ||||
| 			if not element.getName()=='value': continue | ||||
| 			yield element.getData().decode('utf-8') | ||||
| 
 | ||||
| 	def get_value(self): | ||||
| 		if self.type in ('boolean',): | ||||
| 			if self.getTagData('value') in (1, 'true'): | ||||
|  | @ -430,8 +444,10 @@ class DataField(xmpp.Node, object): | |||
| 		for element in self.getChildren(): | ||||
| 			if not isinstance(element, xmpp.Node): continue | ||||
| 			if not element.getName()=='option': continue | ||||
| 			if element.getTag('value') is None: raise BadDataFormNode | ||||
| 			yield element.getAttr('label'), element.getTag('value').getData() | ||||
| 			try: | ||||
| 				yield element.getAttr('label'), element.getTag('value').getData() | ||||
| 			except TypeError: | ||||
| 				raise BadDataFormNode | ||||
| 
 | ||||
| 	def get_options(self): | ||||
| 		""" Returns a list of tuples: (label, value). """ | ||||
|  |  | |||
							
								
								
									
										148
									
								
								src/dataforms.py
									
										
									
									
									
								
							
							
						
						
									
										148
									
								
								src/dataforms.py
									
										
									
									
									
								
							|  | @ -17,6 +17,8 @@ | |||
| """ This module contains widget that can display data form (JEP-0004). """ | ||||
| 
 | ||||
| import gtk | ||||
| import pango | ||||
| 
 | ||||
| import gtkgui_helpers | ||||
| 
 | ||||
| import common.xmpp as xmpp | ||||
|  | @ -27,12 +29,13 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 	""" Data Form widget. Use like any other widget. """ | ||||
| 	def __init__(self, dataformnode=None): | ||||
| 		""" Create a widget. """ | ||||
| 		gtk.Alignment.__init__(self) | ||||
| 		gtk.Alignment.__init__(self, xscale=1.0, yscale=1.0) | ||||
| 
 | ||||
| 		self._data_form = None | ||||
| 
 | ||||
| 		self.xml=gtkgui_helpers.get_glade('data_form_window.glade', 'data_form_scrolledwindow') | ||||
| 		self.instructions = self.xml.get_widget('form_instructions_label') | ||||
| 		self.separator = self.xml.get_widget('form_instructions_hseparator') | ||||
| 		self.container = self.xml.get_widget('container_vbox') | ||||
| 
 | ||||
| 		self.add(self.xml.get_widget('data_form_scrolledwindow')) | ||||
|  | @ -54,6 +57,18 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 		self.form.show() | ||||
| 		self.container.pack_end(self.form, expand=True, fill=True) | ||||
| 
 | ||||
| 		if dataform.instructions is None: | ||||
| 			self.instructions.set_no_show_all(True) | ||||
| 			self.instructions.hide() | ||||
| 			self.separator.set_no_show_all(True) | ||||
| 			self.separator.hide() | ||||
| 		else: | ||||
| 			self.instructions.set_text(dataform.instructions) | ||||
| 			self.instructions.set_no_show_all(False) | ||||
| 			self.instructions.show() | ||||
| 			self.separator.set_no_show_all(False) | ||||
| 			self.separator.show() | ||||
| 
 | ||||
| 	def get_data_form(self): | ||||
| 		""" Data form displayed in the widget or None if no form. """ | ||||
| 		return self._data_form | ||||
|  | @ -81,39 +96,6 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 		""" Treat 'us' as one widget. """ | ||||
| 		self.show_all() | ||||
| 
 | ||||
| #?	def filled_data_form(self): | ||||
| #?		""" Generates form that contains values filled by user. """ | ||||
| #?		assert isinstance(self._data_form, dataforms.DataForm) | ||||
| #? | ||||
| #?		form = xmpp.Node('x', {'xmlns':xmpp.NS_DATA, 'type':'submit'}) | ||||
| #? | ||||
| #? | ||||
| #?		for field in self._data_form.kids: | ||||
| #?			if not isinstance(field, xmpp.DataField): continue | ||||
| #?			 | ||||
| #?			ftype = field.getType() | ||||
| #?			if ftype not in ('boolean', 'fixed', 'hidden', 'jid-multi', | ||||
| #?				'jid-single', 'list-multi', 'list-single', | ||||
| #?				'text-multi', 'text-private', 'text-single'): | ||||
| #?				ftype = 'text-single' | ||||
| #? | ||||
| #?			if ftype in ('fixed',): | ||||
| #?				continue | ||||
| #? | ||||
| #?			newfield = xmpp.Node('field', {'var': field.getVar()}) | ||||
| #? | ||||
| #?			if ftype in ('jid-multi', 'list-multi', 'text-multi'): | ||||
| #?				for value in field.getValues(): | ||||
| #?					newvalue = xmpp.Node('value', {}, [value]) | ||||
| #?					newfield.addChild(node=newvalue) | ||||
| #?			else: | ||||
| #?				newvalue = xmpp.Node('value', {}, [field.getValue()]) | ||||
| #?				newfield.addChild(node=newvalue) | ||||
| #? | ||||
| #?			form.addChild(node=newfield) | ||||
| #? | ||||
| #?		return form | ||||
| 
 | ||||
| # "private" methods | ||||
| 
 | ||||
| # we have actually two different kinds of data forms: one is a simple form to fill, | ||||
|  | @ -129,6 +111,8 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 			assert dataform.mode==dataforms.DATAFORM_SINGLE | ||||
| 
 | ||||
| 			gtk.Table.__init__(self) | ||||
| 			self.set_col_spacings(6) | ||||
| 			self.set_row_spacings(6) | ||||
| 
 | ||||
| 			self._data_form = dataform | ||||
| 
 | ||||
|  | @ -162,10 +146,8 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 					commonwidget=False | ||||
| 					widget = gtk.Label(field.value) | ||||
| 					widget.set_line_wrap(True) | ||||
| 					self.attach(widget, leftattach, rightattach, linecounter, linecounter+1) | ||||
| 
 | ||||
| 				elif field.type in ('jid-multi'): | ||||
| 					widget = gtk.Label(field.type) | ||||
| 					self.attach(widget, leftattach, rightattach, linecounter, linecounter+1, | ||||
| 						xoptions=gtk.FILL, yoptions=gtk.FILL) | ||||
| 
 | ||||
| 				elif field.type == 'list-single': | ||||
| 					# TODO: When more than few choices, make a list | ||||
|  | @ -204,6 +186,42 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 						field.value = u'' | ||||
| 					widget.set_text(field.value) | ||||
| 
 | ||||
| 				elif field.type == 'jid-multi': | ||||
| 					commonwidget = False | ||||
| 
 | ||||
| 					xml = gtkgui_helpers.get_glade('data_form_window.glade', 'item_list_table') | ||||
| 					widget = xml.get_widget('item_list_table') | ||||
| 					treeview = xml.get_widget('item_treeview') | ||||
| 
 | ||||
| 					listmodel = gtk.ListStore(str, bool) | ||||
| 					for value in field.iter_values(): | ||||
| 						# nobody will create several megabytes long stanza | ||||
| 						listmodel.insert(999999, (value,False)) | ||||
| 
 | ||||
| 					treeview.set_model(listmodel) | ||||
| 
 | ||||
| 					renderer = gtk.CellRendererText() | ||||
| 					renderer.set_property('ellipsize', pango.ELLIPSIZE_START) | ||||
| 					renderer.set_property('editable', True) | ||||
| 					renderer.connect('edited', | ||||
| 						self.on_jid_multi_cellrenderertext_edited, listmodel, field) | ||||
| 
 | ||||
| 					treeview.append_column(gtk.TreeViewColumn(None, renderer, | ||||
| 						text=0, editable=1)) | ||||
| 
 | ||||
| 					xml.get_widget('add_button').connect('clicked', | ||||
| 						self.on_jid_multi_add_button_clicked, listmodel, field) | ||||
| 					xml.get_widget('edit_button').connect('clicked', | ||||
| 						self.on_jid_multi_edit_button_clicked, treeview) | ||||
| 					xml.get_widget('remove_button').connect('clicked', | ||||
| 						self.on_jid_multi_remove_button_clicked, treeview) | ||||
| 					xml.get_widget('clear_button').connect('clicked', | ||||
| 						self.on_jid_multi_clean_button_clicked, listmodel, field) | ||||
| 
 | ||||
| 					self.attach(widget, 1, 2, linecounter, linecounter+1) | ||||
| 
 | ||||
| 					del xml | ||||
| 
 | ||||
| 				elif field.type == 'text-private': | ||||
| 					widget = gtk.Entry() | ||||
| 					widget.connect('changed', self.on_text_single_entry_changed, field) | ||||
|  | @ -214,13 +232,20 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 
 | ||||
| 				elif field.type == 'text-multi': | ||||
| 					# TODO: bigger text view | ||||
| 					widget = gtk.TextView() | ||||
| 					widget.set_wrap_mode(gtk.WRAP_WORD) | ||||
| 					widget.get_buffer().connect('changed', self.on_text_multi_textbuffer_changed, | ||||
| 					commonwidget = False | ||||
| 
 | ||||
| 					textwidget = gtk.TextView() | ||||
| 					textwidget.set_wrap_mode(gtk.WRAP_WORD) | ||||
| 					textwidget.get_buffer().connect('changed', self.on_text_multi_textbuffer_changed, | ||||
| 						field) | ||||
| 					if field.value is None: | ||||
| 						field.value = u'' | ||||
| 					widget.get_buffer().set_text(field.value) | ||||
| 					textwidget.get_buffer().set_text(field.value) | ||||
| 					 | ||||
| 					widget = gtk.ScrolledWindow() | ||||
| 					widget.add(textwidget) | ||||
| 
 | ||||
| 					self.attach(widget, 1, 2, linecounter, linecounter+1) | ||||
| 
 | ||||
| 				else:# field.type == 'text-single' or field.type is nonstandard: | ||||
| 					# JEP says that if we don't understand some type, we | ||||
|  | @ -234,11 +259,13 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 				if commonlabel and field.label is not None: | ||||
| 					label = gtk.Label(field.label) | ||||
| 					label.set_alignment(1.0, 0.5) | ||||
| 					self.attach(label, 0, 1, linecounter, linecounter+1) | ||||
| 					self.attach(label, 0, 1, linecounter, linecounter+1, | ||||
| 						xoptions=gtk.FILL, yoptions=gtk.FILL) | ||||
| 
 | ||||
| 				if commonwidget: | ||||
| 					assert widget is not None | ||||
| 					self.attach(widget, 1, 2, linecounter, linecounter+1) | ||||
| 					self.attach(widget, 1, 2, linecounter, linecounter+1, | ||||
| 						yoptions=gtk.FILL) | ||||
| 				widget.show_all() | ||||
| 
 | ||||
| 				if commondesc and field.description is not None: | ||||
|  | @ -247,7 +274,8 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 						gtkgui_helpers.escape_for_pango_markup(field.description)+\ | ||||
| 						'</small>') | ||||
| 					label.set_line_wrap(True) | ||||
| 					self.attach(label, 2, 3, linecounter, linecounter+1) | ||||
| 					self.attach(label, 2, 3, linecounter, linecounter+1, | ||||
| 						xoptions=gtk.FILL|gtk.SHRINK, yoptions=gtk.FILL|gtk.SHRINK) | ||||
| 
 | ||||
| 				linecounter+=1 | ||||
| 			if self.get_property('visible'): | ||||
|  | @ -264,10 +292,11 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 			field.value = value | ||||
| 
 | ||||
| 		def on_list_multi_checkbutton_toggled(self, widget, field, value): | ||||
| 			# TODO: make some methods like add_value and remove_value | ||||
| 			if widget.get_active() and value not in field.value: | ||||
| 				field.value.append(value) | ||||
| 				field.value += [value] | ||||
| 			elif not widget.get_active() and value in field.value: | ||||
| 				field.value.remove(value) | ||||
| 				field.value = [v for v in field.value if v!=value] | ||||
| 
 | ||||
| 		def on_text_single_entry_changed(self, widget, field): | ||||
| 			field.value = widget.get_text() | ||||
|  | @ -277,6 +306,31 @@ class DataFormWidget(gtk.Alignment, object): | |||
| 				widget.get_start_iter(), | ||||
| 				widget.get_end_iter()) | ||||
| 
 | ||||
| 		def on_jid_multi_cellrenderertext_edited(self, cell, path, newtext, model, field): | ||||
| 			old=model[path][0] | ||||
| 			model[path][0]=newtext | ||||
| 
 | ||||
| 			values = field.values | ||||
| 			values[values.index(old)]=newtext | ||||
| 			field.values = values | ||||
| 
 | ||||
| 		def on_jid_multi_add_button_clicked(self, widget, model, field): | ||||
| 			iter = model.insert(999999, ("new@jid",)) | ||||
| 			field.value += ["new@jid"] | ||||
| 
 | ||||
| 		def on_jid_multi_edit_button_clicked(self, widget, treeview): | ||||
| 			model, iter = treeview.get_selection().get_selected() | ||||
| 			assert iter is not None | ||||
| 
 | ||||
| 			model[iter][1]=True | ||||
| 
 | ||||
| 		def on_jid_multi_remove_button_clicked(self, widget, model, field): | ||||
| 			pass | ||||
| 
 | ||||
| 		def on_jid_multi_clean_button_clicked(self, widget, model, field): | ||||
| 			model.clear() | ||||
| 			del field.value | ||||
| 
 | ||||
| 	class MultipleForm(gtk.Alignment, object): | ||||
| 		def __init__(self, dataform): | ||||
| 			assert dataform.mode==dataforms.DATAFORM_MULTIPLE | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue