Package gui :: Module relax_gui
[hide private]
[frames] | no frames]

Source Code for Module gui.relax_gui

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009 Michael Bieri                                            # 
  4  # Copyright (C) 2010-2012 Edward d'Auvergne                                   # 
  5  #                                                                             # 
  6  # This file is part of the program relax.                                     # 
  7  #                                                                             # 
  8  # relax is free software; you can redistribute it and/or modify               # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation; either version 2 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # relax is distributed in the hope that it will be useful,                    # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with relax; if not, write to the Free Software                        # 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 21  #                                                                             # 
 22  ############################################################################### 
 23   
 24  # Module docstring. 
 25  """Main module for the relax graphical user interface.""" 
 26   
 27  # Python module imports. 
 28  import os 
 29  from os import F_OK, access, getcwd, mkdir, sep 
 30  import platform 
 31  from re import search 
 32  from string import split 
 33  import sys 
 34  from textwrap import wrap 
 35  from thread import start_new_thread 
 36  from time import sleep 
 37  import webbrowser 
 38  import wx 
 39  from wx.lib import buttons 
 40   
 41  # relax module imports. 
 42  from data import Relax_data_store; ds = Relax_data_store() 
 43  from data.gui import Gui 
 44  from info import Info_box 
 45  from generic_fns import state 
 46  from generic_fns.pipes import cdp_name 
 47  from generic_fns.reset import reset 
 48  from relax_errors import RelaxError 
 49  from relax_io import io_streams_restore 
 50  from status import Status; status = Status() 
 51  import test_suite.test_suite_runner 
 52  from version import version 
 53   
 54  # relaxGUI module imports. 
 55  from gui.about import About_gui, About_relax 
 56  from gui.analyses import Analysis_controller 
 57  from gui.base_classes import Container 
 58  from gui.spin_viewer.frame import Spin_view_window 
 59  from gui.controller import Controller 
 60  from gui.filedialog import RelaxFileDialog 
 61  from gui.fonts import font 
 62  from gui.icons import Relax_task_bar_icon, relax_icons 
 63  from gui.interpreter import Interpreter 
 64  from gui.menu import Menu 
 65  from gui.message import error_message, Question 
 66  from gui.misc import gui_to_str, open_file, protected_exec 
 67  from gui import paths 
 68  from gui.pipe_editor import Pipe_editor 
 69  from gui.references import References 
 70  from gui.relax_prompt import Prompt 
 71  from gui.results_viewer import Results_viewer 
 72  from gui.settings import Free_file_format, load_sequence 
 73  from gui.user_functions import User_functions; user_functions = User_functions() 
 74   
 75   
