[med-svn] [openmolar] 01/01: Imported Upstream version 0.5.0~18

Dmitry Smirnov onlyjob at moszumanska.debian.org
Thu Mar 27 00:57:34 UTC 2014


This is an automated email from the git hooks/post-receive script.

onlyjob pushed a commit to branch upstream
in repository openmolar.

commit 44a5937 (upstream)
Author: Dmitry Smirnov <onlyjob at member.fsf.org>
Date:   Thu Mar 27 00:17:59 2014

    Imported Upstream version 0.5.0~18
---
 .../debian_packaging/dh_python2/debian/changelog   |  63 +++++
 src/openmolar/dbtools/patient_class.py             |   1 +
 src/openmolar/dbtools/patient_write_changes.py     |  35 +--
 src/openmolar/dbtools/queries.py                   |   2 +-
 src/openmolar/qt-designer/chooseDocument.ui        | 284 ---------------------
 src/openmolar/qt-designer/main.ui                  |  47 ++--
 src/openmolar/qt-designer/om_pyuic4.py             |  10 +-
 .../qt4gui/compiled_uis/Ui_chooseDocument.py       | 155 -----------
 src/openmolar/qt4gui/compiled_uis/Ui_main.py       |  41 +--
 .../qt4gui/customwidgets/simple_chartwidget.py     |   6 +-
 src/openmolar/qt4gui/customwidgets/toothProps.py   |  11 +
 .../qt4gui/dialogs/alter_denture_dialog.py         |   2 +-
 src/openmolar/qt4gui/dialogs/bridge_dialog.py      |   4 +-
 src/openmolar/qt4gui/dialogs/child_smile_dialog.py |  85 +++++-
 src/openmolar/qt4gui/dialogs/document_dialog.py    | 175 +++++++++++++
 src/openmolar/qt4gui/dialogs/new_bridge_dialog.py  |   6 +-
 src/openmolar/qt4gui/dialogs/new_denture_dialog.py |   2 +-
 src/openmolar/qt4gui/dialogs/post_choice_dialog.py | 108 ++++++++
 src/openmolar/qt4gui/fees/fees_module.py           |  63 -----
 src/openmolar/qt4gui/fees/manipulate_plan.py       |   8 +-
 src/openmolar/qt4gui/maingui.py                    |  19 +-
 src/openmolar/qt4gui/printing/bulk_mail.py         | 195 ++++++++------
 .../resources/Dental_Information_Guide_2008_v4.pdf | Bin 203670 -> 0 bytes
 .../resources/Dental_Information_Guide_2009.pdf    | Bin 144403 -> 0 bytes
 src/openmolar/resources/guidance-issue-2-v17.pdf   | Bin 2086685 -> 0 bytes
 .../resources/information-guide-2012-final.pdf     | Bin 142017 -> 0 bytes
 .../resources/information_guide_2010_v2.pdf        | Bin 169209 -> 0 bytes
 src/openmolar/resources/scotNHSremuneration08.pdf  | Bin 433371 -> 0 bytes
 src/openmolar/resources/scotNHSremuneration09.pdf  | Bin 3459955 -> 0 bytes
 src/openmolar/resources/scotNHSremuneration10.pdf  | Bin 1032670 -> 0 bytes
 src/openmolar/resources/scotNHSremuneration12.pdf  | Bin 1338672 -> 0 bytes
 src/openmolar/resources/scotNHSremuneration13.pdf  | Bin 1477732 -> 0 bytes
 src/openmolar/resources/ssi_20100208_en.pdf        | Bin 369039 -> 0 bytes
 src/openmolar/settings/fee_tables.py               |  16 +-
 src/openmolar/settings/localsettings.py            |  13 +-
 src/openmolar/settings/urls.py                     |  37 +++
 src/openmolar/settings/version.py                  |   2 +-
 37 files changed, 715 insertions(+), 675 deletions(-)

