Index: src/sas/qtgui/AddText.py
===================================================================
--- src/sas/qtgui/AddText.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
+++ src/sas/qtgui/AddText.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -0,0 +1,47 @@
+from PyQt4 import QtGui
+
+import sas.sasview
+
+from sas.qtgui.UI.AddTextUI import Ui_AddText
+
+class AddText(QtGui.QDialog, Ui_AddText):
+    """ Simple GUI for a single line text query """
+    def __init__(self, parent=None):
+        super(AddText, self).__init__(parent)
+        self.setupUi(self)
+
+        self._font = QtGui.QFont()
+        self._color = "black"
+        self.btnFont.clicked.connect(self.onFontChange)
+        self.btnColor.clicked.connect(self.onColorChange)
+
+    def text(self):
+        return self.textEdit.toPlainText()
+
+    def font(self):
+        return self._font
+
+    def color(self):
+        return self._color
+
+    def onFontChange(self, event):
+        """
+        Pop up the standard Qt Font change dialog
+        """
+        self._font, ok = QtGui.QFontDialog.getFont(parent=self)
+        if ok:
+            self.textEdit.setFont(self._font)
+
+    def onColorChange(self, event):
+        """
+        Pop up the standard Qt color change dialog
+        """
+        # Pick up the chosen color
+        self._color = QtGui.QColorDialog.getColor(parent=self)
+        # Update the text control
+        palette = QtGui.QPalette()
+        palette.setColor(QtGui.QPalette.Text, self._color)
+        self.textEdit.setPalette(palette)
+
+        # Save the color as #RRGGBB
+        self._color = str(self._color.name())
Index: src/sas/qtgui/DataExplorer.py
===================================================================
--- src/sas/qtgui/DataExplorer.py	(revision edbd4b6908fb314d8766a349cf5ae5c6ff8c6cfe)
+++ src/sas/qtgui/DataExplorer.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -401,16 +401,12 @@
         new_plot = Plotter(self)
 
-        def addDataPlot(plot, plot_set):
-            plot.data = plot_set
-            plot.plot()
-
         def addDataPlot2D(plot_set):
             plot2D = Plotter2D(self)
-            addDataPlot(plot2D, plot_set)
+            plot2D.plot(plot_set)
             self.plotAdd(plot2D)
 
         for plot_set in plots:
             if isinstance(plot_set, Data1D):
-                addDataPlot(new_plot, plot_set)
+                new_plot.plot(plot_set)
             elif isinstance(plot_set, Data2D):
                 addDataPlot2D(plot_set)
@@ -418,5 +414,4 @@
                 msg = "Incorrect data type passed to Plotting"
                 raise AttributeError, msg
-
 
         if plots and \
Index: src/sas/qtgui/GUITests.py
===================================================================
--- src/sas/qtgui/GUITests.py	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/GUITests.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -2,4 +2,5 @@
 
 from UnitTesting import AboutBoxTest
+from UnitTesting import AddTextTest
 from UnitTesting import DataExplorerTest
 from UnitTesting import WelcomePanelTest
