Index: src/sas/qtgui/DataExplorer.py
===================================================================
--- src/sas/qtgui/DataExplorer.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/DataExplorer.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -2,4 +2,5 @@
 import sys
 import os
+import time
 import logging
 
@@ -16,4 +17,6 @@
 from sas.sascalc.dataloader.loader import Loader
 from sas.sasgui.guiframe.data_manager import DataManager
+from sas.sasgui.guiframe.dataFitting import Data1D
+from sas.sasgui.guiframe.dataFitting import Data2D
 
 from DroppableDataLoadWidget import DroppableDataLoadWidget
@@ -57,4 +60,13 @@
         self._helpView = QtWebKit.QWebView()
 
+        # Context menu in the treeview
+        #self.treeView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
+        #self.actionDataInfo.triggered.connect(self.contextDataInfo)
+        #self.treeView.addAction(self.actionDataInfo)
+
+        # Custom context menu
+        self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
+        self.treeView.customContextMenuRequested.connect(self.onCustomContextMenu)
+
         # Connect the comboboxes
         self.cbSelect.currentIndexChanged.connect(self.selectData)
@@ -62,5 +74,5 @@
         #self.closeEvent.connect(self.closeEvent)
         # self.aboutToQuit.connect(self.closeEvent)
-
+        self.communicator = self.parent.communicator()
         self.communicator.fileReadSignal.connect(self.loadFromURL)
 
@@ -133,5 +145,5 @@
         # get content of dir into a list
         path_str = [os.path.join(os.path.abspath(folder), filename)
-                        for filename in os.listdir(folder)]
+                    for filename in os.listdir(folder)]
 
         self.loadFromURL(path_str)
@@ -144,6 +156,9 @@
         delete_msg = "This operation will delete the checked data sets and all the dependents." +\
                      "\nDo you want to continue?"
-        reply = QtGui.QMessageBox.question(self, 'Warning', delete_msg,
-                QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
+        reply = QtGui.QMessageBox.question(self,
+                                           'Warning',
+                                           delete_msg,
+                                           QtGui.QMessageBox.Yes,
+                                           QtGui.QMessageBox.No)
 
         if reply == QtGui.QMessageBox.No:
@@ -201,5 +216,4 @@
 
         # Set the signal handlers
-        self.communicator = self._perspective.communicator()
         self.communicator.updateModelFromPerspectiveSignal.connect(self.updateModelFromPerspective)
 
@@ -254,4 +268,8 @@
                     theories_copied += 1
                     new_item = self.recursivelyCloneItem(subitem)
+                    # Append a "unique" descriptor to the name
+                    time_bit = str(time.time())[7:-1].replace('.','')
+                    new_name = new_item.text() + '_@' + time_bit
+                    new_item.setText(new_name)
                     self.theory_model.appendRow(new_item)
             self.theory_model.reset()
@@ -261,7 +279,7 @@
             return
         elif theories_copied == 1:
-            freeze_msg = "1 theory sent to Theory tab"
+            freeze_msg = "1 theory copied to the Theory tab as a data set"
         elif theories_copied > 1:
-            freeze_msg = "%i theories sent to Theory tab" % theories_copied
+            freeze_msg = "%i theories copied to the Theory tab as data sets" % theories_copied
         else:
             freeze_msg = "Unexpected number of theories copied: %i" % theories_copied
@@ -313,9 +331,8 @@
             return
 
-        #if type(paths) == QtCore.QStringList:
         if isinstance(paths, QtCore.QStringList):
             paths = [str(f) for f in paths]
 
-        if paths.__class__.__name__ != "list":
+        if type(paths) is not list:
             paths = [paths]
 
@@ -335,5 +352,8 @@
         error_message = ""
 
-        for p_file in path:
+        number_of_files = len(path)
+        self.communicator.progressBarUpdateSignal.emit(0.0)
+
+        for index, p_file in enumerate(path):
             basename = os.path.basename(p_file)
             _, extension = os.path.splitext(basename)
@@ -406,4 +426,7 @@
                 info = "error"
 
+            current_percentage = int(100.0* index/number_of_files)
+            self.communicator.progressBarUpdateSignal.emit(current_percentage)
+
         if any_error or error_message:
             self.communicator.statusBarUpdateSignal.emit(error_message)
@@ -412,4 +435,5 @@
             message = "Loading Data Complete! "
         message += log_msg
+        self.communicator.progressBarUpdateSignal.emit(-1)
 
         return output, message
@@ -461,5 +485,5 @@
 
                 try:
-                    is1D = item.child(0).data().toPyObject().__class__.__name__ == 'Data1D'
+                    is1D = type(item.child(0).data().toPyObject()) is Data1D
                 except AttributeError:
                     msg = "Bad structure of the data model."
@@ -475,5 +499,5 @@
 
                 try:
-                    is1D = item.child(0).data().toPyObject().__class__.__name__ == 'Data1D'
+                    is1D = type(item.child(0).data().toPyObject()) is Data1D
                 except AttributeError:
                     msg = "Bad structure of the data model."
@@ -489,5 +513,5 @@
                 item.setCheckState(QtCore.Qt.Unchecked)
                 try:
-                    is2D = item.child(0).data().toPyObject().__class__.__name__ == 'Data2D'
+                    is2D = type(item.child(0).data().toPyObject()) is Data2D
                 except AttributeError:
                     msg = "Bad structure of the data model."
@@ -503,5 +527,5 @@
 
                 try:
-                    is2D = item.child(0).data().toPyObject().__class__.__name__ == 'Data2D'
+                    is2D = type(item.child(0).data().toPyObject()) is Data2D
                 except AttributeError:
                     msg = "Bad structure of the data model."
@@ -516,4 +540,19 @@
             raise Exception, msg
 
+    def contextDataInfo(self):
+        """
+        """
+        print("contextDataInfo TRIGGERED")
+        pass
+
+    def onCustomContextMenu(self, position):
+        """
+        """
+        print "onCustomContextMenu triggered at point ", position.x(), position.y()
+        index = self.treeView.indexAt(position)
+        if index.isValid():
+            print "VALID CONTEXT MENU"
+    #    self.context_menu.exec(self.treeView.mapToGlobal(position))
+        pass
 
     def loadComplete(self, output):
@@ -521,7 +560,9 @@
         Post message to status bar and update the data manager
         """
+        assert type(output) == tuple
+
         # Reset the model so the view gets updated.
         self.model.reset()
-        assert type(output) == tuple
+        self.communicator.progressBarUpdateSignal.emit(-1)
 
         output_data = output[0]
Index: src/sas/qtgui/DroppableDataLoadWidget.py
===================================================================
--- src/sas/qtgui/DroppableDataLoadWidget.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/DroppableDataLoadWidget.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -16,4 +16,6 @@
         self.setAcceptDrops(True)
         self.communicator = guimanager.communicator()
+        flags = QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint
+        self.setWindowFlags(flags)
 
     def dragIsOK(self, event):
@@ -22,8 +24,5 @@
         """
         # Analyze mime data
-        if event.mimeData().hasUrls() and self.currentIndex() == 0:
-            return True
-        else:
-            return False
+        return bool(event.mimeData().hasUrls() and self.currentIndex() == 0)
 
     def dragEnterEvent(self, event):
@@ -61,2 +60,7 @@
             event.ignore()
 
+    def closeEvent(self, event):
+        """
+        Overwrite the close event - no close!
+        """
+        event.ignore()
Index: src/sas/qtgui/GuiManager.py
===================================================================
--- src/sas/qtgui/GuiManager.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/GuiManager.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -60,10 +60,8 @@
         # Add FileDialog widget as docked
         self.filesWidget = DataExplorerWindow(parent, self)
-        #flags = (QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowMinimizeButtonHint)
-        flags = (QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint |
-                 QtCore.Qt.WindowMinMaxButtonsHint)
-
-        self.dockedFilesWidget = QtGui.QDockWidget("Data explorer", self._workspace, flags=flags)
+
+        self.dockedFilesWidget = QtGui.QDockWidget("Data explorer", self._workspace)
         self.dockedFilesWidget.setWidget(self.filesWidget)
+        self.dockedFilesWidget.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
         self._workspace.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockedFilesWidget)
 