diff --git a/build_scripts/debian_packaging/dh_python2/debian/changelog b/build_scripts/debian_packaging/dh_python2/debian/changelog
index 888ca75..b2d604f 100644
--- a/build_scripts/debian_packaging/dh_python2/debian/changelog
+++ b/build_scripts/debian_packaging/dh_python2/debian/changelog
@@ -1,3 +1,66 @@
+openmolar (0.5.0-beta18-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream (removes pdf files from resources)
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Wed, 26 Mar 2014 17:18:44 +0000
+
+
+openmolar (0.5.0-beta17-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Fri, 14 Mar 2014 12:24:30 +0000
+
+
+openmolar (0.5.0-beta16-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Tue, 28 Jan 2014 16:44:38 +0000
+
+
+openmolar (0.5.0-beta15-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Wed, 22 Jan 2014 15:42:53 +0000
+
+
+openmolar (0.5.0-beta14-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Wed, 22 Jan 2014 14:51:41 +0000
+
+
+openmolar (0.5.0-beta13-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Tue, 24 Dec 2013 00:53:40 +0000
+
+
+openmolar (0.5.0-beta12-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Tue, 17 Dec 2013 11:41:05 +0000
+
+
+openmolar (0.5.0-beta11-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Mon, 16 Dec 2013 23:58:03 +0000
+
+
+openmolar (0.5.0-beta10-0~__DIST__0) __DIST__; urgency=low
+
+  * New Upstream
+
+ -- Neil Wallace <rowinggolfer at googlemail.com>  Mon, 16 Dec 2013 12:36:29 +0000
+
+
 openmolar (0.5.0-beta09-0~__DIST__0) __DIST__; urgency=low
 
   * New Upstream
diff --git a/src/openmolar/dbtools/patient_class.py b/src/openmolar/dbtools/patient_class.py
index 407fe0c..28d6bcd 100644
--- a/src/openmolar/dbtools/patient_class.py
+++ b/src/openmolar/dbtools/patient_class.py
@@ -513,6 +513,7 @@ class patient(object):
             est = estimates.Estimate()
 
             est.ix = ix
+            est.courseno = row[11]
             est.number = row[1]
             est.itemcode = row[2]
             est.description = row[3]
diff --git a/src/openmolar/dbtools/patient_write_changes.py b/src/openmolar/dbtools/patient_write_changes.py
index af0c216..457f008 100644
--- a/src/openmolar/dbtools/patient_write_changes.py
+++ b/src/openmolar/dbtools/patient_write_changes.py
@@ -42,7 +42,7 @@ insert into clinical_memos (serialno, synopsis, author, datestamp)
 values (%s, %s, %s, NOW())'''
 
 def all_changes(pt, changes):
-    LOGGER.debug("writing_changes to patient")
+    LOGGER.debug("writing_changes to patient - %s"% str(changes))
     if changes == []:
         LOGGER.warning(
             "write changes called, but no changes for patient %d!"% (
@@ -50,7 +50,6 @@ def all_changes(pt, changes):
         )
         return True
     else:
-
         #set up some booleans to prevent multiple updates of the same data
         #example exemption AND exemption text have changed..
         exemptionsHandled = False
@@ -114,7 +113,7 @@ def all_changes(pt, changes):
 
                 for est in pt.estimates:
                     if est.ix == None: #--new item
-                        values = (pt.serialno, pt.courseno0, est.number,
+                        values = (pt.serialno, est.courseno, est.number,
                         est.itemcode, est.description,
                         est.fee, est.ptfee, est.feescale, est.csetype,
                         est.dent, localsettings.operator)
@@ -123,12 +122,6 @@ def all_changes(pt, changes):
                             (ESTS_INS_QUERY, values, est.tx_hashes)
                             )
 
-                        #for tx_hash in est.tx_hashes:
-                        #    values = (tx_hash,)
-                        #    sqlcommands["estimate_insertions"].append(
-                        #    (EST_LINK_INS_QUERY, values)
-                        #    )
-
                     elif est.ix in oldEstDict.keys():
                         oldEst = oldEstDict[est.ix]
 
@@ -162,11 +155,6 @@ def all_changes(pt, changes):
                                 query += 'dent=%d,'
                                 values.append(est.dent)
 
-                            #obsolete code.. completed is now in tx_hash!
-                            #if oldEst.completed != est.completed:
-                            #    query += 'completed=%s,'
-                            #   values.append(est.completed)
-
                             query += ('modified_by = %s, '
                             'time_stamp = NOW() where ix = %s')
 
@@ -177,15 +165,18 @@ def all_changes(pt, changes):
                             (query, tuple(values), est))
 
                         oldEstDict.pop(est.ix)
+
+
                 #-- all that is left in oldEstDict now are items which
                 #-- have been removed.
-                #-- so remove from database also.
-                for ix in oldEstDict.keys():
+                #-- so remove from database if they are current course!
+                for ix, old_est in oldEstDict.iteritems():
                     #--removed
-                    values = (ix,)
-                    deletions = sqlcommands["estimate_deletions"]
-                    deletions.append((EST_DEL_QUERY, values))
-                    deletions.append((EST_LINK_DEL_QUERY, values))
+                    if old_est.courseno == pt.courseno0:
+                        values = (ix,)
+                        deletions = sqlcommands["estimate_deletions"]
+                        deletions.append((EST_DEL_QUERY, values))
+                        deletions.append((EST_LINK_DEL_QUERY, values))
 
             elif change == "treatment_course": #patient.CURRTRT_ATTS:
                 for trt_att in CURRTRT_ATTS:
@@ -218,14 +209,14 @@ def all_changes(pt, changes):
         sqlcommands['currtrtmt'] = ((query, values),)
 
     if sqlcommands != {} or estimate_commands != {}:
+        LOGGER.debug(sqlcommands)
+        LOGGER.debug(estimate_commands)
         db = connect()
         cursor = db.cursor()
         tables = sqlcommands.keys()
         for table in tables:
             for query, values in sqlcommands[table]:
                 try:
-                    LOGGER.debug(query)
-                    LOGGER.debug(values)
                     cursor.execute(query, values)
                 except Exception as exc:
                     LOGGER.exception("error executing query %s"% query)
diff --git a/src/openmolar/dbtools/queries.py b/src/openmolar/dbtools/queries.py
index 8ece442..dd7bac4 100644
--- a/src/openmolar/dbtools/queries.py
+++ b/src/openmolar/dbtools/queries.py
@@ -7,7 +7,7 @@
 # for more details.
 
 ESTS_QUERY = '''SELECT newestimates.ix, number, itemcode, description,
-fee, ptfee, feescale, csetype, dent, est_link2.completed, tx_hash
+fee, ptfee, feescale, csetype, dent, est_link2.completed, tx_hash, courseno
 from newestimates right join est_link2 on newestimates.ix = est_link2.est_id
 where serialno=%s and courseno=%s order by itemcode, ix'''
 
diff --git a/src/openmolar/qt-designer/chooseDocument.ui b/src/openmolar/qt-designer/chooseDocument.ui
deleted file mode 100644
index 059ea7f..0000000
--- a/src/openmolar/qt-designer/chooseDocument.ui
+++ /dev/null
@@ -1,284 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>394</width>
-    <height>270</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Choose a Document</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QTabWidget" name="tabWidget">
-     <property name="currentIndex">
-      <number>4</number>
-     </property>
-     <widget class="QWidget" name="tab">
-      <attribute name="title">
-       <string>2008</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_2">
-       <item>
-        <widget class="QRadioButton" name="remuneration_radioButton">
-         <property name="text">
-          <string>NHS Schedule of Remuneration April 2008</string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="info_radioButton">
-         <property name="text">
-          <string>NHS "Information Guide" 2008</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>128</width>
-           <height>10</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_2">
-      <attribute name="title">
-       <string>2009</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_3">
-       <item>
-        <widget class="QRadioButton" name="remuneration2009_radioButton">
-         <property name="text">
-          <string>NHS Schedule of Remuneration</string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="info2009_radioButton">
-         <property name="text">
-          <string>NHS "Information Guide"</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>128</width>
-           <height>10</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_3">
-      <attribute name="title">
-       <string>2010</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_6">
-       <item>
-        <widget class="QRadioButton" name="remuneration2010_radioButton">
-         <property name="text">
-          <string>NHS Schedule of Remuneration</string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="info2010_radioButton">
-         <property name="text">
-          <string>NHS "Information Guide"</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_5">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>128</width>
-           <height>25</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_4">
-      <attribute name="title">
-       <string>2012</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_8">
-       <item>
-        <widget class="QRadioButton" name="remuneration2012_radioButton">
-         <property name="text">
-          <string>NHS Schedule of Remuneration</string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="info2012_radioButton">
-         <property name="text">
-          <string>NHS "Information Guide"</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="terms_radioButton">
-         <property name="text">
-          <string>NHS terms and conditions</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_7">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>128</width>
-           <height>15</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_5">
-      <attribute name="title">
-       <string>2013</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_4">
-       <item>
-        <widget class="QRadioButton" name="remuneration2013_radioButton">
-         <property name="text">
-          <string>NHS Schedule of Remuneration</string>
-         </property>
-         <property name="checked">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="tooth_specific_radioButton">
-         <property name="text">
-          <string>Tooth Specific Guidance</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="info2013_radioButton">
-         <property name="text">
-          <string>NHS "Information Guide"</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QRadioButton" name="terms2013_radioButton">
-         <property name="text">
-          <string>NHS terms and conditions</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_8">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>128</width>
-           <height>63</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>Choose a document to view</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="terms_buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>terms_buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>Dialog</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>terms_buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>Dialog</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>
diff --git a/src/openmolar/qt-designer/main.ui b/src/openmolar/qt-designer/main.ui
index 87d9b0c..d3604d6 100644
--- a/src/openmolar/qt-designer/main.ui
+++ b/src/openmolar/qt-designer/main.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>943</width>
-    <height>642</height>
+    <width>964</width>
+    <height>631</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -62,8 +62,8 @@
         <rect>
          <x>0</x>
          <y>0</y>
-         <width>1071</width>
-         <height>585</height>
+         <width>964</width>
+         <height>592</height>
         </rect>
        </property>
        <layout class="QHBoxLayout" name="horizontalLayout_7">
@@ -463,8 +463,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>850</width>
-                      <height>477</height>
+                      <width>469</width>
+                      <height>462</height>
                      </rect>
                     </property>
                     <layout class="QVBoxLayout" name="verticalLayout_6">
@@ -1696,8 +1696,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>441</width>
-                      <height>423</height>
+                      <width>423</width>
+                      <height>421</height>
                      </rect>
                     </property>
                     <layout class="QGridLayout" name="gridLayout">
@@ -1989,8 +1989,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>303</width>
-                      <height>471</height>
+                      <width>283</width>
+                      <height>470</height>
                      </rect>
                     </property>
                     <layout class="QHBoxLayout" name="horizontalLayout_26">
@@ -2280,7 +2280,7 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>846</width>
+                      <width>739</width>
                       <height>456</height>
                      </rect>
                     </property>
@@ -2949,7 +2949,7 @@
                    </property>
                    <property name="minimumSize">
                     <size>
-                     <width>180</width>
+                     <width>200</width>
                      <height>0</height>
                     </size>
                    </property>
@@ -2961,8 +2961,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>153</width>
-                      <height>224</height>
+                      <width>139</width>
+                      <height>212</height>
                      </rect>
                     </property>
                     <layout class="QVBoxLayout" name="verticalLayout_9">
@@ -3079,7 +3079,7 @@ Note - this will not remove items which are currently there. </string>
                       <x>0</x>
                       <y>0</y>
                       <width>252</width>
-                      <height>376</height>
+                      <height>374</height>
                      </rect>
                     </property>
                     <layout class="QGridLayout" name="gridLayout_15">
@@ -3512,7 +3512,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                      <x>0</x>
                      <y>0</y>
                      <width>118</width>
-                     <height>92</height>
+                     <height>110</height>
                     </rect>
                    </property>
                    <layout class="QVBoxLayout" name="verticalLayout_20">
@@ -4527,12 +4527,12 @@ If the "changes only" checkbox is checked, only data which has been ch
                    <number>3</number>
                   </property>
                   <item>
-                   <widget class="QPushButton" name="nhsRegs_pushButton">
+                   <widget class="QPushButton" name="documents_pushButton">
                     <property name="toolTip">
                      <string>Open A PDF of the latest NHS Regulations</string>
                     </property>
                     <property name="text">
-                     <string>NHS Documents</string>
+                     <string>Documents</string>
                     </property>
                     <property name="icon">
                      <iconset resource="../resources/resources.qrc">
@@ -4960,8 +4960,8 @@ If the "changes only" checkbox is checked, only data which has been ch
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>943</width>
-     <height>22</height>
+     <width>964</width>
+     <height>17</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuMenu">
@@ -5054,6 +5054,8 @@ If the "changes only" checkbox is checked, only data which has been ch
     <addaction name="actionSet_Assistant"/>
     <addaction name="actionSet_Surgery_Number"/>
     <addaction name="separator"/>
+    <addaction name="actionDocuments_Dialog"/>
+    <addaction name="separator"/>
     <addaction name="actionEdit_Phrasebooks"/>
    </widget>
    <addaction name="menuMenu"/>
@@ -5202,6 +5204,11 @@ If the "changes only" checkbox is checked, only data which has been ch
     <string>Edit Phrasebooks</string>
    </property>
   </action>
+  <action name="actionDocuments_Dialog">
+   <property name="text">
+    <string>Documents Dialog</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/src/openmolar/qt-designer/om_pyuic4.py b/src/openmolar/qt-designer/om_pyuic4.py
index f9bcd5a..7060d84 100755
--- a/src/openmolar/qt-designer/om_pyuic4.py
+++ b/src/openmolar/qt-designer/om_pyuic4.py
@@ -62,9 +62,13 @@ def compile_ui(ui_fname, outdir=""):
 
     logger.info("compiling %s"% ui_fname)
 
-    f = open(pyfile,"w")
-    uic.compileUi(ui_fname, f, execute=MAKE_EX)
-    f.close()
+    try:
+    	f = open(pyfile,"w")
+    	uic.compileUi(ui_fname, f, execute=MAKE_EX)
+    except IOError: #ui has been removed by git?
+        pass
+    finally:    
+        f.close()
 
     f = open(pyfile,"r")
     data = f.read()
diff --git a/src/openmolar/qt4gui/compiled_uis/Ui_chooseDocument.py b/src/openmolar/qt4gui/compiled_uis/Ui_chooseDocument.py
deleted file mode 100644
index 219ac59..0000000
--- a/src/openmolar/qt4gui/compiled_uis/Ui_chooseDocument.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file '/home/neil/openmolar/openmolar1/src/openmolar/qt-designer/chooseDocument.ui'
-#
-# Created: Wed Nov  6 23:05:24 2013
-#      by: PyQt4 UI code generator 4.10.3
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
-    _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
-    def _fromUtf8(s):
-        return s
-
-
-class Ui_Dialog(object):
-    def setupUi(self, Dialog):
-        Dialog.setObjectName(_fromUtf8("Dialog"))
-        Dialog.resize(394, 270)
-        self.verticalLayout = QtGui.QVBoxLayout(Dialog)
-        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
-        self.tabWidget = QtGui.QTabWidget(Dialog)
-        self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
-        self.tab = QtGui.QWidget()
-        self.tab.setObjectName(_fromUtf8("tab"))
-        self.verticalLayout_2 = QtGui.QVBoxLayout(self.tab)
-        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
-        self.remuneration_radioButton = QtGui.QRadioButton(self.tab)
-        self.remuneration_radioButton.setChecked(True)
-        self.remuneration_radioButton.setObjectName(_fromUtf8("remuneration_radioButton"))
-        self.verticalLayout_2.addWidget(self.remuneration_radioButton)
-        self.info_radioButton = QtGui.QRadioButton(self.tab)
-        self.info_radioButton.setObjectName(_fromUtf8("info_radioButton"))
-        self.verticalLayout_2.addWidget(self.info_radioButton)
-        spacerItem = QtGui.QSpacerItem(128, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_2.addItem(spacerItem)
-        self.tabWidget.addTab(self.tab, _fromUtf8(""))
-        self.tab_2 = QtGui.QWidget()
-        self.tab_2.setObjectName(_fromUtf8("tab_2"))
-        self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_2)
-        self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
-        self.remuneration2009_radioButton = QtGui.QRadioButton(self.tab_2)
-        self.remuneration2009_radioButton.setChecked(True)
-        self.remuneration2009_radioButton.setObjectName(_fromUtf8("remuneration2009_radioButton"))
-        self.verticalLayout_3.addWidget(self.remuneration2009_radioButton)
-        self.info2009_radioButton = QtGui.QRadioButton(self.tab_2)
-        self.info2009_radioButton.setObjectName(_fromUtf8("info2009_radioButton"))
-        self.verticalLayout_3.addWidget(self.info2009_radioButton)
-        spacerItem1 = QtGui.QSpacerItem(128, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_3.addItem(spacerItem1)
-        self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
-        self.tab_3 = QtGui.QWidget()
-        self.tab_3.setObjectName(_fromUtf8("tab_3"))
-        self.verticalLayout_6 = QtGui.QVBoxLayout(self.tab_3)
-        self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6"))
-        self.remuneration2010_radioButton = QtGui.QRadioButton(self.tab_3)
-        self.remuneration2010_radioButton.setChecked(True)
-        self.remuneration2010_radioButton.setObjectName(_fromUtf8("remuneration2010_radioButton"))
-        self.verticalLayout_6.addWidget(self.remuneration2010_radioButton)
-        self.info2010_radioButton = QtGui.QRadioButton(self.tab_3)
-        self.info2010_radioButton.setObjectName(_fromUtf8("info2010_radioButton"))
-        self.verticalLayout_6.addWidget(self.info2010_radioButton)
-        spacerItem2 = QtGui.QSpacerItem(128, 25, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_6.addItem(spacerItem2)
-        self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
-        self.tab_4 = QtGui.QWidget()
-        self.tab_4.setObjectName(_fromUtf8("tab_4"))
-        self.verticalLayout_8 = QtGui.QVBoxLayout(self.tab_4)
-        self.verticalLayout_8.setObjectName(_fromUtf8("verticalLayout_8"))
-        self.remuneration2012_radioButton = QtGui.QRadioButton(self.tab_4)
-        self.remuneration2012_radioButton.setChecked(True)
-        self.remuneration2012_radioButton.setObjectName(_fromUtf8("remuneration2012_radioButton"))
-        self.verticalLayout_8.addWidget(self.remuneration2012_radioButton)
-        self.info2012_radioButton = QtGui.QRadioButton(self.tab_4)
-        self.info2012_radioButton.setObjectName(_fromUtf8("info2012_radioButton"))
-        self.verticalLayout_8.addWidget(self.info2012_radioButton)
-        self.terms_radioButton = QtGui.QRadioButton(self.tab_4)
-        self.terms_radioButton.setObjectName(_fromUtf8("terms_radioButton"))
-        self.verticalLayout_8.addWidget(self.terms_radioButton)
-        spacerItem3 = QtGui.QSpacerItem(128, 15, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_8.addItem(spacerItem3)
-        self.tabWidget.addTab(self.tab_4, _fromUtf8(""))
-        self.tab_5 = QtGui.QWidget()
-        self.tab_5.setObjectName(_fromUtf8("tab_5"))
-        self.verticalLayout_4 = QtGui.QVBoxLayout(self.tab_5)
-        self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
-        self.remuneration2013_radioButton = QtGui.QRadioButton(self.tab_5)
-        self.remuneration2013_radioButton.setChecked(True)
-        self.remuneration2013_radioButton.setObjectName(_fromUtf8("remuneration2013_radioButton"))
-        self.verticalLayout_4.addWidget(self.remuneration2013_radioButton)
-        self.tooth_specific_radioButton = QtGui.QRadioButton(self.tab_5)
-        self.tooth_specific_radioButton.setObjectName(_fromUtf8("tooth_specific_radioButton"))
-        self.verticalLayout_4.addWidget(self.tooth_specific_radioButton)
-        self.info2013_radioButton = QtGui.QRadioButton(self.tab_5)
-        self.info2013_radioButton.setObjectName(_fromUtf8("info2013_radioButton"))
-        self.verticalLayout_4.addWidget(self.info2013_radioButton)
-        self.terms2013_radioButton = QtGui.QRadioButton(self.tab_5)
-        self.terms2013_radioButton.setObjectName(_fromUtf8("terms2013_radioButton"))
-        self.verticalLayout_4.addWidget(self.terms2013_radioButton)
-        spacerItem4 = QtGui.QSpacerItem(128, 63, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.verticalLayout_4.addItem(spacerItem4)
-        self.tabWidget.addTab(self.tab_5, _fromUtf8(""))
-        self.verticalLayout.addWidget(self.tabWidget)
-        self.label = QtGui.QLabel(Dialog)
-        self.label.setObjectName(_fromUtf8("label"))
-        self.verticalLayout.addWidget(self.label)
-        self.terms_buttonBox = QtGui.QDialogButtonBox(Dialog)
-        self.terms_buttonBox.setOrientation(QtCore.Qt.Horizontal)
-        self.terms_buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
-        self.terms_buttonBox.setObjectName(_fromUtf8("terms_buttonBox"))
-        self.verticalLayout.addWidget(self.terms_buttonBox)
-
-        self.retranslateUi(Dialog)
-        self.tabWidget.setCurrentIndex(4)
-        QtCore.QObject.connect(self.terms_buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
-        QtCore.QObject.connect(self.terms_buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
-        QtCore.QMetaObject.connectSlotsByName(Dialog)
-
-    def retranslateUi(self, Dialog):
-        Dialog.setWindowTitle(_("Choose a Document"))
-        self.remuneration_radioButton.setText(_("NHS Schedule of Remuneration April 2008"))
-        self.info_radioButton.setText(_("NHS \"Information Guide\" 2008"))
-        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _("2008"))
-        self.remuneration2009_radioButton.setText(_("NHS Schedule of Remuneration"))
-        self.info2009_radioButton.setText(_("NHS \"Information Guide\""))
-        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _("2009"))
-        self.remuneration2010_radioButton.setText(_("NHS Schedule of Remuneration"))
-        self.info2010_radioButton.setText(_("NHS \"Information Guide\""))
-        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _("2010"))
-        self.remuneration2012_radioButton.setText(_("NHS Schedule of Remuneration"))
-        self.info2012_radioButton.setText(_("NHS \"Information Guide\""))
-        self.terms_radioButton.setText(_("NHS terms and conditions"))
-        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _("2012"))
-        self.remuneration2013_radioButton.setText(_("NHS Schedule of Remuneration"))
-        self.tooth_specific_radioButton.setText(_("Tooth Specific Guidance"))
-        self.info2013_radioButton.setText(_("NHS \"Information Guide\""))
-        self.terms2013_radioButton.setText(_("NHS terms and conditions"))
-        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _("2013"))
-        self.label.setText(_("Choose a document to view"))
-
-
-if __name__ == "__main__":
-    import gettext
-    gettext.install("openmolar")
-    import sys
-    app = QtGui.QApplication(sys.argv)
-    Dialog = QtGui.QDialog()
-    ui = Ui_Dialog()
-    ui.setupUi(Dialog)
-    Dialog.show()
-    sys.exit(app.exec_())
-
diff --git a/src/openmolar/qt4gui/compiled_uis/Ui_main.py b/src/openmolar/qt4gui/compiled_uis/Ui_main.py
index 2cb1e6e..df65668 100644
--- a/src/openmolar/qt4gui/compiled_uis/Ui_main.py
+++ b/src/openmolar/qt4gui/compiled_uis/Ui_main.py
@@ -2,7 +2,7 @@
 
 # Form implementation generated from reading ui file '/home/neil/openmolar/openmolar1/src/openmolar/qt-designer/main.ui'
 #
-# Created: Mon Dec 16 11:22:23 2013
+# Created: Wed Mar 26 16:50:07 2014
 #      by: PyQt4 UI code generator 4.10.3
 #
 # WARNING! All changes made in this file will be lost!
@@ -19,7 +19,7 @@ except AttributeError:
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName(_fromUtf8("MainWindow"))
-        MainWindow.resize(943, 642)
+        MainWindow.resize(964, 631)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
@@ -45,7 +45,7 @@ class Ui_MainWindow(object):
         self.scrollArea_main.setWidgetResizable(True)
         self.scrollArea_main.setObjectName(_fromUtf8("scrollArea_main"))
         self.scrollAreaWidgetContents_12 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_12.setGeometry(QtCore.QRect(0, 0, 1071, 585))
+        self.scrollAreaWidgetContents_12.setGeometry(QtCore.QRect(0, 0, 964, 592))
         self.scrollAreaWidgetContents_12.setObjectName(_fromUtf8("scrollAreaWidgetContents_12"))
         self.horizontalLayout_7 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents_12)
         self.horizontalLayout_7.setSpacing(0)
@@ -216,7 +216,7 @@ class Ui_MainWindow(object):
         self.scrollArea_4.setWidgetResizable(True)
         self.scrollArea_4.setObjectName(_fromUtf8("scrollArea_4"))
         self.scrollAreaWidgetContents_7 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_7.setGeometry(QtCore.QRect(0, 0, 850, 477))
+        self.scrollAreaWidgetContents_7.setGeometry(QtCore.QRect(0, 0, 469, 462))
         self.scrollAreaWidgetContents_7.setObjectName(_fromUtf8("scrollAreaWidgetContents_7"))
         self.verticalLayout_6 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents_7)
         self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6"))
@@ -679,7 +679,7 @@ class Ui_MainWindow(object):
         self.scrollArea_5.setWidgetResizable(True)
         self.scrollArea_5.setObjectName(_fromUtf8("scrollArea_5"))
         self.scrollAreaWidgetContents_8 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_8.setGeometry(QtCore.QRect(0, 0, 441, 423))
+        self.scrollAreaWidgetContents_8.setGeometry(QtCore.QRect(0, 0, 423, 421))
         self.scrollAreaWidgetContents_8.setObjectName(_fromUtf8("scrollAreaWidgetContents_8"))
         self.gridLayout = QtGui.QGridLayout(self.scrollAreaWidgetContents_8)
         self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
@@ -821,7 +821,7 @@ class Ui_MainWindow(object):
         self.scrollArea_2.setWidgetResizable(True)
         self.scrollArea_2.setObjectName(_fromUtf8("scrollArea_2"))
         self.scrollAreaWidgetContents_5 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_5.setGeometry(QtCore.QRect(0, 0, 303, 471))
+        self.scrollAreaWidgetContents_5.setGeometry(QtCore.QRect(0, 0, 283, 470))
         self.scrollAreaWidgetContents_5.setObjectName(_fromUtf8("scrollAreaWidgetContents_5"))
         self.horizontalLayout_26 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents_5)
         self.horizontalLayout_26.setSpacing(3)
@@ -948,7 +948,7 @@ class Ui_MainWindow(object):
         self.scrollArea_6.setWidgetResizable(True)
         self.scrollArea_6.setObjectName(_fromUtf8("scrollArea_6"))
         self.scrollAreaWidgetContents_9 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_9.setGeometry(QtCore.QRect(0, 0, 846, 456))
+        self.scrollAreaWidgetContents_9.setGeometry(QtCore.QRect(0, 0, 739, 456))
         self.scrollAreaWidgetContents_9.setObjectName(_fromUtf8("scrollAreaWidgetContents_9"))
         self.gridLayout_4 = QtGui.QGridLayout(self.scrollAreaWidgetContents_9)
         self.gridLayout_4.setMargin(0)
@@ -1239,11 +1239,11 @@ class Ui_MainWindow(object):
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
         self.scrollArea.setSizePolicy(sizePolicy)
-        self.scrollArea.setMinimumSize(QtCore.QSize(180, 0))
+        self.scrollArea.setMinimumSize(QtCore.QSize(200, 0))
         self.scrollArea.setWidgetResizable(True)
         self.scrollArea.setObjectName(_fromUtf8("scrollArea"))
         self.scrollAreaWidgetContents_4 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 153, 224))
+        self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 139, 212))
         self.scrollAreaWidgetContents_4.setObjectName(_fromUtf8("scrollAreaWidgetContents_4"))
         self.verticalLayout_9 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents_4)
         self.verticalLayout_9.setObjectName(_fromUtf8("verticalLayout_9"))
@@ -1289,7 +1289,7 @@ class Ui_MainWindow(object):
         self.perioCharts_scrollArea.setWidgetResizable(True)
         self.perioCharts_scrollArea.setObjectName(_fromUtf8("perioCharts_scrollArea"))
         self.scrollAreaWidgetContents_6 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_6.setGeometry(QtCore.QRect(0, 0, 252, 376))
+        self.scrollAreaWidgetContents_6.setGeometry(QtCore.QRect(0, 0, 252, 374))
         self.scrollAreaWidgetContents_6.setObjectName(_fromUtf8("scrollAreaWidgetContents_6"))
         self.gridLayout_15 = QtGui.QGridLayout(self.scrollAreaWidgetContents_6)
         self.gridLayout_15.setObjectName(_fromUtf8("gridLayout_15"))
@@ -1479,7 +1479,7 @@ class Ui_MainWindow(object):
         self.scrollArea_8.setWidgetResizable(True)
         self.scrollArea_8.setObjectName(_fromUtf8("scrollArea_8"))
         self.scrollAreaWidgetContents_13 = QtGui.QWidget()
-        self.scrollAreaWidgetContents_13.setGeometry(QtCore.QRect(0, 0, 118, 92))
+        self.scrollAreaWidgetContents_13.setGeometry(QtCore.QRect(0, 0, 118, 110))
         self.scrollAreaWidgetContents_13.setObjectName(_fromUtf8("scrollAreaWidgetContents_13"))
         self.verticalLayout_20 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents_13)
         self.verticalLayout_20.setSpacing(0)
@@ -1913,10 +1913,10 @@ class Ui_MainWindow(object):
         self.verticalLayout_13.setSpacing(3)
         self.verticalLayout_13.setMargin(3)
         self.verticalLayout_13.setObjectName(_fromUtf8("verticalLayout_13"))
-        self.nhsRegs_pushButton = QtGui.QPushButton(self.groupBox)
-        self.nhsRegs_pushButton.setIcon(icon11)
-        self.nhsRegs_pushButton.setObjectName(_fromUtf8("nhsRegs_pushButton"))
-        self.verticalLayout_13.addWidget(self.nhsRegs_pushButton)
+        self.documents_pushButton = QtGui.QPushButton(self.groupBox)
+        self.documents_pushButton.setIcon(icon11)
+        self.documents_pushButton.setObjectName(_fromUtf8("documents_pushButton"))
+        self.verticalLayout_13.addWidget(self.documents_pushButton)
         self.verticalLayout_10.addWidget(self.groupBox)
         spacerItem21 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
         self.verticalLayout_10.addItem(spacerItem21)
@@ -2088,7 +2088,7 @@ class Ui_MainWindow(object):
         self.verticalLayout_18.addWidget(self.scrollArea_main)
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(MainWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 943, 22))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 964, 17))
         self.menubar.setObjectName(_fromUtf8("menubar"))
         self.menuMenu = QtGui.QMenu(self.menubar)
         self.menuMenu.setObjectName(_fromUtf8("menuMenu"))
@@ -2170,6 +2170,8 @@ class Ui_MainWindow(object):
         self.actionSet_Surgery_Number.setObjectName(_fromUtf8("actionSet_Surgery_Number"))
         self.actionEdit_Phrasebooks = QtGui.QAction(MainWindow)
         self.actionEdit_Phrasebooks.setObjectName(_fromUtf8("actionEdit_Phrasebooks"))
+        self.actionDocuments_Dialog = QtGui.QAction(MainWindow)
+        self.actionDocuments_Dialog.setObjectName(_fromUtf8("actionDocuments_Dialog"))
         self.menuMenu.addAction(self.action_save_patient)
         self.menuMenu.addAction(self.action_Open_Patient)
         self.menuMenu.addSeparator()
@@ -2206,6 +2208,8 @@ class Ui_MainWindow(object):
         self.menuTools.addAction(self.actionSet_Assistant)
         self.menuTools.addAction(self.actionSet_Surgery_Number)
         self.menuTools.addSeparator()
+        self.menuTools.addAction(self.actionDocuments_Dialog)
+        self.menuTools.addSeparator()
         self.menuTools.addAction(self.actionEdit_Phrasebooks)
         self.menubar.addAction(self.menuMenu.menuAction())
         self.menubar.addAction(self.menu_Prefences.menuAction())
@@ -2533,8 +2537,8 @@ class Ui_MainWindow(object):
         self.feeCompress_radioButton.setToolTip(_("Quickly compress all items"))
         self.feeCompress_radioButton.setText(_("Compress All Sections"))
         self.groupBox.setTitle(_("Resources"))
-        self.nhsRegs_pushButton.setToolTip(_("Open A PDF of the latest NHS Regulations"))
-        self.nhsRegs_pushButton.setText(_("NHS Documents"))
+        self.documents_pushButton.setToolTip(_("Open A PDF of the latest NHS Regulations"))
+        self.documents_pushButton.setText(_("Documents"))
         self.feeadjuster_groupBox.setTitle(_("Advanced Options"))
         self.feetable_xml_pushButton.setText(_("FeeScale Editor"))
         self.feescale_tester_pushButton.setText(_("FeeScale Tester"))
@@ -2598,6 +2602,7 @@ class Ui_MainWindow(object):
         self.actionSet_Surgery_Number.setText(_("Set Surgery Number"))
         self.actionSet_Surgery_Number.setToolTip(_("Set Surgery Number (used so other applications can see which record is loaded)"))
         self.actionEdit_Phrasebooks.setText(_("Edit Phrasebooks"))
+        self.actionDocuments_Dialog.setText(_("Documents Dialog"))
 
 from PyQt4 import QtWebKit
 from openmolar.qt4gui import resources_rc
diff --git a/src/openmolar/qt4gui/customwidgets/simple_chartwidget.py b/src/openmolar/qt4gui/customwidgets/simple_chartwidget.py
index 14c0dec..6dcb3f9 100644
--- a/src/openmolar/qt4gui/customwidgets/simple_chartwidget.py
+++ b/src/openmolar/qt4gui/customwidgets/simple_chartwidget.py
@@ -32,7 +32,7 @@ class SimpleChartWidg(QtGui.QWidget):
     a custom widget to show a standard UK dental chart
     - allows for user navigation with mouse and/or keyboard
     '''
-    def __init__(self, parent=None):
+    def __init__(self, parent=None, auto_ctrl_key=False):
         QtGui.QWidget.__init__(self, parent)
 
         self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
@@ -40,6 +40,7 @@ class SimpleChartWidg(QtGui.QWidget):
 
         self.grid = GRID
 
+        self.auto_ctrl_key = auto_ctrl_key
         self.selected = set()
         self.highlighted = [-1, -1]
         self.prevSelect = ()
@@ -131,7 +132,8 @@ class SimpleChartWidg(QtGui.QWidget):
     def mousePressEvent(self, event):
         '''overrides QWidget's mouse event'''
         shiftClick = (event.modifiers() == QtCore.Qt.ShiftModifier)
-        ctrlClick = (event.modifiers() == QtCore.Qt.ControlModifier)
+        ctrlClick = self.auto_ctrl_key or (
+            event.modifiers() == QtCore.Qt.ControlModifier)
         if not (shiftClick or ctrlClick):
             self.selected.clear()
         xOffset = self.width() / 16
diff --git a/src/openmolar/qt4gui/customwidgets/toothProps.py b/src/openmolar/qt4gui/customwidgets/toothProps.py
index 932378e..f58d230 100644
--- a/src/openmolar/qt4gui/customwidgets/toothProps.py
+++ b/src/openmolar/qt4gui/customwidgets/toothProps.py
@@ -16,6 +16,7 @@ from openmolar.settings import allowed
 from openmolar.qt4gui.compiled_uis import Ui_toothProps
 from openmolar.qt4gui import colours
 from openmolar.qt4gui.dialogs.crown_choice_dialog import CrownChoiceDialog
+from openmolar.qt4gui.dialogs.post_choice_dialog import PostChoiceDialog
 from openmolar.qt4gui.dialogs.implant_choice_dialog import ImplantChoiceDialog
 from openmolar.qt4gui.dialogs.chart_tx_choice_dialog import ChartTxChoiceDialog
 from openmolar.qt4gui.dialogs.bridge_dialog import BridgeDialog
@@ -254,6 +255,7 @@ class ToothPropertyEditingWidget(QtGui.QWidget, Ui_toothProps.Ui_Form):
         self.selectedTooth = ""
         self.comboboxes = []
         self.crown_but = QtGui.QPushButton(_("Crowns"))
+        self.post_but = QtGui.QPushButton(_("Posts"))
         self.bridge_but = QtGui.QPushButton(_("Bridges"))
         self.implant_but = QtGui.QPushButton(_("Implants"))
         self.fs_but = QtGui.QPushButton(_("Fissure Sealants"))
@@ -266,6 +268,7 @@ class ToothPropertyEditingWidget(QtGui.QWidget, Ui_toothProps.Ui_Form):
         vlayout.addWidget(self.fs_but)
         vlayout.addWidget(self.endo_but)
         vlayout.addWidget(self.crown_but)
+        vlayout.addWidget(self.post_but)
         vlayout.addWidget(self.bridge_but)
         vlayout.addWidget(self.surgical_but)
         vlayout.addWidget(self.implant_but)
@@ -325,6 +328,7 @@ class ToothPropertyEditingWidget(QtGui.QWidget, Ui_toothProps.Ui_Form):
         '''
         self.is_Static = arg
         self.comments_comboBox.setEnabled(arg)
+        self.ex_pushButton.setEnabled(not arg)
 
     def comments(self,arg):
         '''
@@ -500,6 +504,12 @@ class ToothPropertyEditingWidget(QtGui.QWidget, Ui_toothProps.Ui_Form):
             self.lineEdit.addItem(dl.chosen_shortcut)
             self.lineEdit.additional()
 
+    def posts(self):
+        dl = PostChoiceDialog(self.is_Static, self.om_gui)
+        if dl.exec_():
+            self.lineEdit.addItem(dl.chosen_shortcut)
+            self.lineEdit.additional()
+
     def bridge(self):
         dl = BridgeDialog(self.om_gui)
         if dl.exec_():
@@ -600,6 +610,7 @@ class ToothPropertyEditingWidget(QtGui.QWidget, Ui_toothProps.Ui_Form):
         QtCore.SIGNAL("currentIndexChanged (const QString&)"), self.comments)
 
         self.crown_but.clicked.connect(self.crown)
+        self.post_but.clicked.connect(self.posts)
         self.bridge_but.clicked.connect(self.bridge)
         self.implant_but.clicked.connect(self.implant_but_clicked)
 
diff --git a/src/openmolar/qt4gui/dialogs/alter_denture_dialog.py b/src/openmolar/qt4gui/dialogs/alter_denture_dialog.py
index f246672..a61a22f 100644
--- a/src/openmolar/qt4gui/dialogs/alter_denture_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/alter_denture_dialog.py
@@ -192,7 +192,7 @@ class PageThree(_OptionPage):
         _OptionPage.__init__(self, parent)
         self.label.setText(_(
         "Please select teeth to be added to this denture"))
-        self.chartwidg = SimpleChartWidg(self)
+        self.chartwidg = SimpleChartWidg(self, auto_ctrl_key=True)
         if parent.is_upper_input:
             self.chartwidg.disable_lowers()
         else:
diff --git a/src/openmolar/qt4gui/dialogs/bridge_dialog.py b/src/openmolar/qt4gui/dialogs/bridge_dialog.py
index cd652a1..dc8987e 100644
--- a/src/openmolar/qt4gui/dialogs/bridge_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/bridge_dialog.py
@@ -31,10 +31,10 @@ from openmolar.qt4gui.dialogs.new_bridge_dialog import NewBridgeDialog
 LOGGER = logging.getLogger("openmolar")
 
 class BridgeDialog(BaseDialog):
-    chosen_treatments = []
     def __init__(self, om_gui = None):
         BaseDialog.__init__(self, om_gui)
 
+        self.chosen_treatments = []
         self.om_gui = om_gui
         message = _("Bridge Treatment Dialog")
         self.setWindowTitle(message)
@@ -94,4 +94,4 @@ if __name__ == "__main__":
     if dl.exec_():
         print dl.chosen_treatments
     else:
-        print "dialog rejected"
\ No newline at end of file
+        print "dialog rejected"
diff --git a/src/openmolar/qt4gui/dialogs/child_smile_dialog.py b/src/openmolar/qt4gui/dialogs/child_smile_dialog.py
index bee6aae..152ea7c 100644
--- a/src/openmolar/qt4gui/dialogs/child_smile_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/child_smile_dialog.py
@@ -57,6 +57,8 @@ EXAMPLE_RESULT = '''
 </html>
 '''
 
+TODAYS_LOOKUPS = {} #{"IV1 1PP": "SIMD Area: 1"}
+
 class ChildSmileDialog(BaseDialog):
     result = ""
     is_checking_website = False
@@ -71,9 +73,24 @@ class ChildSmileDialog(BaseDialog):
         self.simd_label = QtGui.QLabel()
         self.header_label.setAlignment(QtCore.Qt.AlignCenter)
 
+        self.tbi_checkbox = QtGui.QCheckBox(
+            _("ToothBrushing Instruction Given"))
+        self.tbi_checkbox.setChecked(True)
+
+        self.di_checkbox = QtGui.QCheckBox(_("Dietary Advice Given"))
+        self.di_checkbox.setChecked(True)
+
+        self.fl_checkbox = QtGui.QCheckBox(_("Fluoride Varnish Applied"))
+        self.fl_checkbox.setToolTip(
+            _("Fee claimable for patients betwen 2 and 5"))
+        self.fl_checkbox.setChecked(2 <= self.main_ui.pt.ageYears <=5)
+
         self.insertWidget(self.header_label)
         self.insertWidget(self.pcde_le)
         self.insertWidget(self.simd_label)
+        self.insertWidget(self.tbi_checkbox)
+        self.insertWidget(self.di_checkbox)
+        self.insertWidget(self.fl_checkbox)
 
         self.pcde_le.textEdited.connect(self.check_pcde)
 
@@ -116,6 +133,15 @@ class ChildSmileDialog(BaseDialog):
         '''
         poll the server for a simd for a postcode
         '''
+        global TODAYS_LOOKUPS
+        try:
+            self.result = TODAYS_LOOKUPS[self.pcde]
+            self.simd_label.setText(self.result)
+            self.enableApply(True)
+            LOGGER.debug("simd_lookup unnecessary, value known")
+            return
+        except KeyError:
+            pass
         try:
             self.is_checking_website = True
             QtCore.QTimer.singleShot(15000, self.check_hung)
@@ -132,6 +158,7 @@ class ChildSmileDialog(BaseDialog):
             response = urllib2.urlopen(req)
             result = response.read()
             self.result = self._parse_result(result)
+            TODAYS_LOOKUPS[self.pcde] = self.result
             self.simd_label.setText(self.result)
 
             self.enableApply(True)
@@ -153,9 +180,53 @@ class ChildSmileDialog(BaseDialog):
     def simd_number(self):
         return int(re.search("(\d+)", self.result).groups()[0])
 
+    @property
+    def tbi_performed(self):
+        return self.tbi_checkbox.isChecked()
+
+    @property
+    def di_performed(self):
+        return self.di_checkbox.isChecked()
+
+    @property
+    def fl_applied(self):
+        return self.fl_checkbox.isChecked()
+
+    @property
+    def tx_items(self):
+        age = self.main_ui.pt.ageYears
+        dentist = localsettings.clinicianNo in localsettings.dentDict.keys()
+        LOGGER.debug("Performed by dentist = %s"% dentist)
+        if age < 3:
+            if self.simd_number < 4:
+                yield ("other", "CS1")
+            else:
+                yield ("other", "CS2")
+            if self.tbi_performed:
+                code = "TB1" if dentist else "TB2"
+                yield ("other", code)
+            if self.di_performed:
+                code = "DI1" if dentist else "DI2"
+                yield ("other", code)
+        else:
+            if self.simd_number < 4:
+                yield ("other", "CS3")
+            if self.tbi_performed:
+                code = "TB3" if dentist else "TB4"
+                yield ("other", code)
+            if self.di_performed:
+                code = "DI3" if dentist else "DI4"
+                yield ("other", code)
+
+        if 2 <= age <= 5:
+            if self.fl_applied:
+                yield ("other", "CSFL")
+
+
     def exec_(self):
         self.check_pcde()
-        QtCore.QTimer.singleShot(0, self.postcode_warning)
+        QtCore.QTimer.singleShot(100, self.postcode_warning)
+
         if BaseDialog.exec_(self):
             if self.valid_postcode:
                 self.main_ui.pt.pcde = self.pcde
@@ -167,7 +238,7 @@ class ChildSmileDialog(BaseDialog):
 
 
 if __name__ == "__main__":
-
+    LOGGER.setLevel(logging.DEBUG)
     def _mock_function(*args):
         pass
     from collections import namedtuple
@@ -176,13 +247,19 @@ if __name__ == "__main__":
     app = QtGui.QApplication([])
 
     ui = QtGui.QMainWindow()
-    ui.pt = namedtuple("pt",("pcde",))
+    ui.pt = namedtuple("pt",("pcde","ageYears"))
 
     ui.pt.pcde = "Iv1 1P"
+    ui.pt.ageYears = 3
     ui.addNewNote = _mock_function
 
     dl = ChildSmileDialog(ui)
     #print dl._parse_result(EXAMPLE_RESULT)
     if dl.exec_():
         print (dl.result)
-        print (dl.simd_number)
\ No newline at end of file
+        print (dl.simd_number)
+        print ("toothbrush instruction = %s"% dl.tbi_performed)
+        print ("dietary advice = %s"% dl.di_performed)
+
+        for item in dl.tx_items:
+            print item
\ No newline at end of file
diff --git a/src/openmolar/qt4gui/dialogs/document_dialog.py b/src/openmolar/qt4gui/dialogs/document_dialog.py
new file mode 100644
index 0000000..38d45e8
--- /dev/null
+++ b/src/openmolar/qt4gui/dialogs/document_dialog.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+###############################################################################
+##                                                                           ##
+##  Copyright 2014 Neil Wallace <neil at openmolar.com>                         ##
+##                                                                           ##
+##  This program is free software: you can redistribute it and/or modify     ##
+##  it under the terms of the GNU General Public License as published by     ##
+##  the Free Software Foundation, either version 3 of the License, or        ##
+##  (at your option) any later version.                                      ##
+##                                                                           ##
+##  This program is distributed in the hope that it will be useful,          ##
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of           ##
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            ##
+##  GNU General Public License for more details.                             ##
+##                                                                           ##
+##  You should have received a copy of the GNU General Public License        ##
+##  along with this program.  If not, see <http://www.gnu.org/licenses/>.    ##
+##                                                                           ##
+###############################################################################
+
+import logging
+import os
+
+from PyQt4 import QtGui, QtCore
+
+from openmolar.settings import localsettings, urls
+from openmolar.qt4gui.dialogs.base_dialogs import ExtendableDialog
+
+from xml.dom import minidom
+
+LOGGER = logging.getLogger("openmolar")
+
+def _null_func():
+    return None
+
+class _FileListWidget(QtGui.QScrollArea):
+    def __init__(self, files, parent=None):
+        assert files != [], "no files passed to FileListWidget"
+        QtGui.QScrollArea.__init__(self, parent)
+        self.files = files
+        self.labels = files
+        self.radio_buts = []
+        self.layout_widgets()
+        self.radio_buts[0].setChecked(True)
+
+    def layout_widgets(self):
+        frame = QtGui.QFrame(self)
+        layout = QtGui.QVBoxLayout(frame)
+        self.setWidget(frame)
+        self.setWidgetResizable(True)
+        for file_ in self.files:
+            rb = QtGui.QRadioButton(file_)
+            layout.addWidget(rb)
+            self.radio_buts.append(rb)
+
+    def selected_file(self):
+        for i, rb in enumerate(self.radio_buts):
+            if rb.isChecked():
+                return self.files[i]
+
+    def sizeHint(self):
+        return QtCore.QSize(200,400)
+
+class _LabelledFileListWidget(_FileListWidget):
+    def __init__(self, nodelist, parent=None):
+        QtGui.QScrollArea.__init__(self, parent)
+        self.files = []
+        self.labels = []
+        self.radio_buts = []
+        for doc_node in nodelist:
+            self.files.append(doc_node.getAttribute("filename"))
+            self.labels.append(doc_node.getAttribute("title"))
+        assert self.files != [], "no files passed to _LabelledFileListWidget"
+        self.layout_widgets()
+
+class DocumentDialog(ExtendableDialog):
+    def __init__(self, parent=None):
+        ExtendableDialog.__init__(self, parent, remove_stretch=True)
+
+        title = _("Openmolar Documents Dialog")
+        self.setWindowTitle(title)
+        label = QtGui.QLabel("<b>%s</b>"% _("Please choose a document to open"))
+        label.setAlignment(QtCore.Qt.AlignCenter)
+
+        self.chosen_document = None
+
+        message = '<p>%s<br /><a href="%s">%s</a></p>'% (
+             _("For help configuring this feature, see"),
+             urls.DOCUMENT_HELP, urls.DOCUMENT_HELP)
+
+        advanced_label = QtGui.QLabel(message)
+        advanced_label.setOpenExternalLinks(True)
+        self.add_advanced_widget(advanced_label)
+
+        files = os.listdir(localsettings.DOCS_DIRECTORY)
+
+        if files == []:
+            widg = QtGui.QLabel("<p>%s %s</p><hr />%s"% (
+            _("You have no documents stored in"),
+            localsettings.DOCS_DIRECTORY, message))
+            widg.setAlignment(QtCore.Qt.AlignCenter)
+            widg.setOpenExternalLinks(True)
+            widg.selected_file = _null_func
+
+        elif "docs.xml" in files:
+            dom = None
+            try:
+                control_f = os.path.join(
+                    localsettings.DOCS_DIRECTORY, "docs.xml")
+                dom = minidom.parse(control_f)
+                doc_node = dom.getElementsByTagName("documents")[0]
+                widg = QtGui.QTabWidget()
+                for group in doc_node.getElementsByTagName("group"):
+                    docs = group.getElementsByTagName("document")
+                    group_widg = _LabelledFileListWidget(docs)
+                    tab = widg.addTab(group_widg, group.getAttribute("heading"))
+                    group_widg.radio_buts[0].setChecked(True)
+                widg.selected_file = widg.currentWidget().selected_file
+            except:
+                LOGGER.exception("unable to parse '%s'"% control_f)
+                widg = QtGui.QLabel(_("docs.xml is not parseable"))
+
+        else:
+            #self.remove_spacer()
+            widg = _FileListWidget(files)
+
+        self.enableApply(bool(widg.selected_file()))
+        self.insertWidget(label)
+        self.insertWidget(widg)
+        self._widg = widg
+
+    @property
+    def widg(self):
+        try:
+            return self._widg.currentWidget()
+        except AttributeError:
+            return self._widg
+
+    def sizeHint(self):
+        return QtCore.QSize(400,350)
+
+    def _open_document(self):
+        '''
+        open the chosen document
+        '''
+        doc = self.widg.selected_file()
+        if doc is None:
+            return
+        try:
+            doc = os.path.abspath(
+            os.path.join(localsettings.DOCS_DIRECTORY, doc))
+            LOGGER.info("opening %s"% doc)
+            localsettings.openPDF(doc)
+        except Exception as exc:
+            message = _("Error opening PDF file")
+            LOGGER.exception(message)
+            self.parent().advise(message, 2)
+
+    def exec_(self):
+        if ExtendableDialog.exec_(self):
+            self._open_document()
+            return True
+        return False
+
+
+if __name__ == "__main__":
+    app = QtGui.QApplication([])
+    def advise(message, severity):
+        QtGui.QMessageBox.information(dl, "message", message)
+    
+    mw = QtGui.QWidget()
+    dl = DocumentDialog(mw)
+    dl.exec_()
diff --git a/src/openmolar/qt4gui/dialogs/new_bridge_dialog.py b/src/openmolar/qt4gui/dialogs/new_bridge_dialog.py
index f9ac8e4..f7a4012 100644
--- a/src/openmolar/qt4gui/dialogs/new_bridge_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/new_bridge_dialog.py
@@ -163,7 +163,7 @@ class PageThree(_OptionPage):
         self.dl = parent
         self.label.setText(_(
         "Please select teeth which are to be used as retainers"))
-        self.chartwidg = SimpleChartWidg(self)
+        self.chartwidg = SimpleChartWidg(self, auto_ctrl_key=True)
         layout = QtGui.QVBoxLayout(self.frame)
         layout.addWidget(self.chartwidg)
 
@@ -188,7 +188,7 @@ class PageFour(_OptionPage):
         self.dl = parent
         self.label.setText(_(
         "Please select teeth which are to be used as pontics"))
-        self.chartwidg = SimpleChartWidg(self)
+        self.chartwidg = SimpleChartWidg(self, auto_ctrl_key=True)
         layout = QtGui.QVBoxLayout(self.frame)
         layout.addWidget(self.chartwidg)
 
@@ -216,10 +216,10 @@ class AcceptPage(_OptionPage):
         self.frame.hide()
 
 class NewBridgeDialog(ExtendableDialog):
-    chosen_properties = {}
     def __init__(self, om_gui = None):
         ExtendableDialog.__init__(self, om_gui)
 
+        self.chosen_properties = {}
         self.om_gui = om_gui
         message = (_("Chart/Plan a Bridge"))
         self.setWindowTitle(message)
diff --git a/src/openmolar/qt4gui/dialogs/new_denture_dialog.py b/src/openmolar/qt4gui/dialogs/new_denture_dialog.py
index 91d5720..9a1d44f 100644
--- a/src/openmolar/qt4gui/dialogs/new_denture_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/new_denture_dialog.py
@@ -171,7 +171,7 @@ class PageThree(_OptionPage):
         self.dl = parent
         self.label.setText(_(
         "Please select teeth which this denture is to replace"))
-        self.chartwidg = SimpleChartWidg(self)
+        self.chartwidg = SimpleChartWidg(self, auto_ctrl_key=True)
         layout = QtGui.QVBoxLayout(self.frame)
         layout.addWidget(self.chartwidg)
 
diff --git a/src/openmolar/qt4gui/dialogs/post_choice_dialog.py b/src/openmolar/qt4gui/dialogs/post_choice_dialog.py
new file mode 100644
index 0000000..add085a
--- /dev/null
+++ b/src/openmolar/qt4gui/dialogs/post_choice_dialog.py
@@ -0,0 +1,108 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+###############################################################################
+##                                                                           ##
+##  Copyright 2013, Neil Wallace <rowinggolfer at googlemail.com>               ##
+##                                                                           ##
+##  This program is free software: you can redistribute it and/or modify     ##
+##  it under the terms of the GNU General Public License as published by     ##
+##  the Free Software Foundation, either version 3 of the License, or        ##
+##  (at your option) any later version.                                      ##
+##                                                                           ##
+##  This program is distributed in the hope that it will be useful,          ##
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of           ##
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            ##
+##  GNU General Public License for more details.                             ##
+##                                                                           ##
+##  You should have received a copy of the GNU General Public License        ##
+##  along with this program.  If not, see <http://www.gnu.org/licenses/>.    ##
+##                                                                           ##
+###############################################################################
+
+from collections import namedtuple
+from functools import partial
+
+from PyQt4 import QtCore, QtGui
+
+from openmolar.settings import localsettings
+from openmolar.qt4gui.dialogs.base_dialogs import ExtendableDialog
+
+PostChartButton = namedtuple('PostChartButton',
+    ("shortcut", "description", "tooltip"))
+
+STATIC_LIST = []
+for shortcut, description in (
+("CR,C1", _("Cast Precious Metal")),
+("CR,C2", _("Cast Non-Precious Metal")),
+("CR,OP", _("Other")),
+):
+    pcb = PostChartButton(shortcut, description, "")
+    STATIC_LIST.append(pcb)
+
+class PostChoiceDialog(ExtendableDialog):
+    def __init__(self, static, parent=None):
+        ExtendableDialog.__init__(self, parent, remove_stretch=True)
+        self.setWindowTitle(_("Post Choice Dialog"))
+        self.om_gui = parent
+        self.chosen_shortcut = None
+
+        scroll_area = QtGui.QScrollArea()
+        frame = QtGui.QFrame()
+        scroll_area.setWidget(frame)
+        scroll_area.setWidgetResizable(True)
+        self.but_layout = QtGui.QGridLayout(frame)
+        self.insertWidget(scroll_area)
+
+        self.apply_but.hide()
+
+        if static:
+            self.more_but.hide()
+            self.add_buttons(STATIC_LIST)
+        else:
+            all_posts_but = QtGui.QPushButton(
+            _("Show Post types from all feescales"))
+            all_posts_but.clicked.connect(self._show_all_posts)
+            self.add_advanced_widget(all_posts_but)
+
+            self.add_buttons(
+                self.om_gui.pt.fee_table.ui_lists["post_buttons"])
+
+    def sizeHint(self):
+        return QtCore.QSize(400, 500)
+
+    def add_buttons(self, post_chart_buttons):
+        while self.but_layout.count():
+            widget_item = self.but_layout.takeAt(0)
+            widget_item.widget().setParent(None)
+        row = 0
+        for row, post_button in enumerate(post_chart_buttons):
+            but = QtGui.QPushButton(post_button.description)
+            but.setToolTip(post_button.tooltip)
+            but.clicked.connect(
+                partial(self.but_clicked, post_button.shortcut))
+            self.but_layout.addWidget(but, row//2, row%2)
+        self.but_layout.setRowStretch((row+2)//2,100)
+
+    def _show_all_posts(self):
+        self.add_buttons(localsettings.FEETABLES.ui_post_chart_buttons)
+        self.hide_extension()
+
+    def but_clicked(self, shortcut):
+        self.chosen_shortcut = shortcut
+        self.accept()
+
+if __name__ == "__main__":
+    from gettext import gettext as _
+    from openmolar.dbtools.patient_class import patient
+
+    app = QtGui.QApplication([])
+    mw = QtGui.QWidget()
+    mw.pt = patient(11956)
+    dl = PostChoiceDialog(True, mw)
+    if dl.exec_():
+        print dl.chosen_shortcut
+    localsettings.loadFeeTables()
+    dl = PostChoiceDialog(False, mw)
+    if dl.exec_():
+        print dl.chosen_shortcut
\ No newline at end of file
diff --git a/src/openmolar/qt4gui/fees/fees_module.py b/src/openmolar/qt4gui/fees/fees_module.py
index 8353ac7..a7f4789 100644
--- a/src/openmolar/qt4gui/fees/fees_module.py
+++ b/src/openmolar/qt4gui/fees/fees_module.py
@@ -33,7 +33,6 @@ from openmolar.qt4gui.feescale_editor import FeescaleEditor
 from openmolar.qt4gui.printing import om_printing
 from openmolar.qt4gui.dialogs import permissions
 from openmolar.qt4gui.dialogs.payment_dialog import PaymentDialog
-from openmolar.qt4gui.compiled_uis import Ui_chooseDocument
 
 LOGGER = logging.getLogger("openmolar")
 
@@ -268,68 +267,6 @@ def feeSearch(om_gui):
             message += " " + _("usercodes or descriptions")
         om_gui.advise(message, 1)
 
-def nhsRegsPDF(om_gui):
-    '''
-    I have some stored PDF documents
-    the user wants to see these
-    '''
-    Dialog = QtGui.QDialog(om_gui)
-    dl = Ui_chooseDocument.Ui_Dialog()
-    dl.setupUi(Dialog)
-    if Dialog.exec_():
-        if dl.tabWidget.currentIndex() == 0:
-            if dl.info_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "Dental_Information_Guide_2008_v4.pdf")
-            else:
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "scotNHSremuneration08.pdf")
-        elif dl.tabWidget.currentIndex() == 1:
-            if dl.info2009_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "Dental_Information_Guide_2009.pdf")
-            else:
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "scotNHSremuneration09.pdf")
-        elif dl.tabWidget.currentIndex() == 2:
-            if dl.info2010_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "information_guide_2010_v2.pdf")
-            else:
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "scotNHSremuneration10.pdf")
-        elif dl.tabWidget.currentIndex() == 3:
-            if dl.info2012_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "information-guide-2012-final.pdf")
-            elif dl.terms_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "ssi_20100208_en.pdf")
-            else:
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "scotNHSremuneration12.pdf")
-        else:
-            if dl.info2013_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "information-guide-2012-final.pdf")
-            elif dl.tooth_specific_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "guidance-issue-2-v17.pdf")
-            elif dl.terms2013_radioButton.isChecked():
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "ssi_20100208_en.pdf")
-            else:
-                doc = os.path.join(localsettings.wkdir, 'resources',
-                "scotNHSremuneration13.pdf")
-
-        try:
-            print "opening %s"% doc
-            localsettings.openPDF(doc)
-        except Exception as exc:
-            message = _("Error opening PDF file")
-            LOGGER.exception(message)
-            om_gui.advise(message, 2)
-
 def chooseFeescale(om_gui, i):
     '''
     receives signals from the choose feescale combobox
diff --git a/src/openmolar/qt4gui/fees/manipulate_plan.py b/src/openmolar/qt4gui/fees/manipulate_plan.py
index abc36f6..944e568 100644
--- a/src/openmolar/qt4gui/fees/manipulate_plan.py
+++ b/src/openmolar/qt4gui/fees/manipulate_plan.py
@@ -321,7 +321,8 @@ def plan_viewer_context_menu(om_gui, att, values, point):
     provides and handles a context menu for the ui.plan_listView and
     the ui.planChartWidget
     '''
