source: sasview/src/sas/qtgui/MainWindow/GuiManager.py @ cd2cc745

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since cd2cc745 was 83eb5208, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Putting files in more ordered fashion

  • Property mode set to 100644
File size: 24.4 KB
RevLine 
[f721030]1import sys
[0cd8612]2import os
[9e426c1]3import subprocess
4import logging
5import json
6import webbrowser
[f721030]7
8from PyQt4 import QtCore
9from PyQt4 import QtGui
[1042dba]10from PyQt4 import QtWebKit
11
12from twisted.internet import reactor
[f721030]13# General SAS imports
[31c5b58]14
[1042dba]15from sas.sasgui.guiframe.data_manager import DataManager
[9e426c1]16from sas.sasgui.guiframe.proxy import Connection
[83eb5208]17from sas.qtgui.Utilities.SasviewLogger import XStream
18from sas.qtgui.Utilities.IPythonWidget import IPythonWidget
19import sas.qtgui.Utilities.LocalConfig as LocalConfig
20import sas.qtgui.Utilities.GuiUtils as GuiUtils
21
22from sas.qtgui.MainWindow.UI.AcknowledgementsUI import Ui_Acknowledgements
23from sas.qtgui.MainWindow.AboutBox import AboutBox
24from sas.qtgui.MainWindow.WelcomePanel import WelcomePanel
25
26from sas.qtgui.Calculators.SldPanel import SldPanel
27from sas.qtgui.Calculators.DensityPanel import DensityPanel
28from sas.qtgui.Calculators.KiessigPanel import KiessigPanel
29from sas.qtgui.Calculators.SlitSizeCalculator import SlitSizeCalculator
[f721030]30
31# Perspectives
[83eb5208]32import sas.qtgui.Perspectives as Perspectives
[6c8fb2c]33from sas.qtgui.Perspectives.Fitting.FittingPerspective import FittingWindow
[83eb5208]34from sas.qtgui.MainWindow.DataExplorer import DataExplorerWindow
[f51ed67]35
36class Acknowledgements(QtGui.QDialog, Ui_Acknowledgements):
37    def __init__(self, parent=None):
38        QtGui.QDialog.__init__(self, parent)
39        self.setupUi(self)
[f721030]40
41class GuiManager(object):
42    """
43    Main SasView window functionality
44    """
[31c5b58]45    ## TODO: CHANGE FOR SHIPPED PATH IN RELEASE
46    HELP_DIRECTORY_LOCATION = "docs/sphinx-docs/build/html"
[9e426c1]47
[6fd4e36]48    def __init__(self, parent=None):
[f721030]49        """
[257bd57]50        Initialize the manager as a child of MainWindow.
[f721030]51        """
[6fd4e36]52        self._workspace = parent
[f721030]53        self._parent = parent
54
[6fd4e36]55        # Reactor - singleton
[f721030]56        self.setReactor(reactor)
57
58        # Add signal callbacks
59        self.addCallbacks()
60
61        # Create the data manager
[1042dba]62        # TODO: pull out all required methods from DataManager and reimplement
63        self._data_manager = DataManager()
[f721030]64
65        # Create action triggers
66        self.addTriggers()
67
68        # Populate menus with dynamic data
[481ff26]69        #
[f721030]70        # Analysis/Perspectives - potentially
71        # Window/current windows
72        #
73        # Widgets
74        #
[5236449]75        # Current displayed perspective
76        self._current_perspective = None
77
78        # Invoke the initial perspective
79        self.perspectiveChanged("Fitting")
80
[0cd8612]81        self.addWidgets()
[f721030]82
[0cd8612]83        # Fork off logging messages to the Log Window
[8cb6cd6]84        XStream.stdout().messageWritten.connect(self.listWidget.insertPlainText)
85        XStream.stderr().messageWritten.connect(self.listWidget.insertPlainText)
86
[0cd8612]87        # Log the start of the session
88        logging.info(" --- SasView session started ---")
89        # Log the python version
90        logging.info("Python: %s" % sys.version)
[9e426c1]91
[e540cd2]92        # Set up the status bar
93        self.statusBarSetup()
[9e426c1]94
[f721030]95        # Show the Welcome panel
96        self.welcomePanel = WelcomePanel()
97        self._workspace.workspace.addWindow(self.welcomePanel)
98
[1042dba]99        # Current help file
100        self._helpView = QtWebKit.QWebView()
[9e426c1]101        # Needs URL like path, so no path.join() here
102        self._helpLocation = self.HELP_DIRECTORY_LOCATION + "/index.html"
103
104        # Current tutorial location
[31c5b58]105        self._tutorialLocation = os.path.abspath(os.path.join(self.HELP_DIRECTORY_LOCATION,
[9e426c1]106                                              "_downloads",
[31c5b58]107                                              "Tutorial.pdf"))
[0cd8612]108    def addWidgets(self):
109        """
110        Populate the main window with widgets
111
112        TODO: overwrite close() on Log and DR widgets so they can be hidden/shown
113        on request
114        """
115        # Add FileDialog widget as docked
[630155bd]116        self.filesWidget = DataExplorerWindow(self._parent, self, manager=self._data_manager)
[0cd8612]117
118        self.dockedFilesWidget = QtGui.QDockWidget("Data Explorer", self._workspace)
119        self.dockedFilesWidget.setWidget(self.filesWidget)
[83d6249]120
[0cd8612]121        # Disable maximize/minimize and close buttons
122        self.dockedFilesWidget.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
123        self._workspace.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
124                                      self.dockedFilesWidget)
125
126        # Add the console window as another docked widget
127        self.logDockWidget = QtGui.QDockWidget("Log Explorer", self._workspace)
128        self.logDockWidget.setObjectName("LogDockWidget")
129        self.listWidget = QtGui.QTextBrowser()
130        self.logDockWidget.setWidget(self.listWidget)
131        self._workspace.addDockWidget(QtCore.Qt.BottomDockWidgetArea,
132                                      self.logDockWidget)
133
134        # Add other, minor widgets
135        self.ackWidget = Acknowledgements()
136        self.aboutWidget = AboutBox()
137
[1d85b5e]138        # Add calculators - floating for usability
139        self.SLDCalculator = SldPanel(self)
140        self.DVCalculator = DensityPanel(self)
[363fbfa]141        #self.KIESSIGCalculator = DensityPanel(self)#KiessigPanel(self)
[a8ec5b1]142        self.KIESSIGCalculator = KiessigPanel(self)
[abc5e70]143        self.SlitSizeCalculator = SlitSizeCalculator(self)
[83d6249]144
[e540cd2]145    def statusBarSetup(self):
146        """
147        Define the status bar.
148        | <message label> .... | Progress Bar |
149
150        Progress bar invisible until explicitly shown
151        """
152        self.progress = QtGui.QProgressBar()
153        self._workspace.statusbar.setSizeGripEnabled(False)
154
155        self.statusLabel = QtGui.QLabel()
156        self.statusLabel.setText("Welcome to SasView")
[8cb6cd6]157        self._workspace.statusbar.addPermanentWidget(self.statusLabel, 1)
[e540cd2]158        self._workspace.statusbar.addPermanentWidget(self.progress, stretch=0)
[8cb6cd6]159        self.progress.setRange(0, 100)
[e540cd2]160        self.progress.setValue(0)
161        self.progress.setTextVisible(True)
162        self.progress.setVisible(False)
163
[f721030]164    def fileRead(self, data):
165        """
[f82ab8c]166        Callback for fileDataReceivedSignal
[f721030]167        """
168        pass
[481ff26]169
[8cb6cd6]170    def workspace(self):
171        """
172        Accessor for the main window workspace
173        """
174        return self._workspace.workspace
175
[83d6249]176    def perspectiveChanged(self, perspective_name):
177        """
178        Respond to change of the perspective signal
179        """
180        # Close the previous perspective
181        if self._current_perspective:
[b1e36a3]182            self._current_perspective.setClosable()
[83d6249]183            self._current_perspective.close()
184        # Default perspective
[811bec1]185        self._current_perspective = Perspectives.PERSPECTIVES[str(perspective_name)](parent=self)
[9c391946]186
[83d6249]187        self._workspace.workspace.addWindow(self._current_perspective)
[9c391946]188        # Resize to the workspace height
189        workspace_height = self._workspace.workspace.sizeHint().height()
190        perspective_size = self._current_perspective.sizeHint()
191        if workspace_height < perspective_size.height:
192            perspective_width = perspective_size.width()
193            self._current_perspective.resize(perspective_width, workspace_height-10)
[83d6249]194        self._current_perspective.show()
195
[f721030]196    def updatePerspective(self, data):
197        """
[71361f0]198        Update perspective with data sent.
[f721030]199        """
200        assert isinstance(data, list)
201        if self._current_perspective is not None:
202            self._current_perspective.setData(data.values())
203        else:
204            msg = "No perspective is currently active."
205            logging.info(msg)
[481ff26]206
[f721030]207    def communicator(self):
[257bd57]208        """ Accessor for the communicator """
[f721030]209        return self.communicate
210
211    def reactor(self):
[257bd57]212        """ Accessor for the reactor """
[f721030]213        return self._reactor
214
215    def setReactor(self, reactor):
[257bd57]216        """ Reactor setter """
[f721030]217        self._reactor = reactor
218
219    def perspective(self):
[257bd57]220        """ Accessor for the perspective """
[f721030]221        return self._current_perspective
222
[e540cd2]223    def updateProgressBar(self, value):
224        """
225        Update progress bar with the required value (0-100)
226        """
[8cb6cd6]227        assert -1 <= value <= 100
[e540cd2]228        if value == -1:
229            self.progress.setVisible(False)
230            return
231        if not self.progress.isVisible():
232            self.progress.setTextVisible(True)
233            self.progress.setVisible(True)
234
235        self.progress.setValue(value)
236
[f721030]237    def updateStatusBar(self, text):
238        """
[71361f0]239        Set the status bar text
[f721030]240        """
[e540cd2]241        self.statusLabel.setText(text)
[f721030]242
[1042dba]243    def createGuiData(self, item, p_file=None):
244        """
245        Access the Data1D -> plottable Data1D conversion
246        """
247        return self._data_manager.create_gui_data(item, p_file)
[f721030]248
249    def setData(self, data):
250        """
251        Sends data to current perspective
252        """
253        if self._current_perspective is not None:
254            self._current_perspective.setData(data.values())
255        else:
256            msg = "Guiframe does not have a current perspective"
257            logging.info(msg)
258
[9e426c1]259    def quitApplication(self):
260        """
261        Close the reactor and exit nicely.
262        """
263        # Display confirmation messagebox
264        quit_msg = "Are you sure you want to exit the application?"
265        reply = QtGui.QMessageBox.question(
[481ff26]266            self._parent,
[7451b88]267            'Information',
[481ff26]268            quit_msg,
269            QtGui.QMessageBox.Yes,
270            QtGui.QMessageBox.No)
[9e426c1]271
272        # Exit if yes
[7451b88]273        if reply == QtGui.QMessageBox.Yes:
274            reactor.callFromThread(reactor.stop)
275            return True
276
277        return False
[9e426c1]278
279    def checkUpdate(self):
280        """
281        Check with the deployment server whether a new version
282        of the application is available.
283        A thread is started for the connecting with the server. The thread calls
284        a call-back method when the current version number has been obtained.
285        """
286        version_info = {"version": "0.0.0"}
287        c = Connection(LocalConfig.__update_URL__, LocalConfig.UPDATE_TIMEOUT)
288        response = c.connect()
[71361f0]289        if response is None:
290            return
291        try:
292            content = response.read().strip()
293            logging.info("Connected to www.sasview.org. Latest version: %s"
294                            % (content))
295            version_info = json.loads(content)
296            self.processVersion(version_info)
297        except ValueError, ex:
298            logging.info("Failed to connect to www.sasview.org:", ex)
[481ff26]299
[f82ab8c]300    def processVersion(self, version_info):
[9e426c1]301        """
302        Call-back method for the process of checking for updates.
303        This methods is called by a VersionThread object once the current
304        version number has been obtained. If the check is being done in the
305        background, the user will not be notified unless there's an update.
306
307        :param version: version string
308        """
309        try:
310            version = version_info["version"]
311            if version == "0.0.0":
312                msg = "Could not connect to the application server."
313                msg += " Please try again later."
314                self.communicate.statusBarUpdateSignal.emit(msg)
315
316            elif cmp(version, LocalConfig.__version__) > 0:
317                msg = "Version %s is available! " % str(version)
[f82ab8c]318                if "download_url" in version_info:
319                    webbrowser.open(version_info["download_url"])
[9e426c1]320                else:
[f82ab8c]321                    webbrowser.open(LocalConfig.__download_page__)
[9e426c1]322                self.communicate.statusBarUpdateSignal.emit(msg)
323            else:
324                msg = "You have the latest version"
325                msg += " of %s" % str(LocalConfig.__appname__)
326                self.communicate.statusBarUpdateSignal.emit(msg)
327        except:
328            msg = "guiframe: could not get latest application"
329            msg += " version number\n  %s" % sys.exc_value
330            logging.error(msg)
[f82ab8c]331            msg = "Could not connect to the application server."
332            msg += " Please try again later."
333            self.communicate.statusBarUpdateSignal.emit(msg)
[9e426c1]334
[f721030]335    def addCallbacks(self):
336        """
[9e426c1]337        Method defining all signal connections for the gui manager
[f721030]338        """
[0cd8612]339        self.communicate = GuiUtils.Communicate()
[f721030]340        self.communicate.fileDataReceivedSignal.connect(self.fileRead)
341        self.communicate.statusBarUpdateSignal.connect(self.updateStatusBar)
342        self.communicate.updatePerspectiveWithDataSignal.connect(self.updatePerspective)
[e540cd2]343        self.communicate.progressBarUpdateSignal.connect(self.updateProgressBar)
[83d6249]344        self.communicate.perspectiveChangedSignal.connect(self.perspectiveChanged)
[cbcdd2c]345        self.communicate.updateTheoryFromPerspectiveSignal.connect(self.updateTheoryFromPerspective)
[f721030]346
347    def addTriggers(self):
348        """
349        Trigger definitions for all menu/toolbar actions.
350        """
351        # File
352        self._workspace.actionLoadData.triggered.connect(self.actionLoadData)
353        self._workspace.actionLoad_Data_Folder.triggered.connect(self.actionLoad_Data_Folder)
354        self._workspace.actionOpen_Project.triggered.connect(self.actionOpen_Project)
355        self._workspace.actionOpen_Analysis.triggered.connect(self.actionOpen_Analysis)
356        self._workspace.actionSave.triggered.connect(self.actionSave)
357        self._workspace.actionSave_Analysis.triggered.connect(self.actionSave_Analysis)
358        self._workspace.actionQuit.triggered.connect(self.actionQuit)
359        # Edit
360        self._workspace.actionUndo.triggered.connect(self.actionUndo)
361        self._workspace.actionRedo.triggered.connect(self.actionRedo)
362        self._workspace.actionCopy.triggered.connect(self.actionCopy)
363        self._workspace.actionPaste.triggered.connect(self.actionPaste)
364        self._workspace.actionReport.triggered.connect(self.actionReport)
365        self._workspace.actionReset.triggered.connect(self.actionReset)
366        self._workspace.actionExcel.triggered.connect(self.actionExcel)
367        self._workspace.actionLatex.triggered.connect(self.actionLatex)
368
369        # View
370        self._workspace.actionShow_Grid_Window.triggered.connect(self.actionShow_Grid_Window)
371        self._workspace.actionHide_Toolbar.triggered.connect(self.actionHide_Toolbar)
372        self._workspace.actionStartup_Settings.triggered.connect(self.actionStartup_Settings)
373        self._workspace.actionCategry_Manager.triggered.connect(self.actionCategry_Manager)
374        # Tools
375        self._workspace.actionData_Operation.triggered.connect(self.actionData_Operation)
376        self._workspace.actionSLD_Calculator.triggered.connect(self.actionSLD_Calculator)
377        self._workspace.actionDensity_Volume_Calculator.triggered.connect(self.actionDensity_Volume_Calculator)
[363fbfa]378        self._workspace.actionKeissig_Calculator.triggered.connect(self.actionKiessig_Calculator)
379        #self._workspace.actionKIESSING_Calculator.triggered.connect(self.actionKIESSING_Calculator)
[f721030]380        self._workspace.actionSlit_Size_Calculator.triggered.connect(self.actionSlit_Size_Calculator)
381        self._workspace.actionSAS_Resolution_Estimator.triggered.connect(self.actionSAS_Resolution_Estimator)
382        self._workspace.actionGeneric_Scattering_Calculator.triggered.connect(self.actionGeneric_Scattering_Calculator)
383        self._workspace.actionPython_Shell_Editor.triggered.connect(self.actionPython_Shell_Editor)
384        self._workspace.actionImage_Viewer.triggered.connect(self.actionImage_Viewer)
385        # Fitting
386        self._workspace.actionNew_Fit_Page.triggered.connect(self.actionNew_Fit_Page)
387        self._workspace.actionConstrained_Fit.triggered.connect(self.actionConstrained_Fit)
388        self._workspace.actionCombine_Batch_Fit.triggered.connect(self.actionCombine_Batch_Fit)
389        self._workspace.actionFit_Options.triggered.connect(self.actionFit_Options)
390        self._workspace.actionFit_Results.triggered.connect(self.actionFit_Results)
391        self._workspace.actionChain_Fitting.triggered.connect(self.actionChain_Fitting)
392        self._workspace.actionEdit_Custom_Model.triggered.connect(self.actionEdit_Custom_Model)
393        # Window
394        self._workspace.actionCascade.triggered.connect(self.actionCascade)
[e540cd2]395        self._workspace.actionTile.triggered.connect(self.actionTile)
[f721030]396        self._workspace.actionArrange_Icons.triggered.connect(self.actionArrange_Icons)
397        self._workspace.actionNext.triggered.connect(self.actionNext)
398        self._workspace.actionPrevious.triggered.connect(self.actionPrevious)
399        # Analysis
400        self._workspace.actionFitting.triggered.connect(self.actionFitting)
401        self._workspace.actionInversion.triggered.connect(self.actionInversion)
402        self._workspace.actionInvariant.triggered.connect(self.actionInvariant)
403        # Help
404        self._workspace.actionDocumentation.triggered.connect(self.actionDocumentation)
405        self._workspace.actionTutorial.triggered.connect(self.actionTutorial)
406        self._workspace.actionAcknowledge.triggered.connect(self.actionAcknowledge)
407        self._workspace.actionAbout.triggered.connect(self.actionAbout)
408        self._workspace.actionCheck_for_update.triggered.connect(self.actionCheck_for_update)
409
410    #============ FILE =================
411    def actionLoadData(self):
412        """
[9e426c1]413        Menu File/Load Data File(s)
[f721030]414        """
[5032ea68]415        self.filesWidget.loadFile()
[f721030]416
417    def actionLoad_Data_Folder(self):
418        """
[9e426c1]419        Menu File/Load Data Folder
[f721030]420        """
[5032ea68]421        self.filesWidget.loadFolder()
[f721030]422
423    def actionOpen_Project(self):
424        """
[630155bd]425        Menu Open Project
[f721030]426        """
[630155bd]427        self.filesWidget.loadProject()
[f721030]428
429    def actionOpen_Analysis(self):
430        """
431        """
432        print("actionOpen_Analysis TRIGGERED")
433        pass
434
435    def actionSave(self):
436        """
[630155bd]437        Menu Save Project
[f721030]438        """
[630155bd]439        self.filesWidget.saveProject()
[f721030]440
441    def actionSave_Analysis(self):
442        """
443        """
444        print("actionSave_Analysis TRIGGERED")
[481ff26]445
[f721030]446        pass
447
448    def actionQuit(self):
449        """
[1042dba]450        Close the reactor, exit the application.
[f721030]451        """
[9e426c1]452        self.quitApplication()
[f721030]453
454    #============ EDIT =================
455    def actionUndo(self):
456        """
457        """
458        print("actionUndo TRIGGERED")
459        pass
460
461    def actionRedo(self):
462        """
463        """
464        print("actionRedo TRIGGERED")
465        pass
466
467    def actionCopy(self):
468        """
469        """
470        print("actionCopy TRIGGERED")
471        pass
472
473    def actionPaste(self):
474        """
475        """
476        print("actionPaste TRIGGERED")
477        pass
478
479    def actionReport(self):
480        """
481        """
482        print("actionReport TRIGGERED")
483        pass
484
485    def actionReset(self):
486        """
487        """
[0cd8612]488        logging.warning(" *** actionOpen_Analysis logging *******")
489        print("actionReset print TRIGGERED")
490        sys.stderr.write("STDERR - TRIGGERED")
[f721030]491        pass
492
493    def actionExcel(self):
494        """
495        """
496        print("actionExcel TRIGGERED")
497        pass
498
499    def actionLatex(self):
500        """
501        """
502        print("actionLatex TRIGGERED")
503        pass
504
505    #============ VIEW =================
506    def actionShow_Grid_Window(self):
507        """
508        """
509        print("actionShow_Grid_Window TRIGGERED")
510        pass
511
512    def actionHide_Toolbar(self):
513        """
[e540cd2]514        Toggle toolbar vsibility
[f721030]515        """
[e540cd2]516        if self._workspace.toolBar.isVisible():
517            self._workspace.actionHide_Toolbar.setText("Show Toolbar")
518            self._workspace.toolBar.setVisible(False)
519        else:
520            self._workspace.actionHide_Toolbar.setText("Hide Toolbar")
521            self._workspace.toolBar.setVisible(True)
[f721030]522        pass
523
524    def actionStartup_Settings(self):
525        """
526        """
527        print("actionStartup_Settings TRIGGERED")
528        pass
529
530    def actionCategry_Manager(self):
531        """
532        """
533        print("actionCategry_Manager TRIGGERED")
534        pass
535
536    #============ TOOLS =================
537    def actionData_Operation(self):
538        """
539        """
540        print("actionData_Operation TRIGGERED")
541        pass
542
543    def actionSLD_Calculator(self):
544        """
545        """
[1d85b5e]546        self.SLDCalculator.show()
[f721030]547
548    def actionDensity_Volume_Calculator(self):
549        """
550        """
[1d85b5e]551        self.DVCalculator.show()
[f721030]552
[363fbfa]553    def actionKiessig_Calculator(self):
554        """
555        """
556        #self.DVCalculator.show()
557        self.KIESSIGCalculator.show()
558
[f721030]559    def actionSlit_Size_Calculator(self):
560        """
561        """
[a8ec5b1]562        self.SlitSizeCalculator.show()
[f721030]563
564    def actionSAS_Resolution_Estimator(self):
565        """
566        """
567        print("actionSAS_Resolution_Estimator TRIGGERED")
568        pass
569
570    def actionGeneric_Scattering_Calculator(self):
571        """
572        """
573        print("actionGeneric_Scattering_Calculator TRIGGERED")
574        pass
575
576    def actionPython_Shell_Editor(self):
577        """
[1af348e]578        Display the Jupyter console as a docked widget.
[f721030]579        """
[1af348e]580        terminal = IPythonWidget()
581
582        # Add the console window as another docked widget
583        self.ipDockWidget = QtGui.QDockWidget("IPython", self._workspace)
584        self.ipDockWidget.setObjectName("IPythonDockWidget")
585        self.ipDockWidget.setWidget(terminal)
586        self._workspace.addDockWidget(QtCore.Qt.RightDockWidgetArea,
587                                      self.ipDockWidget)
[f721030]588
589    def actionImage_Viewer(self):
590        """
591        """
592        print("actionImage_Viewer TRIGGERED")
593        pass
594
595    #============ FITTING =================
596    def actionNew_Fit_Page(self):
597        """
[60af928]598        Add a new, empty Fit page in the fitting perspective.
[f721030]599        """
[60af928]600        # Make sure the perspective is correct
601        per = self.perspective()
602        if not isinstance(per, FittingWindow):
603            return
604        per.addFit(None)
[f721030]605
606    def actionConstrained_Fit(self):
607        """
608        """
609        print("actionConstrained_Fit TRIGGERED")
610        pass
611
612    def actionCombine_Batch_Fit(self):
613        """
614        """
615        print("actionCombine_Batch_Fit TRIGGERED")
616        pass
617
618    def actionFit_Options(self):
619        """
620        """
621        print("actionFit_Options TRIGGERED")
622        pass
623
624    def actionFit_Results(self):
625        """
626        """
627        print("actionFit_Results TRIGGERED")
628        pass
629
630    def actionChain_Fitting(self):
631        """
632        """
633        print("actionChain_Fitting TRIGGERED")
634        pass
635
636    def actionEdit_Custom_Model(self):
637        """
638        """
639        print("actionEdit_Custom_Model TRIGGERED")
640        pass
641
642    #============ ANALYSIS =================
643    def actionFitting(self):
644        """
645        """
646        print("actionFitting TRIGGERED")
647        pass
648
649    def actionInversion(self):
650        """
651        """
652        print("actionInversion TRIGGERED")
653        pass
654
655    def actionInvariant(self):
656        """
657        """
658        print("actionInvariant TRIGGERED")
659        pass
660
661    #============ WINDOW =================
662    def actionCascade(self):
663        """
[e540cd2]664        Arranges all the child windows in a cascade pattern.
[f721030]665        """
[e540cd2]666        self._workspace.workspace.cascade()
[f721030]667
[e540cd2]668    def actionTile(self):
[f721030]669        """
[e540cd2]670        Tile workspace windows
[f721030]671        """
[e540cd2]672        self._workspace.workspace.tile()
[f721030]673
674    def actionArrange_Icons(self):
675        """
[e540cd2]676        Arranges all iconified windows at the bottom of the workspace
[f721030]677        """
[e540cd2]678        self._workspace.workspace.arrangeIcons()
[f721030]679
680    def actionNext(self):
681        """
[e540cd2]682        Gives the input focus to the next window in the list of child windows.
[f721030]683        """
[e540cd2]684        self._workspace.workspace.activateNextWindow()
[f721030]685
686    def actionPrevious(self):
687        """
[e540cd2]688        Gives the input focus to the previous window in the list of child windows.
[f721030]689        """
[e540cd2]690        self._workspace.workspace.activatePreviousWindow()
[f721030]691
692    #============ HELP =================
693    def actionDocumentation(self):
694        """
[9e426c1]695        Display the documentation
696
697        TODO: use QNetworkAccessManager to assure _helpLocation is valid
[f721030]698        """
[1042dba]699        self._helpView.load(QtCore.QUrl(self._helpLocation))
700        self._helpView.show()
[f721030]701
702    def actionTutorial(self):
703        """
[9e426c1]704        Open the tutorial PDF file with default PDF renderer
[f721030]705        """
[9e426c1]706        # Not terribly safe here. Shell injection warning.
707        # isfile() helps but this probably needs a better solution.
708        if os.path.isfile(self._tutorialLocation):
709            result = subprocess.Popen([self._tutorialLocation], shell=True)
[f721030]710
711    def actionAcknowledge(self):
712        """
[9e426c1]713        Open the Acknowledgements widget
[f721030]714        """
[9e426c1]715        self.ackWidget.show()
[f721030]716
717    def actionAbout(self):
718        """
[9e426c1]719        Open the About box
[f721030]720        """
[f82ab8c]721        # Update the about box with current version and stuff
722
723        # TODO: proper sizing
724        self.aboutWidget.show()
[f721030]725
726    def actionCheck_for_update(self):
727        """
[9e426c1]728        Menu Help/Check for Update
[f721030]729        """
[9e426c1]730        self.checkUpdate()
731
[cbcdd2c]732    def updateTheoryFromPerspective(self, index):
733        """
734        Catch the theory update signal from a perspective
735        Send the request to the DataExplorer for updating the theory model.
736        """
737        self.filesWidget.updateTheoryFromPerspective(index)
738
739
[f721030]740
Note: See TracBrowser for help on using the repository browser.