@@ -71,5 +69,6 @@
         self.aboutWidget = AboutBox()
 
-        # Disable the close button (?)
+        # Set up the status bar
+        self.statusBarSetup()
 
         # Show the Welcome panel
@@ -95,4 +94,23 @@
         # Default perspective
         self._current_perspective = self.invariantWidget
+
+    def statusBarSetup(self):
+        """
+        Define the status bar.
+        | <message label> .... | Progress Bar |
+
+        Progress bar invisible until explicitly shown
+        """
+        self.progress = QtGui.QProgressBar()
+        self._workspace.statusbar.setSizeGripEnabled(False)
+
+        self.statusLabel = QtGui.QLabel()
+        self.statusLabel.setText("Welcome to SasView")
+        self._workspace.statusbar.addPermanentWidget(self.statusLabel,1)
+        self._workspace.statusbar.addPermanentWidget(self.progress, stretch=0)
+        self.progress.setRange(0,100)
+        self.progress.setValue(0)
+        self.progress.setTextVisible(True)
+        self.progress.setVisible(False)
 
     def fileRead(self, data):
@@ -133,8 +151,23 @@
         return self._current_perspective
 
+    def updateProgressBar(self, value):
+        """
+        Update progress bar with the required value (0-100)
+        """
+        assert(-1 <= value <= 100)
+        if value == -1:
+            self.progress.setVisible(False)
+            return
+        if not self.progress.isVisible():
+            self.progress.setTextVisible(True)
+            self.progress.setVisible(True)
+
+        self.progress.setValue(value)
+
     def updateStatusBar(self, text):
         """
         """
-        self._workspace.statusbar.showMessage(text)
+        #self._workspace.statusbar.showMessage(text)
+        self.statusLabel.setText(text)
 
     def createGuiData(self, item, p_file=None):
@@ -237,4 +270,5 @@
         self.communicate.statusBarUpdateSignal.connect(self.updateStatusBar)
         self.communicate.updatePerspectiveWithDataSignal.connect(self.updatePerspective)
+        self.communicate.progressBarUpdateSignal.connect(self.updateProgressBar)
 
     def addTriggers(self):
