Changeset 481ff26 in sasview
- Timestamp:
- Jul 4, 2016 5:32:49 AM (8 years ago)
- 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:
- f0f309d
- Parents:
- f82ab8c
- Location:
- src/sas/qtgui
- Files:
-
- 1 added
- 1 deleted
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/AboutBox.py
rf82ab8c r481ff26 1 # global2 import sys3 import os4 1 import functools 5 6 from PyQt4 import QtCore7 from PyQt4 import QtGui8 from PyQt4 import QtWebKit9 2 10 3 import sas.sasview … … 28 21 """ 29 22 version = sas.sasview.__version__ 30 build = sas.sasview.__build__31 23 32 version_text = r'<html><head/><body><p><span style=" font-size:24pt;">'\33 + str(version) + r'</span></p></body></html>'34 24 self.lblVersion.setText(str(version)) 35 25 lbl_font = self.font() … … 42 32 about_text += '<p>Comments? Bugs? Requests?<br/>' 43 33 about_text += r'<a href=mailto:help@sasview.org>Send us a ticket</a></p><br/>' 44 about_text += r'<a href=https://github.com/SasView/sasview/releases>Get the latest version</a></p><br/>' 34 about_text += r'<a href=' + str(LocalConfig.__download_page__)\ 35 + 'Get the latest version</a></p><br/>' 45 36 self.lblAbout.setText(about_text) 46 37 … … 52 43 Add actions to the logo push buttons 53 44 """ 54 self.cmdLinkUT.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._inst_url)) 55 self.cmdLinkUMD.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._umd_url)) 56 self.cmdLinkNIST.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._nist_url)) 57 self.cmdLinkSNS.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._sns_url)) 58 self.cmdLinkISIS.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._isis_url)) 59 self.cmdLinkESS.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._ess_url)) 60 self.cmdLinkILL.clicked.connect(functools.partial(GuiUtils.openLink, LocalConfig._ill_url)) 45 self.cmdLinkUT.clicked.connect(functools.partial( 46 GuiUtils.openLink, LocalConfig._inst_url)) 47 self.cmdLinkUMD.clicked.connect(functools.partial( 48 GuiUtils.openLink, LocalConfig._umd_url)) 49 self.cmdLinkNIST.clicked.connect(functools.partial( 50 GuiUtils.openLink, LocalConfig._nist_url)) 51 self.cmdLinkSNS.clicked.connect(functools.partial( 52 GuiUtils.openLink, LocalConfig._sns_url)) 53 self.cmdLinkISIS.clicked.connect(functools.partial( 54 GuiUtils.openLink, LocalConfig._isis_url)) 55 self.cmdLinkESS.clicked.connect(functools.partial( 56 GuiUtils.openLink, LocalConfig._ess_url)) 57 self.cmdLinkILL.clicked.connect(functools.partial( 58 GuiUtils.openLink, LocalConfig._ill_url)) 61 59 62 60 self.cmdOK.clicked.connect(self.close) -
src/sas/qtgui/DataExplorer.py
rf82ab8c r481ff26 7 7 from PyQt4 import QtGui 8 8 from PyQt4 import QtWebKit 9 from PyQt4.Qt import QMutex 10 9 11 from twisted.internet import threads 10 12 … … 38 40 self.loader = Loader() 39 41 self.manager = DataManager() 42 43 # Be careful with twisted threads. 44 self.mutex = QMutex() 40 45 41 46 # Connect the buttons … … 46 51 self.cmdSendTo.clicked.connect(self.sendData) 47 52 self.cmdNew.clicked.connect(self.newPlot) 53 self.cmdHelp.clicked.connect(self.displayHelp) 54 self.cmdHelp_2.clicked.connect(self.displayHelp) 55 56 # Display HTML content 57 self._helpView = QtWebKit.QWebView() 48 58 49 59 # Connect the comboboxes … … 56 66 57 67 # Proxy model for showing a subset of Data1D/Data2D content 58 self.proxy = QtGui.QSortFilterProxyModel(self) 59 self.proxy.setSourceModel(self.model) 68 self.data_proxy = QtGui.QSortFilterProxyModel(self) 69 self.data_proxy.setSourceModel(self.model) 70 71 # Don't show "empty" rows with data objects 72 self.data_proxy.setFilterRegExp(r"[^()]") 60 73 61 74 # The Data viewer is QTreeView showing the proxy model 62 self.treeView.setModel(self.proxy) 75 self.treeView.setModel(self.data_proxy) 76 77 # Proxy model for showing a subset of Theory content 78 self.theory_proxy = QtGui.QSortFilterProxyModel(self) 79 self.theory_proxy.setSourceModel(self.theory_model) 80 81 # Don't show "empty" rows with data objects 82 self.theory_proxy.setFilterRegExp(r"[^()]") 63 83 64 84 # Theory model view 65 #self.freezeView.setModel(self.theory_model)85 self.freezeView.setModel(self.theory_proxy) 66 86 67 87 def closeEvent(self, event): … … 70 90 """ 71 91 event.ignore() 92 93 def displayHelp(self): 94 """ 95 Show the "Loading data" section of help 96 """ 97 _TreeLocation = "html/user/sasgui/guiframe/data_explorer_help.html" 98 self._helpView.load(QtCore.QUrl(_TreeLocation)) 99 self._helpView.show() 72 100 73 101 def loadFromURL(self, url): … … 81 109 """ 82 110 Called when the "Load" button pressed. 83 Opens the Qt "Open File..." dialog 111 Opens the Qt "Open File..." dialog 84 112 """ 85 113 path_str = self.chooseFiles() … … 91 119 """ 92 120 Called when the "File/Load Folder" menu item chosen. 93 Opens the Qt "Open Folder..." dialog 94 """ 95 dir = QtGui.QFileDialog.getExistingDirectory(self, "Choose a directory", "",121 Opens the Qt "Open Folder..." dialog 122 """ 123 folder = QtGui.QFileDialog.getExistingDirectory(self, "Choose a directory", "", 96 124 QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog) 97 if dir is None:98 return 99 100 dir = str(dir)101 102 if not os.path.isdir( dir):125 if folder is None: 126 return 127 128 folder = str(folder) 129 130 if not os.path.isdir(folder): 103 131 return 104 132 105 133 # get content of dir into a list 106 path_str = [os.path.join(os.path.abspath(dir), filename) for filename in os.listdir(dir)] 134 path_str = [os.path.join(os.path.abspath(folder), filename) 135 for filename in os.listdir(folder)] 107 136 108 137 self.loadFromURL(path_str) … … 211 240 and copying it to a separate top-level item. 212 241 """ 213 import copy214 242 # Figure out which _inner_ rows are checked 215 243 # Use 'while' so the row count is forced at every iteration 216 244 outer_index = -1 245 theories_copied = 0 217 246 while outer_index < self.model.rowCount(): 218 247 outer_index += 1 … … 220 249 if not outer_item: 221 250 continue 222 for inner_index in xrange(outer_item.rowCount()): 251 for inner_index in xrange(outer_item.rowCount()): # Should be just two rows: data and Info 223 252 subitem = outer_item.child(inner_index) 224 253 if subitem and subitem.isCheckable() and subitem.checkState() == QtCore.Qt.Checked: 225 # Update the main model 226 new_item = subitem.takeRow(inner_index) 227 #new_item = QtGui.QStandardItem(subitem) 228 #new_item = subitem.clone() 229 #new_item = QtGui.QStandardItem() 230 #new_item = copy.deepcopy(subitem) 231 #super(new_item, self).__init__() 232 self.model.insertRow(0, new_item) 233 outer_index += 1 234 235 self.model.reset() 254 theories_copied += 1 255 new_item = self.recursivelyCloneItem(subitem) 256 self.theory_model.appendRow(new_item) 257 self.theory_model.reset() 258 259 freeze_msg = "" 260 if theories_copied == 0: 261 return 262 elif theories_copied == 1: 263 freeze_msg = "1 theory sent to Theory tab" 264 elif theories_copied > 1: 265 freeze_msg = "%i theories sent to Theory tab" % theories_copied 266 else: 267 freeze_msg = "Unexpected number of theories copied: %i" % theories_copied 268 raise AttributeError, freeze_msg 269 self.communicator.statusBarUpdateSignal.emit(freeze_msg) 270 # Actively switch tabs 271 self.setCurrentIndex(1) 272 273 def recursivelyCloneItem(self, item): 274 """ 275 Clone QStandardItem() object 276 """ 277 new_item = item.clone() 278 # clone doesn't do deepcopy :( 279 for child_index in xrange(item.rowCount()): 280 child_item = self.recursivelyCloneItem(item.child(child_index)) 281 new_item.setChild(child_index, child_item) 282 return new_item 236 283 237 284 def newPlot(self): … … 266 313 return 267 314 268 if type(paths) == QtCore.QStringList: 315 #if type(paths) == QtCore.QStringList: 316 if isinstance(paths, QtCore.QStringList): 269 317 paths = [str(f) for f in paths] 270 318 … … 276 324 def readData(self, path): 277 325 """ 278 verbatim copy /paste from279 sasgui\guiframe\local_perspectives\data_loader\data_loader.py326 verbatim copy-paste from 327 sasgui.guiframe.local_perspectives.data_loader.data_loader.py 280 328 slightly modified for clarity 281 329 """ … … 286 334 data_error = False 287 335 error_message = "" 288 336 289 337 for p_file in path: 290 info = "info"291 338 basename = os.path.basename(p_file) 292 339 _, extension = os.path.splitext(basename) … … 315 362 316 363 for item in output_objects: 317 # cast sascalc.dataloader.data_info.Data1D into sasgui.guiframe.dataFitting.Data1D 364 # cast sascalc.dataloader.data_info.Data1D into 365 # sasgui.guiframe.dataFitting.Data1D 318 366 # TODO : Fix it 319 367 new_data = self.manager.create_gui_data(item, p_file) 320 368 output[new_data.id] = new_data 369 370 # Model update should be protected 371 self.mutex.lock() 321 372 self.updateModel(new_data, p_file) 322 373 self.model.reset() 323 324 374 QtGui.qApp.processEvents() 375 self.mutex.unlock() 325 376 326 377 if hasattr(item, 'errors'): … … 354 405 error_message += "%s\n" % str(p_file) 355 406 info = "error" 356 407 357 408 if any_error or error_message: 358 # self.loadUpdate(output=output, message=error_message, info=info)359 409 self.communicator.statusBarUpdateSignal.emit(error_message) 360 410 … … 362 412 message = "Loading Data Complete! " 363 413 message += log_msg 414 364 415 return output, message 365 416 … … 470 521 Post message to status bar and update the data manager 471 522 """ 472 # Don't show "empty" rows with data objects473 self.proxy.setFilterRegExp(r"[^()]")474 475 523 # Reset the model so the view gets updated. 476 524 self.model.reset() 477 assert type(output) == tuple525 assert type(output) == tuple 478 526 479 527 output_data = output[0] … … 486 534 def updateModel(self, data, p_file): 487 535 """ 536 Add data and Info fields to the model item 488 537 """ 489 538 # Structure of the model 490 539 # checkbox + basename 540 # |-------> Data.D object 491 541 # |-------> Info 492 # |----> Data.D object493 542 # |----> Title: 494 543 # |----> Run: … … 519 568 # New row in the model 520 569 self.model.appendRow(checkbox_item) 521 570 522 571 def updateModelFromPerspective(self, model_item): 523 572 """ … … 537 586 # Pass acting as a debugger anchor 538 587 pass 539 588 540 589 541 590 if __name__ == "__main__": -
src/sas/qtgui/DroppableDataLoadWidget.py
rf82ab8c r481ff26 3 3 4 4 # UI 5 from UI.TabbedFileLoadUI import DataLoadWidget 6 # from UI.Test2DataExplorerUI import DataLoadWidget 5 from UI.DataExplorerUI import DataLoadWidget 7 6 8 7 class DroppableDataLoadWidget(DataLoadWidget): … … 23 22 """ 24 23 # Analyze mime data 25 if event.mimeData().hasUrls() :24 if event.mimeData().hasUrls() and self.currentIndex() == 0: 26 25 return True 27 26 else: -
src/sas/qtgui/GuiManager.py
rf82ab8c r481ff26 29 29 Main SasView window functionality 30 30 """ 31 HELP_DIRECTORY_LOCATION ="html"31 HELP_DIRECTORY_LOCATION = "html" 32 32 33 33 def __init__(self, mainWindow=None, reactor=None, parent=None): 34 34 """ 35 36 """ 35 """ 36 37 37 self._workspace = mainWindow 38 38 self._parent = parent … … 52 52 53 53 # Populate menus with dynamic data 54 # 54 # 55 55 # Analysis/Perspectives - potentially 56 56 # Window/current windows 57 57 # 58 59 58 # Widgets 60 59 # … … 62 61 self.filesWidget = DataExplorerWindow(parent, self) 63 62 #flags = (QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowMinimizeButtonHint) 64 flags = (QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowMinMaxButtonsHint ) 63 flags = (QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | 64 QtCore.Qt.WindowMinMaxButtonsHint) 65 65 66 66 self.dockedFilesWidget = QtGui.QDockWidget("Data explorer", self._workspace, flags=flags) … … 95 95 # Default perspective 96 96 self._current_perspective = self.invariantWidget 97 97 98 98 def fileRead(self, data): 99 99 """ … … 101 101 """ 102 102 pass 103 103 104 104 def updatePerspective(self, data): 105 105 """ … … 111 111 msg = "No perspective is currently active." 112 112 logging.info(msg) 113 114 113 114 115 115 def communicator(self): 116 116 """ … … 143 143 """ 144 144 return self._data_manager.create_gui_data(item, p_file) 145 146 def addData(self, data_list):147 """148 receive a dictionary of data from loader149 store them its data manager if possible150 send to data the current active perspective if the data panel151 is not active.152 :param data_list: dictionary of data's ID and value Data153 """154 #Store data into manager155 #self._data_manager.add_data(data_list)156 157 # set data in the data panel158 #if self._data_panel is not None:159 # data_state = self._data_manager.get_data_state(data_list.keys())160 # self._data_panel.load_data_list(data_state)161 162 #if the data panel is shown wait for the user to press a button163 #to send data to the current perspective. if the panel is not164 #show automatically send the data to the current perspective165 #style = self.__gui_style & GUIFRAME.MANAGER_ON166 #if style == GUIFRAME.MANAGER_ON:167 # #wait for button press from the data panel to set_data168 # if self._data_panel is not None:169 # self._data_panel.frame.Show(True)170 #else:171 #automatically send that to the current perspective172 #self.setData(data_id=data_list.keys())173 pass174 145 175 146 def setData(self, data): … … 190 161 quit_msg = "Are you sure you want to exit the application?" 191 162 reply = QtGui.QMessageBox.question( 192 193 194 195 196 163 self._parent, 164 'Warning', 165 quit_msg, 166 QtGui.QMessageBox.Yes, 167 QtGui.QMessageBox.No) 197 168 198 169 if reply == QtGui.QMessageBox.No: … … 201 172 # Exit if yes 202 173 reactor.callFromThread(reactor.stop) 203 sys.exit()204 174 205 175 def checkUpdate(self): … … 221 191 except: 222 192 logging.info("Failed to connect to www.sasview.org") 223 self.processVersion(version_info) 224 193 self.processVersion(version_info) 194 225 195 def processVersion(self, version_info): 226 196 """ … … 365 335 """ 366 336 print("actionSave_Analysis TRIGGERED") 367 337 368 338 pass 369 339 -
src/sas/qtgui/GuiUtils.py
rf82ab8c r481ff26 5 5 import os 6 6 import sys 7 import time8 7 import imp 9 8 import warnings 10 import re11 9 import webbrowser 12 10 import urlparse … … 14 12 warnings.simplefilter("ignore") 15 13 import logging 16 import traceback17 14 18 15 from PyQt4 import QtCore … … 74 71 return userdir 75 72 76 def _find_local_config( file, path):73 def _find_local_config(confg_file, path): 77 74 """ 78 75 Find configuration file for the current application … … 81 78 fObj = None 82 79 try: 83 fObj, path_config, descr = imp.find_module( file, [path])84 config_module = imp.load_module( file, fObj, path_config, descr)80 fObj, path_config, descr = imp.find_module(confg_file, [path]) 81 config_module = imp.load_module(confg_file, fObj, path_config, descr) 85 82 except: 86 logging.error("Error loading %s/%s: %s" % (path, file, sys.exc_value))83 logging.error("Error loading %s/%s: %s" % (path, confg_file, sys.exc_value)) 87 84 finally: 88 85 if fObj is not None: 89 86 fObj.close() 90 logging.info("GuiManager loaded %s/%s" % (path, file))87 logging.info("GuiManager loaded %s/%s" % (path, confg_file)) 91 88 return config_module 92 89 … … 238 235 else: 239 236 # otherwise just add a naked item 240 info_item = QtGui.QStandardItem("Info") 237 info_item = QtGui.QStandardItem("Info") 241 238 242 239 # Add the actual Data1D/Data2D object … … 274 271 # TODO: assure item type is correct (either data1/2D or Plotter) 275 272 plot_data.append(item_2.child(0).data().toPyObject()) 276 273 277 274 return plot_data 278 275 … … 286 283 info_item = QtGui.QStandardItem("Info") 287 284 288 title_item = QtGui.QStandardItem("Title: "+ data.title)285 title_item = QtGui.QStandardItem("Title: " + data.title) 289 286 info_item.appendRow(title_item) 290 run_item = QtGui.QStandardItem("Run: "+ str(data.run))287 run_item = QtGui.QStandardItem("Run: " + str(data.run)) 291 288 info_item.appendRow(run_item) 292 type_item = QtGui.QStandardItem("Type: "+ str(data.__class__.__name__))289 type_item = QtGui.QStandardItem("Type: " + str(data.__class__.__name__)) 293 290 info_item.appendRow(type_item) 294 291 295 292 if data.path: 296 path_item = QtGui.QStandardItem("Path: "+ data.path)293 path_item = QtGui.QStandardItem("Path: " + data.path) 297 294 info_item.appendRow(path_item) 298 295 299 296 if data.instrument: 300 instr_item 297 instr_item = QtGui.QStandardItem("Instrument: " + data.instrument) 301 298 info_item.appendRow(instr_item) 302 299 -
src/sas/qtgui/MainWindow.py
rf82ab8c r481ff26 25 25 def closeEvent(self, event): 26 26 self.guiManager.quitApplication() 27 27 28 28 29 def SplashScreen(): -
src/sas/qtgui/UI/DataExplorerUI.ui
rf721030 r481ff26 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <ui version="4.0"> 3 <class>Data ExplorerUI</class>4 <widget class="Q Dialog" name="DataExplorerUI">3 <class>DataLoadWidget</class> 4 <widget class="QTabWidget" name="DataLoadWidget"> 5 5 <property name="geometry"> 6 6 <rect> 7 7 <x>0</x> 8 8 <y>0</y> 9 <width> 454</width>10 <height> 577</height>9 <width>517</width> 10 <height>693</height> 11 11 </rect> 12 12 </property> 13 <property name="sizePolicy"> 14 <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> 15 <horstretch>0</horstretch> 16 <verstretch>0</verstretch> 17 </sizepolicy> 18 </property> 13 19 <property name="windowTitle"> 14 <string> Dialog</string>20 <string>TabWidget</string> 15 21 </property> 16 <layout class="QGridLayout" name="gridLayout_4"> 17 <item row="0" column="0"> 18 <widget class="QLabel" name="label"> 19 <property name="text"> 20 <string>Selection Options</string> 21 </property> 22 </widget> 23 </item> 24 <item row="1" column="0"> 25 <widget class="QComboBox" name="comboBox"> 26 <item> 27 <property name="text"> 28 <string>Select all</string> 22 <property name="windowIcon"> 23 <iconset resource="main_resources.qrc"> 24 <normaloff>:/res/ball.ico</normaloff>:/res/ball.ico</iconset> 25 </property> 26 <property name="currentIndex"> 27 <number>0</number> 28 </property> 29 <widget class="QWidget" name="dataTab"> 30 <attribute name="title"> 31 <string>Data</string> 32 </attribute> 33 <layout class="QGridLayout" name="gridLayout_6"> 34 <item row="0" column="0"> 35 <widget class="QGroupBox" name="groupBox"> 36 <property name="title"> 37 <string>Data</string> 29 38 </property> 30 </item> 31 <item> 32 <property name="text"> 33 <string>Unselect all</string> 34 </property> 35 </item> 36 <item> 37 <property name="text"> 38 <string>Select all 1D</string> 39 </property> 40 </item> 41 <item> 42 <property name="text"> 43 <string>Unselect all 1D</string> 44 </property> 45 </item> 46 <item> 47 <property name="text"> 48 <string>Select all 2D</string> 49 </property> 50 </item> 51 <item> 52 <property name="text"> 53 <string>Unselect all 2D</string> 54 </property> 55 </item> 56 </widget> 57 </item> 58 <item row="1" column="1"> 59 <spacer name="horizontalSpacer_2"> 60 <property name="orientation"> 61 <enum>Qt::Horizontal</enum> 62 </property> 63 <property name="sizeHint" stdset="0"> 64 <size> 65 <width>278</width> 66 <height>20</height> 67 </size> 68 </property> 69 </spacer> 70 </item> 71 <item row="2" column="0" colspan="2"> 72 <widget class="QGroupBox" name="groupBox"> 73 <property name="title"> 74 <string>Data</string> 75 </property> 76 <layout class="QGridLayout" name="gridLayout"> 39 <layout class="QGridLayout" name="gridLayout"> 40 <item row="0" column="0"> 41 <layout class="QHBoxLayout" name="horizontalLayout_2"> 42 <item> 43 <widget class="QPushButton" name="cmdLoad"> 44 <property name="text"> 45 <string>Load</string> 46 </property> 47 </widget> 48 </item> 49 <item> 50 <widget class="QComboBox" name="cbSelect"> 51 <property name="sizePolicy"> 52 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 53 <horstretch>0</horstretch> 54 <verstretch>0</verstretch> 55 </sizepolicy> 56 </property> 57 <item> 58 <property name="text"> 59 <string>Select all</string> 60 </property> 61 </item> 62 <item> 63 <property name="text"> 64 <string>Unselect all</string> 65 </property> 66 </item> 67 <item> 68 <property name="text"> 69 <string>Select all 1D</string> 70 </property> 71 </item> 72 <item> 73 <property name="text"> 74 <string>Unselect all 1D</string> 75 </property> 76 </item> 77 <item> 78 <property name="text"> 79 <string>Select all 2D</string> 80 </property> 81 </item> 82 <item> 83 <property name="text"> 84 <string>Unselect all 2D</string> 85 </property> 86 </item> 87 </widget> 88 </item> 89 <item> 90 <spacer name="horizontalSpacer_7"> 91 <property name="orientation"> 92 <enum>Qt::Horizontal</enum> 93 </property> 94 <property name="sizeHint" stdset="0"> 95 <size> 96 <width>128</width> 97 <height>20</height> 98 </size> 99 </property> 100 </spacer> 101 </item> 102 <item> 103 <widget class="QPushButton" name="cmdDeleteData"> 104 <property name="text"> 105 <string>Delete</string> 106 </property> 107 </widget> 108 </item> 109 </layout> 110 </item> 111 <item row="1" column="0"> 112 <widget class="QTreeView" name="treeView"> 113 <property name="acceptDrops"> 114 <bool>true</bool> 115 </property> 116 <property name="editTriggers"> 117 <set>QAbstractItemView::NoEditTriggers</set> 118 </property> 119 <property name="dragEnabled"> 120 <bool>true</bool> 121 </property> 122 <property name="dragDropOverwriteMode"> 123 <bool>true</bool> 124 </property> 125 <property name="dragDropMode"> 126 <enum>QAbstractItemView::DropOnly</enum> 127 </property> 128 <property name="defaultDropAction"> 129 <enum>Qt::CopyAction</enum> 130 </property> 131 <property name="selectionMode"> 132 <enum>QAbstractItemView::ExtendedSelection</enum> 133 </property> 134 <attribute name="headerVisible"> 135 <bool>false</bool> 136 </attribute> 137 </widget> 138 </item> 139 <item row="2" column="0"> 140 <layout class="QHBoxLayout" name="horizontalLayout"> 141 <item> 142 <widget class="QPushButton" name="cmdFreeze"> 143 <property name="text"> 144 <string>Freeze Theory</string> 145 </property> 146 </widget> 147 </item> 148 <item> 149 <spacer name="horizontalSpacer"> 150 <property name="orientation"> 151 <enum>Qt::Horizontal</enum> 152 </property> 153 <property name="sizeHint" stdset="0"> 154 <size> 155 <width>58</width> 156 <height>20</height> 157 </size> 158 </property> 159 </spacer> 160 </item> 161 <item> 162 <widget class="QToolButton" name="cmdSendTo"> 163 <property name="text"> 164 <string>...</string> 165 </property> 166 <property name="icon"> 167 <iconset resource="main_resources.qrc"> 168 <normaloff>:/res/file_send-128.png</normaloff>:/res/file_send-128.png</iconset> 169 </property> 170 <property name="iconSize"> 171 <size> 172 <width>32</width> 173 <height>32</height> 174 </size> 175 </property> 176 </widget> 177 </item> 178 <item> 179 <widget class="QComboBox" name="cbFitting"> 180 <property name="sizePolicy"> 181 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 182 <horstretch>0</horstretch> 183 <verstretch>0</verstretch> 184 </sizepolicy> 185 </property> 186 <property name="sizeAdjustPolicy"> 187 <enum>QComboBox::AdjustToContents</enum> 188 </property> 189 <item> 190 <property name="text"> 191 <string>Fitting</string> 192 </property> 193 </item> 194 <item> 195 <property name="text"> 196 <string>Pr inversion</string> 197 </property> 198 </item> 199 <item> 200 <property name="text"> 201 <string>Invariant</string> 202 </property> 203 </item> 204 </widget> 205 </item> 206 <item> 207 <widget class="QCheckBox" name="chkBatch"> 208 <property name="text"> 209 <string>Batch mode</string> 210 </property> 211 </widget> 212 </item> 213 </layout> 214 </item> 215 </layout> 216 </widget> 217 </item> 218 <item row="1" column="0"> 219 <layout class="QGridLayout" name="gridLayout_2"> 77 220 <item row="0" column="0"> 78 <widget class="QTreeView" name="treeView"> 79 <property name="dragEnabled"> 80 <bool>true</bool> 81 </property> 82 <property name="dragDropMode"> 83 <enum>QAbstractItemView::DragDrop</enum> 84 </property> 85 <property name="defaultDropAction"> 86 <enum>Qt::CopyAction</enum> 87 </property> 88 <property name="selectionMode"> 89 <enum>QAbstractItemView::ExtendedSelection</enum> 90 </property> 221 <widget class="QGroupBox" name="groupBox_3"> 222 <property name="title"> 223 <string>Plot</string> 224 </property> 225 <layout class="QGridLayout" name="gridLayout_3"> 226 <item row="0" column="0"> 227 <widget class="QPushButton" name="cmdNew"> 228 <property name="text"> 229 <string>Create New</string> 230 </property> 231 </widget> 232 </item> 233 <item row="1" column="0"> 234 <widget class="QPushButton" name="cmdAppend"> 235 <property name="text"> 236 <string>Append to</string> 237 </property> 238 </widget> 239 </item> 240 <item row="1" column="1"> 241 <widget class="QComboBox" name="cbgraph"> 242 <property name="sizePolicy"> 243 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 244 <horstretch>0</horstretch> 245 <verstretch>0</verstretch> 246 </sizepolicy> 247 </property> 248 <property name="sizeAdjustPolicy"> 249 <enum>QComboBox::AdjustToContents</enum> 250 </property> 251 <item> 252 <property name="text"> 253 <string>Graph1</string> 254 </property> 255 </item> 256 </widget> 257 </item> 258 </layout> 91 259 </widget> 92 260 </item> 93 261 <item row="0" column="1"> 94 <layout class="QVBoxLayout" name="verticalLayout"> 95 <item> 96 <widget class="QPushButton" name="pushButton"> 97 <property name="text"> 98 <string>Load</string> 99 </property> 100 </widget> 101 </item> 102 <item> 103 <widget class="QPushButton" name="pushButton_2"> 104 <property name="text"> 105 <string>Delete</string> 106 </property> 107 </widget> 108 </item> 109 <item> 110 <spacer name="verticalSpacer_2"> 111 <property name="orientation"> 112 <enum>Qt::Vertical</enum> 113 </property> 114 <property name="sizeHint" stdset="0"> 115 <size> 116 <width>20</width> 117 <height>141</height> 118 </size> 119 </property> 120 </spacer> 121 </item> 122 </layout> 123 </item> 124 <item row="1" column="0" colspan="2"> 125 <layout class="QHBoxLayout" name="horizontalLayout"> 126 <item> 127 <widget class="QPushButton" name="pushButton_6"> 128 <property name="text"> 129 <string>Send to</string> 130 </property> 131 </widget> 132 </item> 133 <item> 134 <widget class="QComboBox" name="comboBox_3"> 135 <property name="sizePolicy"> 136 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 137 <horstretch>0</horstretch> 138 <verstretch>0</verstretch> 139 </sizepolicy> 140 </property> 141 <item> 142 <property name="text"> 143 <string>Fitting</string> 144 </property> 145 </item> 146 <item> 147 <property name="text"> 148 <string>Pr inversion</string> 149 </property> 150 </item> 151 <item> 152 <property name="text"> 153 <string>Invariant</string> 154 </property> 155 </item> 156 </widget> 157 </item> 158 <item> 159 <widget class="QCheckBox" name="checkBox"> 160 <property name="text"> 161 <string>Batch mode</string> 162 </property> 163 </widget> 164 </item> 165 <item> 166 <spacer name="horizontalSpacer"> 167 <property name="orientation"> 168 <enum>Qt::Horizontal</enum> 169 </property> 170 <property name="sizeHint" stdset="0"> 171 <size> 172 <width>197</width> 173 <height>20</height> 174 </size> 175 </property> 176 </spacer> 177 </item> 178 </layout> 179 </item> 180 </layout> 181 </widget> 182 </item> 183 <item row="3" column="0" colspan="2"> 184 <widget class="QGroupBox" name="groupBox_2"> 185 <property name="title"> 186 <string>Theory</string> 187 </property> 188 <layout class="QGridLayout" name="gridLayout_2"> 189 <item row="0" column="0" rowspan="2"> 190 <widget class="QListView" name="listView"/> 191 </item> 192 <item row="0" column="1"> 193 <widget class="QPushButton" name="pushButton_3"> 194 <property name="text"> 195 <string>Freeze</string> 196 </property> 197 </widget> 198 </item> 199 <item row="1" column="1"> 200 <spacer name="verticalSpacer"> 262 <spacer name="horizontalSpacer_3"> 201 263 <property name="orientation"> 202 <enum>Qt:: Vertical</enum>264 <enum>Qt::Horizontal</enum> 203 265 </property> 204 266 <property name="sizeHint" stdset="0"> 205 267 <size> 206 <width> 20</width>207 <height>1 98</height>268 <width>108</width> 269 <height>111</height> 208 270 </size> 209 271 </property> 210 272 </spacer> 211 273 </item> 274 <item row="0" column="2" alignment="Qt::AlignBottom"> 275 <widget class="QPushButton" name="cmdHelp"> 276 <property name="text"> 277 <string>Help</string> 278 </property> 279 </widget> 280 </item> 212 281 </layout> 213 </widget> 214 </item> 215 <item row="4" column="0"> 216 <widget class="QGroupBox" name="groupBox_3"> 217 <property name="title"> 218 <string>Plot</string> 219 </property> 220 <layout class="QGridLayout" name="gridLayout_3"> 282 </item> 283 </layout> 284 </widget> 285 <widget class="QWidget" name="theoryTab"> 286 <attribute name="title"> 287 <string>Theory</string> 288 </attribute> 289 <layout class="QGridLayout" name="gridLayout_8"> 290 <item row="0" column="0"> 291 <widget class="QGroupBox" name="groupBox_2"> 292 <property name="title"> 293 <string>Theory</string> 294 </property> 295 <layout class="QGridLayout" name="gridLayout_4"> 296 <item row="0" column="0"> 297 <layout class="QHBoxLayout" name="horizontalLayout_3"> 298 <item> 299 <spacer name="horizontalSpacer_5"> 300 <property name="orientation"> 301 <enum>Qt::Horizontal</enum> 302 </property> 303 <property name="sizeHint" stdset="0"> 304 <size> 305 <width>353</width> 306 <height>20</height> 307 </size> 308 </property> 309 </spacer> 310 </item> 311 <item> 312 <widget class="QPushButton" name="cmdDeleteTheory"> 313 <property name="text"> 314 <string>Delete</string> 315 </property> 316 </widget> 317 </item> 318 </layout> 319 </item> 320 <item row="1" column="0"> 321 <widget class="QTreeView" name="freezeView"> 322 <attribute name="headerVisible"> 323 <bool>false</bool> 324 </attribute> 325 </widget> 326 </item> 327 </layout> 328 </widget> 329 </item> 330 <item row="1" column="0"> 331 <layout class="QGridLayout" name="gridLayout_5"> 221 332 <item row="0" column="0"> 222 <widget class="QPushButton" name="pushButton_4"> 333 <widget class="QGroupBox" name="groupBox_4"> 334 <property name="title"> 335 <string>Plot</string> 336 </property> 337 <layout class="QGridLayout" name="gridLayout_7"> 338 <item row="0" column="0"> 339 <widget class="QPushButton" name="cmdNew_2"> 340 <property name="text"> 341 <string>Create New</string> 342 </property> 343 </widget> 344 </item> 345 <item row="1" column="0"> 346 <widget class="QPushButton" name="cmdAppend_2"> 347 <property name="text"> 348 <string>Append to</string> 349 </property> 350 </widget> 351 </item> 352 <item row="1" column="1"> 353 <widget class="QComboBox" name="cbgraph_2"> 354 <property name="sizePolicy"> 355 <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> 356 <horstretch>0</horstretch> 357 <verstretch>0</verstretch> 358 </sizepolicy> 359 </property> 360 <property name="sizeAdjustPolicy"> 361 <enum>QComboBox::AdjustToContents</enum> 362 </property> 363 <item> 364 <property name="text"> 365 <string>Graph1</string> 366 </property> 367 </item> 368 </widget> 369 </item> 370 </layout> 371 </widget> 372 </item> 373 <item row="0" column="1"> 374 <spacer name="horizontalSpacer_4"> 375 <property name="orientation"> 376 <enum>Qt::Horizontal</enum> 377 </property> 378 <property name="sizeHint" stdset="0"> 379 <size> 380 <width>108</width> 381 <height>111</height> 382 </size> 383 </property> 384 </spacer> 385 </item> 386 <item row="0" column="2" alignment="Qt::AlignBottom"> 387 <widget class="QPushButton" name="cmdHelp_2"> 223 388 <property name="text"> 224 <string> New</string>389 <string>Help</string> 225 390 </property> 226 391 </widget> 227 392 </item> 228 <item row="1" column="0">229 <widget class="QPushButton" name="pushButton_5">230 <property name="text">231 <string>Append to</string>232 </property>233 </widget>234 </item>235 <item row="1" column="1">236 <widget class="QComboBox" name="comboBox_2">237 <property name="sizePolicy">238 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">239 <horstretch>0</horstretch>240 <verstretch>0</verstretch>241 </sizepolicy>242 </property>243 <item>244 <property name="text">245 <string>Graph1</string>246 </property>247 </item>248 </widget>249 </item>250 393 </layout> 251 </widget> 252 </item> 253 </layout> 254 <zorder>groupBox_3</zorder> 255 <zorder>groupBox_2</zorder> 256 <zorder>groupBox</zorder> 257 <zorder>comboBox</zorder> 258 <zorder>label</zorder> 259 <zorder>horizontalSpacer_2</zorder> 394 </item> 395 </layout> 396 </widget> 260 397 </widget> 261 <resources/> 398 <resources> 399 <include location="main_resources.qrc"/> 400 </resources> 262 401 <connections/> 263 402 </ui> -
src/sas/qtgui/UI/TabbedFileLoadUI.py
rf82ab8c r481ff26 133 133 self.freezeView = QtGui.QTreeView(self.groupBox_2) 134 134 self.freezeView.setObjectName(_fromUtf8("freezeView")) 135 self.freezeView.header().setVisible(False) 135 136 self.gridLayout_4.addWidget(self.freezeView, 0, 0, 1, 2) 136 137 self.gridLayout_7.addWidget(self.groupBox_2, 0, 0, 1, 2) -
src/sas/qtgui/UI/TabbedFileLoadUI.ui
rf82ab8c r481ff26 281 281 </item> 282 282 <item row="0" column="0" colspan="2"> 283 <widget class="QTreeView" name="freezeView"/> 283 <widget class="QTreeView" name="freezeView"> 284 <attribute name="headerVisible"> 285 <bool>false</bool> 286 </attribute> 287 </widget> 284 288 </item> 285 289 </layout> -
src/sas/qtgui/UnitTesting/DataExplorerTest.py
rf82ab8c r481ff26 49 49 def testDefaults(self): 50 50 '''Test the GUI in its default state''' 51 # Tab widget 51 52 self.assertIsInstance(self.form, QTabWidget) 52 self.assertIsInstance(self.form.treeView, QTreeView)53 self.assertIsInstance(self.form.freezeView, QTreeView)54 53 self.assertEqual(self.form.count(), 2) 55 54 55 # Buttons - data tab 56 56 self.assertEqual(self.form.cmdLoad.text(), "Load") 57 57 self.assertEqual(self.form.cmdDeleteData.text(), "Delete") 58 58 self.assertEqual(self.form.cmdDeleteTheory.text(), "Delete") 59 self.assertEqual(self.form.cmdFreeze.text(), "Freeze") 60 self.assertEqual(self.form.cmdSendTo.text(), "Send to") 59 self.assertEqual(self.form.cmdFreeze.text(), "Freeze Theory") 60 self.assertEqual(self.form.cmdSendTo.text(), "...") 61 self.assertEqual(self.form.cmdSendTo.iconSize(), QSize(32, 32)) 62 self.assertIsInstance(self.form.cmdSendTo.icon(), QIcon) 61 63 self.assertEqual(self.form.chkBatch.text(), "Batch mode") 62 64 self.assertFalse(self.form.chkBatch.isChecked()) 63 65 66 # Buttons - theory tab 67 68 # Combo boxes 64 69 self.assertEqual(self.form.cbSelect.count(), 6) 65 70 self.assertEqual(self.form.cbSelect.currentIndex(), 0) 66 71 67 # Class is in the default state even without pressing OK 72 # Models - data 73 self.assertIsInstance(self.form.model, QStandardItemModel) 68 74 self.assertEqual(self.form.treeView.model().rowCount(), 0) 69 75 self.assertEqual(self.form.treeView.model().columnCount(), 0) 70 76 self.assertEqual(self.form.model.rowCount(), 0) 71 77 self.assertEqual(self.form.model.columnCount(), 0) 78 self.assertIsInstance(self.form.data_proxy, QSortFilterProxyModel) 79 self.assertEqual(self.form.data_proxy.sourceModel(), self.form.model) 80 self.assertEqual("[^()]", str(self.form.data_proxy.filterRegExp().pattern())) 81 self.assertIsInstance(self.form.treeView, QTreeView) 82 83 # Models - theory 84 self.assertIsInstance(self.form.theory_model, QStandardItemModel) 85 self.assertEqual(self.form.freezeView.model().rowCount(), 0) 86 self.assertEqual(self.form.freezeView.model().columnCount(), 0) 87 self.assertEqual(self.form.theory_model.rowCount(), 0) 88 self.assertEqual(self.form.theory_model.columnCount(), 0) 89 self.assertIsInstance(self.form.theory_proxy, QSortFilterProxyModel) 90 self.assertEqual(self.form.theory_proxy.sourceModel(), self.form.theory_model) 91 self.assertEqual("[^()]", str(self.form.theory_proxy.filterRegExp().pattern())) 92 self.assertIsInstance(self.form.freezeView, QTreeView) 93 72 94 73 95 def testLoadButton(self): … … 153 175 QTest.mouseClick(deleteButton, Qt.LeftButton) 154 176 177 def testDeleteTheory(self): 178 """ 179 Test that clicking "Delete" in theories tab removes selected indices 180 """ 181 deleteButton = self.form.cmdDeleteTheory 182 183 # Mock the confirmation dialog with return=No 184 QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.No) 185 186 # Populate the model 187 item1 = QtGui.QStandardItem(True) 188 item1.setCheckable(True) 189 item1.setCheckState(QtCore.Qt.Checked) 190 item1.setText("item 1") 191 self.form.theory_model.appendRow(item1) 192 item2 = QtGui.QStandardItem(True) 193 item2.setCheckable(True) 194 item2.setCheckState(QtCore.Qt.Unchecked) 195 item2.setText("item 2") 196 self.form.theory_model.appendRow(item2) 197 198 # Assure the model contains two items 199 self.assertEqual(self.form.theory_model.rowCount(), 2) 200 201 # Assure the checkboxes are on 202 self.assertTrue(item1.checkState() == QtCore.Qt.Checked) 203 self.assertTrue(item2.checkState() == QtCore.Qt.Unchecked) 204 205 # Click on the delete button 206 QTest.mouseClick(deleteButton, Qt.LeftButton) 207 208 # Test the warning dialog called once 209 self.assertTrue(QtGui.QMessageBox.question.called) 210 211 # Assure the model still contains the items 212 self.assertEqual(self.form.theory_model.rowCount(), 2) 213 214 # Now, mock the confirmation dialog with return=Yes 215 QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.Yes) 216 217 # Click on the delete button 218 QTest.mouseClick(deleteButton, Qt.LeftButton) 219 220 # Test the warning dialog called once 221 self.assertTrue(QtGui.QMessageBox.question.called) 222 223 # Assure the model contains 1 item 224 self.assertEqual(self.form.theory_model.rowCount(), 1) 225 226 # Set the remaining item to checked 227 self.form.theory_model.item(0).setCheckState(QtCore.Qt.Checked) 228 229 # Click on the delete button again 230 QTest.mouseClick(deleteButton, Qt.LeftButton) 231 232 # Assure the model contains no items 233 self.assertEqual(self.form.theory_model.rowCount(), 0) 234 235 # Click delete once again to assure no nasty behaviour on empty model 236 QTest.mouseClick(deleteButton, Qt.LeftButton) 237 238 155 239 def testSendToButton(self): 156 240 """ … … 253 337 # self.form.cbSelect.setCurrentIndex(6) 254 338 339 def testFreezeTheory(self): 340 """ 341 Assure theory freeze functionality works 342 """ 343 # Not yet tested - agree on design first. 344 pass 345 346 def testRecursivelyCloneItem(self): 347 """ 348 Test the rescursive QAbstractItem/QStandardItem clone 349 """ 350 # Create an item with several branches 351 item1 = QtGui.QStandardItem() 352 item2 = QtGui.QStandardItem() 353 item3 = QtGui.QStandardItem() 354 item4 = QtGui.QStandardItem() 355 item5 = QtGui.QStandardItem() 356 item6 = QtGui.QStandardItem() 357 358 item4.appendRow(item5) 359 item2.appendRow(item4) 360 item2.appendRow(item6) 361 item1.appendRow(item2) 362 item1.appendRow(item3) 363 364 # Clone 365 new_item = self.form.recursivelyCloneItem(item1) 366 367 # assure the trees look identical 368 self.assertEqual(item1.rowCount(), new_item.rowCount()) 369 self.assertEqual(item1.child(0).rowCount(), new_item.child(0).rowCount()) 370 self.assertEqual(item1.child(1).rowCount(), new_item.child(1).rowCount()) 371 self.assertEqual(item1.child(0).child(0).rowCount(), new_item.child(0).child(0).rowCount()) 372 255 373 def testReadData(self): 256 374 """ … … 281 399 self.assertEqual(model_name, filename[0]) 282 400 401 def testDisplayHelp(self): 402 """ 403 Test that the Help window gets shown correctly 404 """ 405 partial_url = "sasgui/guiframe/data_explorer_help.html" 406 button1 = self.form.cmdHelp 407 button2 = self.form.cmdHelp_2 408 409 # Click on the Help button 410 QTest.mouseClick(button1, Qt.LeftButton) 411 qApp.processEvents() 412 413 # Check the browser 414 self.assertIn(partial_url, str(self.form._helpView.url())) 415 # Close the browser 416 self.form._helpView.close() 417 418 # Click on the Help_2 button 419 QTest.mouseClick(button2, Qt.LeftButton) 420 qApp.processEvents() 421 # Check the browser 422 self.assertIn(partial_url, str(self.form._helpView.url())) 423 283 424 def testLoadFile(self): 284 425 """ … … 292 433 Test the list of known extensions 293 434 """ 294 list = self.form.getWlist() 435 w_list = self.form.getWlist() 436 295 437 defaults = 'All (*.*);;canSAS files (*.xml);;SESANS files' +\ 296 438 ' (*.ses);;ASCII files (*.txt);;IGOR 2D files (*.asc);;' +\ 297 439 'IGOR/DAT 2D Q_map files (*.dat);;IGOR 1D files (*.abs);;'+\ 298 440 'HFIR 1D files (*.d1d);;DANSE files (*.sans);;NXS files (*.nxs)' 299 self.assertEqual(defaults, list) 441 default_list = defaults.split(';;') 442 443 for format in default_list: 444 self.assertIn(format, w_list) 300 445 301 446 def testLoadComplete(self): -
src/sas/qtgui/UnitTesting/DroppableDataLoadWidgetTest.py
rf82ab8c r481ff26 6 6 from PyQt4.QtCore import Qt 7 7 from DroppableDataLoadWidget import DroppableDataLoadWidget 8 from GuiUtils import * 8 9 9 10 app = QApplication(sys.argv) … … 13 14 def setUp(self): 14 15 '''Create the GUI''' 15 self.form = DroppableDataLoadWidget() 16 class dummy_manager(object): 17 def communicator(self): 18 return Communicate() 19 def perspective(self): 20 return MyPerspective() 21 22 self.form = DroppableDataLoadWidget(None, guimanager=dummy_manager()) 23 # create dummy mime objects 24 25 def testDragIsOK(self): 26 """ 27 Test the item being dragged over the load widget 28 """ 29 pass 30 31 def testDropEvent(self): 32 """ 33 Test what happens if an object is dropped onto the load widget 34 """ 35 pass 16 36 17 37 if __name__ == "__main__": -
src/sas/qtgui/UnitTesting/GuiManagerTest.py
rf82ab8c r481ff26 87 87 # See that the MessageBox method got called 88 88 self.assertTrue(QMessageBox.question.called) 89 # Also, sys.exit() called90 self.assertTrue(sys.exit.called)91 89 92 90 def testCheckUpdate(self):
Note: See TracChangeset
for help on using the changeset viewer.