-    qmenu = QtGui.QMenu(om_gui)
+    if len(values) == 0:
+        return
 
     if len(values) > 1:
         treatments = []
@@ -330,6 +331,7 @@ def plan_viewer_context_menu(om_gui, att, values, point):
         complete_txs(om_gui, treatments, confirm_multiples=True)
         return
 
+    qmenu = QtGui.QMenu(om_gui)
     value = values[0]
     message = "%s %s %s"% (_("Complete"), att, value)
     complete_action = QtGui.QAction(message, om_gui)
@@ -357,7 +359,8 @@ def cmp_viewer_context_menu(om_gui, att, values, point):
     provides and handles a context menu for the ui.completed_listView and
     the ui.completedChartWidget
     '''
-    qmenu = QtGui.QMenu(om_gui)
+    if len(values) == 0:
+        return
 
     if len(values) > 1:
         treatments = []
@@ -366,6 +369,7 @@ def cmp_viewer_context_menu(om_gui, att, values, point):
         reverse_txs(om_gui, treatments, confirm_multiples=True)
         return
 
+    qmenu = QtGui.QMenu(om_gui)
     value = values[0]
 
     if att == "exam":
diff --git a/src/openmolar/qt4gui/maingui.py b/src/openmolar/qt4gui/maingui.py
index 5919f0d..f5500e8 100755
--- a/src/openmolar/qt4gui/maingui.py
+++ b/src/openmolar/qt4gui/maingui.py
@@ -85,6 +85,7 @@ from openmolar.qt4gui.dialogs.nhs_forms_config_dialog \
     import NHSFormsConfigDialog
 from openmolar.qt4gui.dialogs.advanced_tx_planning_dialog \
     import AdvancedTxPlanningDialog
+from openmolar.qt4gui.dialogs.document_dialog import DocumentDialog
 
 #secondary applications
 from openmolar.qt4gui.tools import new_setup
@@ -1869,11 +1870,12 @@ class OpenmolarGui(QtGui.QMainWindow):
         '''
         fees_module.feetester(self)
 