@@ -284,6 +318,5 @@
         # Window
         self._workspace.actionCascade.triggered.connect(self.actionCascade)
-        self._workspace.actionTile_Horizontally.triggered.connect(self.actionTile_Horizontally)
-        self._workspace.actionTile_Vertically.triggered.connect(self.actionTile_Vertically)
+        self._workspace.actionTile.triggered.connect(self.actionTile)
         self._workspace.actionArrange_Icons.triggered.connect(self.actionArrange_Icons)
         self._workspace.actionNext.triggered.connect(self.actionNext)
@@ -402,6 +435,12 @@
     def actionHide_Toolbar(self):
         """
-        """
-        print("actionHide_Toolbar TRIGGERED")
+        Toggle toolbar vsibility
+        """
+        if self._workspace.toolBar.isVisible():
+            self._workspace.actionHide_Toolbar.setText("Show Toolbar")
+            self._workspace.toolBar.setVisible(False)
+        else:
+            self._workspace.actionHide_Toolbar.setText("Hide Toolbar")
+            self._workspace.toolBar.setVisible(True)
         pass
 
@@ -532,37 +571,31 @@
     def actionCascade(self):
         """
-        """
-        print("actionCascade TRIGGERED")
-        pass
-
-    def actionTile_Horizontally(self):
-        """
-        """
-        print("actionTile_Horizontally TRIGGERED")
-        pass
-
-    def actionTile_Vertically(self):
-        """
-        """
-        print("actionTile_Vertically TRIGGERED")
-        pass
+        Arranges all the child windows in a cascade pattern.
+        """
+        self._workspace.workspace.cascade()
+
+    def actionTile(self):
+        """
+        Tile workspace windows
+        """
+        self._workspace.workspace.tile()
 
     def actionArrange_Icons(self):
         """
-        """
-        print("actionArrange_Icons TRIGGERED")
-        pass
+        Arranges all iconified windows at the bottom of the workspace
+        """
+        self._workspace.workspace.arrangeIcons()
 
     def actionNext(self):
         """
-        """
-        print("actionNext TRIGGERED")
-        pass
+        Gives the input focus to the next window in the list of child windows.
+        """
+        self._workspace.workspace.activateNextWindow()
 
     def actionPrevious(self):
         """
-        """
-        print("actionPrevious TRIGGERED")
-        pass
+        Gives the input focus to the previous window in the list of child windows.
+        """
+        self._workspace.workspace.activatePreviousWindow()
 
     #============ HELP =================
Index: src/sas/qtgui/GuiUtils.py
===================================================================
--- src/sas/qtgui/GuiUtils.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/GuiUtils.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -80,5 +80,5 @@
         fObj, path_config, descr = imp.find_module(confg_file, [path])
         config_module = imp.load_module(confg_file, fObj, path_config, descr)
-    except:
+    except ImportError:
         logging.error("Error loading %s/%s: %s" % (path, confg_file, sys.exc_value))
     finally:
@@ -104,7 +104,7 @@
         logging.info("using default local_config")
     else:
-        logging.info("found local_config in %s" % os.getcwd())
+        logging.info("found local_config in %s", os.getcwd())
 else:
-    logging.info("found local_config in %s" % PATH_APP)
+    logging.info("found local_config in %s", PATH_APP)
 
 
@@ -118,7 +118,7 @@
         logging.info(msgConfig)
     else:
-        logging.info("using custom_config in %s" % os.getcwd())
+        logging.info("using custom_config in %s", os.getcwd())
 else:
-    logging.info("using custom_config from %s" % c_conf_dir)
+    logging.info("using custom_config from %s", c_conf_dir)
 
 #read some constants from config
@@ -154,5 +154,5 @@
     else:
         DEFAULT_OPEN_FOLDER = PATH_APP
-except:
+except AttributeError:
     DATALOADER_SHOW = True
     TOOLBAR_SHOW = True
@@ -181,5 +181,5 @@
 try:
     PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST)
-except:
+except AttributeError:
     PLUGINS_WLIST = ''
 APPLICATION_WLIST = config.APPLICATION_WLIST
@@ -214,4 +214,7 @@
     plotRequestedSignal = QtCore.pyqtSignal(str)
 
+    # Progress bar update value
+    progressBarUpdateSignal = QtCore.pyqtSignal(int)
+
 
 def updateModelItem(item, update_data, name=""):
@@ -220,6 +223,6 @@
     Adds QVariant 'update_data' to that row.
     """
-    assert type(item) == QtGui.QStandardItem
-    assert type(update_data) == QtCore.QVariant
+    assert isinstance(item, QtGui.QStandardItem)
+    assert isinstance(update_data, QtCore.QVariant)
 
     checkbox_item = QtGui.QStandardItem(True)
@@ -230,5 +233,5 @@
     # Add "Info" item
     py_update_data = update_data.toPyObject()
-    if type(py_update_data) == (Data1D or Data2D):
+    if isinstance(py_update_data, (Data1D or Data2D)):
         # If Data1/2D added - extract Info from it
         info_item = infoFromData(py_update_data)
