1   
   2   
   3   
   4   
   5   
   6   
   7   
   8   
   9   
  10   
  11   
  12   
  13   
  14   
  15   
  16   
  17   
  18   
  19   
  20   
  21   
  22   
  23  """Base class module for the wizard GUI elements.""" 
  24   
  25   
  26  import wx 
  27  from wx.lib import buttons, scrolledpanel 
  28   
  29   
  30  from data_store import Relax_data_store; ds = Relax_data_store() 
  31  from graphics import IMAGE_PATH, fetch_icon 
  32  from gui.fonts import font 
  33  from gui.icons import relax_icons 
  34  from gui.interpreter import Interpreter; interpreter = Interpreter() 
  35  from gui.misc import add_border, bitmap_setup 
  36  from gui.string_conv import float_to_gui, str_to_gui 
  37  from lib.check_types import is_float 
  38  from lib.errors import RelaxImplementError 
  39  from status import Status; status = Status() 
  40   
  41   
  42   
  43  ESC_ID = wx.NewId() 
  44   
  45   
  46   
  47 -class Wiz_page(wx.Panel): 
   48      """The wizard pages to be placed inside the wizard. 
  49   
  50      To inherit from this class, you must minimally supply the add_contents() method.  This method should build the specific GUI elements.  The following methods are also designed to be overwritten: 
  51   
  52          - add_artwork(), this builds the left hand artwork section of the page. 
  53          - add_contents(), this builds the right hand section of the page. 
  54          - on_display(), this is executed when the page is displayed. 
  55          - on_display_post(), this is executed when the page is displayed, directly after the on_display method. 
  56          - on_execute(), this is executed when the wizard is terminated or the apply button is hit. 
  57          - on_next(), this is executed when moving to the next wizard page. 
  58   
  59      The following methods can be used by add_contents() to create standard GUI elements: 
  60   
  61          - chooser() 
  62          - combo_box() 
  63          - file_selection() 
  64          - input_field() 
  65          - text() 
  66   
  67      These are described in full detail in their docstrings. 
  68      """ 
  69   
  70       
  71      art_spacing = 20 
  72      divider = None 
  73      height_element = 27 
  74      image_path = IMAGE_PATH + "relax.gif" 
  75      main_text = '' 
  76      setup_fail = False 
  77      size_button = (100, 33) 
  78      size_square_button = (33, 33) 
  79      title = '' 
  80   
  81 -    def __init__(self, parent, height_desc=220): 
   82          """Set up the window. 
  83   
  84          @param parent:          The parent GUI element. 
  85          @type parent:           wx.object instance 
  86          @keyword height_desc:   The height in pixels of the description part of the wizard. 
  87          @type height_desc:      int or None 
  88          """ 
  89   
  90           
  91          self.parent = parent 
  92          self.height_desc = height_desc 
  93   
  94           
  95          wx.Panel.__init__(self, parent, id=-1) 
  96   
  97           
  98          self.exec_status = False 
  99   
 100           
 101          box_main = wx.BoxSizer(wx.HORIZONTAL) 
 102          self.SetSizer(box_main) 
 103   
 104           
 105          self.add_artwork(box_main) 
 106   
 107           
 108          image_x, image_y = self.image.GetSize() 
 109   
 110           
 111          self._main_size = parent._size_x - image_x - self.art_spacing - 2*parent._border 
 112          if self.divider: 
 113              self._div_left = self.divider 
 114              self._div_right = self._main_size - self.divider 
 115          else: 
 116              self._div_left = self._div_right = self._main_size / 2 
 117   
 118           
 119          main_sizer = self._build_main_section(box_main) 
 120   
 121           
 122          self._add_title(main_sizer) 
 123   
 124           
 125          self.add_desc(main_sizer, max_y=self.height_desc) 
 126   
 127           
 128          main_sizer.AddStretchSpacer() 
 129          self.add_contents(main_sizer) 
  130   
 131   
 132 -    def _add_title(self, sizer): 
  133          """Add the title to the dialog. 
 134   
 135          @param sizer:   A sizer object. 
 136          @type sizer:    wx.Sizer instance 
 137          """ 
 138   
 139           
 140          sizer.AddSpacer(10) 
 141   
 142           
 143          title = wx.StaticText(self, -1, self.title) 
 144   
 145           
 146          title.SetFont(font.title) 
 147   
 148           
 149          sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 0) 
 150   
 151           
 152          sizer.AddSpacer(10) 
  153   
 154   
 155 -    def _apply(self, event=None): 
  156          """Apply the operation. 
 157   
 158          @keyword event: The wx event. 
 159          @type event:    wx event 
 160          """ 
 161   
 162           
 163          wx.BeginBusyCursor() 
 164   
 165           
 166          self.exec_status = self.on_execute() 
 167   
 168           
 169          if not self.exec_status: 
 170              if wx.IsBusy(): 
 171                  wx.EndBusyCursor() 
 172              return 
 173   
 174           
 175          self.on_completion() 
 176   
 177           
 178          self.on_apply() 
 179   
 180           
 181          if wx.IsBusy(): 
 182              wx.EndBusyCursor() 
  183   
 184   
 185 -    def _build_main_section(self, sizer): 
  186          """Add the main part of the dialog. 
 187   
 188          @param sizer:   A sizer object. 
 189          @type sizer:    wx.Sizer instance 
 190          @return:        The sizer object for the main part of the dialog. 
 191          @rtype:         wx.Sizer instance 
 192          """ 
 193   
 194           
 195          main_sizer = wx.BoxSizer(wx.VERTICAL) 
 196   
 197           
 198          sizer.Add(main_sizer, 1, wx.EXPAND|wx.ALL, 0) 
 199   
 200           
 201          return main_sizer 
  202   
 203   
 204 -    def add_artwork(self, sizer): 
  205          """Add the artwork to the dialog. 
 206   
 207          @param sizer:   A sizer object. 
 208          @type sizer:    wx.Sizer instance 
 209          """ 
 210   
 211           
 212          if self.image_path: 
 213              self.image = wx.StaticBitmap(self, -1, bitmap_setup(self.image_path)) 
 214              sizer.Add(self.image, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 0) 
 215   
 216           
 217          sizer.AddSpacer(self.art_spacing) 
  218   
 219   
 220 -    def add_contents(self, sizer): 
  221          """Add the specific GUI elements (dummy method). 
 222   
 223          @param sizer:   A sizer object. 
 224          @type sizer:    wx.Sizer instance 
 225          """ 
 226   
 227           
 228          raise RelaxImplementError 
  229   
 230   
 231 -    def add_desc(self, sizer, max_y=220): 
  232          """Add the description to the dialog. 
 233   
 234          @param sizer:   A sizer object. 
 235          @type sizer:    wx.Sizer instance 
 236          @keyword max_y: The maximum height, in number of pixels, for the description. 
 237          @type max_y:    int 
 238          """ 
 239   
 240           
 241          sizer.AddSpacer(5) 
 242          sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0) 
 243          sizer.AddSpacer(5) 
 244   
 245           
 246          panel = scrolledpanel.ScrolledPanel(self, -1, name="desc") 
 247   
 248           
 249          panel_sizer = wx.BoxSizer(wx.VERTICAL) 
 250   
 251           
 252          text = wx.StaticText(panel, -1, self.main_text, style=wx.TE_MULTILINE) 
 253          text.SetFont(font.normal) 
 254   
 255           
 256          text.Wrap(self._main_size - 20) 
 257   
 258           
 259          x, y = text.GetSizeTuple() 
 260   
 261           
 262          if y > max_y-10: 
 263               
 264              panel.SetInitialSize((self._main_size, max_y)) 
 265   
 266           
 267          else: 
 268               
 269              text.Wrap(self._main_size) 
 270   
 271               
 272              panel.SetInitialSize(text.GetSize()) 
 273   
 274           
 275          panel_sizer.Add(text, 0, wx.ALIGN_LEFT, 0) 
 276   
 277           
 278          panel.SetSizer(panel_sizer) 
 279          panel.SetAutoLayout(1) 
 280          panel.SetupScrolling(scroll_x=False, scroll_y=True) 
 281          sizer.Add(panel, 0, wx.ALL|wx.EXPAND) 
 282   
 283           
 284          sizer.AddSpacer(5) 
 285          sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0) 
 286          sizer.AddSpacer(5) 
  287   
 288   
 289 -    def on_apply(self): 
  290          """To be over-ridden if an action is to be performed on hitting the apply button. 
 291   
 292          This method will be called when clicking on the apply button. 
 293          """ 
  294   
 295   
 297          """To be over-ridden if an action is to be performed just before moving back to the previous page. 
 298   
 299          This method is called when moving back to the previous page of the wizard. 
 300          """ 
  301   
 302   
 303 -    def on_completion(self): 
  304          """To be over-ridden if an action is to be performed just after executing self.on_execute(). 
 305   
 306          This method is called just after self.on_execute() has been called 
 307          """ 
  308   
 309   
 310 -    def on_display(self): 
  311          """To be over-ridden if an action is to be performed prior to displaying the page. 
 312   
 313          This method will be called by the wizard class method _display_page() just after hiding all other pages but prior to displaying this page. 
 314          """ 
  315   
 316   
 317 -    def on_display_post(self): 
  318          """To be over-ridden if an action is to be performed after the execution of the on_display() method. 
 319   
 320          This method will be called by the wizard class method _display_page() just after hiding all other pages but prior to displaying this page. 
 321          """ 
  322   
 323   
 324 -    def on_execute(self): 
  325          """To be over-ridden if an action is to be performed just before exiting the page. 
 326   
 327          This method is called when terminating the wizard or hitting the apply button. 
 328          """ 
 329   
 330          return True 
  331   
 332   
 334          """To be over-ridden if an action is to be performed when a page is newly displayed. 
 335   
 336          This method will be called by the wizard class method _display_page() at the very end. 
 337          """ 
  338   
 339   
 341          """To be over-ridden if an action is to be performed just before moving to the next page. 
 342   
 343          This method is called when moving to the next page of the wizard. 
 344          """ 
   345   
 346   
 347   
 349      """The wizard.""" 
 350   
 351       
 352      _size_button = (100, 33) 
 353      ICON_APPLY = fetch_icon('oxygen.actions.dialog-ok-apply', "22x22") 
 354      ICON_BACK = fetch_icon('oxygen.actions.go-previous-view', "22x22") 
 355      ICON_CANCEL = fetch_icon('oxygen.actions.dialog-cancel', "22x22") 
 356      ICON_FINISH = fetch_icon('oxygen.actions.dialog-ok', "22x22") 
 357      ICON_NEXT = fetch_icon('oxygen.actions.go-next-view', "22x22") 
 358      ICON_OK = fetch_icon('oxygen.actions.dialog-ok', "22x22") 
 359      ICON_SKIP = fetch_icon('oxygen.actions.arrow-right-double-relax-blue', "22x22") 
 360      TEXT_APPLY = " Apply" 
 361      TEXT_BACK = " Back" 
 362      TEXT_CANCEL = " Cancel" 
 363      TEXT_FINISH = " Finish" 
 364      TEXT_NEXT = " Next" 
 365      TEXT_OK = " OK" 
 366      TEXT_SKIP = " Skip" 
 367   
 368   
 369 -    def __init__(self, parent=None, size_x=400, size_y=400, title='', border=10, style=wx.DEFAULT_DIALOG_STYLE): 
  370          """Set up the window. 
 371   
 372          @keyword parent:    The parent window. 
 373          @type parent:       wx.Window instance 
 374          @keyword size_x:    The width of the wizard. 
 375          @type size_x:       int 
 376          @keyword size_y:    The height of the wizard. 
 377          @type size_y:       int 
 378          @keyword title:     The title of the wizard dialog. 
 379          @type title:        str 
 380          @keyword border:    The size of the border inside the wizard. 
 381          @type border:       int 
 382          @keyword style:     The dialog style. 
 383          @type style:        wx style 
 384          """ 
 385   
 386           
 387          self._size_x = size_x 
 388          self._size_y = size_y 
 389          self._border = border 
 390          self.title = title 
 391   
 392           
 393          wx.Dialog.__init__(self, parent, id=-1, title=title, style=style) 
 394   
 395           
 396          self.SetIcons(relax_icons) 
 397   
 398           
 399          sizer = wx.BoxSizer(wx.VERTICAL) 
 400          self.SetSizer(sizer) 
 401   
 402           
 403          self._main_sizer = add_border(sizer, border=border, packing=wx.VERTICAL) 
 404   
 405           
 406          self.SetSize((size_x, size_y)) 
 407   
 408           
 409          self.Centre() 
 410   
 411           
 412          self._current_page = 0 
 413          self._num_pages = 0 
 414          self._pages = [] 
 415          self._page_sizers = [] 
 416          self._button_sizers = [] 
 417          self._top_sizers = [] 
 418          self._button_apply_flag = [] 
 419          self._button_skip_flag = [] 
 420          self._buttons = [] 
 421          self._button_ids = [] 
 422          self._exec_on_next = [] 
 423          self._exec_count = [] 
 424          self._proceed_on_error = [] 
 425          self._uf_flush = [] 
 426          self._seq_fn_list = [] 
 427          self._seq_next = [] 
 428          self._seq_prev = [] 
 429          self._skip_flag = [] 
 430   
 431           
 432          self._buttons_built = False 
 433   
 434           
 435          self.Bind(wx.EVT_CLOSE, self._handler_close) 
 436   
 437           
 438          self.acc_list = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, ESC_ID)] 
 439          self.acc_table = wx.AcceleratorTable(self.acc_list) 
 440          self.SetAcceleratorTable(self.acc_table) 
 441          self.Bind(wx.EVT_MENU, self._handler_escape, id=ESC_ID) 
  442   
 443   
 444 -    def _apply(self, event=None): 
  445          """Execute the current page's 'Apply' method. 
 446   
 447          @keyword event: The wx event. 
 448          @type event:    wx event 
 449          """ 
 450   
 451           
 452          self._pages[self._current_page]._apply() 
  453   
 454   
 554   
 555   
 557          """Cancel the operation. 
 558   
 559          @keyword event: The wx event. 
 560          @type event:    wx event 
 561          """ 
 562   
 563           
 564          self._pages[self._current_page].on_next() 
 565   
 566           
 567          self.Close() 
  568   
 569   
 570 -    def _display_page(self, i): 
  571          """Display the given page. 
 572   
 573          @param i:   The index of the page to display. 
 574          @type i:    int 
 575          """ 
 576   
 577           
 578          for j in range(self._num_pages): 
 579              if self._main_sizer.IsShown(self._page_sizers[j]): 
 580                  self._main_sizer.Hide(self._page_sizers[j]) 
 581   
 582           
 583          if status.show_gui: 
 584              self._main_sizer.Show(self._page_sizers[i]) 
 585   
 586           
 587          self._pages[i].on_display() 
 588          self._pages[i].on_display_post() 
 589   
 590           
 591          self.Layout() 
 592          self.Refresh() 
 593   
 594           
 595          self._pages[i].on_init() 
 596   
 597           
 598          self._pages[i].SetFocus() 
  599   
 600   
 602          """Return to the previous page. 
 603   
 604          @keyword event: The wx event. 
 605          @type event:    wx event 
 606          """ 
 607   
 608           
 609          self._pages[self._current_page].on_back() 
 610   
 611           
 612          self._current_page = self._seq_prev[self._current_page] 
 613   
 614           
 615          self._display_page(self._current_page) 
  616   
 617   
 619          """Move to the next page. 
 620   
 621          @keyword event: The wx event. 
 622          @type event:    wx event 
 623          """ 
 624   
 625           
 626          self._pages[self._current_page].on_next() 
 627   
 628           
 629          if not self._skip_flag[self._current_page]: 
 630               
 631              if self._exec_on_next[self._current_page]: 
 632                  self._pages[self._current_page]._apply(event) 
 633   
 634                   
 635                  if self._uf_flush[self._current_page]: 
 636                      interpreter.flush() 
 637   
 638                   
 639                  if not self._pages[self._current_page].exec_status: 
 640                       
 641                      if not self._proceed_on_error[self._current_page]: 
 642                          return 
 643   
 644                   
 645                  self._exec_count[self._current_page] += 1 
 646   
 647           
 648          next_page = self._seq_fn_list[self._current_page]() 
 649   
 650           
 651          if next_page >= len(self._pages): 
 652              self._ok(None) 
 653              return 
 654   
 655           
 656          self._seq_next[self._current_page] = next_page 
 657          self._seq_prev[next_page] = self._current_page 
 658   
 659           
 660          self._current_page = next_page 
 661   
 662           
 663          self._display_page(self._current_page) 
  664   
 665   
 667          """Event handler for the close window action. 
 668   
 669          @keyword event: The wx event. 
 670          @type event:    wx event 
 671          """ 
 672   
 673           
 674          self._pages[self._current_page].on_next() 
 675   
 676           
 677          event.Skip() 
  678   
 679   
 681          """Event handler for key strokes. 
 682   
 683          @keyword event: The wx event. 
 684          @type event:    wx event 
 685          """ 
 686   
 687           
 688          self.Close() 
  689   
 690   
 692          """Standard function for setting the next page to the one directly next in the sequence. 
 693   
 694          @return:    The index of the next page, which is the current page index plus one. 
 695          @rtype:     int 
 696          """ 
 697   
 698           
 699          return self._current_page + 1 
  700   
 701   
 702 -    def _ok(self, event=None): 
  703          """Accept the operation. 
 704   
 705          @keyword event: The wx event. 
 706          @type event:    wx event 
 707          """ 
 708   
 709           
 710          for i in self._seq_loop(): 
 711              if not self._exec_count[i] and not self._skip_flag[i]: 
 712                   
 713                  self._pages[i]._apply(event) 
 714   
 715                   
 716                  if self._uf_flush[i]: 
 717                      interpreter.flush() 
 718   
 719                   
 720                  if not self._pages[self._current_page].exec_status: 
 721                       
 722                      if not self._proceed_on_error[self._current_page]: 
 723                          return 
 724   
 725                   
 726                  self._exec_count[i] += 1 
 727   
 728           
 729          self._pages[self._current_page].on_next() 
 730   
 731           
 732          if self.IsModal(): 
 733              self.EndModal(wx.ID_OK) 
 734          else: 
 735              self.Close() 
  736   
 737   
 739          """Loop over the sequence in the forwards direction.""" 
 740   
 741           
 742          current = 0 
 743   
 744           
 745          yield current 
 746   
 747           
 748          while True: 
 749               
 750              next = self._seq_next[current] 
 751              current = next 
 752   
 753               
 754              if next == None: 
 755                  break 
 756   
 757               
 758              yield next 
  759   
 760   
 761 -    def _skip(self, event=None): 
  762          """Skip the page. 
 763   
 764          @keyword event: The wx event. 
 765          @type event:    wx event 
 766          """ 
 767   
 768           
 769          self._skip_flag[self._current_page] = True 
 770   
 771           
 772          self._go_next(None) 
  773   
 774   
 776          """Override the default wx.Dialog.Destroy() method.""" 
 777   
 778           
 779          self.Close() 
 780   
 781           
 782          for i in range(len(self._buttons)): 
 783               
 784              for name in self._buttons[i]: 
 785                  if hasattr(self._buttons[i][name], 'Destroy'): 
 786                      self._buttons[i][name].Destroy() 
 787                      self._buttons[i][name] = None 
 788   
 789               
 790              if hasattr(self._pages[i], 'Destroy'): 
 791                  self._pages[i].Destroy() 
 792                  self._pages[i] = None 
 793   
 794           
 795          super(Wiz_window, self).DestroyChildren() 
 796          super(Wiz_window, self).Destroy() 
  797   
 798   
 799 -    def add_page(self, panel, apply_button=True, skip_button=False, exec_on_next=True, proceed_on_error=True, uf_flush=False): 
  800          """Add a new page to the wizard. 
 801   
 802          @param panel:               The page to add to the wizard. 
 803          @type panel:                wx.Panel instance 
 804          @keyword apply_button:      A flag which if true will show the apply button for that page. 
 805          @type apply_button:         bool 
 806          @keyword skip_button:       A flag which if true will show the skip button for that page. 
 807          @type skip_button:          bool 
 808          @keyword exec_on_next:      A flag which if true will run the on_execute() method when clicking on the next button. 
 809          @type exec_on_next:         bool 
 810          @keyword proceed_on_error:  A flag which if True will proceed to the next page (or quit if there are no more pages) despite the occurrence of an error in execution.  If False, the page will remain open (the GUI interpreter thread will be flushed first to synchronise). 
 811          @type proceed_on_error:     bool 
 812          @keyword uf_flush:          A flag which if True will cause the GUI interpreter thread to be flushed to clear out all user function call prior to proceeding. 
 813          @type uf_flush:             bool 
 814          @return:                    The index of the page in the wizard. 
 815          @rtype:                     int 
 816          """ 
 817   
 818           
 819          index = self._num_pages 
 820          self._num_pages += 1 
 821          self._pages.append(panel) 
 822   
 823           
 824          self._page_sizers.append(wx.BoxSizer(wx.VERTICAL)) 
 825          self._main_sizer.Add(self._page_sizers[index], 1, wx.ALL|wx.EXPAND, 0) 
 826   
 827           
 828          self._top_sizers.append(wx.BoxSizer(wx.VERTICAL)) 
 829          self._page_sizers[index].Add(self._top_sizers[index], 1, wx.ALL|wx.EXPAND, 0) 
 830   
 831           
 832          self._top_sizers[index].Add(panel, 1, wx.ALL|wx.EXPAND, 0) 
 833   
 834           
 835          self._button_sizers.append(wx.BoxSizer(wx.HORIZONTAL)) 
 836   
 837           
 838          self._page_sizers[index].Add(self._button_sizers[index], 0, wx.ALIGN_RIGHT|wx.ALL, 0) 
 839   
 840           
 841          self._button_apply_flag.append(apply_button) 
 842          self._button_skip_flag.append(skip_button) 
 843   
 844           
 845          self._buttons.append({'back': None, 
 846                                'apply': None, 
 847                                'next': None, 
 848                                'ok': None, 
 849                                'finish': None, 
 850                                'cancel': None}) 
 851   
 852           
 853          self._button_ids.append({'back': -1, 
 854                                   'apply': -1, 
 855                                   'next': -1, 
 856                                   'ok': -1, 
 857                                   'finish': -1, 
 858                                   'cancel': -1}) 
 859   
 860           
 861          self._exec_on_next.append(exec_on_next) 
 862   
 863           
 864          self._exec_count.append(0) 
 865   
 866           
 867          self._proceed_on_error.append(proceed_on_error) 
 868   
 869           
 870          if not proceed_on_error or uf_flush: 
 871              self._uf_flush.append(True) 
 872          else: 
 873              self._uf_flush.append(False) 
 874   
 875           
 876          self._seq_fn_list.append(self._next_fn) 
 877          self._seq_next.append(None) 
 878          self._seq_prev.append(None) 
 879   
 880           
 881          self._skip_flag.append(False) 
 882   
 883           
 884          panel.page_index = index 
 885   
 886           
 887          return index 
  888   
 889   
 891          """Prevent moving forwards (or unblock). 
 892   
 893          @keyword block: A flag which if True will block forwards movement and if False will unblock. 
 894          @type block:    bool 
 895          """ 
 896   
 897           
 898          buttons = ['next', 'ok', 'finish'] 
 899   
 900           
 901          for i in range(len(buttons)): 
 902               
 903              button = self._buttons[self._current_page][buttons[i]] 
 904              if button == None: 
 905                  continue 
 906   
 907               
 908              if block: 
 909                  button.Disable() 
 910   
 911               
 912              else: 
 913                  button.Enable() 
  914   
 915   
 916 -    def get_page(self, index): 
  917          """Get a page from the wizard. 
 918   
 919          @param index:   The index of the page. 
 920          @type index:    int 
 921          @return:        The page object. 
 922          @rtype:         Wiz_page instance. 
 923          """ 
 924   
 925           
 926          return self._pages[index] 
  927   
 928   
 930          """Reset the wizard.""" 
 931   
 932           
 933          for i in range(len(self._exec_count)): 
 934              self._exec_count[i] = 0 
  935   
 936   
 937 -    def run(self, modal=False): 
  938          """Execute the wizard. 
 939   
 940          @keyword modal: A flag which if True will cause the wizard to be run as a modal dialog. 
 941          @type modal:    bool 
 942          @return:        The status from the modal operation, i.e. True if the wizard is run, False if cancelled or other error occur.  For modeless operation, this returns nothing. 
 943          @rtype:         bool or None 
 944          """ 
 945   
 946           
 947          for i in range(self._num_pages): 
 948              if self._pages[i].setup_fail: 
 949                  return 
 950   
 951           
 952          if not self._buttons_built: 
 953              self._build_buttons() 
 954   
 955           
 956          self._display_page(0) 
 957   
 958           
 959          if self._pages[0].setup_fail: 
 960              return 
 961   
 962           
 963          if not status.show_gui: 
 964              return 
 965   
 966           
 967          if modal: 
 968               
 969              wiz_status = self.ShowModal() 
 970   
 971               
 972              return wiz_status 
 973   
 974           
 975          else: 
 976               
 977              self.Show() 
  978   
 979   
 981          """A user specified function for non-linear page changing. 
 982   
 983          @param index:   The index of the page the function should be associated with. 
 984          @type index:    int 
 985          @param fn:      The function for determining the page after the current.  This function should return the index of the next page. 
 986          @type fn:       func or method. 
 987          """ 
 988   
 989           
 990          self._seq_fn_list[index] = fn 
  991   
 992   
 993 -    def setup_page(self, page=None, **kargs): 
  994          """Allow a specified user function page to be remotely set up. 
 995   
 996          @keyword page:  The page to setup.  This is the page index key. 
 997          @type page:     str 
 998          """ 
 999   
1000           
1001          page = self.get_page(self.page_indices[page]) 
1002   
1003           
1004          for arg in kargs: 
1005               
1006              value = kargs[arg] 
1007              if isinstance(value, str): 
1008                  value = str_to_gui(value) 
1009              elif is_float(value): 
1010                  value = float_to_gui(value) 
1011   
1012               
1013              page.SetValue(arg, value) 
  1014