Index: src/sas/qtgui/DataExplorer.py
===================================================================
--- src/sas/qtgui/DataExplorer.py	(revision 8cb6cd6e52ab1f1031a89aeaad89921ef6ed9e98)
+++ src/sas/qtgui/DataExplorer.py	(revision 4b71e919d11ca53f1721dd9c28b6eaa80628737d)
@@ -44,4 +44,7 @@
         self.loader = Loader()
         self.manager = DataManager()
+        self.txt_widget = QtGui.QTextEdit(None)
+        # self.txt_widget = GuiUtils.DisplayWindow()
+
 
         # Be careful with twisted threads.
@@ -65,12 +68,8 @@
         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)
+        self.contextMenu()
 
         # Connect the comboboxes
@@ -612,18 +611,87 @@
             raise Exception, msg
 
-    def contextDataInfo(self):
-        """
-        """
-        print("contextDataInfo TRIGGERED")
-        pass
+    def contextMenu(self):
+        """
+        Define actions and layout of the right click context menu
+        """
+        # Create a custom menu based on actions defined in the UI file
+        self.context_menu = QtGui.QMenu(self)
+        self.context_menu.addAction(self.actionDataInfo)
+        self.context_menu.addAction(self.actionSaveAs)
+        self.context_menu.addAction(self.actionQuickPlot)
+        self.context_menu.addSeparator()
+        self.context_menu.addAction(self.actionQuick3DPlot)
+        self.context_menu.addAction(self.actionEditMask)
+
+        # Define the callbacks
+        self.actionDataInfo.triggered.connect(self.showDataInfo)
+        self.actionSaveAs.triggered.connect(self.saveDataAs)
+        self.actionQuickPlot.triggered.connect(self.quickDataPlot)
+        self.actionQuick3DPlot.triggered.connect(self.quickData3DPlot)
+        self.actionEditMask.triggered.connect(self.showEditDataMask)
 
     def onCustomContextMenu(self, position):
         """
-        """
-        print "onCustomContextMenu triggered at point ", position.x(), position.y()
+        Show the right-click context menu in the data treeview
+        """
         index = self.treeView.indexAt(position)
         if index.isValid():
-            print "VALID CONTEXT MENU"
-    #    self.context_menu.exec(self.treeView.mapToGlobal(position))
+            model_item = self.model.itemFromIndex(self.data_proxy.mapToSource(index))
+            # Find the mapped index
+            orig_index = model_item.isCheckable()
+            if orig_index:
+                # Check the data to enable/disable actions
+                is_2D = isinstance(model_item.child(0).data().toPyObject(), Data2D)
+                self.actionQuick3DPlot.setEnabled(is_2D)
+                self.actionEditMask.setEnabled(is_2D)
+                # Fire up the menu
+                self.context_menu.exec_(self.treeView.mapToGlobal(position))
+
+    def showDataInfo(self):
+        """
+        Show a simple read-only text edit with data information.
+        """
+        index = self.treeView.selectedIndexes()[0]
+        model_item = self.model.itemFromIndex(self.data_proxy.mapToSource(index))
+        data = model_item.child(0).data().toPyObject()
+        if data.__class__.__name__ == "Data1D":
+            text_to_show = GuiUtils.retrieveData1d(data)
+            self.txt_widget.resize(420,600)
+        else:
+            text_to_show = GuiUtils.retrieveData2d(data)
+            self.txt_widget.resize(700,600)
+
+        self.txt_widget.setReadOnly(True)
+        self.txt_widget.setWindowFlags(QtCore.Qt.Window)
+        self.txt_widget.setWindowIcon(QtGui.QIcon(":/res/ball.ico"))
+        self.txt_widget.setWindowTitle("Data Info: %s" % data.filename)
+        self.txt_widget.insertPlainText(text_to_show)
+
+        self.txt_widget.show()
+        vertical_scroll_bar = self.txt_widget.verticalScrollBar()
+        vertical_scroll_bar.triggerAction(QtGui.QScrollBar.SliderToMinimum)
+
+    def saveDataAs(self):
+        """
+        """
+        print "saveDataAs"
+        pass
+
+    def quickDataPlot(self):
+        """
+        """
+        print "quickDataPlot"
+        pass
+
+    def quickData3DPlot(self):
+        """
+        """
+        print "quickData3DPlot"
+        pass
+
+    def showEditDataMask(self):
+        """
+        """
+        print "showEditDataMask"
         pass
 
Index: src/sas/qtgui/GuiUtils.py
===================================================================
--- src/sas/qtgui/GuiUtils.py	(revision 8cb6cd6e52ab1f1031a89aeaad89921ef6ed9e98)
+++ src/sas/qtgui/GuiUtils.py	(revision 4b71e919d11ca53f1721dd9c28b6eaa80628737d)
@@ -332,2 +332,93 @@
         msg = "Attempt at opening an invalid URL"
         raise AttributeError, msg
+
+def retrieveData1d(data):
+    """
+    Retrieve 1D data from file and construct its text
+    representation
+    """
+    try:
+        xmin = min(data.x)
+        ymin = min(data.y)
+    except:
+        msg = "Unable to find min/max of \n data named %s" % \
+                    data.filename
+        logging.error(msg)
+        raise ValueError, msg
+
+    text = data.__str__()
+    text += 'Data Min Max:\n'
+    text += 'X_min = %s:  X_max = %s\n' % (xmin, max(data.x))
+    text += 'Y_min = %s:  Y_max = %s\n' % (ymin, max(data.y))
+    if data.dy != None:
+        text += 'dY_min = %s:  dY_max = %s\n' % (min(data.dy), max(data.dy))
+    text += '\nData Points:\n'
+    x_st = "X"
+    for index in range(len(data.x)):
+        if data.dy != None and len(data.dy) > index:
+            dy_val = data.dy[index]
+        else:
+            dy_val = 0.0
+        if data.dx != None and len(data.dx) > index:
+            dx_val = data.dx[index]
+        else:
+            dx_val = 0.0
+        if data.dxl != None and len(data.dxl) > index:
+            if index == 0:
+                x_st = "Xl"
+            dx_val = data.dxl[index]
+        elif data.dxw != None and len(data.dxw) > index:
+            if index == 0:
+                x_st = "Xw"
+            dx_val = data.dxw[index]
+
+        if index == 0:
+            text += "<index> \t<X> \t<Y> \t<dY> \t<d%s>\n" % x_st
+        text += "%s \t%s \t%s \t%s \t%s\n" % (index,
+                                                data.x[index],
+                                                data.y[index],
+                                                dy_val,
+                                                dx_val)
+    return text
+
+def retrieveData2d(data):
+    """
+    Retrieve 1D data from file and construct its text
+    representation
+    """
+    text = data.__str__()
+    text += 'Data Min Max:\n'
+    text += 'I_min = %s\n' % min(data.data)
+    text += 'I_max = %s\n\n' % max(data.data)
+    text += 'Data (First 2501) Points:\n'
+    text += 'Data columns include err(I).\n'
+    text += 'ASCII data starts here.\n'
+    text += "<index> \t<Qx> \t<Qy> \t<I> \t<dI> \t<dQparal> \t<dQperp>\n"
+    di_val = 0.0
+    dx_val = 0.0
+    dy_val = 0.0
+    len_data = len(data.qx_data)
+    for index in xrange(0, len_data):
+        x_val = data.qx_data[index]
+        y_val = data.qy_data[index]
+        i_val = data.data[index]
+        if data.err_data != None:
+            di_val = data.err_data[index]
+        if data.dqx_data != None:
+            dx_val = data.dqx_data[index]
+        if data.dqy_data != None:
+            dy_val = data.dqy_data[index]
+
+        text += "%s \t%s \t%s \t%s \t%s \t%s \t%s\n" % (index,
+                                                        x_val,
+                                                        y_val,
+                                                        i_val,
+                                                        di_val,
+                                                        dx_val,
+                                                        dy_val)
+        # Takes too long time for typical data2d: Break here
+        if index >= 2500:
+            text += ".............\n"
+            break
+
+    return text