@@ -254,9 +257,7 @@
     Returns the list of plots for items in the model which are checked
     """
-    assert type(model_item) == QtGui.QStandardItemModel
-
-    checkbox_item = QtGui.QStandardItem(True)
+    assert isinstance(model_item, QtGui.QStandardItemModel)
+
     plot_data = []
-
     # Iterate over model looking for items with checkboxes
     for index in range(model_item.rowCount()):
@@ -279,5 +280,5 @@
     and add them to a model item
     """
-    assert type(data) in [Data1D, Data2D]
+    assert isinstance(data, (Data1D, Data2D))
 
     info_item = QtGui.QStandardItem("Info")
Index: src/sas/qtgui/LocalConfig.py
===================================================================
--- src/sas/qtgui/LocalConfig.py	(revision f721030e66e61dc6279aa8e024da03b25f8e0d42)
+++ src/sas/qtgui/LocalConfig.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -4,7 +4,8 @@
 import time
 import os
+import logging
+
 from sas.sasgui.guiframe.gui_style import GUIFRAME
 import sas.sasview
-import logging
 
 # Version of the application
@@ -58,5 +59,5 @@
 
 icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images"))
-logging.info("icon path: %s" % icon_path)
+logging.info("icon path: %s", icon_path)
 media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media"))
 test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test"))
@@ -133,8 +134,8 @@
 
 def printEVT(message):
+    """
+    Post a debug message to console/file
+    """
     if __EVT_DEBUG__:
-        """
-        :TODO - Need method doc string
-        """
         print "%g:  %s" % (time.clock(), message)
 
Index: src/sas/qtgui/MainWindow.py
===================================================================
--- src/sas/qtgui/MainWindow.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/MainWindow.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -1,5 +1,4 @@
 import sys
 
-from PyQt4 import QtCore
 from PyQt4 import QtGui
 
Index: src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision 1042dbac0d9a9f513386ed723f3d110463dce201)
+++ src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -43,4 +43,5 @@
         super(InvariantWindow, self).__init__(parent)
         self.setWindowTitle("Invariant Perspective")
+
         # initial input params
         self._background = 0.0
@@ -95,7 +96,13 @@
         self.setupMapper()
 
+    def closeEvent(self, event):
+        """
+        Overwrite the default close method of QWidget
+        """
+        # No close on perspectives - one must always be active.
+        event.ignore()
+
     def communicator(self):
-        """
-        """
+        """ Getter for the communicator """
         return self.communicate
 
Index: src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.py	(revision 488c49d59f65f588ab30dc9447de6dc0335177cc)
+++ src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -26,5 +26,5 @@
     def setupUi(self, tabbedInvariantUI):
         tabbedInvariantUI.setObjectName(_fromUtf8("tabbedInvariantUI"))
-        tabbedInvariantUI.resize(465, 408)
+        tabbedInvariantUI.resize(466, 408)
         self.gridLayout_11 = QtGui.QGridLayout(tabbedInvariantUI)
         self.gridLayout_11.setObjectName(_fromUtf8("gridLayout_11"))
@@ -45,5 +45,6 @@
         self.horizontalLayout_4.addWidget(self.label)
         self.lineEdit = QtGui.QLineEdit(self.groupBox)
-        self.lineEdit.setEnabled(False)
+        self.lineEdit.setEnabled(True)
+        self.lineEdit.setFrame(False)
         self.lineEdit.setReadOnly(False)
         self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
@@ -85,4 +86,8 @@
         self.lineEdit_14 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_14.setEnabled(True)
+        self.lineEdit_14.setAutoFillBackground(True)
+        self.lineEdit_14.setStyleSheet(_fromUtf8(""))
+        self.lineEdit_14.setFrame(True)
+        self.lineEdit_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_14.setReadOnly(True)
         self.lineEdit_14.setObjectName(_fromUtf8("lineEdit_14"))
@@ -93,4 +98,6 @@
         self.lineEdit_15 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_15.setEnabled(True)
+        self.lineEdit_15.setFrame(True)
+        self.lineEdit_15.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_15.setReadOnly(True)
         self.lineEdit_15.setObjectName(_fromUtf8("lineEdit_15"))
@@ -101,4 +108,6 @@
         self.lineEdit_17 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_17.setEnabled(True)
+        self.lineEdit_17.setFrame(True)
+        self.lineEdit_17.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_17.setReadOnly(True)
         self.lineEdit_17.setObjectName(_fromUtf8("lineEdit_17"))
@@ -109,4 +118,6 @@
         self.lineEdit_16 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_16.setEnabled(True)
+        self.lineEdit_16.setFrame(True)
+        self.lineEdit_16.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_16.setReadOnly(True)
         self.lineEdit_16.setObjectName(_fromUtf8("lineEdit_16"))
@@ -125,5 +136,8 @@
         self.lineEdit_19 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_19.setEnabled(True)
-        self.lineEdit_19.setStyleSheet(_fromUtf8("background-color: rgb(253, 253, 126);"))
+        self.lineEdit_19.setStyleSheet(_fromUtf8("background-color: rgb(253, 253, 126);\n"
+"font: bold 8pt \"MS Shell Dlg 2\";"))
+        self.lineEdit_19.setFrame(True)
+        self.lineEdit_19.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_19.setReadOnly(True)
         self.lineEdit_19.setObjectName(_fromUtf8("lineEdit_19"))
