Changeset 28a84e9 in sasview


Ignore:
Timestamp:
Jul 30, 2016 4:22:07 PM (8 years ago)
Author:
Piotr Rozyczko <piotr.rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
39551a68
Parents:
4b71e91
Message:

More context menu functionality in Data Explorer

Location:
src/sas/qtgui
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/DataExplorer.py

    r4b71e91 r28a84e9  
    655655        model_item = self.model.itemFromIndex(self.data_proxy.mapToSource(index)) 
    656656        data = model_item.child(0).data().toPyObject() 
    657         if data.__class__.__name__ == "Data1D": 
     657        if isinstance(data, Data1D): 
    658658            text_to_show = GuiUtils.retrieveData1d(data) 
     659            # Hardcoded sizes to enable full width rendering with default font 
    659660            self.txt_widget.resize(420,600) 
    660661        else: 
    661662            text_to_show = GuiUtils.retrieveData2d(data) 
     663            # Hardcoded sizes to enable full width rendering with default font 
    662664            self.txt_widget.resize(700,600) 
    663665 
     
    669671 
    670672        self.txt_widget.show() 
     673        # Move the slider all the way up, if present 
    671674        vertical_scroll_bar = self.txt_widget.verticalScrollBar() 
    672675        vertical_scroll_bar.triggerAction(QtGui.QScrollBar.SliderToMinimum) 
     
    674677    def saveDataAs(self): 
    675678        """ 
    676         """ 
    677         print "saveDataAs" 
    678         pass 
     679        Save the data points as either txt or xml 
     680        """ 
     681        index = self.treeView.selectedIndexes()[0] 
     682        model_item = self.model.itemFromIndex(self.data_proxy.mapToSource(index)) 
     683        data = model_item.child(0).data().toPyObject() 
     684        if isinstance(data, Data1D): 
     685            GuiUtils.saveData1D(data) 
     686        else: 
     687            GuiUtils.saveData2D(data) 
    679688 
    680689    def quickDataPlot(self): 
     
    727736        #                 |----> Process 
    728737        #                          |-----> process[0].name 
    729         # 
     738        #     |-------> THEORIES 
    730739 
    731740        # Top-level item: checkbox with label 
     
    744753        info_item = GuiUtils.infoFromData(data) 
    745754 
    746         # Set info_item as the only child 
     755        # Set info_item as the first child 
    747756        checkbox_item.setChild(1, info_item) 
     757 
     758        # Caption for the theories 
     759        checkbox_item.setChild(2, QtGui.QStandardItem("THEORIES")) 
    748760 
    749761        # New row in the model 
    750762        self.model.appendRow(checkbox_item) 
     763 
    751764 
    752765    def updateModelFromPerspective(self, model_item): 
  • src/sas/qtgui/GuiUtils.py

    r4b71e91 r28a84e9  
    11""" 
    2     Global defaults and various utility functions usable by the general GUI 
     2Global defaults and various utility functions usable by the general GUI 
    33""" 
    44 
     
    2828from sas.sasgui.guiframe.dataFitting import Data1D 
    2929from sas.sasgui.guiframe.dataFitting import Data2D 
     30from sas.sascalc.dataloader.loader import Loader 
    3031 
    3132 
     
    338339    representation 
    339340    """ 
     341    if not isinstance(data, Data1D): 
     342        msg = "Incorrect type passed to retrieveData1d" 
     343        raise AttributeError, msg 
    340344    try: 
    341345        xmin = min(data.x) 
     
    423427 
    424428    return text 
     429 
     430def _onTXTSave(data, path): 
     431    """ 
     432    Save file as formatted txt 
     433    """ 
     434    with open(path,'w') as out: 
     435        has_errors = True 
     436        if data.dy == None or data.dy == []: 
     437            has_errors = False 
     438        # Sanity check 
     439        if has_errors: 
     440            try: 
     441                if len(data.y) != len(data.dy): 
     442                    has_errors = False 
     443            except: 
     444                has_errors = False 
     445        if has_errors: 
     446            if data.dx != None and data.dx != []: 
     447                out.write("<X>   <Y>   <dY>   <dX>\n") 
     448            else: 
     449                out.write("<X>   <Y>   <dY>\n") 
     450        else: 
     451            out.write("<X>   <Y>\n") 
     452 
     453        for i in range(len(data.x)): 
     454            if has_errors: 
     455                if data.dx != None and data.dx != []: 
     456                    if  data.dx[i] != None: 
     457                        out.write("%g  %g  %g  %g\n" % (data.x[i], 
     458                                                        data.y[i], 
     459                                                        data.dy[i], 
     460                                                        data.dx[i])) 
     461                    else: 
     462                        out.write("%g  %g  %g\n" % (data.x[i], 
     463                                                    data.y[i], 
     464                                                    data.dy[i])) 
     465                else: 
     466                    out.write("%g  %g  %g\n" % (data.x[i], 
     467                                                data.y[i], 
     468                                                data.dy[i])) 
     469            else: 
     470                out.write("%g  %g\n" % (data.x[i], 
     471                                        data.y[i])) 
     472 
     473def saveData1D(data): 
     474    """ 
     475    Save 1D data points 
     476    """ 
     477    default_name = os.path.basename(data.filename) 
     478    default_name, extension = os.path.splitext(default_name) 
     479    default_name += "_out" + extension 
     480 
     481    wildcard = "Text files (*.txt);;"\ 
     482                "CanSAS 1D files(*.xml)" 
     483    kwargs = { 
     484        'caption'   : 'Save As', 
     485        'directory' : default_name, 
     486        'filter'    : wildcard, 
     487        'parent'    : None, 
     488    } 
     489    # Query user for filename. 
     490    filename = QtGui.QFileDialog.getSaveFileName(**kwargs) 
     491 
     492    # User cancelled. 
     493    if not filename: 
     494        return 
     495 
     496    filename = str(filename) 
     497 
     498    #Instantiate a loader 
     499    loader = Loader() 
     500    if os.path.splitext(filename)[1].lower() == ".txt": 
     501        _onTXTSave(data, filename) 
     502    if os.path.splitext(filename)[1].lower() == ".xml": 
     503        loader.save(filename, data, ".xml") 
     504 
     505def saveData2D(data): 
     506    """ 
     507    Save data2d dialog 
     508    """ 
     509    default_name = os.path.basename(data.filename) 
     510    default_name, _ = os.path.splitext(default_name) 
     511    ext_format = ".dat" 
     512    default_name += "_out" + ext_format 
     513 
     514    wildcard = "IGOR/DAT 2D file in Q_map (*.dat)" 
     515    kwargs = { 
     516        'caption'   : 'Save As', 
     517        'directory' : default_name, 
     518        'filter'    : wildcard, 
     519        'parent'    : None, 
     520    } 
     521    # Query user for filename. 
     522    filename = QtGui.QFileDialog.getSaveFileName(**kwargs) 
     523 
     524    # User cancelled. 
     525    if not filename: 
     526        return 
     527    filename = str(filename) 
     528    #Instantiate a loader 
     529    loader = Loader() 
     530 
     531    if os.path.splitext(filename)[1].lower() == ext_format: 
     532        loader.save(filename, data, ext_format) 
  • src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py

    r8cb6cd6 r28a84e9  
    1717from UI.TabbedInvariantUI import tabbedInvariantUI 
    1818from InvariantDetails import DetailsDialog 
    19 from Plotter import Plotter 
    2019from InvariantUtils import WIDGETS 
    2120 
     
    5857        self._helpView = QtWebKit.QWebView() 
    5958        self.detailsDialog = DetailsDialog(self) 
    60         # self._plotter = Plotter(self) 
    6159 
    6260        self._low_extrapolate = False 
     
    6563        self._high_extrapolate = False 
    6664        self._high_power_value  = False 
     65 
     66        # No reason to have this widget resizable 
     67        self.setFixedSize(422, 400) 
    6768 
    6869        self.communicate = GuiUtils.Communicate() 
     
    159160        """ 
    160161        """ 
    161         self._plotter = Plotter(self) 
    162         if self._low_extrapolate or self._high_extrapolate: 
    163             self._plotter.show() 
    164162        self.model = model 
    165163        self.mapper.toFirst() 
     
    236234            self.model.setItem(WIDGETS.W_VOLUME_FRACTION_ERR, item) 
    237235        try: 
    238             surface, surface_error                 = \ 
     236            surface, surface_error = \ 
    239237                inv.get_surface_with_error(self._contrast, self._porod) 
    240238        except Exception as ex: 
     
    251249            return self.model 
    252250 
    253         self._plotter.clean() 
    254         self._plotter.x_label("Q(A$^{-1}$)") 
    255         self._plotter.y_label("Intensity(cm$^{-1}$)") 
    256  
    257251        if self._low_extrapolate: 
    258252            # for presentation in InvariantDetails 
     
    266260            # Plot the chart 
    267261            title = "Low-Q extrapolation" 
    268             self._plotter.data(extrapolated_data) 
    269             self._plotter.title(title) 
    270             self._plotter.plot() 
    271262 
    272263            # Convert the data into plottable 
     
    295286            # Plot the chart 
    296287            title = "High-Q extrapolation" 
    297             self._plotter.data(high_out_data) 
    298             self._plotter.title(title) 
    299             self._plotter.plot() 
    300288 
    301289            # Add the plot to the model item 
  • src/sas/qtgui/UnitTesting/DataExplorerTest.py

    r8cb6cd6 r28a84e9  
    619619            self.form.updateModelFromPerspective(bad_item) 
    620620 
     621    def testContextMenu(self): 
     622        """ 
     623        See if the context menu is present 
     624        """ 
     625        # get Data1D 
     626        p_file=["cyl_400_20.txt"] 
     627        # Read in the file 
     628        output, message = self.form.readData(p_file) 
     629        self.form.loadComplete((output, message)) 
     630 
     631        # Pick up the treeview index corresponding to that file 
     632        index = self.form.treeView.indexAt(QtCore.QPoint(5,5)) 
     633        self.form.show() 
     634 
     635        # Find out the center pointof the treeView row 
     636        rect = self.form.treeView.visualRect(index).center() 
     637 
     638        self.form.context_menu.exec_ = MagicMock() 
     639 
     640        # Move the mouse pointer to the first row 
     641        QTest.mouseMove(self.form.treeView.viewport(), pos=rect) 
     642 
     643        # This doesn't invoke the action/signal. Investigate why? 
     644        # QTest.mouseClick(self.form.treeView.viewport(), Qt.RightButton, pos=rect) 
     645 
     646        # Instead, send the signal directly 
     647        self.form.treeView.customContextMenuRequested.emit(rect) 
     648 
     649        # app.exec_() # debug 
     650 
     651        # See that the menu has been shown 
     652        self.form.context_menu.exec_.assert_called_once() 
     653 
     654    def testShowDataInfo(self): 
     655        """ 
     656        Test of the showDataInfo method 
     657        """ 
     658        # get Data1D 
     659        p_file=["cyl_400_20.txt"] 
     660        # Read in the file 
     661        output, message = self.form.readData(p_file) 
     662        self.form.loadComplete((output, message)) 
     663 
     664        # select the data 
     665        self.form.treeView.selectAll() 
     666 
     667        # Call the tested method 
     668        self.form.showDataInfo() 
     669 
     670        # Test the properties 
     671        self.assertTrue(self.form.txt_widget.isReadOnly()) 
     672        self.assertEqual(self.form.txt_widget.windowTitle(), "Data Info: cyl_400_20.txt") 
     673        self.assertIn("Waveln_max", self.form.txt_widget.toPlainText()) 
     674 
     675        # Slider moved all the way up 
     676        self.assertEqual(self.form.txt_widget.verticalScrollBar().sliderPosition(), 0) 
     677 
     678    def testSaveDataAs(self): 
     679        """ 
     680        Test the Save As context menu action 
     681        """ 
     682        # get Data1D 
     683        p_file=["cyl_400_20.txt"] 
     684        # Read in the file 
     685        output, message = self.form.readData(p_file) 
     686        self.form.loadComplete((output, message)) 
     687 
     688        # select the data 
     689        self.form.treeView.selectAll() 
     690 
     691        QFileDialog.getSaveFileName = MagicMock() 
     692 
     693        # Call the tested method 
     694        self.form.saveDataAs() 
     695        QFileDialog.getSaveFileName.assert_called_with( 
     696                                caption="Save As", 
     697                                directory='cyl_400_20_out.txt', 
     698                                filter='Text files (*.txt);;CanSAS 1D files(*.xml)', 
     699                                parent=None) 
     700        QFileDialog.getSaveFileName.assert_called_once() 
     701 
     702        # get Data2D 
     703        p_file=["Dec07031.ASC"] 
     704        # Read in the file 
     705        output, message = self.form.readData(p_file) 
     706        self.form.loadComplete((output, message)) 
     707 
     708        # select the data 
     709        index = self.form.model.index(1, 0) 
     710        selmodel = self.form.treeView.selectionModel() 
     711        selmodel.setCurrentIndex(index, QItemSelectionModel.NoUpdate) 
     712        selmodel.select(index, QItemSelectionModel.Select|QItemSelectionModel.Rows) 
     713 
     714        QFileDialog.getSaveFileName = MagicMock() 
     715 
     716        # Call the tested method 
     717        self.form.saveDataAs() 
     718        QFileDialog.getSaveFileName.assert_called_with( 
     719                                caption="Save As", 
     720                                directory='Dec07031_out.dat', 
     721                                filter='IGOR/DAT 2D file in Q_map (*.dat)', 
     722                                parent=None) 
     723        QFileDialog.getSaveFileName.assert_called_once() 
     724 
     725 
    621726if __name__ == "__main__": 
    622727    unittest.main() 
  • src/sas/qtgui/UnitTesting/GuiUtilsTest.py

    re540cd2 r28a84e9  
    1313# Tested module 
    1414from GuiUtils import * 
     15 
     16class FakeData(object): 
     17    '''Data1D/2D object for testing''' 
     18    def __init__(self): 
     19        self.x = [] 
     20        self.y = [] 
    1521 
    1622class GuiUtilsTest(unittest.TestCase): 
     
    189195            openLink(bad_url3) 
    190196 
     197    def testRetrieveData1d(self): 
     198        """ 
     199        """ 
     200        self.assertRaises(retrieveData1d("BOOP")) 
     201 
     202        # data = FakeData()         
     203        pass 
     204 
     205    def testRetrieveData2d(self): 
     206        """ 
     207        """ 
     208        pass 
     209 
     210    def testOnTXTSave(self): 
     211        """ 
     212        """ 
     213        pass 
     214 
     215    def testSaveData1D(self): 
     216        """ 
     217        """ 
     218        pass 
     219 
     220    def testSaveData2D(self): 
     221        """ 
     222        """ 
     223        pass 
     224 
    191225if __name__ == "__main__": 
    192226    unittest.main() 
Note: See TracChangeset for help on using the changeset viewer.