@@ -22,4 +23,5 @@
     suites = (
         unittest.makeSuite(AboutBoxTest.AboutBoxTest,          'test'),
+        unittest.makeSuite(AddTextTest.AddTextTest,          'test'),
         unittest.makeSuite(DataExplorerTest.DataExplorerTest,  'test'),
         unittest.makeSuite(WelcomePanelTest.WelcomePanelTest,  'test'),
Index: src/sas/qtgui/PlotUtilities.py
===================================================================
--- src/sas/qtgui/PlotUtilities.py	(revision fecfe283c4a23a8b1ec879117e43b24a7fce28a4)
+++ src/sas/qtgui/PlotUtilities.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -175,2 +175,48 @@
 
     return image
+
+def rescale(lo, hi, step, pt=None, bal=None, scale='linear'):
+    """
+    Rescale (lo,hi) by step, returning the new (lo,hi)
+    The scaling is centered on pt, with positive values of step
+    driving lo/hi away from pt and negative values pulling them in.
+    If bal is given instead of point, it is already in [0,1] coordinates.
+
+    This is a helper function for step-based zooming.
+    """
+    # Convert values into the correct scale for a linear transformation
+    # TODO: use proper scale transformers
+    loprev = lo
+    hiprev = hi
+    if scale == 'log':
+        assert lo > 0
+        if lo > 0:
+            lo = numpy.log10(lo)
+        if hi > 0:
+            hi = numpy.log10(hi)
+        if pt is not None:
+            pt = numpy.log10(pt)
+
+    # Compute delta from axis range * %, or 1-% if persent is negative
+    if step > 0:
+        delta = float(hi - lo) * step / 100
+    else:
+        delta = float(hi - lo) * step / (100 - step)
+
+    # Add scale factor proportionally to the lo and hi values,
+    # preserving the
+    # point under the mouse
+    if bal is None:
+        bal = float(pt - lo) / (hi - lo)
+    lo = lo - (bal * delta)
+    hi = hi + (1 - bal) * delta
+
+    # Convert transformed values back to the original scale
+    if scale == 'log':
+        if (lo <= -250) or (hi >= 250):
+            lo = loprev
+            hi = hiprev
+        else:
+            lo, hi = numpy.power(10., lo), numpy.power(10., hi)
+    return (lo, hi)
+
Index: src/sas/qtgui/Plotter.py
===================================================================
--- src/sas/qtgui/Plotter.py	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/Plotter.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -2,8 +2,11 @@
 
 import matplotlib.pyplot as plt
-
+from matplotlib.font_manager import FontProperties
+
+from sas.sasgui.guiframe.dataFitting import Data1D
 from sas.sasgui.plottools import transform
 from sas.sasgui.plottools.convert_units import convert_unit
 from sas.qtgui.PlotterBase import PlotterBase
+from sas.qtgui.AddText import AddText
 
 class PlotterWidget(PlotterBase):
@@ -27,8 +30,13 @@
         self.title(title=value.title)
 
-    def plot(self, marker=None, linestyle=None, hide_error=False):
+    def plot(self, data=None, marker=None, linestyle=None, hide_error=False):
         """
         Plot self._data
         """
+        # Data1D
+        if isinstance(data, Data1D):
+            self.data = data
+        assert(self._data)
+
         # Shortcut for an axis
         ax = self.ax
@@ -45,5 +53,6 @@
                     marker=marker,
                     linestyle=linestyle,
-                    label=self._title)
+                    label=self._title,
+                    picker=True)
         else:
             ax.errorbar(self._data.view.x, self._data.view.y,
@@ -54,8 +63,11 @@
                         lolims=False, uplims=False,
                         xlolims=False, xuplims=False,
-                        label=self._title)
+                        label=self._title,
+                        picker=True)
 
         # Now add the legend with some customizations.
-        legend = ax.legend(loc='upper right', shadow=True)
+        self.legend = ax.legend(loc='upper right', shadow=True)
+        #self.legend.get_frame().set_alpha(0.4)
+        self.legend.set_picker(True)
 
         # Current labels for axes
@@ -142,13 +154,51 @@
         Show a dialog allowing adding custom text to the chart
         """
-        print("onAddText")
-        pass
+        self.addText = AddText(self)
+        if self.addText.exec_() == QtGui.QDialog.Accepted:
+            # Retrieve the new text, its font and color
+            extra_text = self.addText.text()
+            extra_font = self.addText.font()
+            extra_color = self.addText.color()
+
+            # Place the text on the screen at (0,0)
+            pos_x = self.x_click
+            pos_y = self.y_click
+
+            # Map QFont onto MPL font
+            mpl_font = FontProperties()
+            mpl_font.set_size(int(extra_font.pointSize()))
+            mpl_font.set_family(str(extra_font.family()))
+            mpl_font.set_weight(int(extra_font.weight()))
+            # MPL style names
+            styles = ['normal', 'italic', 'oblique']
+            # QFont::Style maps directly onto the above
+            try:
+                mpl_font.set_style(styles[extra_font.style()])
+            except:
+                pass
+
+            if len(extra_text) > 0:
+                new_text = self.ax.text(str(pos_x),
+                                        str(pos_y),
+                                        extra_text,
+                                        color=extra_color,
+                                        fontproperties=mpl_font)
+                # Update the list of annotations
+                self.textList.append(new_text)
+                self.canvas.draw_idle()
 
     def onRemoveText(self):
         """