@@ -134,5 +148,8 @@
         self.lineEdit_18 = QtGui.QLineEdit(self.groupBox_7)
         self.lineEdit_18.setEnabled(True)
-        self.lineEdit_18.setStyleSheet(_fromUtf8("background-color: rgb(253, 253, 126);"))
+        self.lineEdit_18.setStyleSheet(_fromUtf8("background-color: rgb(253, 253, 126);\n"
+"font: bold 8pt \"MS Shell Dlg 2\";"))
+        self.lineEdit_18.setFrame(True)
+        self.lineEdit_18.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
         self.lineEdit_18.setReadOnly(True)
         self.lineEdit_18.setObjectName(_fromUtf8("lineEdit_18"))
Index: src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.ui	(revision 488c49d59f65f588ab30dc9447de6dc0335177cc)
+++ src/sas/qtgui/Perspectives/Invariant/UI/TabbedInvariantUI.ui	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -7,5 +7,5 @@
     <x>0</x>
     <y>0</y>
-    <width>465</width>
+    <width>466</width>
     <height>408</height>
    </rect>
@@ -43,4 +43,7 @@
              <widget class="QLineEdit" name="lineEdit">
               <property name="enabled">
+               <bool>true</bool>
+              </property>
+              <property name="frame">
                <bool>false</bool>
               </property>
@@ -122,4 +125,16 @@
              <bool>true</bool>
             </property>
+            <property name="autoFillBackground">
+             <bool>true</bool>
+            </property>
+            <property name="styleSheet">
+             <string notr="true"/>
+            </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
             <property name="readOnly">
              <bool>true</bool>
@@ -139,4 +154,10 @@
              <bool>true</bool>
             </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
             <property name="readOnly">
              <bool>true</bool>
@@ -156,4 +177,10 @@
              <bool>true</bool>
             </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+            </property>
             <property name="readOnly">
              <bool>true</bool>
@@ -172,4 +199,10 @@
             <property name="enabled">
              <bool>true</bool>
+            </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
             </property>
             <property name="readOnly">
@@ -206,5 +239,12 @@
             </property>
             <property name="styleSheet">
-             <string notr="true">background-color: rgb(253, 253, 126);</string>
+             <string notr="true">background-color: rgb(253, 253, 126);
+font: bold 8pt &quot;MS Shell Dlg 2&quot;;</string>
+            </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
             </property>
             <property name="readOnly">
@@ -226,5 +266,12 @@
             </property>
             <property name="styleSheet">
-             <string notr="true">background-color: rgb(253, 253, 126);</string>
+             <string notr="true">background-color: rgb(253, 253, 126);
+font: bold 8pt &quot;MS Shell Dlg 2&quot;;</string>
+            </property>
+            <property name="frame">
+             <bool>true</bool>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
             </property>
             <property name="readOnly">
@@ -578,4 +625,5 @@
   </layout>
  </widget>
+ <resources/>
  <connections/>
 </ui>
Index: src/sas/qtgui/UI/DataExplorerUI.py
===================================================================
--- src/sas/qtgui/UI/DataExplorerUI.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/UI/DataExplorerUI.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -69,4 +69,5 @@
         self.gridLayout.addLayout(self.horizontalLayout_2, 0, 0, 1, 1)
         self.treeView = QtGui.QTreeView(self.groupBox)
+        self.treeView.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
         self.treeView.setAcceptDrops(True)
         self.treeView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
@@ -191,4 +192,14 @@
         self.gridLayout_8.addLayout(self.gridLayout_5, 1, 0, 1, 1)
         DataLoadWidget.addTab(self.theoryTab, _fromUtf8(""))
+        self.actionDataInfo = QtGui.QAction(DataLoadWidget)
+        self.actionDataInfo.setObjectName(_fromUtf8("actionDataInfo"))
+        self.actionSaveAs = QtGui.QAction(DataLoadWidget)
+        self.actionSaveAs.setObjectName(_fromUtf8("actionSaveAs"))
+        self.actionQuickPlot = QtGui.QAction(DataLoadWidget)
+        self.actionQuickPlot.setObjectName(_fromUtf8("actionQuickPlot"))
+        self.actionQuick3DPlot = QtGui.QAction(DataLoadWidget)
+        self.actionQuick3DPlot.setObjectName(_fromUtf8("actionQuick3DPlot"))
+        self.actionEditMask = QtGui.QAction(DataLoadWidget)
+        self.actionEditMask.setObjectName(_fromUtf8("actionEditMask"))
 
         self.retranslateUi(DataLoadWidget)
@@ -227,4 +238,9 @@
         self.cmdHelp_2.setText(_translate("DataLoadWidget", "Help", None))
         DataLoadWidget.setTabText(DataLoadWidget.indexOf(self.theoryTab), _translate("DataLoadWidget", "Theory", None))
+        self.actionDataInfo.setText(_translate("DataLoadWidget", "Data Info", None))
+        self.actionSaveAs.setText(_translate("DataLoadWidget", "Save As", None))
+        self.actionQuickPlot.setText(_translate("DataLoadWidget", "Quick Plot", None))
+        self.actionQuick3DPlot.setText(_translate("DataLoadWidget", "Quick 3DPlot (slow)", None))
+        self.actionEditMask.setText(_translate("DataLoadWidget", "Edit Mask", None))
 
 import main_resources_rc