-    def nhsRegs_pushButton_clicked(self):
+    def documents_pushButton_clicked(self):
         '''
         user should be offered a PDF of the current regulations
         '''
-        fees_module.nhsRegsPDF(self)
+        dl = DocumentDialog()
+        dl.exec_()
 
     def feeScale_clicked(self, model_index):
         '''
@@ -2449,7 +2451,8 @@ class OpenmolarGui(QtGui.QMainWindow):
         A function to implement NHS Scotland's Childsmile.
         '''
         dl = ChildSmileDialog(self)
-        dl.exec_()
+        if dl.exec_():
+            manipulate_plan.add_treatments_to_plan(self, dl.tx_items, True)
 
     def notes_link_clicked(self, url):
         url_text = url.toString()
@@ -2551,6 +2554,8 @@ class OpenmolarGui(QtGui.QMainWindow):
         QtCore.SIGNAL("clicked()"), self.childsmile_button_clicked)
 
         self.ui.actionSurgery_Mode.toggled.connect(self.set_surgery_mode)
+        self.ui.actionDocuments_Dialog.triggered.connect(
+            self.documents_pushButton_clicked)
 
     def signals_admin(self):
         #admin frame
@@ -2932,8 +2937,8 @@ class OpenmolarGui(QtGui.QMainWindow):
         QtCore.QObject.connect(self.ui.feeCompress_radioButton,
         QtCore.SIGNAL("clicked()"), self.feeExpand_radiobuttons_clicked)
 