-        Remove the most recent added text
-        """
-        print("onRemoveText")
-        pass
+        Remove the most recently added text
+        """
+        num_text = len(self.textList)
+        if num_text < 1:
+            return
+        txt = self.textList[num_text - 1]
+        text_remove = txt.get_text()
+        txt.remove()
+        self.textList.remove(txt)
+
+        self.canvas.draw_idle()
 
     def onSetGraphRange(self):
@@ -172,4 +222,5 @@
         # Clear the plot first
         plt.cla()
+        self.ax.cla()
 
         # Changing the scale might be incompatible with
Index: src/sas/qtgui/Plotter2D.py
===================================================================
--- src/sas/qtgui/Plotter2D.py	(revision c4e54008b22a99cb838269a4dfa2d88e1259f308)
+++ src/sas/qtgui/Plotter2D.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -6,8 +6,9 @@
 
 DEFAULT_CMAP = pylab.cm.jet
+from mpl_toolkits.mplot3d import Axes3D
 
 import sas.qtgui.PlotUtilities as PlotUtilities
 from sas.qtgui.PlotterBase import PlotterBase
-from mpl_toolkits.mplot3d import Axes3D
+from sas.sasgui.guiframe.dataFitting import Data2D
 
 # Minimum value of Z for which we will present data.
@@ -43,8 +44,14 @@
         self.title(title=data.title)
 
-    def plot(self, marker=None, linestyle=None):
+    def plot(self, data=None, marker=None, linestyle=None):
         """
         Plot 2D self._data
         """
+        # Assing data
+        if isinstance(data, Data2D):
+            self.data = data
+
+        assert(self._data)
+
         # Toggle the scale
         zmin_2D_temp = self.zmin
Index: src/sas/qtgui/PlotterBase.py
===================================================================
--- src/sas/qtgui/PlotterBase.py	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/PlotterBase.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -1,3 +1,4 @@
 import pylab
+import numpy
 
 from PyQt4 import QtGui
@@ -13,7 +14,10 @@
 
 DEFAULT_CMAP = pylab.cm.jet
+from sas.sasgui.plottools.binder import BindArtist
+
 from sas.qtgui.ScaleProperties import ScaleProperties
 from sas.qtgui.WindowTitle import WindowTitle
 import sas.qtgui.PlotHelper as PlotHelper
+import sas.qtgui.PlotUtilities as PlotUtilities
 
 class PlotterBase(QtGui.QWidget):
@@ -53,4 +57,15 @@
         self.y_label = "log10(y)"
 