76 -class Main(wx.Frame):
77 """The main GUI class.""" 78 79 # Hard coded variables. 80 min_width = 1000 81 min_height = 600 82
83 - def __init__(self, parent=None, id=-1, title="", script=None):
84 """Initialise the main relax GUI frame.""" 85 86 # Store the wxPython info for os/machine/version specific hacks. 87 status.wx_info = {} 88 status.wx_info["version"] = split(wx.__version__, '.') 89 status.wx_info["minor"] = "%s.%s" % (status.wx_info["version"][0], status.wx_info["version"][1]) 90 status.wx_info["os"] = sys.platform 91 status.wx_info["build"] = None 92 if search('gtk2', wx.version()): 93 status.wx_info["build"] = 'gtk' 94 elif search('cocoa', wx.version()): 95 status.wx_info["build"] = 'cocoa' 96 elif search('mac-unicode', wx.version()): 97 status.wx_info["build"] = 'carbon' 98 status.wx_info["full"] = None 99 if status.wx_info["build"]: 100 status.wx_info["full"] = "%s-%s" % (status.wx_info["os"], status.wx_info["build"]) 101 102 # Some internal variables. 103 self.test_suite_flag = False 104 105 # The main window style. 106 style = wx.DEFAULT_FRAME_STYLE 107 if not status.debug and status.wx_info["os"] != 'darwin': 108 style = style | wx.MAXIMIZE 109 110 # Execute the base class __init__ method. 111 super(Main, self).__init__(parent=parent, id=id, title=title, style=style) 112 113 # Force the main window to start maximised (needed for MS Windows). 114 if not status.debug and status.wx_info["os"] != 'darwin': 115 self.Maximize() 116 117 # Set up some standard interface-wide fonts. 118 font.setup() 119 120 # Set up the relax icons. 121 relax_icons.setup() 122 self.SetIcons(relax_icons) 123 124 # Set up the Mac OS X task bar icon. 125 if status.wx_info["os"] == 'darwin' and status.wx_info["build"] != 'gtk': 126 self.taskbar_icon = Relax_task_bar_icon(self) 127 128 # Initialise some variables for the GUI. 129 self.launch_dir = getcwd() 130 131 # Set up the frame. 132 self.Layout() 133 self.SetSize((self.min_width, self.min_height)) 134 self.SetMinSize((self.min_width, self.min_height)) 135 self.Centre() 136 137 # The analysis window object storage. 138 self.analysis = Analysis_controller(self) 139 140 # The calculation threads list. 141 self.calc_threads = [] 142 143 # Initialise the GUI data. 144 self.init_data() 145 146 # Build the menu bar. 147 self.menu = Menu(self) 148 149 # Build the toolbar. 150 self.toolbar() 151 152 # Build the controller, but don't show it. 153 self.controller = Controller(self) 154 155 # Set the title. 156 self.SetTitle("relax " + version) 157 158 # Set up the status bar. 159 self.status_bar = self.CreateStatusBar(3, 0) 160 self.status_bar.SetStatusWidths([-4, -1, -2]) 161 self.update_status_bar() 162 163 # Add the start screen. 164 self.add_start_screen() 165 166 # Close Box event. 167 self.Bind(wx.EVT_CLOSE, self.exit_gui) 168 169 # Initialise the special interpreter thread object. 170 self.interpreter = Interpreter() 171 172 # Register functions with the observer objects. 173 status.observers.pipe_alteration.register('status bar', self.update_status_bar) 174 status.observers.result_file.register('gui', self.show_results_viewer_no_warn) 175 status.observers.exec_lock.register('gui', self.enable) 176 177 # Run a script. 178 if script: 179 wx.CallAfter(user_functions.script.script_exec, script)
180 181
182 - def about_gui(self, event):
183 """The about message for the relax GUI. 184 185 @param event: The wx event. 186 @type event: wx event 187 """ 188 189 # Build the dialog. 190 dialog = About_gui(None, -1, "") 191 192 # The dialog. 193 if status.show_gui: 194 dialog.Show()
195 196
197 - def about_relax(self, event):
198 """The about message for relax. 199 200 @param event: The wx event. 201 @type event: wx event 202 """ 203 204 # Build the dialog. 205 dialog = About_relax(None, -1) 206 207 # The dialog. 208 if status.show_gui: 209 dialog.Show()
210 211
212 - def action_state_save(self, event):
213 """Save the program state. 214 215 @param event: The wx event. 216 @type event: wx event 217 """ 218 219 # Not saved yet, therefore pass execution to state_save_as(). 220 if not self.save_file: 221 self.action_state_save_as(event) 222 return 223 224 # Save. 225 self.state_save()
226 227
228 - def action_state_save_as(self, event):
229 """Save the program state with file name selection. 230 231 @param event: The wx event. 232 @type event: wx event 233 """ 234 235 # The dialog. 236 dialog = RelaxFileDialog(parent=self, message='Select the relax save state file', defaultFile='state.bz2', wildcard='relax save file (*.bz2)|*.bz2', style=wx.FD_SAVE) 237 238 # Show the dialog and catch if no file has been selected. 239 if status.show_gui and dialog.ShowModal() != wx.ID_OK: 240 # Don't do anything. 241 return 242 243 # The file. 244 file_name = dialog.get_file() 245 246 # Set the file name. 247 self.save_file = file_name 248 249 # Save. 250 self.state_save()
251 252
253 - def add_start_screen(self):
254 """Create a start screen for the main window when no analyses exist.""" 255 256 # The sizer for the main GUI window. 257 sizer = wx.BoxSizer(wx.VERTICAL) 258 self.SetSizer(sizer) 259 260 # The relax icon. 261 image = wx.StaticBitmap(self, -1, wx.Bitmap(paths.IMAGE_PATH+'ulysses_shadowless_400x168.png', wx.BITMAP_TYPE_ANY)) 262 263 # Add the icon to the main spacer with spacing. 264 sizer.AddStretchSpacer() 265 sizer.Add(image, 0, wx.ALIGN_CENTER_HORIZONTAL, 0) 266 sizer.AddStretchSpacer() 267 268 # Re-perform the layout of the GUI elements, and refresh. 269 self.Layout() 270 self.Refresh()
271 272
273 - def close_windows(self):
274 """Throw a warning to close all of the non-essential windows when execution is locked. 275 276 This is to speed up the calculations by avoiding window updates. 277 """ 278 279 # Init the window list. 280 win_list = [] 281 282 # Is the spin viewer window open? 283 if hasattr(self, 'spin_viewer') and self.spin_viewer.IsShown(): 284 win_list.append('The spin viewer window') 285 286 # Is the pipe editor window open? 287 if hasattr(self, 'pipe_editor') and self.pipe_editor.IsShown(): 288 win_list.append('The data pipe editor window') 289 290 # Is the results viewer window open? 291 if hasattr(self, 'results_viewer') and self.results_viewer.IsShown(): 292 win_list.append('The results viewer window') 293 294 # The windows are not open, so quit. 295 if not len(win_list): 296 return 297 298 # The text. 299 text = "The following windows are currently open:\n\n" 300 for win in win_list: 301 text = "%s\t%s.\n" % (text, win) 302 text = text + "\nClosing these will significantly speed up the calculations." 303 304 # Display the error message dialog. 305 dlg = wx.MessageDialog(self, text, caption="Close windows", style=wx.OK|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 306 if status.show_gui: 307 dlg.ShowModal() 308 309 # Otherwise output to stderr. 310 else: 311 sys.stderr.write(text)
312 313
314 - def contact_relax(self, event):
315 """Write an email to the relax mailing-list using the standard mailing program.""" 316 webbrowser.open_new('mailto:relax-users@gna.org')
317 318
319 - def enable(self):
320 """Enable and disable certain parts of the main window with the execution lock.""" 321 322 # Flag for enabling or disabling the elements. 323 enable = False 324 if not status.exec_lock.locked(): 325 enable = True 326 327 # The toolbar. 328 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_NEW, enable) 329 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_CLOSE, enable) 330 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_CLOSE_ALL, enable) 331 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_OPEN, enable) 332 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_SAVE, enable) 333 wx.CallAfter(self.toolbar.EnableTool, self.TB_FILE_SAVE_AS, enable)
334 335
336 - def exit_gui(self, event=None):
337 """Catch the main window closure and perform the exit procedure. 338 339 @param event: The wx event. 340 @type event: wx event 341 """ 342 343 # Ask if the user is sure they would like to exit. 344 doexit = wx.ID_YES 345 if status.show_gui and not ds.is_empty(): 346 doexit = Question('Are you sure you would like to quit relax? All unsaved data will be lost.', title='Exit relax', default=True).ShowModal() 347 348 # Exit. 349 if doexit == wx.ID_YES: 350 # Restore the IO streams. 351 io_streams_restore(verbosity=0) 352 353 # The relax information box. 354 info = Info_box() 355 356 # The width of the printout. 357 if platform.uname()[0] in ['Windows', 'Microsoft']: 358 width = 80 359 else: 360 width = 100 361 362 # A print out. 363 text = "\n\nThank you for citing:\n" 364 text = text + "\n\nrelaxGUI\n========\n\n" 365 for line in wrap(info.bib['Bieri11'].cite_short(), width): 366 text = text + line + '\n' 367 text = text + "\n\n\nrelax\n=====\n\n" 368 for line in wrap(info.bib['dAuvergneGooley08a'].cite_short(), width): 369 text = text + line + '\n' 370 text = text + '\n' 371 for line in wrap(info.bib['dAuvergneGooley08b'].cite_short(), width): 372 text = text + line + '\n' 373 text = text + '\n' 374 sys.stdout.write(text) 375 376 # Remove the Mac OS X task bar icon. 377 if hasattr(self, 'taskbar_icon'): 378 self.taskbar_icon.Destroy() 379 380 # End application. 381 wx.Exit()
382 383
384 - def init_data(self):
385 """Initialise the data used by the GUI interface.""" 386 387 # Temporary data: the save file. 388 self.save_file = None 389 390 # Add the GUI object to the data store. 391 ds.relax_gui = Gui()
392 393
394 - def free_file_format_settings(self, event):
395 """Open the free file format settings window. 396 397 @param event: The wx event. 398 @type event: wx event 399 """ 400 401 # Build the window. 402 win = Free_file_format() 403 404 # Show the window. 405 if status.show_gui: 406 win.Show()
407 408
409 - def references(self, event):
410 """Display the references relevant for relax. 411 412 @param event: The wx event. 413 @type event: wx event 414 """ 415 416 # Build and show the references window. 417 self.references = References(self) 418 if status.show_gui: 419 self.references.Show()
420 421
422 - def relax_manual(self, event):
423 """Display the relax manual. 424 425 @param event: The wx event. 426 @type event: wx event 427 """ 428 429 # The PDF manual. 430 file = status.install_path + sep+"docs"+sep+"relax.pdf" 431 432 # Test if it exists. 433 if not access(file, F_OK): 434 error_message("The relax manual '%s' cannot be found. Please compile using the scons program." % file) 435 return 436 437 # Open the relax PDF manual using the native PDF reader. 438 open_file(file)
439 440
441 - def run_test_suite(self, event, categories=['system', 'unit', 'gui']):
442 """Execute the full test suite. 443 444 @param event: The wx event. 445 @type event: wx event 446 @keyword categories: The list of test categories to run, for example ['system', 'unit', 'gui'] for all tests. 447 @type categories: list of str 448 """ 449 450 # Ask if this should be done. 451 msg = "In running the test suite, relax will be reset and all data lost. Are you sure you would like to run the test suite?" 452 if Question(msg, parent=self, default=False).ShowModal() == wx.ID_NO: 453 return 454 455 # Set the test suite flag. 456 self.test_suite_flag = True 457 458 # Change the cursor to waiting. 459 wx.BeginBusyCursor() 460 461 # Set a new style to stay on top, refreshing to update the style (needed for Mac OS X and MS Windows). 462 orig_style = self.controller.GetWindowStyle() 463 self.controller.SetWindowStyle(orig_style | wx.STAY_ON_TOP) 464 self.controller.Refresh() 465 466 # Make the relax controller modal so that all other windows are deactivated (to stop users from clicking on things). 467 self.controller.MakeModal(True) 468 469 # Close all open windows. 470 if hasattr(self, 'spin_viewer'): 471 self.spin_viewer.Close() 472 if hasattr(self, 'pipe_editor'): 473 self.pipe_editor.Close() 474 if hasattr(self, 'results_viewer'): 475 self.results_viewer.Close() 476 if hasattr(self, 'relax_prompt'): 477 self.relax_prompt.Close() 478 479 # Reset relax. 480 reset() 481 482 # Show the relax controller. 483 self.show_controller(event) 484 485 # Yield 486 wx.GetApp().Yield(True) 487 488 # Prevent all new GUI elements from being shown. 489 status.show_gui = False 490 491 # Run the tests. 492 runner = test_suite.test_suite_runner.Test_suite_runner([], from_gui=True, categories=categories) 493 runner.run_all_tests() 494 495 # Reactive the GUI. 496 status.show_gui = True 497 498 # Turn off the busy cursor. 499 if wx.IsBusy(): 500 wx.EndBusyCursor() 501 502 # Restore the controller. 503 self.controller.SetWindowStyle(orig_style) 504 self.controller.MakeModal(False) 505 self.controller.Refresh() 506 507 # Unset the test suite flag. 508 self.test_suite_flag = False
509 510
511 - def run_test_suite_gui(self, event):
512 """Execute the GUI tests. 513 514 @param event: The wx event. 515 @type event: wx event 516 """ 517 518 # Forward the call. 519 self.run_test_suite(event, categories=['gui'])
520 521
522 - def run_test_suite_sys(self, event):
523 """Execute the system tests. 524 525 @param event: The wx event. 526 @type event: wx event 527 """ 528 529 # Forward the call. 530 self.run_test_suite(event, categories=['system'])
531 532
533 - def run_test_suite_unit(self, event):
534 """Execute the unit tests. 535 536 @param event: The wx event. 537 @type event: wx event 538 """ 539 540 # Forward the call. 541 self.run_test_suite(event, categories=['unit'])
542 543
544 - def show_controller(self, event):
545 """Display the relax controller window. 546 547 @param event: The wx event. 548 @type event: wx event 549 """ 550 551 # Bring the window to the front. 552 if self.controller.IsShown(): 553 self.controller.Raise() 554 return 555 556 # Open the window. 557 if status.show_gui: 558 self.controller.Show()
559 560
561 - def show_pipe_editor(self, event):
562 """Display the data pipe editor window. 563 564 @param event: The wx event. 565 @type event: wx event 566 """ 567 568 # Throw a warning if the execution lock is on. 569 if status.exec_lock.locked(): 570 dlg = wx.MessageDialog(self, "Leaving the pipe editor window open will slow down the calculations.", caption="Warning", style=wx.OK|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 571 if status.show_gui: 572 dlg.ShowModal() 573 574 # Build the pipe editor if needed. 575 if not hasattr(self, 'pipe_editor'): 576 self.pipe_editor = Pipe_editor(gui=self) 577 578 # Bring the window to the front. 579 if self.pipe_editor.IsShown(): 580 self.pipe_editor.Raise() 581 return 582 583 # Open the window. 584 if status.show_gui and not self.pipe_editor.IsShown(): 585 self.pipe_editor.Show()
586 587
588 - def show_prompt(self, event):
589 """Display the relax prompt window. 590 591 @param event: The wx event. 592 @type event: wx event 593 """ 594 595 # Build the relax prompt if needed. 596 if not hasattr(self, 'relax_prompt'): 597 self.relax_prompt = Prompt(None, -1, "", parent=self) 598 599 # Bring the window to the front. 600 if self.relax_prompt.IsShown(): 601 self.relax_prompt.Raise() 602 return 603 604 # Open the window. 605 if status.show_gui: 606 self.relax_prompt.Show()
607 608
609 - def show_results_viewer(self, event=None):
610 """Display the analysis results. 611 612 @param event: The wx event. 613 @type event: wx event 614 """ 615 616 # Show the results viewer in a thread safe way. 617 wx.CallAfter(self.show_results_viewer_safe, warn=True)
618 619
620 - def show_results_viewer_safe(self, warn=False):
621 """Display the analysis results in a thread safe wx.CallAfter call. 622 623 @keyword warn: A flag which if True will cause a message dialog to appear warning about keeping the window open with the execution lock. 624 @type warn: bool 625 """ 626 627 # Throw a warning if the execution lock is on. 628 if warn and status.exec_lock.locked(): 629 dlg = wx.MessageDialog(self, "Leaving the results viewer window open will slow down the calculations.", caption="Warning", style=wx.OK|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 630 if status.show_gui: 631 wx.CallAfter(dlg.ShowModal) 632 633 # Create the results viewer window if needed. 634 if not hasattr(self, 'results_viewer'): 635 self.results_viewer = Results_viewer(self) 636 637 # Bring the window to the front. 638 if self.results_viewer.IsShown(): 639 self.results_viewer.Raise() 640 return 641 642 # Open the window. 643 if status.show_gui and not self.results_viewer.IsShown(): 644 self.results_viewer.Show()
645 646
648 """Display the analysis results.""" 649 650 # Show the results viewer in a thread safe way with no warning dialog. 651 wx.CallAfter(self.show_results_viewer_safe, warn=False)
652 653
654 - def show_tree(self, event):
655 """Display the molecule, residue, and spin tree window. 656 657 @param event: The wx event. 658 @type event: wx event 659 """ 660 661 # Throw a warning if the execution lock is on. 662 if status.exec_lock.locked(): 663 dlg = wx.MessageDialog(self, "Leaving the spin viewer window open will slow down the calculations.", caption="Warning", style=wx.OK|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 664 if status.show_gui: 665 dlg.ShowModal() 666 667 # Build the spin view window. 668 if not hasattr(self, 'spin_viewer'): 669 self.spin_viewer = Spin_view_window(None, -1, "", parent=self) 670 671 # Bring the window to the front. 672 if self.spin_viewer.IsShown(): 673 self.spin_viewer.Raise() 674 return 675 676 # Open the window (the GUI flag check is inside the Show method). 677 if status.show_gui and not self.spin_viewer.IsShown(): 678 self.spin_viewer.Show()
679 680
681 - def state_load(self, event=None, file_name=None):
682 """Load the program state. 683 684 @param event: The wx event. 685 @type event: wx event 686 @keyword file_name: The name of the file to load (for dialogless operation). 687 @type file_name: str 688 """ 689 690 # Execution lock. 691 if status.exec_lock.locked(): 692 return 693 694 # Warning. 695 if not self.analysis.init_state: 696 # The message. 697 msg = "Loading a saved relax state file will cause all unsaved data to be lost. Are you sure you would to open a save file?" 698 699 # The dialog. 700 if status.show_gui and Question(msg, default=True, size=(400, 150)).ShowModal() == wx.ID_NO: 701 return 702 703 # Open the dialog. 704 if not file_name: 705 dialog = RelaxFileDialog(parent=self, message='Select the relax save state file', defaultFile='state.bz2', wildcard='relax save files (*.bz2;*.gz)|*.bz2;*.gz|All files (*)|*', style=wx.FD_OPEN) 706 707 # Show the dialog and catch if no file has been selected. 708 if status.show_gui and dialog.ShowModal() != wx.ID_OK: 709 # Don't do anything. 710 return 711 712 # The file. 713 file_name = gui_to_str(dialog.get_file()) 714 715 # Yield to allow the cursor to be changed. 716 wx.Yield() 717 718 # Change the cursor to waiting, and freeze the GUI. 719 wx.BeginBusyCursor() 720 self.Freeze() 721 722 # Make sure the GUI returns to normal if a failure occurs. 723 try: 724 # Delete the current tabs. 725 self.analysis.delete_all() 726 727 # Reset the relax data store. 728 reset() 729 730 # The new save file name. 731 self.save_file = file_name 732 733 # Load the relax state. 734 if protected_exec(state.load_state, file_name, verbosity=0): 735 # Reconstruct the analyses. 736 self.analysis.load_from_store() 737 738 # Update the core of the GUI to match the new data store. 739 self.sync_ds(upload=False) 740 741 # File loading failure. 742 else: 743 # Reinitialise the GUI data store structure. 744 self.init_data() 745 746 # Reset the cursor, and thaw the GUI. 747 finally: 748 self.Thaw() 749 750 # Turn off the busy cursor. 751 if wx.IsBusy(): 752 wx.EndBusyCursor()
753 754
755 - def state_save(self):
756 """Save the program state.""" 757 758 # Update the data store to match the GUI. 759 self.sync_ds(upload=True) 760 761 # Save the relax state (with save user feedback). 762 try: 763 wx.BeginBusyCursor() 764 state.save_state(self.save_file, verbosity=0, force=True) 765 766 # Sleep a little so the user sees the busy cursor and knows that a save has occurred! 767 sleep(1) 768 769 # Turn off the user feedback. 770 finally: 771 if wx.IsBusy(): 772 wx.EndBusyCursor()
773 774
775 - def sync_ds(self, upload=False):
776 """Synchronise the GUI and the relax data store, both ways. 777 778 This method allows the GUI information to be uploaded into the relax data store, or for the information in the relax data store to be downloaded by the GUI. 779 780 @keyword upload: A flag which if True will cause the GUI to send data to the relax data store. If False, data will be downloaded from the relax data store to update the GUI. 781 @type upload: bool 782 """ 783 784 # Loop over each analysis. 785 for page in self.analysis.analysis_loop(): 786 # Execute the analysis page specific update methods. 787 if hasattr(page, 'sync_ds'): 788 page.sync_ds(upload)
789 790
791 - def toolbar(self):
792 """Create the toolbar.""" 793 794 # Init. 795 self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT) 796 797 # The new analysis button. 798 self.TB_FILE_NEW = wx.NewId() 799 self.toolbar.AddLabelTool(self.TB_FILE_NEW, "New analysis", wx.Bitmap(paths.icon_22x22.new, wx.BITMAP_TYPE_ANY), shortHelp="New analysis") 800 self.Bind(wx.EVT_TOOL, self.analysis.menu_new, id=self.TB_FILE_NEW) 801 802 # The close analysis button. 803 self.TB_FILE_CLOSE = wx.NewId() 804 self.toolbar.AddLabelTool(self.TB_FILE_CLOSE, "Close analysis", wx.Bitmap(paths.icon_22x22.document_close, wx.BITMAP_TYPE_ANY), shortHelp="Close analysis") 805 self.Bind(wx.EVT_TOOL, self.analysis.menu_close, id=self.TB_FILE_CLOSE) 806 807 # The close all analyses button. 808 self.TB_FILE_CLOSE_ALL = wx.NewId() 809 self.toolbar.AddLabelTool(self.TB_FILE_CLOSE_ALL, "Close all analyses", wx.Bitmap(paths.icon_22x22.dialog_close, wx.BITMAP_TYPE_ANY), shortHelp="Close all analyses") 810 self.Bind(wx.EVT_TOOL, self.analysis.menu_close_all, id=self.TB_FILE_CLOSE_ALL) 811 812 # A separator. 813 self.toolbar.AddSeparator() 814 815 # The open state button. 816 self.TB_FILE_OPEN = wx.NewId() 817 self.toolbar.AddLabelTool(self.TB_FILE_OPEN, "Open relax state", wx.Bitmap(paths.icon_22x22.document_open, wx.BITMAP_TYPE_ANY), shortHelp="Open relax state") 818 self.Bind(wx.EVT_TOOL, self.state_load, id=self.TB_FILE_OPEN) 819 820 # The save state button. 821 self.TB_FILE_SAVE = wx.NewId() 822 self.toolbar.AddLabelTool(self.TB_FILE_SAVE, "Save relax state", wx.Bitmap(paths.icon_22x22.document_save, wx.BITMAP_TYPE_ANY), shortHelp="Save relax state") 823 self.Bind(wx.EVT_TOOL, self.action_state_save, id=self.TB_FILE_SAVE) 824 825 # The save as button. 826 self.TB_FILE_SAVE_AS = wx.NewId() 827 self.toolbar.AddLabelTool(self.TB_FILE_SAVE_AS, "Save as", wx.Bitmap(paths.icon_22x22.document_save_as, wx.BITMAP_TYPE_ANY), shortHelp="Save as") 828 self.Bind(wx.EVT_TOOL, self.action_state_save_as, id=self.TB_FILE_SAVE_AS) 829 830 # A separator. 831 self.toolbar.AddSeparator() 832 833 # The relax controller button. 834 self.TB_VIEW_CONTROLLER = wx.NewId() 835 self.toolbar.AddLabelTool(self.TB_VIEW_CONTROLLER, "Controller", wx.Bitmap(paths.icon_22x22.preferences_system_performance, wx.BITMAP_TYPE_ANY), shortHelp="relax controller") 836 self.Bind(wx.EVT_TOOL, self.show_controller, id=self.TB_VIEW_CONTROLLER) 837 838 # The spin viewer button. 839 self.TB_VIEW_SPIN_VIEW = wx.NewId() 840 self.toolbar.AddLabelTool(self.TB_VIEW_SPIN_VIEW, "Spin viewer", wx.Bitmap(paths.icon_22x22.spin, wx.BITMAP_TYPE_ANY), shortHelp="Spin viewer window") 841 self.Bind(wx.EVT_TOOL, self.show_tree, id=self.TB_VIEW_SPIN_VIEW) 842 843 # The results viewer button. 844 self.TB_VIEW_RESULTS = wx.NewId() 845 self.toolbar.AddLabelTool(self.TB_VIEW_RESULTS, "Results viewer", wx.Bitmap(paths.icon_22x22.view_statistics, wx.BITMAP_TYPE_ANY), shortHelp="Results viewer window") 846 self.Bind(wx.EVT_TOOL, self.show_results_viewer, id=self.TB_VIEW_RESULTS) 847 848 # The data pipe editor button. 849 self.TB_VIEW_PIPE_EDIT = wx.NewId() 850 self.toolbar.AddLabelTool(self.TB_VIEW_PIPE_EDIT, "Data pipe editor", wx.Bitmap(paths.icon_22x22.pipe, wx.BITMAP_TYPE_ANY), shortHelp="Data pipe editor") 851 self.Bind(wx.EVT_TOOL, self.show_pipe_editor, id=self.TB_VIEW_PIPE_EDIT) 852 853 # The relax prompt button. 854 self.TB_VIEW_PROMPT = wx.NewId() 855 self.toolbar.AddLabelTool(self.TB_VIEW_PROMPT, "relax prompt", wx.Bitmap(paths.icon_22x22.relax_prompt, wx.BITMAP_TYPE_ANY), shortHelp="The relax prompt GUI window") 856 self.Bind(wx.EVT_TOOL, self.show_prompt, id=self.TB_VIEW_PROMPT) 857 858 # Build the toolbar. 859 self.toolbar.Realize()
860 861
862 - def update_status_bar(self):
863 """Update the status bar info.""" 864 865 # Set the current data pipe info. 866 pipe = cdp_name() 867 868 # No data pipe. 869 if pipe == None: 870 pipe = '' 871 872 # Set the status. 873 wx.CallAfter(self.status_bar.SetStatusText, "(C) 2001-2012 the relax development team", 0) 874 wx.CallAfter(self.status_bar.SetStatusText, "Current data pipe:", 1) 875 wx.CallAfter(self.status_bar.SetStatusText, pipe, 2)
876