-        QtCore.QObject.connect(self.ui.nhsRegs_pushButton,
-        QtCore.SIGNAL("clicked()"), self.nhsRegs_pushButton_clicked)
+        self.ui.documents_pushButton.clicked.connect(
+            self.documents_pushButton_clicked)
 
         QtCore.QObject.connect(self.ui.feeSearch_lineEdit,
         QtCore.SIGNAL("returnPressed()"), self.feeSearch_lineEdit_edited)
@@ -3085,6 +3090,10 @@ class OpenmolarGui(QtGui.QMainWindow):
         Adds ALL tooth items to the estimate.
         prompts the user to confirm tooth treatment fees
         '''
+        if not self.pt.underTreatment:
+            self.advise(
+            _("Recalculate Estimate is for active courses only"), 1)
+            return
         result=QtGui.QMessageBox.question(self, "Confirm",
         u"%s<hr /><i>(%s)</i>"% (
         _("Scrap the estimate and re-price everything?"),
diff --git a/src/openmolar/qt4gui/printing/bulk_mail.py b/src/openmolar/qt4gui/printing/bulk_mail.py
index 8a57cfb..21d0714 100644
--- a/src/openmolar/qt4gui/printing/bulk_mail.py
+++ b/src/openmolar/qt4gui/printing/bulk_mail.py
@@ -8,10 +8,13 @@
 
 from __future__ import division
 
+import logging
 import os
 import re
 import sys
 
+LOGGER = logging.getLogger("openmolar")
+
 from PyQt4 import QtCore, QtGui
 
 from openmolar.settings import localsettings
@@ -27,7 +30,7 @@ _("We are writing to inform you that your dental examination is now due."),
 _("Please contact the surgery to arrange an appointment. *")
 )
 
-FAMILY_BODY = '''%s\n\n%s'''%(
+FAMILY_BODY = '''%s\n%s'''%(
 _("We are writing to inform you that your dental examinations are now due."),
 _("Please contact the surgery to arrange suitable appointments. *"),
 )
@@ -41,34 +44,45 @@ please accept our apologies and ignore this letter.''')
 
 
 try:
-    f = open(os.path.join(
-        localsettings.localFileDirectory, "recall_footer.txt"), "r")
-    PROMO_TEXT = f.read()
+    filepath = os.path.join(localsettings.localFileDirectory,
+        "recall_footer.txt")
+    f = open(filepath, "r")
+    CUSTOM_TEXT = f.read()
     f.close()
 except IOError:
-    print "no recall footer found"
-    PROMO_TEXT= ""
+    LOGGER.warning("no recall footer found in '%s'"% filepath)
+    CUSTOM_TEXT= ""
+
+try:
+    filepath = os.path.join(localsettings.localFileDirectory,
+        "recall_postscript.txt")
+    f = open(filepath, "r")
+    PS_TEXT = f.read()
+    f.close()
+except IOError:
+    LOGGER.exception("no recall ps found in %s"% filepath)
+    PS_TEXT= ""
 
 
 class OMLetter(object):
     def __init__(self, recipients):
         self.recipients = recipients
-        
-    
+
+
     @property
     def head(self):
         return self.recipients[0]
-    
+
     @property
     def recd(self):
         return self.head.recd
-    
+
     @property
     def _topline(self):
         head = self.head
         line_ = u"%s %s %s"% (
             head.title,
-            head.fname.strip(), 
+            head.fname.strip(),
             head.sname.strip()
             )
         for r in self.recipients[1:]:
@@ -80,65 +94,65 @@ class OMLetter(object):
         if ", " in line_:
             i = line_.rindex(", ")
             line_ = "%s and%s"% (line_[:i], line_[i+1:])
-        
+
         return line_
-    
+
     @property
     def address(self):
         head = self.head
-            
+
         address_ = u'%s\n%s\n%s\n%s\n%s\n%s\n%s'% (
             self._topline,
-            head.addr1.title(), 
+            head.addr1.title(),
             head.addr2.title(),
-            head.addr3.title(), 
+            head.addr3.title(),
             head.town,
-            head.county, 
+            head.county,
             head.pcde)
 
         while re.search(" *\n *\n", address_):
             address_ = re.sub(" *\n\n", "\n", address_)
-        
+
         return address_
-    
+
     @property
     def subjects(self):
         subjects_ = []
         for r in self.recipients:
             subjects_.append("%s %s %s - %s %s"% (
-                r.title, r.fname, r.sname, 
+                r.title, r.fname, r.sname,
                 _("our ref"), r.serialno))
         return subjects_
-    
+
     @property
     def subject_text(self):
         text = ""
         for subject in self.subjects:
             text += "%s\n"% subject
         return text
-    
+
     @property
     def is_family(self):
         return len(self.recipients) > 1
-    
+
     @property
     def salutation(self):
-        
+
         if self.is_family:
             salut_ = _("Patients")
         elif self.head.age < 18:
             salut_ = self.head.fname
         else:
             salut_ = "%s %s"% (self.head.title, self.head.sname.strip())
-            
+
         return u"%s %s,"% (SALUTATION, salut_)
-    
+
     @property
     def text(self):
         if self.is_family:
             return FAMILY_BODY
         return BODY
-        
+
 class TreeItem(object):
     def __init__(self, data, parent=None):
         self.parentItem = parent
@@ -407,7 +421,10 @@ class bulkMails(object):
         font = QtGui.QFont("Sans", 11)
         fm = QtGui.QFontMetrics(font)
         line_height = fm.height()
-        
+
+        italic_font = QtGui.QFont(font)
+        italic_font.setItalic(True)
+
         sigFont = QtGui.QFont("URW Chancery L",15)
         sigFont.setBold(True)
         sig_font_height = QtGui.QFontMetrics(sigFont).height()*1.2
@@ -417,20 +434,20 @@ class bulkMails(object):
 
         LEFT = 60
         RIGHT = 80
-        TOP = 130
+        TOP = 170
         RECT_WIDTH = pageRect.width() - (LEFT + RIGHT)
 
-        ADDRESS_LEFT = 100
-        ADDRESS_HEIGHT = 100
+        ADDRESS_LEFT = 80
+        ADDRESS_HEIGHT = 140
         FOOTER_HEIGHT = 150
-        DATE_HEIGHT = 3 * line_height
+        DATE_HEIGHT = 1 * line_height
         BODY_HEIGHT = pageRect.height() - (
             TOP + ADDRESS_HEIGHT + FOOTER_HEIGHT + DATE_HEIGHT)
 
         addressRect = QtCore.QRectF(ADDRESS_LEFT, TOP,
                                     300, ADDRESS_HEIGHT)
 