Index: src/sas/qtgui/UI/DataExplorerUI.ui
===================================================================
--- src/sas/qtgui/UI/DataExplorerUI.ui	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/UI/DataExplorerUI.ui	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -111,4 +111,7 @@
        <item row="1" column="0">
         <widget class="QTreeView" name="treeView">
+         <property name="contextMenuPolicy">
+          <enum>Qt::NoContextMenu</enum>
+         </property>
          <property name="acceptDrops">
           <bool>true</bool>
@@ -395,4 +398,29 @@
    </layout>
   </widget>
+  <action name="actionDataInfo">
+   <property name="text">
+    <string>Data Info</string>
+   </property>
+  </action>
+  <action name="actionSaveAs">
+   <property name="text">
+    <string>Save As</string>
+   </property>
+  </action>
+  <action name="actionQuickPlot">
+   <property name="text">
+    <string>Quick Plot</string>
+   </property>
+  </action>
+  <action name="actionQuick3DPlot">
+   <property name="text">
+    <string>Quick 3DPlot (slow)</string>
+   </property>
+  </action>
+  <action name="actionEditMask">
+   <property name="text">
+    <string>Edit Mask</string>
+   </property>
+  </action>
  </widget>
  <resources>
Index: src/sas/qtgui/UI/MainWindowUI.py
===================================================================
--- src/sas/qtgui/UI/MainWindowUI.py	(revision f721030e66e61dc6279aa8e024da03b25f8e0d42)
+++ src/sas/qtgui/UI/MainWindowUI.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -26,5 +26,5 @@
     def setupUi(self, MainWindow):
         MainWindow.setObjectName(_fromUtf8("MainWindow"))
-        MainWindow.resize(915, 555)
+        MainWindow.resize(915, 527)
         icon = QtGui.QIcon()
         icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/res/ball.ico")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
@@ -157,6 +157,6 @@
         self.actionCascade = QtGui.QAction(MainWindow)
         self.actionCascade.setObjectName(_fromUtf8("actionCascade"))
-        self.actionTile_Horizontally = QtGui.QAction(MainWindow)
-        self.actionTile_Horizontally.setObjectName(_fromUtf8("actionTile_Horizontally"))
+        self.actionTile = QtGui.QAction(MainWindow)
+        self.actionTile.setObjectName(_fromUtf8("actionTile"))
         self.actionTile_Vertically = QtGui.QAction(MainWindow)
         self.actionTile_Vertically.setObjectName(_fromUtf8("actionTile_Vertically"))
@@ -240,6 +240,5 @@
         self.menuFitting.addAction(self.actionEdit_Custom_Model)
         self.menuWindow.addAction(self.actionCascade)
-        self.menuWindow.addAction(self.actionTile_Horizontally)
-        self.menuWindow.addAction(self.actionTile_Vertically)
+        self.menuWindow.addAction(self.actionTile)
         self.menuWindow.addSeparator()
         self.menuWindow.addAction(self.actionArrange_Icons)
@@ -331,5 +330,5 @@
         self.actionEdit_Custom_Model.setText(_translate("MainWindow", "Edit Custom Model", None))
         self.actionCascade.setText(_translate("MainWindow", "Cascade", None))
-        self.actionTile_Horizontally.setText(_translate("MainWindow", "Tile Horizontally", None))
+        self.actionTile.setText(_translate("MainWindow", "Tile", None))
         self.actionTile_Vertically.setText(_translate("MainWindow", "Tile Vertically", None))
         self.actionArrange_Icons.setText(_translate("MainWindow", "Arrange Icons", None))
Index: src/sas/qtgui/UI/MainWindowUI.ui
===================================================================
--- src/sas/qtgui/UI/MainWindowUI.ui	(revision f721030e66e61dc6279aa8e024da03b25f8e0d42)
+++ src/sas/qtgui/UI/MainWindowUI.ui	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -8,5 +8,5 @@
     <y>0</y>
     <width>915</width>
-    <height>555</height>
+    <height>527</height>
    </rect>
   </property>
@@ -112,6 +112,5 @@
     </property>
     <addaction name="actionCascade"/>
-    <addaction name="actionTile_Horizontally"/>
-    <addaction name="actionTile_Vertically"/>
+    <addaction name="actionTile"/>
     <addaction name="separator"/>
     <addaction name="actionArrange_Icons"/>
@@ -399,7 +398,7 @@
    </property>
   </action>
-  <action name="actionTile_Horizontally">
-   <property name="text">
-    <string>Tile Horizontally</string>
+  <action name="actionTile">
+   <property name="text">
+    <string>Tile</string>
    </property>
   </action>
Index: src/sas/qtgui/UnitTesting/AboutBoxTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/AboutBoxTest.py	(revision f82ab8cebb48e29a3c2598340d12929e037d764c)
+++ src/sas/qtgui/UnitTesting/AboutBoxTest.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -76,5 +76,5 @@
                 LocalConfig._ill_url,
                 LocalConfig._inst_url]
-        
+
         # Press the buttons
         buttonList = self.widget.findChildren(QPushButton)
Index: src/sas/qtgui/UnitTesting/DataExplorerTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/DataExplorerTest.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/UnitTesting/DataExplorerTest.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -92,5 +92,8 @@
         self.assertIsInstance(self.form.freezeView, QTreeView)
 