+        # Mouse click related
+        self.x_click = None
+        self.y_click = None
+        self.event_pos = None
+        self.leftdown = False
+        self.gotLegend = 0
+
+        # Annotations
+        self.selectedText = None
+        self.textList = []
+
         # Pre-define the Scale properties dialog
         self.properties = ScaleProperties(self,
@@ -66,6 +81,16 @@
         self.ax = self.figure.add_subplot(self.current_plot)
 
+        # Remove this, DAMMIT
+        self.axes = [self.ax]
+
         # Set the background color to white
         self.canvas.figure.set_facecolor('#FFFFFF')
+
+        # Canvas event handlers
+        self.canvas.mpl_connect('button_release_event', self.onMplMouseUp)
+        self.canvas.mpl_connect('button_press_event', self.onMplMouseDown)
+        self.canvas.mpl_connect('motion_notify_event', self.onMplMouseMotion)
+        self.canvas.mpl_connect('pick_event', self.onMplPick)
+        self.canvas.mpl_connect('scroll_event', self.onMplWheel)
 
         if not quickplot:
@@ -166,5 +191,4 @@
         """
         Define common context menu and associated actions for the MPL widget
-        TODO: move to plotter1d/plotter2d
         """
         raise NotImplementedError("Context menu method must be implemented in derived class.")
@@ -180,5 +204,171 @@
         Display the context menu
         """
-        self.contextMenu.exec_(self.canvas.mapToGlobal(event.pos()))
+        event_pos = event.pos()
+        self.contextMenu.exec_(self.canvas.mapToGlobal(event_pos))
+
+    def onMplMouseDown(self, event):
+        """
+        Left button down and ready to drag
+        """
+        # Check that the LEFT button was pressed
+        if event.button == 1:
+            self.leftdown = True
+            ax = event.inaxes
+            for text in self.textList:
+                if text.contains(event)[0]: # If user has clicked on text
+                    self.selectedText = text
+                    return
+
+            if ax != None:
+                self.xInit, self.yInit = event.xdata, event.ydata
+                try:
+                    self.x_click = float(event.xdata)  # / size_x
+                    self.y_click = float(event.ydata)  # / size_y
+                except:
+                    self.position = None
+
+    def onMplMouseUp(self, event):
+        """
+        Set the data coordinates of the click
+        """
+        self.x_click = event.xdata
+        self.y_click = event.ydata
+
+        # Check that the LEFT button was released
+        if event.button == 1:
+            self.leftdown = False
+            #self.leftup = True
+            self.selectedText = None
+
+        #release the legend
+        if self.gotLegend == 1:
+            self.gotLegend = 0
+
+    def onMplMouseMotion(self, event):
+        """
+        Check if the left button is press and the mouse in moving.
+        Compute delta for x and y coordinates and then perform the drag
+        """
+        if self.gotLegend == 1 and self.leftdown:
+            self.onLegendMotion(event)
+            return
+
+        if self.leftdown and self.selectedText is not None:
+            # User has clicked on text and is dragging
+            ax = event.inaxes
+            if ax != None:
+                # Only move text if mouse is within axes
+                self.selectedText.set_position((event.xdata, event.ydata))
+                self.canvas.draw_idle()
+            else:
+                # User has dragged outside of axes
+                self.selectedText = None
+            return
+
+    def onMplPick(self, event):
+        """
+        On pick legend
+        """
+        legend = self.legend
+        if event.artist == legend:
+            # Get the box of the legend.
+            bbox = self.legend.get_window_extent()
+            # Get mouse coordinates at time of pick.
+            self.mouse_x = event.mouseevent.x
+            self.mouse_y = event.mouseevent.y
+            # Get legend coordinates at time of pick.
+            self.legend_x = bbox.xmin
+            self.legend_y = bbox.ymin
+            # Indicate we picked up the legend.
+            self.gotLegend = 1
+
+            #self.legend.legendPatch.set_alpha(0.5)
+
+    def onLegendMotion(self, event):
+        """
+        On legend in motion
+        """
+        ax = event.inaxes
+        if ax == None:
+            return
+        # Event occurred inside a plotting area
+        lo_x, hi_x = ax.get_xlim()
+        lo_y, hi_y = ax.get_ylim()
+        # How much the mouse moved.
+        x = mouse_diff_x = self.mouse_x - event.x
+        y = mouse_diff_y = self.mouse_y - event.y
+        # Put back inside
+        if x < lo_x:
+            x = lo_x
+        if x > hi_x:
+            x = hi_x
+        if y < lo_y:
+            y = lo_y
+        if y > hi_y:
+            y = hi_y
+        # Move the legend from its previous location by that same amount
+        loc_in_canvas = self.legend_x - mouse_diff_x, \
+                        self.legend_y - mouse_diff_y
+        # Transform into legend coordinate system
+        trans_axes = self.legend.parent.transAxes.inverted()
+        loc_in_norm_axes = trans_axes.transform_point(loc_in_canvas)
+        self.legend_pos_loc = tuple(loc_in_norm_axes)
+        self.legend._loc = self.legend_pos_loc
+        # self.canvas.draw()
+        self.canvas.draw_idle()
+
+    def onMplWheel(self, event):
+        """
+        Process mouse wheel as zoom events
+        """
+        ax = event.inaxes
+        step = event.step
+
+        if ax != None:
+            # Event occurred inside a plotting area
+            lo, hi = ax.get_xlim()
+            lo, hi = PlotUtilities.rescale(lo, hi, step,
+                              pt=event.xdata, scale=ax.get_xscale())
+            if not self.xscale == 'log' or lo > 0:
+                self._scale_xlo = lo
+                self._scale_xhi = hi
+                ax.set_xlim((lo, hi))
+
+            lo, hi = ax.get_ylim()
+            lo, hi = PlotUtilities.rescale(lo, hi, step, pt=event.ydata,
+                              scale=ax.get_yscale())
+            if not self.yscale == 'log' or lo > 0:
+                self._scale_ylo = lo
+                self._scale_yhi = hi
+                ax.set_ylim((lo, hi))
+        else:
+            # Check if zoom happens in the axes
+            xdata, ydata = None, None
+            x, y = event.x, event.y
+
+            for ax in self.axes:
+                insidex, _ = ax.xaxis.contains(event)
+                if insidex:
+                    xdata, _ = ax.transAxes.inverted().transform_point((x, y))
+                insidey, _ = ax.yaxis.contains(event)
+                if insidey:
+                    _, ydata = ax.transAxes.inverted().transform_point((x, y))
+            if xdata is not None:
+                lo, hi = ax.get_xlim()
+                lo, hi = PlotUtilities.rescale(lo, hi, step,
+                                  bal=xdata, scale=ax.get_xscale())
+                if not self.xscale == 'log' or lo > 0:
+                    self._scale_xlo = lo
+                    self._scale_xhi = hi
+                    ax.set_xlim((lo, hi))
+            if ydata is not None:
+                lo, hi = ax.get_ylim()
+                lo, hi = PlotUtilities.rescale(lo, hi, step, bal=ydata,
+                                  scale=ax.get_yscale())
+                if not self.yscale == 'log' or lo > 0:
+                    self._scale_ylo = lo
+                    self._scale_yhi = hi
+                    ax.set_ylim((lo, hi))
+        self.canvas.draw_idle()
 
     def clean(self):
Index: src/sas/qtgui/UI/AddTextUI.ui
===================================================================
--- src/sas/qtgui/UI/AddTextUI.ui	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
+++ src/sas/qtgui/UI/AddTextUI.ui	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddText</class>
+ <widget class="QDialog" name="AddText">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>432</width>
+    <height>324</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>Add Text</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Custom Text </string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QTextEdit" name="textEdit">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>44</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="2" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="btnFont">
+       <property name="text">
+        <string>Font...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnColor">
+       <property name="text">
+        <string>Color...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>AddText</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>AddText</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: src/sas/qtgui/UI/convert_all.sh
===================================================================
--- src/sas/qtgui/UI/convert_all.sh	(revision 39687521cf8722fe4e3c7749fbed09f108160510)
+++ src/sas/qtgui/UI/convert_all.sh	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -1,5 +1,5 @@
 # UI -> PY
 for filename in *.ui; do
-  pyuic4 $filename > "`basename "$filename" .ui`.py"
+  pyuic.bat $filename > "`basename "$filename" .ui`.py"
 done
 
Index: src/sas/qtgui/UnitTesting/AddTextTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/AddTextTest.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
+++ src/sas/qtgui/UnitTesting/AddTextTest.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -0,0 +1,61 @@
+import sys
+import unittest
+from mock import MagicMock
+
+from PyQt4 import QtGui
+
+# set up import paths
+import path_prepare
+
+# Local
+from AddText import AddText
+
+app = QtGui.QApplication(sys.argv)
+
+class AddTextTest(unittest.TestCase):
+    '''Test the AddText'''
+    def setUp(self):
+        '''Create the AddText'''
+        self.widget = AddText(None)
+
+    def tearDown(self):
+        '''Destroy the GUI'''
+        self.widget.close()
+        self.widget = None
+
+    def testDefaults(self):
+        '''Test the GUI in its default state'''
+        self.assertIsInstance(self.widget, QtGui.QDialog)
+        self.assertIsInstance(self.widget._font, QtGui.QFont)
+        self.assertEqual(self.widget._color, "black")
+        
+    def testOnFontChange(self):
+        '''Test the QFontDialog output'''
+        font_1 = QtGui.QFont("Helvetica", 15)
+        QtGui.QFontDialog.getFont = MagicMock(return_value=(font_1, True))
+        # Call the method
+        self.widget.onFontChange(None)
+        # Check that the text field got the new font info
+        self.assertEqual(self.widget.textEdit.currentFont(), font_1)
+
+        # See that rejecting the dialog doesn't modify the font
+        font_2 = QtGui.QFont("Arial", 9)
+        QtGui.QFontDialog.getFont = MagicMock(return_value=(font_2, False))
+        # Call the method
+        self.widget.onFontChange(None)
+        # Check that the text field retained the previous font info
+        self.assertEqual(self.widget.textEdit.currentFont(), font_1)
+
+    def testOnColorChange(self):
+        ''' Test the QColorDialog output'''
+        new_color = QtGui.QColor("red")
+        QtGui.QColorDialog.getColor = MagicMock(return_value=new_color)
+        # Call the method
+        self.widget.onColorChange(None)
+        # Check that the text field got the new color info for text
+        self.assertEqual(self.widget.textEdit.palette().color(QtGui.QPalette.Text), new_color)
+        # ... and the hex value of this color is correct
+        self.assertEqual(self.widget.color(), "#ff0000")
+        
+if __name__ == "__main__":
+    unittest.main()
Index: src/sas/qtgui/UnitTesting/PlotterBaseTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/PlotterBaseTest.py	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/UnitTesting/PlotterBaseTest.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -157,5 +157,5 @@
 
     def testOnWindowsTitle(self):
-        ''' test changing the plot title'''
+        """ Test changing the plot title"""
         # Mock the modal dialog's response
         QtGui.QDialog.exec_ = MagicMock(return_value=QtGui.QDialog.Accepted)
@@ -171,4 +171,24 @@
         self.assertEqual(self.plotter.windowTitle(), "I am a new title")
 
+    def testOnMplMouseDown(self):
+        """ Test what happens on mouse click down in chart """
+        pass
+
+    def testOnMplMouseUp(self):
+        """ Test what happens on mouse release in chart """
+        pass
+
+    def testOnMplMouseMotion(self):
+        """ Test what happens on mouse move in chart """
+        pass
+
+    def testOnMplPick(self):
+        """ Test what happens on mouse pick in chart """
+        pass
+
+    def testOnMplWheel(self):
+        """ Test what happens on mouse pick in chart """
+        pass
+
 if __name__ == "__main__":
     unittest.main()
Index: src/sas/qtgui/UnitTesting/PlotterTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/PlotterTest.py	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/UnitTesting/PlotterTest.py	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -154,4 +154,13 @@
         self.assertEqual(self.plotter.ax.get_ylabel(), "$ \\ \\ ^{4}(()^{4})$")
 
+    def testAddText(self):
+        """ Checks the functionality of adding text to graph """
+        pass
+
+    def testOnRemoveText(self):
+        """ Cheks if annotations can be removed from the graph """
+        pass
+
+
 if __name__ == "__main__":
     unittest.main()
Index: src/sas/qtgui/run_tests.bat
===================================================================
--- src/sas/qtgui/run_tests.bat	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/run_tests.bat	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -17,3 +17,3 @@
 python -m UnitTesting.ScalePropertiesTest
 python -m UnitTesting.WindowTitleTest
-
+python -m UnitTesting.AddTextTest
Index: src/sas/qtgui/run_tests.sh
===================================================================
--- src/sas/qtgui/run_tests.sh	(revision 27313b77c4e5bef362a7502a76baa9340a740ae8)
+++ src/sas/qtgui/run_tests.sh	(revision 9290b1a2e57458d51b13f1acd1798b999372c7d7)
@@ -16,2 +16,3 @@
 python -m UnitTesting.DensityCalculatorTest
 python -m UnitTesting.WindowTitleTest
+python -m UnitTesting.AddTextTest