-        dateRect = QtCore.QRectF(LEFT, addressRect.bottom(), 
+        dateRect = QtCore.QRectF(LEFT, addressRect.bottom(),
             RECT_WIDTH, DATE_HEIGHT)
 
         bodyRect = QtCore.QRectF(LEFT, dateRect.bottom(),
@@ -468,9 +485,9 @@ class bulkMails(object):
             ##address
             painter.drawText(addressRect, letter.address, option)
             if DEBUG:
-                painter.drawRect(addressRect)
+                painter.drawRect(addressRect.adjusted(2,2,-2,-2))
             ##date
-            
+
             if self.use_given_recall_date:
                 pdate = letter.recd
             else:
@@ -482,96 +499,108 @@ class bulkMails(object):
                 pdate_str = "%s %s"% (localsettings.monthName(pdate),
                 pdate.year)
 
-            painter.drawText(dateRect, pdate_str, 
+            painter.drawText(dateRect, pdate_str,
                 QtGui.QTextOption(QtCore.Qt.AlignRight))
             if DEBUG:
-                painter.drawRect(dateRect)
-
+                painter.drawRect(dateRect.adjusted(2,2,-2,-2))
             ##salutation
             rect = bodyRect.adjusted(
                 0, 0, 0, 2*line_height- bodyRect.height())
             painter.drawText(rect, letter.salutation, option)
             if DEBUG:
-                painter.drawRect(rect)
-            
+                painter.drawRect(rect.adjusted(2,2,-2,-2))
+
             ##subject
-            option = QtGui.QTextOption(QtCore.Qt.AlignCenter)
+            #option = QtGui.QTextOption(QtCore.Qt.AlignCenter)
             font.setBold(True)
             painter.setFont(font)
-            subject_count = len(letter.subjects) + 1            
+            subject_count = len(letter.subjects) + 1
             rect = QtCore.QRectF(
                 rect.bottomLeft().x(), rect.bottomLeft().y(),
                 bodyRect.width(), line_height * subject_count)
-            painter.drawText(rect, letter.subject_text, option)
+
+            subj_rect = rect.adjusted(50,0,-50,0)
+            painter.drawText(subj_rect, letter.subject_text, option)
             if DEBUG:
-                painter.drawRect(rect)
+                painter.drawRect(subj_rect.adjusted(2,2,-2,-2))
             font.setBold(False)
             painter.setFont(font)
-            
+
             ##body
-            option = QtGui.QTextOption(QtCore.Qt.AlignLeft)
-            line_count = letter.text.count("\n")+3            
+            line_count = letter.text.count("\n")+3
             body_rect = QtCore.QRectF(
-                rect.bottomLeft().x(), rect.bottomLeft().y(),
+                rect.bottomLeft().x(), subj_rect.bottomLeft().y(),
                 bodyRect.width(), line_height * line_count)
-            
+
             painter.drawText(body_rect, letter.text, option)
             if DEBUG:
-                painter.drawRect(body_rect)
+                painter.drawRect(body_rect.adjusted(2,2,-2,-2))
 
-            ##signature
-            #place signature immediately after the body text (which will vary)
-            
-            sigRect = QtCore.QRectF(
+            ##custom
+            line_count = CUSTOM_TEXT.count("\n") + 5
+            custom_rect = QtCore.QRectF(
                 body_rect.bottomLeft().x(), body_rect.bottomLeft().y(),
-                body_rect.width(), line_height * 2)
-            painter.drawText(sigRect, SIGN_OFF, option)
+                bodyRect.width(), line_height * line_count)
+
+            painter.setFont(font)
+            painter.drawText(custom_rect, CUSTOM_TEXT, option)
+
+            if DEBUG:
+                painter.drawRect(custom_rect.adjusted(2,2,-2,-2))
+
+            ##signature
+            #place signature immediately after the body
+            # + custom text (which will vary)
+
+            sign_off_rect = QtCore.QRectF(
+                custom_rect.bottomLeft().x(), custom_rect.bottomLeft().y(),
+                body_rect.width(), line_height * 1.5)
+            painter.drawText(sign_off_rect, SIGN_OFF, option)
             if DEBUG:
-                painter.drawRect(sigRect)
+                painter.drawRect(sign_off_rect.adjusted(2,2,-2,-2))
 
-            sigRect = sigRect.adjusted(0, sigRect.height(), 0, sig_font_height)
+            sig_rect = sign_off_rect.adjusted(
+                20, sign_off_rect.height(), 0, sig_font_height)
+            painter.save()
             painter.setFont(sigFont)
-            painter.drawText(sigRect, SIGNATURE, option)
+            painter.drawText(sig_rect, SIGNATURE, option)
             if DEBUG:
-                painter.drawRect(sigRect)
-            
-            option = QtGui.QTextOption(QtCore.Qt.AlignVCenter)
-            
-            ##promo
-            promoRect = QtCore.QRectF(
-                QtCore.QPointF(
-                    sigRect.bottomLeft().x(), sigRect.bottomLeft().y()),
-                QtCore.QPointF(
-                    footerRect.topRight().x(), footerRect.topRight().y())
-                )
-            promoRect = promoRect.adjusted(50, 30, -50, -30)
+                painter.drawRect(sig_rect.adjusted(2,2,-2,-2))
+            painter.restore()
+
+            ##ps
+            line_count = PS_TEXT.count("\n")+2
+            ps_rect = QtCore.QRectF(
+                body_rect.bottomLeft().x(),
+                sig_rect.bottomLeft().y() + line_height,
+                bodyRect.width(), line_height * line_count)
+
             painter.setFont(font)
-            painter.drawText(promoRect, PROMO_TEXT, option)
-            promoRect = promoRect.adjusted(-10, -10, 10, 10)
-            
-            #if DEBUG:
-            painter.drawRect(promoRect)
-            
+            painter.drawText(ps_rect, PS_TEXT, option)
+
+            if DEBUG:
+                painter.drawRect(ps_rect.adjusted(2,2,-2,-2))
+
+            ##footer
             option = QtGui.QTextOption(QtCore.Qt.AlignCenter)
             option.setWrapMode(QtGui.QTextOption.WordWrap)
-            
-            ##footer
+
             painter.drawLine(footerRect.topLeft(), footerRect.topRight())
-            font.setItalic(True)
-            painter.setFont(font)
+            painter.setFont(italic_font)
 
             painter.drawText(footerRect, FOOTER, option)
             if DEBUG:
-                painter.drawRect(footerRect)
+                painter.drawRect(footerRect.adjusted(2,2,-2,-2))
 
             ##fold marks
+            pen = QtGui.QPen(QtGui.QBrush(QtCore.Qt.black),3)
+            painter.setPen(pen)
             top_fold_y = pageRect.height()/3
             painter.drawLine(0, top_fold_y, 10, top_fold_y)
 
             top_fold_y = pageRect.height()*2/3
             painter.drawLine(0, top_fold_y, 10, top_fold_y)
 
-
             painter.restore()
 
 if __name__ == "__main__":
diff --git a/src/openmolar/resources/Dental_Information_Guide_2008_v4.pdf b/src/openmolar/resources/Dental_Information_Guide_2008_v4.pdf
deleted file mode 100644
index 00bdd6f..0000000
Binary files a/src/openmolar/resources/Dental_Information_Guide_2008_v4.pdf and /dev/null differ
diff --git a/src/openmolar/resources/Dental_Information_Guide_2009.pdf b/src/openmolar/resources/Dental_Information_Guide_2009.pdf
deleted file mode 100644
index e91190d..0000000
Binary files a/src/openmolar/resources/Dental_Information_Guide_2009.pdf and /dev/null differ
diff --git a/src/openmolar/resources/guidance-issue-2-v17.pdf b/src/openmolar/resources/guidance-issue-2-v17.pdf
deleted file mode 100644
index 5671939..0000000
Binary files a/src/openmolar/resources/guidance-issue-2-v17.pdf and /dev/null differ
diff --git a/src/openmolar/resources/information-guide-2012-final.pdf b/src/openmolar/resources/information-guide-2012-final.pdf
deleted file mode 100644
index 5ae8189..0000000
Binary files a/src/openmolar/resources/information-guide-2012-final.pdf and /dev/null differ
diff --git a/src/openmolar/resources/information_guide_2010_v2.pdf b/src/openmolar/resources/information_guide_2010_v2.pdf
deleted file mode 100644
index cce9890..0000000
Binary files a/src/openmolar/resources/information_guide_2010_v2.pdf and /dev/null differ
diff --git a/src/openmolar/resources/scotNHSremuneration08.pdf b/src/openmolar/resources/scotNHSremuneration08.pdf
deleted file mode 100755
index a0f2ab6..0000000
Binary files a/src/openmolar/resources/scotNHSremuneration08.pdf and /dev/null differ
diff --git a/src/openmolar/resources/scotNHSremuneration09.pdf b/src/openmolar/resources/scotNHSremuneration09.pdf
deleted file mode 100644
index 6e7a217..0000000
Binary files a/src/openmolar/resources/scotNHSremuneration09.pdf and /dev/null differ
diff --git a/src/openmolar/resources/scotNHSremuneration10.pdf b/src/openmolar/resources/scotNHSremuneration10.pdf
deleted file mode 100644
index d81ae42..0000000
Binary files a/src/openmolar/resources/scotNHSremuneration10.pdf and /dev/null differ
diff --git a/src/openmolar/resources/scotNHSremuneration12.pdf b/src/openmolar/resources/scotNHSremuneration12.pdf
deleted file mode 100644
index 3ec98bc..0000000
Binary files a/src/openmolar/resources/scotNHSremuneration12.pdf and /dev/null differ
diff --git a/src/openmolar/resources/scotNHSremuneration13.pdf b/src/openmolar/resources/scotNHSremuneration13.pdf
deleted file mode 100644
index 0a9c5f2..0000000
Binary files a/src/openmolar/resources/scotNHSremuneration13.pdf and /dev/null differ
diff --git a/src/openmolar/resources/ssi_20100208_en.pdf b/src/openmolar/resources/ssi_20100208_en.pdf
deleted file mode 100644
index c377d0d..0000000
Binary files a/src/openmolar/resources/ssi_20100208_en.pdf and /dev/null differ
diff --git a/src/openmolar/settings/fee_tables.py b/src/openmolar/settings/fee_tables.py
index 47b1a3e..a73e5bc 100644
--- a/src/openmolar/settings/fee_tables.py
+++ b/src/openmolar/settings/fee_tables.py
@@ -82,6 +82,7 @@ class FeeTables(object):
         self.tables = OrderedDict()
         self.warnings = []
         self._ui_crown_chart_buttons = None
+        self._ui_post_chart_buttons = None
         self._ui_implant_chart_buttons = None
         self._ui_fs_chart_buttons = None
         self._ui_endo_chart_buttons = None
@@ -127,6 +128,15 @@ class FeeTables(object):
         return self._ui_crown_chart_buttons
 
     @property
+    def ui_post_chart_buttons(self):
+        '''
+        A list of unique post types from all tables.
+        '''
+        if self._ui_post_chart_buttons is None:
+            self._ui_post_chart_buttons = self.get_all_buts("post_buttons")
+        return self._ui_post_chart_buttons
+
+    @property
     def ui_implant_chart_buttons(self):
         '''
         A list of unique implant types from all tables.
@@ -233,7 +243,8 @@ class FeeTable(object):
             "implant_buttons":[],
             "fs_buttons":[],
             "endo_buttons":[],
-            "surgical_buttons":[]
+            "surgical_buttons":[],
+            "post_buttons":[],
             }
 
     def __repr__(self):
@@ -370,6 +381,9 @@ class FeeTable(object):
         for button in self.get_ui_buttons("crown_chart_button"):
             self.ui_lists["crown_buttons"].append(button)
 
+        for button in self.get_ui_buttons("post_chart_button"):
+            self.ui_lists["post_buttons"].append(button)
+
         for button in self.get_ui_buttons("fs_chart_button"):
             self.ui_lists["fs_buttons"].append(button)
 
diff --git a/src/openmolar/settings/localsettings.py b/src/openmolar/settings/localsettings.py
index 1daa25b..67874d1 100644
--- a/src/openmolar/settings/localsettings.py
+++ b/src/openmolar/settings/localsettings.py
@@ -141,8 +141,12 @@ else:
     global_cflocation = '/etc/openmolar/openmolar.conf'
     localFileDirectory = os.path.join(os.environ.get("HOME"),".openmolar")
 
-cflocation = os.path.join(localFileDirectory,"openmolar.conf")
+cflocation = os.path.join(localFileDirectory, "openmolar.conf")
 TEMP_PDF = os.path.join(localFileDirectory, "temp.pdf")
+DOCS_DIRECTORY = os.path.join(localFileDirectory, "documents")
+
+if not os.path.exists(DOCS_DIRECTORY):
+    os.makedirs(DOCS_DIRECTORY)
 
 #this is updated if correct password is given
 successful_login = False
@@ -179,9 +183,10 @@ def about():
 OpenMolar - open Source dental practice management software.<br />
 Version %s<br />
 Client Schema Version is %s, DataBase is at version %s<br /><hr />
-Copyright (C) 2009  Neil A. Wallace B.Ch.D.<br />
-sourcecode available at <a href="http://launchpad.net/openmolar">
-"http://www.openmolar.com"</a>.
+Copyright (C) 2009-2014 Neil A. Wallace B.Ch.D.<br />
+Project Homepage 
+<a href="http://www.openmolar.com">
+http://www.openmolar.com</a>.
 </p>
 Thanks to <a href="http://rfquerin.org">Richard Querin</a>
 for the wonderful icon and Logo.'''%(
diff --git a/src/openmolar/settings/urls.py b/src/openmolar/settings/urls.py
new file mode 100644
index 0000000..4cb57ea
--- /dev/null
+++ b/src/openmolar/settings/urls.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+###############################################################################
+##                                                                           ##
+##  Copyright 2011-2012,  Neil Wallace <neil at openmolar.com>                  ##
+##                                                                           ##
+##  This program is free software: you can redistribute it and/or modify     ##
+##  it under the terms of the GNU General Public License as published by     ##
+##  the Free Software Foundation, either version 3 of the License, or        ##
+##  (at your option) any later version.                                      ##
+##                                                                           ##
+##  This program is distributed in the hope that it will be useful,          ##
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of           ##
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            ##
+##  GNU General Public License for more details.                             ##
+##                                                                           ##
+##  You should have received a copy of the GNU General Public License        ##
+##  along with this program.  If not, see <http://www.gnu.org/licenses/>.    ##
+##                                                                           ##
+###############################################################################
+
+
+ROOT = "http://www.openmolar.com"
+OM1_ROOT = "%s/om1"% ROOT
+
+DOCUMENT_HELP = "%s/help/documents"% OM1_ROOT
+
+__all__ = (DOCUMENT_HELP, )
+
+
+def _test():
+    for url in __all__:
+        print url
+
+if __name__== "__main__":
+    _test()
diff --git a/src/openmolar/settings/version.py b/src/openmolar/settings/version.py
index 3ec6e82..dbfe35d 100644
--- a/src/openmolar/settings/version.py
+++ b/src/openmolar/settings/version.py
@@ -10,7 +10,7 @@ LOGGER = logging.getLogger("openmolar")
 #this is a fallback version, which will be used if
 #openmolar is not run from a git repository
 #or ig git is not installed.
-VERSION = "0.5.0-beta10"
+VERSION = "0.5.0-beta18"
 
 try:
     p = subprocess.Popen(

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/openmolar.git



More information about the debian-med-commit mailing list