-        
+    def testWidgets(self):
+        """
+        Test if all required widgets got added
+        """        
     def testLoadButton(self):
         loadButton = self.form.cmdLoad
@@ -111,11 +114,12 @@
 
         # Make sure the signal has not been emitted
-        #self.assertEqual(spy_file_read.count(), 0)
+        self.assertEqual(spy_file_read.count(), 0)
 
         # Now, return a single file
         QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=filename)
-        
+
         # Click on the Load button
         QTest.mouseClick(loadButton, Qt.LeftButton)
+        QtGui.qApp.processEvents()
 
         # Test the getOpenFileName() dialog called once
@@ -127,4 +131,23 @@
         #self.assertIn(filename, str(spy_file_read.called()[0]['args'][0]))
 
+    def testLoadFiles(self):
+        """
+        Test progress bar update while loading of multiple files
+        """
+        # Set up the spy on progress bar update signal
+        spy_progress_bar_update = QtSignalSpy(self.form,
+            self.form.communicator.progressBarUpdateSignal)
+
+        # Populate the model
+        filename = ["cyl_400_20.txt", "Dec07031.ASC", "cyl_400_20.txt"]
+        self.form.readData(filename)
+
+        # 0, 0, 33, 66, -1 -> 5 signals reaching progressBar
+        self.assertEqual(spy_progress_bar_update.count(), 5)
+
+        expected_list = [0, 0, 33, 66, -1]
+        spied_list = [spy_progress_bar_update.called()[i]['args'][0] for i in xrange(5)]
+        self.assertEqual(expected_list, spied_list)
+        
     def testDeleteButton(self):
         """
@@ -441,6 +464,6 @@
         default_list = defaults.split(';;')
 
-        for format in default_list:
-            self.assertIn(format, w_list)
+        for def_format in default_list:
+            self.assertIn(def_format, w_list)
        
     def testLoadComplete(self):
Index: src/sas/qtgui/UnitTesting/DroppableDataLoadWidgetTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/DroppableDataLoadWidgetTest.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/UnitTesting/DroppableDataLoadWidgetTest.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -4,7 +4,8 @@
 from PyQt4.QtGui import QApplication
 from PyQt4.QtTest import QTest
-from PyQt4.QtCore import Qt
+from PyQt4 import QtCore
 from DroppableDataLoadWidget import DroppableDataLoadWidget
 from GuiUtils import *
+from UnitTesting.TestUtils import QtSignalSpy
 
 app = QApplication(sys.argv)
@@ -21,5 +22,9 @@
 
         self.form = DroppableDataLoadWidget(None, guimanager=dummy_manager())
-        # create dummy mime objects
+
+        # create dummy mime object
+        self.mime_data = QtCore.QMimeData()
+        self.testfile = 'testfile.txt'
+        self.mime_data.setUrls([QtCore.QUrl(self.testfile)])
 
     def testDragIsOK(self):
@@ -27,5 +32,21 @@
         Test the item being dragged over the load widget
         """
-        pass
+        good_drag_event = QtGui.QDragMoveEvent(QtCore.QPoint(0,0),
+                                               QtCore.Qt.CopyAction,
+                                               self.mime_data,
+                                               QtCore.Qt.LeftButton,
+                                               QtCore.Qt.NoModifier)
+        mime_data = QtCore.QMimeData()
+        bad_drag_event = QtGui.QDragMoveEvent(QtCore.QPoint(0,0),
+                                               QtCore.Qt.CopyAction,
+                                               mime_data,
+                                               QtCore.Qt.LeftButton,
+                                               QtCore.Qt.NoModifier)
+
+        # Call the drag handler with good event
+        self.assertTrue(self.form.dragIsOK(good_drag_event))
+
+        # Call the drag handler with bad event
+        self.assertFalse(self.form.dragIsOK(bad_drag_event))
 
     def testDropEvent(self):
@@ -33,5 +54,17 @@
         Test what happens if an object is dropped onto the load widget
         """
-        pass
+        spy_file_read = QtSignalSpy(self.form, self.form.communicator.fileReadSignal)
+
+        drop_event = QtGui.QDropEvent(QtCore.QPoint(0,0),
+                                           QtCore.Qt.CopyAction,
+                                           self.mime_data,
+                                           QtCore.Qt.LeftButton,
+                                           QtCore.Qt.NoModifier)
+
+        self.form.dropEvent(drop_event)
+        QtGui.qApp.processEvents()
+        self.assertEqual(spy_file_read.count(), 1)
+        self.assertIn(self.testfile, str(spy_file_read.signal(index=0)))
+
 
 if __name__ == "__main__":
Index: src/sas/qtgui/UnitTesting/GuiManagerTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/GuiManagerTest.py	(revision 481ff261d4487dbfcc8eabb342125294e0c6f514)
+++ src/sas/qtgui/UnitTesting/GuiManagerTest.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -12,4 +12,9 @@
 
 # Local
+from DataExplorer import DataExplorerWindow
+from UI.AcknowledgementsUI import Acknowledgements
+from AboutBox import AboutBox
+from WelcomePanel import WelcomePanel
+
 from GuiManager import GuiManager
 from UI.MainWindowUI import MainWindow
@@ -38,7 +43,15 @@
 
     def testDefaults(self):
-        '''Test the object in its default state'''
-        pass
-        
+        """
+        Test the object in its default state
+        """
+        self.assertIsInstance(self.manager.filesWidget, DataExplorerWindow)
+        self.assertIsInstance(self.manager.dockedFilesWidget, QDockWidget)
+        self.assertEqual(self.manager.dockedFilesWidget.features(), QDockWidget.NoDockWidgetFeatures)
+        self.assertEqual(self.manager._workspace.dockWidgetArea(self.manager.dockedFilesWidget), Qt.LeftDockWidgetArea)
+        self.assertIsInstance(self.manager.ackWidget, Acknowledgements)
+        self.assertIsInstance(self.manager.aboutWidget, AboutBox)
+        self.assertIsInstance(self.manager.welcomePanel, WelcomePanel)
+
     def testUpdatePerspective(self):
         """
@@ -76,6 +89,4 @@
         # See that the MessageBox method got called
         self.assertTrue(QMessageBox.question.called)
-        # sys.exit() not called this time
-        self.assertFalse(sys.exit.called)
 
         # Say Yes to the close dialog
@@ -139,18 +150,5 @@
         webbrowser.open.assert_called_with("https://github.com/SasView/sasview/releases")
 
-        ## 4. version > LocalConfig.__version__ and standalone
-        #version_info = {u'version' : u'999.0.0'}
-        #spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal)
-        #webbrowser.open = MagicMock()
-
-        #self.manager.processVersion(version_info, standalone=True)
-
-        #self.assertEqual(spy_status_update.count(), 1)
-        #message = 'See the help menu to download it'
-        #self.assertIn(message, str(spy_status_update.signal(index=0)))
-
-        #self.assertFalse(webbrowser.open.called)
-
-        # 5. couldn't load version
+        # 4. couldn't load version
         version_info = {}
         logging.error = MagicMock()
@@ -173,4 +171,5 @@
         pass
 
+    #### FILE ####
     def testActionLoadData(self):
         """
@@ -185,5 +184,46 @@
         # Test the getOpenFileName() dialog called once
         self.assertTrue(QFileDialog.getOpenFileNames.called)
-        
+
+    def testActionLoadDataFolder(self):
+        """
+        Menu File/Load Data Folder
+        """
+        # Mock the system file open method
+        QFileDialog.getExistingDirectory = MagicMock(return_value=None)
+
+        # invoke the action
+        self.manager.actionLoad_Data_Folder()
+
+        # Test the getOpenFileName() dialog called once
+        self.assertTrue(QFileDialog.getExistingDirectory.called)
+
+    #### VIEW ####
+    def testActionHideToolbar(self):
+        """
+        Menu View/Hide Toolbar
+        """
+        # Need to display the main window to initialize the toolbar.
+        self.manager._workspace.show()
+
+        # Check the initial state
+        self.assertTrue(self.manager._workspace.toolBar.isVisible())
+        self.assertEqual('Hide Toolbar', self.manager._workspace.actionHide_Toolbar.text())
+
+        # Invoke action
+        self.manager.actionHide_Toolbar()
+
+        # Assure changes propagated correctly
+        self.assertFalse(self.manager._workspace.toolBar.isVisible())
+        self.assertEqual('Show Toolbar', self.manager._workspace.actionHide_Toolbar.text())
+
+        # Revert
+        self.manager.actionHide_Toolbar()
+
+        # Assure the original values are back
+        self.assertTrue(self.manager._workspace.toolBar.isVisible())
+        self.assertEqual('Hide Toolbar', self.manager._workspace.actionHide_Toolbar.text())
+
+
+    #### HELP ####
     def testActionDocumentation(self):
         """
Index: src/sas/qtgui/UnitTesting/GuiUtilsTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/GuiUtilsTest.py	(revision f82ab8cebb48e29a3c2598340d12929e037d764c)
+++ src/sas/qtgui/UnitTesting/GuiUtilsTest.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -2,5 +2,4 @@
 import unittest
 import webbrowser
-import urlparse
 
 from PyQt4 import QtCore
@@ -59,5 +58,6 @@
             'updatePerspectiveWithDataSignal',
             'updateModelFromPerspectiveSignal',
-            'plotRequestedSignal'
+            'plotRequestedSignal',
+            'progressBarUpdateSignal',
         ]
 
@@ -188,5 +188,4 @@
         with self.assertRaises(AttributeError):
             openLink(bad_url3)
-        pass
 
 if __name__ == "__main__":
Index: src/sas/qtgui/WelcomePanel.py
===================================================================
--- src/sas/qtgui/WelcomePanel.py	(revision f82ab8cebb48e29a3c2598340d12929e037d764c)
+++ src/sas/qtgui/WelcomePanel.py	(revision e540cd2f6e912b110651b7e76c9b4cc9c7183d9b)
@@ -20,5 +20,4 @@
 
         ver = "\nSasView %s\nBuild: %s" % (version, build)
-        #ver += "\n(c) 2009 - 2013, UTK, UMD, NIST, ORNL, ISIS, ESS and IL"
         ver += LocalConfig._copyright
 
