diff --git a/ChangeLog b/ChangeLog
index fb802cbe9..8cf3080c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-01-02 Alex Roitman  <shura@alex.neuro.umn.edu>
+	* src/Report.py: Add support for a semi-common 'dispf'.
+	* src/ReportOptions.py: Add support for a semi-common 'dispf'.
+	* src/Utils.py (cm2pt): Add function.
+	* src/plugins/AncestorChart.py: Convert to new scheme.
+	* src/plugins/AncestorChart2.py: Convert to new scheme.
+	* src/plugins/DesGraph.py: Convert to new scheme.
+
 2005-01-01  Don Allingham  <dallingham@users.sourceforge.net>
 	* src/EditPerson.py: move strip_id from Utils
 	* src/GrampsCfg.py: use ComboBox for toolbar selection
diff --git a/src/Report.py b/src/Report.py
index f2b9ce13a..b376b5524 100644
--- a/src/Report.py
+++ b/src/Report.py
@@ -691,12 +691,8 @@ class BareReportDialog:
             swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
             self.extra_textbox = gtk.TextView()
             swin.add(self.extra_textbox)
-            
-            try:
-                self.extra_textbox.get_buffer().set_text(string,len(string))
-            except TypeError:
-                self.extra_textbox.get_buffer().set_text(string)
 
+            self.extra_textbox.get_buffer().set_text('\n'.join(string))
             self.extra_textbox.set_editable(1)
             self.add_tooltip(self.extra_textbox,et_tip)
             table.attach(self.extra_textbox_label, 1, 2, row, row+1,
@@ -809,8 +805,9 @@ class BareReportDialog:
             b = self.extra_textbox.get_buffer()
             text_val = unicode(b.get_text(b.get_start_iter(),b.get_end_iter(),gtk.FALSE))
             self.report_text = text_val.split('\n')
+            self.options.handler.set_display_format(self.report_text)
         else:
-            self.report_text = ""
+            self.report_text = []
         
     def parse_other_frames(self):
         """Do nothing.  This sole purpose of this function is to give
@@ -1560,6 +1557,7 @@ class CommandLineReport:
             'filter'    : ["=num","Filter number."],
             'gen'       : ["=num","Number of generations to follow."],
             'pagebbg'   : ["=0/1","Page break between generations."],
+            'dispf'     : ["=str","Display format for the outputbox."],
             }
 
         # Add report-specific options
@@ -1612,7 +1610,14 @@ class CommandLineReport:
             self.options_help['gen'].append("Whatever Number You Wish")
             self.options_help['pagebbg'].append([
                 "No page break","Page break"])
-            self.options_help['page_breaks'].append(True)
+            self.options_help['pagebbg'].append(True)
+
+        if self.options_dict.has_key('dispf'):
+            dispf = ''.join(self.options_dict['dispf']).replace('\\n','\n')
+            self.option_class.handler.set_display_format(dispf)
+
+            self.options_help['dispf'].append(
+                        "Any string -- may use keyword substitutions")
 
         self.option_class.handler.output = self.options_dict['of']
         self.options_help['of'].append(os.path.expanduser("~/whatever_name"))
diff --git a/src/ReportOptions.py b/src/ReportOptions.py
index 4865195c8..070120b15 100644
--- a/src/ReportOptions.py
+++ b/src/ReportOptions.py
@@ -203,7 +203,7 @@ class OptionListCollection:
 
         if not filename or not os.path.isfile(filename):
             filename = const.report_options
-        self.file = os.path.expanduser(filename)
+        self.filename = os.path.expanduser(filename)
 
         self.last_paper_name = self.default_paper_name
         self.last_orientation = self.default_orientation
@@ -300,7 +300,7 @@ class OptionListCollection:
         """
         Saves the current OptionListCollection to the associated file.
         """
-        f = open(self.file,"w")
+        f = open(self.filename,"w")
         f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
         f.write('<reportoptions>\n')
 
@@ -357,7 +357,7 @@ class OptionListCollection:
         try:
             p = make_parser()
             p.setContentHandler(OptionParser(self))
-            p.parse('file://' + self.file)
+            p.parse('file://' + self.filename)
         except (IOError,OSError,SAXParseException):
             pass
 
@@ -565,15 +565,27 @@ class OptionHandler:
         self.style_name = style_name
 
     def get_filter_number(self):
-        try:
+        if self.default_options_dict.has_key('filter'):
             return self.options_dict.get('filter',
                     self.default_options_dict['filter'])
-        except KeyError:
+        else:
             return None
 
     def set_filter_number(self,val):
         self.options_dict['filter'] = val
 
+    def get_display_format(self):
+        if self.default_options_dict.has_key('dispf'):
+            return self.options_dict.get('dispf',
+                    self.default_options_dict['dispf'])
+        else:
+            return []
+
+    def set_display_format(self,val):
+        if type(val) != list:
+            val = val.split('\n')
+        self.options_dict['dispf'] = val
+
     def get_format_name(self):
         return self.format_name
 
@@ -674,6 +686,8 @@ class ReportOptions:
 
             'gen'       - Maximum number of generations to consider.
             'pagebbg'   - Whether or not make page breaks between generations.
+            
+            'dispf'     - Display format for the option box -- graphic reports.
         
 
         A self.enable_dict dictionary MUST be defined here, whose keys
@@ -815,3 +829,11 @@ class ReportOptions:
         This method MUST NOT be overridden by subclasses.
         """
         return self.handler.get_filter_number()
+
+    def get_display_format(self):
+        """
+        Return display format for the option box of graphical report.
+        
+        This method MUST NOT be overridden by subclasses.
+        """
+        return self.handler.get_display_format()
diff --git a/src/Utils.py b/src/Utils.py
index ebdb5af7c..c516d88d7 100644
--- a/src/Utils.py
+++ b/src/Utils.py
@@ -440,11 +440,14 @@ def roman(num):
 
 #-------------------------------------------------------------------------
 #
-#  Convert points to cm
+#  Convert points to cm and back
 #
 #-------------------------------------------------------------------------
-def pt2cm(val):
-    return (float(val)/28.3465)
+def pt2cm(pt):
+    return (float(pt)/28.3465)
+
+def cm2pt(cm):
+    return (float(cm)/2.54)*72
 
 #-------------------------------------------------------------------------
 #
diff --git a/src/plugins/AncestorChart.py b/src/plugins/AncestorChart.py
index dc8665f25..47809e6cb 100644
--- a/src/plugins/AncestorChart.py
+++ b/src/plugins/AncestorChart.py
@@ -27,8 +27,7 @@
 # python modules
 #
 #------------------------------------------------------------------------
-import os
-import string
+from gettext import gettext as _
 
 #------------------------------------------------------------------------
 #
@@ -44,51 +43,58 @@ import gtk
 #------------------------------------------------------------------------
 import BaseDoc
 import Report
-import Errors
-from QuestionDialog import ErrorDialog
 from SubstKeywords import SubstKeywords
-from gettext import gettext as _
+from Utils import pt2cm
+import const
+import ReportOptions
 
+#------------------------------------------------------------------------
+#
+# Constants
+#
+#------------------------------------------------------------------------
 _BORN = _('b.')
 _DIED = _('d.')
 
-#------------------------------------------------------------------------
-#
-# pt2cm - convert points to centimeters
-#
-#------------------------------------------------------------------------
-def pt2cm(pt):
-    return (float(pt)/72.0)*(254.0/100.0)
-
 #------------------------------------------------------------------------
 #
 # AncestorChart
 #
 #------------------------------------------------------------------------
-class AncestorChart:
+class AncestorChart(Report.Report):
+
+    def __init__(self,database,person,options_class):
+        """
+        Creates AncestorChart object that produces the report.
+        
+        The arguments are:
+
+        database        - the GRAMPS database instance
+        person          - currently selected person
+        options_class   - instance of the Options class for this report
+
+        This report needs the following parameters (class variables)
+        that come in the options class.
+        
+        gen       - Maximum number of generations to include.
+        pagebbg   - Whether to include page breaks between generations.
+        dispf     - Display format for the output box.
+        """
+        Report.Report.__init__(self,database,person,options_class)
+
+        (self.max_generations,self.pgbrk) \
+                        = options_class.get_report_generations()
+        self.display = options_class.handler.options_dict['dispf']
 
-    def __init__(self,database,person,max,display,doc,output,newpage=0):
-        self.database = database
-        self.doc = doc
-        self.doc.creator(database.get_researcher().get_name())
         self.map = {}
         self.text = {}
-        self.start = person
-        self.max_generations = max
-        self.output = output
+
         self.box_width = 0
         self.height = 0
         self.lines = 0
-        self.display = display
-        self.newpage = newpage
-        if output:
-            self.standalone = 1
-            self.doc.open(output)
-        else:
-            self.standalone = 0
         self.calc()
         
-    def filter(self,person_handle,index):
+    def apply_filter(self,person_handle,index):
         """traverse the ancestors recursively until either the end
         of a line is found, or until we reach the maximum number of 
         generations that we want to deal with"""
@@ -115,14 +121,11 @@ class AncestorChart:
         family_handle = person.get_main_parents_family_handle()
         if family_handle:
             family = self.database.get_family_from_handle(family_handle)
-            self.filter(family.get_father_handle(),index*2)
-            self.filter(family.get_mother_handle(),(index*2)+1)
+            self.apply_filter(family.get_father_handle(),index*2)
+            self.apply_filter(family.get_mother_handle(),(index*2)+1)
 
     def write_report(self):
 
-        if self.newpage:
-            self.doc.page_break()
-
         generation = 1
         done = 0
         page = 1
@@ -137,8 +140,6 @@ class AncestorChart:
                     self.print_page(index, generation, page)
                     page = page + 1
             generation = generation + 3
-        if self.standalone:
-            self.doc.close()
 
     def calc(self):
         """
@@ -146,7 +147,7 @@ class AncestorChart:
         that and the page dimensions, calculate the proper place to put
         the elements on a page.
         """
-        self.filter(self.start.get_handle(),1)
+        self.apply_filter(self.start_person.get_handle(),1)
 
         self.height = self.lines*pt2cm((125.0*self.font.get_size())/100.0)
         self.box_width = pt2cm(self.box_width+20)
@@ -196,7 +197,7 @@ class AncestorChart:
         if self.map.has_key(start) and index <= 15:
             text = self.text[start]
 
-            name = string.join(text,"\n")
+            name = "\n".join(text)
             self.doc.draw_box("AC-box",name,self.x[level],self.y[index-1])
 
             if index > 1:
@@ -219,222 +220,60 @@ class AncestorChart:
 # 
 #
 #------------------------------------------------------------------------
-def _make_default_style(default_style):
-    """Make the default output style for the Ancestor Chart report."""
-    f = BaseDoc.FontStyle()
-    f.set_size(9)
-    f.set_type_face(BaseDoc.FONT_SANS_SERIF)
-    p = BaseDoc.ParagraphStyle()
-    p.set_font(f)
-    p.set_description(_('The basic style used for the text display.'))
-    default_style.add_style("AC-Normal",p)
+class AncestorChartOptions(ReportOptions.ReportOptions):
 
-#------------------------------------------------------------------------
-#
-# AncestorChartDialog
-#
-#------------------------------------------------------------------------
-class AncestorChartDialog(Report.DrawReportDialog):
+    """
+    Defines options and provides handling interface.
+    """
 
-    report_options = {}
-    
-    def __init__(self,database,person):
-        Report.DrawReportDialog.__init__(self,database,person,self.report_options)
+    def __init__(self,name,person_id=None):
+        ReportOptions.ReportOptions.__init__(self,name,person_id)
 
-    def get_title(self):
-        """The window title for this dialog"""
-        return "%s - %s - GRAMPS" % (_("Ancestor Chart"),_("Graphical Reports"))
+    def enable_options(self):
+        # Semi-common options that should be enabled for this report
+        self.enable_dict = {
+            'gen'       : 10,
+            'pagebbg'   : 0,
+            'dispf'     : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ],
+        }
 
-    def get_header(self, name):
-        """The header line at the top of the dialog contents."""
-        return _("Ancestor Chart for %s") % name
+    def make_default_style(self,default_style):
+        """Make the default output style for the Ancestor Chart report."""
+        f = BaseDoc.FontStyle()
+        f.set_size(9)
+        f.set_type_face(BaseDoc.FONT_SANS_SERIF)
+        p = BaseDoc.ParagraphStyle()
+        p.set_font(f)
+        p.set_description(_('The basic style used for the text display.'))
+        default_style.add_style("AC-Normal",p)
 
-    def get_target_browser_title(self):
-        """The title of the window created when the 'browse' button is
-        clicked in the 'Save As' frame."""
-        return _("Save Ancestor Chart")
-
-    def get_stylesheet_savefile(self):
-        """Where to save user defined styles for this report."""
-        return _style_file
-    
-    def get_report_generations(self):
-        """Default to 10 generations, no page breaks."""
-        return (10, 0)
-    
-    def get_report_extra_textbox_info(self):
+    def get_textbox_info(self):
         """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
+        return (_("Display Format"), self.options_dict['dispf'],
                 _("Allows you to customize the data in the boxes in the report"))
 
-    def make_default_style(self):
-        _make_default_style(self.default_style)
-
-    def make_report(self):
-        """Create the object that will produce the Ancestor Chart.
-        All user dialog has already been handled and the output file
-        opened."""
-
-        try:
-            MyReport = AncestorChart(self.db, self.person, 
-                self.max_gen, self.report_text, self.doc,self.target_path)
-            MyReport.write_report()
-        except Errors.ReportError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except Errors.FilterError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except:
-            import DisplayTrace
-            DisplayTrace.DisplayTrace()
-
-#------------------------------------------------------------------------
-#
-# entry point
-#
-#------------------------------------------------------------------------
-def report(database,person):
-    AncestorChartDialog(database,person)
-
-#------------------------------------------------------------------------
-#
-# Set up sane defaults for the book_item
-#
-#------------------------------------------------------------------------
-_style_file = "ancestor_chart.xml"
-_style_name = "default" 
-
-_person_handle = ""
-_max_gen = 10
-_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ]
-_options = ( _person_handle, _max_gen, _disp_format )
-
-#------------------------------------------------------------------------
-#
-# Book Item Options dialog
-#
-#------------------------------------------------------------------------
-class AncestorChartBareDialog(Report.BareReportDialog):
-
-    def __init__(self,database,person,opt,stl):
-
-        self.options = opt
-        self.db = database
-        if self.options[0]:
-            self.person = self.db.get_person_from_handle(self.options[0])
-        else:
-            self.person = person
-        self.style_name = stl
-
-        Report.BareReportDialog.__init__(self,database,self.person)
-
-        self.max_gen = int(self.options[1])
-        self.disp_format = string.join(self.options[2],'\n')
-        self.new_person = None
-
-        self.generations_spinbox.set_value(self.max_gen)
-        self.extra_textbox.get_buffer().set_text(
-            self.disp_format,len(self.disp_format))
-        
-        self.window.run()
-
-    #------------------------------------------------------------------------
-    #
-    # Customization hooks
-    #
-    #------------------------------------------------------------------------
-    def get_title(self):
-        """The window title for this dialog"""
-        return "%s - GRAMPS Book" % (_("Ancestor Chart"))
-
-    def get_header(self, name):
-        """The header line at the top of the dialog contents"""
-        return _("Ancestor Chart for GRAMPS Book") 
-
-    def get_stylesheet_savefile(self):
-        """Where to save styles for this report."""
-        return _style_file
-    
-    def get_report_generations(self):
-        """Default to 10 generations, no page breaks."""
-        return (10, 0)
-    
-    def get_report_extra_textbox_info(self):
-        """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
-                _("Allows you to customize the data in the boxes in the report"))
-
-    def make_default_style(self):
-        _make_default_style(self.default_style)
-
-    def on_cancel(self, obj):
-        pass
-
-    def on_ok_clicked(self, obj):
-        """The user is satisfied with the dialog choices. Parse all options
-        and close the window."""
-
-        # Preparation
-        self.parse_style_frame()
-        self.parse_report_options_frame()
-        
-        if self.new_person:
-            self.person = self.new_person
-        self.options = ( self.person.get_handle(), self.max_gen, self.report_text )
-        self.style_name = self.selected_style.get_name()
-
-#------------------------------------------------------------------------
-#
-# Function to write Book Item 
-#
-#------------------------------------------------------------------------
-def write_book_item(database,person,doc,options,newpage=0):
-    """Write the Ancestor Chart using options set.
-    All user dialog has already been handled and the output file opened."""
-    try:
-        if options[0]:
-            person = database.get_person_from_handle(options[0])
-        max_gen = int(options[1])
-        disp_format = options[2]
-        return AncestorChart(database, person, max_gen,
-                                   disp_format, doc, None, newpage )
-    except Errors.ReportError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except Errors.FilterError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except:
-        import DisplayTrace
-        DisplayTrace.DisplayTrace()
+    def add_user_options(self,dialog):
+        """
+        Override the base class add_user_options task to add a menu that allows
+        the user to select the sort method.
+        """
+        dialog.get_report_extra_textbox_info = self.get_textbox_info
 
 #------------------------------------------------------------------------
 #
 # 
 #
 #------------------------------------------------------------------------
-from Plugins import register_report, register_book_item
-
+from Plugins import register_report
 register_report(
-    report,
-    _("Ancestor Chart"),
-    category=_("Graphical Reports"),
-    status=(_("Beta")),
-    description=_("Produces a graphical ancestral tree graph"),
-    author_name="Donald N. Allingham",
-    author_email="dallingham@users.sourceforge.net"
+    name = 'ancestor_chart',
+    category = const.CATEGORY_DRAW,
+    report_class = AncestorChart,
+    options_class = AncestorChartOptions,
+    modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
+    translated_name = _("Ancestor Chart"),
+    status = _("Beta"),
+    author_name = "Donald N. Allingham",
+    author_email = "dallingham@users.sourceforge.net",
+    description = _("Produces a graphical ancestral tree graph"),
     )
-
-# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
-register_book_item( 
-    _("Ancestor Chart"), 
-    _("Graphics"),
-    AncestorChartBareDialog,
-    write_book_item,
-    _options,
-    _style_name,
-    _style_file,
-    _make_default_style
-    )
-
diff --git a/src/plugins/AncestorChart2.py b/src/plugins/AncestorChart2.py
index b3c3b6c7e..bc519eb7a 100644
--- a/src/plugins/AncestorChart2.py
+++ b/src/plugins/AncestorChart2.py
@@ -27,11 +27,14 @@
 # python modules
 #
 #------------------------------------------------------------------------
-import os
-import string
 import math
-import types
+from gettext import gettext as _
 
+#------------------------------------------------------------------------
+#
+# gtk
+#
+#------------------------------------------------------------------------
 import gtk
 
 #------------------------------------------------------------------------
@@ -41,39 +44,33 @@ import gtk
 #------------------------------------------------------------------------
 import BaseDoc
 import Report
-import Errors
-from QuestionDialog import ErrorDialog
 from SubstKeywords import SubstKeywords
-from gettext import gettext as _
+from Utils import pt2cm, cm2pt
+import const
+import ReportOptions
 
+#------------------------------------------------------------------------
+#
+# Constants
+#
+#------------------------------------------------------------------------
 _BORN = _('b.')
 _DIED = _('d.')
 
+#------------------------------------------------------------------------
+#
+# log2val
+#
+#------------------------------------------------------------------------
 def log2(val):
     return int(math.log10(val)/math.log10(2))
 
-#------------------------------------------------------------------------
-#
-# pt2cm - convert points to centimeters
-#
-#------------------------------------------------------------------------
-def pt2cm(pt):
-    return (float(pt)/72.0)*(254.0/100.0)
-
-#------------------------------------------------------------------------
-#
-# cm2pt - convert centimeters to points
-#
-#------------------------------------------------------------------------
-def cm2pt(cm):
-    return (float(cm)/2.54)*72
-
 #------------------------------------------------------------------------
 #
 # Layout class
 #
 #------------------------------------------------------------------------
-class GenChart :
+class GenChart:
 
     def __init__(self,generations):
         self.generations = generations
@@ -157,7 +154,7 @@ class GenChart :
 
     def not_blank(self,line):
         for i in line:
-            if i and type(i) == types.TupleType:
+            if i and type(i) == tuple:
                 return 1
         return 0
 
@@ -166,33 +163,48 @@ class GenChart :
 # AncestorChart
 #
 #------------------------------------------------------------------------
-class AncestorChart:
+class AncestorChart(Report.Report):
+
+    def __init__(self,database,person,options_class):
+        """
+        Creates AncestorChart object that produces the report.
+        
+        The arguments are:
+
+        database        - the GRAMPS database instance
+        person          - currently selected person
+        options_class   - instance of the Options class for this report
+
+        This report needs the following parameters (class variables)
+        that come in the options class.
+        
+        gen       - Maximum number of generations to include.
+        pagebbg   - Whether to include page breaks between generations.
+        dispf     - Display format for the output box.
+        singlep   - Whether to scale to fit on a single page.
+        compress  - Whether to compress chart.
+        title     - Title of the report displayed on top.
+        """
+        Report.Report.__init__(self,database,person,options_class)
+
+        (self.max_generations,self.pgbrk) \
+                        = options_class.get_report_generations()
+        self.display = options_class.handler.options_dict['dispf']
+        self.force_fit = options_class.handler.options_dict['singlep']
+        self.compress = options_class.handler.options_dict['compress']
+        self.title = options_class.handler.options_dict['title'].strip()
 
-    def __init__(self,database,person,max,display,doc,output,scale,compress,
-                 title,newpage=0):
-        self.database = database
-        self.doc = doc
-        self.title = title.strip()
-        self.doc.creator(database.get_researcher().get_name())
         self.map = {}
         self.text = {}
-        self.start = person
-        self.max_generations = max
-        self.output = output
+
         self.box_width = 0
         self.box_height = 0
         self.lines = 0
-        self.display = display
-        self.newpage = newpage
-        self.force_fit = scale
-        self.compress = compress
-        if output:
-            self.doc.open(output)
-        self.standalone = output
+
         self.font = self.doc.style_list["AC2-Normal"].get_font()
         self.tfont = self.doc.style_list["AC2-Title"].get_font()
 
-        self.filter(self.start.get_handle(),1)
+        self.apply_filter(self.start_person.get_handle(),1)
 
         keys = self.map.keys()
         keys.sort()
@@ -203,7 +215,7 @@ class AncestorChart:
             self.genchart.set(key,self.map[key])
         self.calc()
 
-    def filter(self,person_handle,index):
+    def apply_filter(self,person_handle,index):
         """traverse the ancestors recursively until either the end
         of a line is found, or until we reach the maximum number of 
         generations that we want to deal with"""
@@ -229,14 +241,11 @@ class AncestorChart:
         family_handle = person.get_main_parents_family_handle()
         if family_handle:
             family = self.database.get_family_from_handle(family_handle)
-            self.filter(family.get_father_handle(),index*2)
-            self.filter(family.get_mother_handle(),(index*2)+1)
+            self.apply_filter(family.get_father_handle(),index*2)
+            self.apply_filter(family.get_mother_handle(),(index*2)+1)
 
     def write_report(self):
 
-        if self.newpage:
-            self.doc.page_break()
-
         generation = 1
         done = 0
         page = 1
@@ -259,8 +268,6 @@ class AncestorChart:
                     startx += self.generations_per_page
                 coly += 1
                 starty += maxh
-        if self.standalone:
-            self.doc.close()
             
     def calc(self):
         """
@@ -351,9 +358,9 @@ class AncestorChart:
             for x in range(startx,stopx):
                 value = self.genchart.get_xy(x,y)
                 if value:
-                    if type(value) == types.TupleType:
+                    if type(value) == tuple:
                         (person,index) = value
-                        text = string.join(self.text[index],"\n")
+                        text = '\n'.join(self.text[index])
                         self.doc.draw_box("AC2-box",text,phys_x*self.delta,
                                           phys_y*self.box_height+self.offset)
                     elif value == 2:
@@ -396,7 +403,7 @@ class AncestorChart:
                 value = self.genchart.get_xy(x,y)
                 if not value:
                     continue
-                if type(value) == types.TupleType:
+                if type(value) == tuple:
                     (person,index) = value
                     if self.genchart.get(index*2):
                         (px,py) = self.genchart.index_to_xy(index*2)
@@ -414,311 +421,110 @@ class AncestorChart:
 # 
 #
 #------------------------------------------------------------------------
-def _make_default_style(default_style):
-    """Make the default output style for the Ancestor Chart report."""
-    f = BaseDoc.FontStyle()
-    f.set_size(9)
-    f.set_type_face(BaseDoc.FONT_SANS_SERIF)
-    p = BaseDoc.ParagraphStyle()
-    p.set_font(f)
-    p.set_description(_('The basic style used for the text display.'))
-    default_style.add_style("AC2-Normal",p)
+class AncestorChartOptions(ReportOptions.ReportOptions):
 
-    f = BaseDoc.FontStyle()
-    f.set_size(16)
-    f.set_type_face(BaseDoc.FONT_SANS_SERIF)
-    p = BaseDoc.ParagraphStyle()
-    p.set_font(f)
-    p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
-    p.set_description(_('The basic style used for the title display.'))
-    default_style.add_style("AC2-Title",p)
+    """
+    Defines options and provides handling interface.
+    """
 
-#------------------------------------------------------------------------
-#
-# AncestorChartDialog
-#
-#------------------------------------------------------------------------
-class AncestorChartDialog(Report.DrawReportDialog):
+    def __init__(self,name,person_id=None):
+        ReportOptions.ReportOptions.__init__(self,name,person_id)
 
-    report_options = {}
-    
-    def __init__(self,database,person):
-        Report.DrawReportDialog.__init__(self,database,person,self.report_options)
+    def set_new_options(self):
+        # Options specific for this report
+        self.options_dict = {
+            'singlep'   : 1,
+            'compress'  : 1,
+            'title'     : '',
+        }
+        self.options_help = {
+            'singlep'   : ("=0/1","Whether to scale to fit on a single page.",
+                            ["Do not scale to fit","Scale to fit"],
+                            True),
+            'compress'  : ("=0/1","Whether to compress chart.",
+                            ["Do not compress chart","Compress chart"],
+                            True),
+            'title'     : ("=str","Title string for the report",
+                            "Whatever String You Wish"),
+        }
 
-    def add_user_options(self):
-        self.title=gtk.Entry()
-        self.title.set_text(self.get_header(self.person.get_primary_name().get_name()))
-        self.title.show()
-        self.add_option(_('Title'),self.title)
-        self.compress = gtk.CheckButton(_('Co_mpress chart'))
-        self.compress.set_active(1)
-        self.compress.show()
-        self.add_option('',self.compress)
-        self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page'))
-        self.scale.set_active(1)
-        self.scale.show()
-        self.add_option('',self.scale)
+    def enable_options(self):
+        # Semi-common options that should be enabled for this report
+        self.enable_dict = {
+            'gen'       : 10,
+            'pagebbg'   : 0,
+            'dispf'     : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ],
+        }
 
-    def get_title(self):
-        """The window title for this dialog"""
-        return "%s - %s - GRAMPS" % (_("Ancestor Chart"),_("Graphical Reports"))
-
-    def get_header(self, name):
-        """The header line at the top of the dialog contents."""
-        return _("Ancestor Chart for %s") % name
-
-    def get_target_browser_title(self):
-        """The title of the window created when the 'browse' button is
-        clicked in the 'Save As' frame."""
-        return _("Save Ancestor Chart")
-
-    def get_stylesheet_savefile(self):
-        """Where to save user defined styles for this report."""
-        return _style_file
-    
-    def get_report_generations(self):
-        """Default to 10 generations, no page breaks."""
-        return (10, 0)
-    
-    def get_report_extra_textbox_info(self):
+    def get_textbox_info(self):
         """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
+        return (_("Display Format"), self.options_dict['dispf'],
                 _("Allows you to customize the data in the boxes in the report"))
 
-    def make_default_style(self):
-        _make_default_style(self.default_style)
+    def add_user_options(self,dialog):
+        """
+        Override the base class add_user_options task to add a menu that allows
+        the user to select the sort method.
+        """
+        dialog.get_report_extra_textbox_info = self.get_textbox_info
 
-    def make_report(self):
-        """Create the object that will produce the Ancestor Chart.
-        All user dialog has already been handled and the output file
-        opened."""
-
-        try:
-            MyReport = AncestorChart(self.db, self.person, 
-                                     self.max_gen, self.report_text,
-                                     self.doc,self.target_path,
-                                     self.scale.get_active(),
-                                     self.compress.get_active(),
-                                     self.title.get_text()
-                                     )
-            MyReport.write_report()
-        except Errors.ReportError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except Errors.FilterError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except:
-            import DisplayTrace
-            DisplayTrace.DisplayTrace()
-
-#------------------------------------------------------------------------
-#
-# entry point
-#
-#------------------------------------------------------------------------
-def report(database,person):
-    AncestorChartDialog(database,person)
-
-#------------------------------------------------------------------------
-#
-# Set up sane defaults for the book_item
-#
-#------------------------------------------------------------------------
-_style_file = "ancestor_chart2.xml"
-_style_name = "default" 
-
-_person_handle = ""
-_max_gen = 10
-_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ]
-_compress = 1
-_scale = 1
-_title = ""
-_options = ( _person_handle, _max_gen, _disp_format, _title, _compress, _scale)
-
-#------------------------------------------------------------------------
-#
-# Book Item Options dialog
-#
-#------------------------------------------------------------------------
-class AncestorChartBareDialog(Report.BareReportDialog):
-
-    def __init__(self,database,person,opt,stl):
-
-        self.options = opt
-        self.db = database
-        if self.options[0]:
-            self.person = self.db.get_person_from_handle(self.options[0])
-        else:
-            self.person = person
-        self.style_name = stl
-
-        Report.BareReportDialog.__init__(self,database,self.person)
-
-        self.max_gen = int(self.options[1])
-        self.disp_format = string.join(self.options[2],'\n')
-        if self.options[3]:
-            self.the_title = self.options[3]
-        else:
-            self.the_title = self.get_the_title(self.person)
-        self.do_compress = int(self.options[4])
-        self.do_scale = int(self.options[5])
-        self.new_person = None
-
-        self.generations_spinbox.set_value(self.max_gen)
-        self.extra_textbox.get_buffer().set_text(
-            self.disp_format,len(self.disp_format))
-        self.compress.set_active(self.do_compress)
-        self.scale.set_active(self.do_scale)
-        self.scale.set_sensitive(self.do_compress)
-        self.title.set_text(self.the_title)
-        
-        self.window.run()
-
-    #------------------------------------------------------------------------
-    #
-    # Customization hooks
-    #
-    #------------------------------------------------------------------------
-    def add_user_options(self):
-        self.title=gtk.Entry()
-        self.title.set_text(self.get_the_title(self.person))
-        self.title.show()
-        self.add_option(_('Title'),self.title)
-        self.compress = gtk.CheckButton(_('Co_mpress chart'))
-        self.compress.set_active(1)
-        self.compress.show()
-        self.add_option('',self.compress)
         self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page'))
-        self.scale.set_active(1)
-        self.scale.set_sensitive(1)
-        self.scale.show()
-        self.add_option('',self.scale)
+        self.scale.set_active(self.options_dict['singlep'])
+        dialog.add_option('',self.scale)
 
-    def get_title(self):
-        """The window title for this dialog"""
-        return "%s - GRAMPS Book" % (_("Ancestor Chart"))
+        self.compress = gtk.CheckButton(_('Co_mpress chart'))
+        self.compress.set_active(self.options_dict['compress'])
+        dialog.add_option('',self.compress)
 
-    def get_the_title(self,person):
-        """The header line at the top of the dialog contents."""
-        return _("Ancestor Chart for %s") % person.get_primary_name().get_name()
-
-    def get_header(self,name):
-        """The header line at the top of the dialog contents"""
-        return _("Ancestor Chart for GRAMPS Book") 
-
-    def get_stylesheet_savefile(self):
-        """Where to save styles for this report."""
-        return _style_file
-    
-    def get_report_generations(self):
-        """Default to 10 generations, no page breaks."""
-        return (10, 0)
-    
-    def get_report_extra_textbox_info(self):
-        """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
-                _("Allows you to customize the data in the boxes in the report"))
-
-    def make_default_style(self):
-        _make_default_style(self.default_style)
-
-    def parse_report_options_frame (self):
-        # Call base class
-        Report.BareReportDialog.parse_report_options_frame (self)
-        self.do_compress = self.compress.get_active()
-        self.do_scale = self.scale.get_active()
-        self.the_title = self.title.get_text()
-
-    def on_center_person_change_clicked(self,obj):
-        import SelectPerson
-        sel_person = SelectPerson.SelectPerson(self.db,_('Select Person'))
-        new_person = sel_person.run()
-        if new_person:
-            self.new_person = new_person
-
-            self.the_title = self.get_the_title(self.new_person)
-            self.title.set_text(self.the_title)
-
-            new_name = new_person.getPrimaryName().getRegularName()
-            if new_name:
-                self.person_label.set_text( "<i>%s</i>" % new_name )
-                self.person_label.set_use_markup(gtk.TRUE)
-
-    def on_cancel(self, obj):
-        pass
-
-    def on_ok_clicked(self, obj):
-        """The user is satisfied with the dialog choices. Parse all options
-        and close the window."""
-
-        # Preparation
-        self.parse_style_frame()
-        self.parse_report_options_frame()
-        
-        if self.new_person:
-            self.person = self.new_person
-        self.options = ( self.person.get_handle(), self.max_gen, self.report_text, 
-                        self.the_title, self.do_compress, self.do_scale )
-        self.style_name = self.selected_style.get_name()
-
-#------------------------------------------------------------------------
-#
-# Function to write Book Item 
-#
-#------------------------------------------------------------------------
-def write_book_item(database,person,doc,options,newpage=0):
-    """Write the Ancestor Chart using options set.
-    All user dialog has already been handled and the output file opened."""
-    try:
-        if options[0]:
-            person = database.get_person_from_handle(options[0])
-        max_gen = int(options[1])
-        disp_format = options[2]
-        if options[3]:
-            title = options[3]
+        self.title_box = gtk.Entry()
+        if self.options_dict['title']:
+            self.title_box.set_text(self.options_dict['title'])
         else:
-            title = ""
-        compress = int(options[4])
-        scale = int(options[5])
-        return AncestorChart(database, person, max_gen,
-                                   disp_format, doc, None, 
-                                   scale, compress, title, newpage )
-    except Errors.ReportError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except Errors.FilterError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except:
-        import DisplayTrace
-        DisplayTrace.DisplayTrace()
+            self.title_box.set_text(dialog.get_header(dialog.person.get_primary_name().get_name()))
+        dialog.add_option(_('Title'),self.title_box)
+
+    def parse_user_options(self,dialog):
+        """
+        Parses the custom options that we have added.
+        """
+        self.options_dict['singlep'] = int(self.scale.get_active ())
+        self.options_dict['compress'] = int(self.compress.get_active ())
+        self.options_dict['title'] = unicode(self.title_box.get_text()).strip()
+
+    def make_default_style(self,default_style):
+        """Make the default output style for the Ancestor Chart report."""
+        f = BaseDoc.FontStyle()
+        f.set_size(9)
+        f.set_type_face(BaseDoc.FONT_SANS_SERIF)
+        p = BaseDoc.ParagraphStyle()
+        p.set_font(f)
+        p.set_description(_('The basic style used for the text display.'))
+        default_style.add_style("AC2-Normal",p)
+
+        f = BaseDoc.FontStyle()
+        f.set_size(16)
+        f.set_type_face(BaseDoc.FONT_SANS_SERIF)
+        p = BaseDoc.ParagraphStyle()
+        p.set_font(f)
+        p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
+        p.set_description(_('The basic style used for the title display.'))
+        default_style.add_style("AC2-Title",p)
 
 #------------------------------------------------------------------------
 #
 # 
 #
 #------------------------------------------------------------------------
-from Plugins import register_report, register_book_item
-
+from Plugins import register_report
 register_report(
-    report,
-    _("Ancestor Chart (Wall Chart)"),
-    category=_("Graphical Reports"),
-    status=(_("Beta")),
-    description=_("Produces a graphical ancestral tree graph"),
-    author_name="Donald N. Allingham",
-    author_email="dallingham@users.sourceforge.net"
-    )
-
-# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
-register_book_item( 
-    _("Ancestor Chart (Wall Chart)"), 
-    _("Graphics"),
-    AncestorChartBareDialog,
-    write_book_item,
-    _options,
-    _style_name,
-    _style_file,
-    _make_default_style
+    name = 'ancestor_chart2',
+    category = const.CATEGORY_DRAW,
+    report_class = AncestorChart,
+    options_class = AncestorChartOptions,
+    modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
+    translated_name = _("Ancestor Chart (Wall Chart)"),
+    status = _("Beta"),
+    author_name = "Donald N. Allingham",
+    author_email = "dallingham@users.sourceforge.net",
+    description = _("Produces a graphical ancestral tree graph"),
     )
diff --git a/src/plugins/DesGraph.py b/src/plugins/DesGraph.py
index adba97346..c9caabbc4 100644
--- a/src/plugins/DesGraph.py
+++ b/src/plugins/DesGraph.py
@@ -27,7 +27,7 @@
 # standard python modules
 #
 #------------------------------------------------------------------------
-import string
+from gettext import gettext as _
 
 #------------------------------------------------------------------------
 #
@@ -44,55 +44,52 @@ import gtk
 import GraphLayout
 import Report
 import BaseDoc
-import Errors
-
 from SubstKeywords import SubstKeywords
-from gettext import gettext as _
-from QuestionDialog import ErrorDialog
+from Utils import pt2cm
+import const
+import ReportOptions
 
+#------------------------------------------------------------------------
+#
+# Constants
+#
+#------------------------------------------------------------------------
 _BORN = _('b.')
 _DIED = _('d.')
-
-#------------------------------------------------------------------------
-#
-# constants
-#
-#------------------------------------------------------------------------
 _sep = 0.5
 
 #------------------------------------------------------------------------
 #
-# pt2cm - convert points to centimeters
+# DescendantGraph
 #
 #------------------------------------------------------------------------
-def pt2cm(pt):
-    return (float(pt)/72.0)*2.54
+class DescendantGraph(Report.Report):
 
-#------------------------------------------------------------------------
-#
-# DescendantReport
-#
-#------------------------------------------------------------------------
-class DescendantReport:
+    def __init__(self,database,person,options_class):
+        """
+        Creates DescendantGraph object that produces the report.
+        
+        The arguments are:
+
+        database        - the GRAMPS database instance
+        person          - currently selected person
+        options_class   - instance of the Options class for this report
+
+        This report needs the following parameters (class variables)
+        that come in the options class.
+        
+        dispf     - Display format for the output box.
+        """
+        Report.Report.__init__(self,database,person,options_class)
+
+        self.display = options_class.handler.options_dict['dispf']
 
-    def __init__(self,database,person,display,doc,output,newpage=0):
-        self.database = database
-        self.doc = doc
-        self.doc.creator(database.get_researcher().get_name())
         self.map = {}
         self.text = {}
-        self.start = person
-        self.output = output
+
         self.box_width = 0
         self.height = 0
         self.lines = 0
-        self.display = display
-        self.newpage = newpage
-        if output:
-            self.standalone = 1
-            self.doc.open(output)
-        else:
-            self.standalone = 0
 
         plist = self.database.get_person_handles(sort_handles=False)
         self.layout = GraphLayout.DescendLine(self.database,plist,person.get_handle())
@@ -214,16 +211,10 @@ class DescendantReport:
                     else:
                         l3.append((nx1,-ny2,-nx2,ny2))
             
-        if self.newpage:
-            self.doc.page_break()
-
         for r in range(len(self.pg)):
             for c in range(len(self.pg[r])):
                 self.print_page(self.pg[r][c],self.ln[r][c],r,c)
         
-        if self.standalone:
-            self.doc.close()
-
     def calc(self):
         """calc - calculate the maximum width that a box needs to be. From
         that and the page dimensions, calculate the proper place to put
@@ -243,8 +234,6 @@ class DescendantReport:
 
         g = BaseDoc.GraphicsStyle()
         self.doc.add_draw_style("line",g)
-        if self.standalone:
-            self.doc.init()
 
     def print_page(self, plist,elist,r,c):
         self.doc.start_page()
@@ -257,7 +246,7 @@ class DescendantReport:
 
         if plist:
             for (p_id,x,y) in plist:
-                name = string.join(self.text[p_id],"\n")
+                name = '\n'.join(self.text[p_id])
                 x = (x-1)*delta + left + _sep
                 y = (y-1)*(self.height+_sep)+top
                 self.doc.draw_box("box",name,x,y)
@@ -307,209 +296,58 @@ class DescendantReport:
 # 
 #
 #------------------------------------------------------------------------
-def _make_default_style(default_style):
-    """Make the default output style for the Descendant Graph report."""
-    f = BaseDoc.FontStyle()
-    f.set_size(9)
-    f.set_type_face(BaseDoc.FONT_SANS_SERIF)
-    p = BaseDoc.ParagraphStyle()
-    p.set_font(f)
-    p.set_description(_('The basic style used for the text display.'))
-    default_style.add_style("DG-Normal",p)
+class DescendantGraphOptions(ReportOptions.ReportOptions):
 
-#------------------------------------------------------------------------
-#
-# DescendantReportDialog
-#
-#------------------------------------------------------------------------
-class DescendantReportDialog(Report.DrawReportDialog):
+    """
+    Defines options and provides handling interface.
+    """
 
-    def __init__(self,database,person):
-        Report.DrawReportDialog.__init__(self,database,person)
+    def __init__(self,name,person_id=None):
+        ReportOptions.ReportOptions.__init__(self,name,person_id)
 
-    def get_title(self):
-        return "%s - %s - GRAMPS" % (_("Descendant Graph"),_("Graphical Reports"))
+    def enable_options(self):
+        # Semi-common options that should be enabled for this report
+        self.enable_dict = {
+            'dispf'     : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ],
+        }
 
-    def get_header(self,name):
-        return _("Descendant Graph for %s") % name
-
-    def get_target_browser_title(self):
-        return _("Save Descendant Graph")
-
-    def get_stylesheet_savefile(self):
-        return _style_file
-
-    def get_report_generations(self):
-        """Default to 10 generations, no page breaks."""
-        return (0, 0)
-    
-    def get_report_extra_textbox_info(self):
+    def get_textbox_info(self):
         """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
-                _("Allows you to customize the data in the boxes in the report"))
-    
-    def make_default_style(self):
-        _make_default_style(self.default_style)
-
-    def make_report(self):
-        """Create the object that will produce the Descendant Graph.
-        All user dialog has already been handled and the output file
-        opened."""
-        try:
-            MyReport = DescendantReport(self.db, self.person, 
-                self.report_text, self.doc, self.target_path)
-            MyReport.write_report()
-        except Errors.ReportError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except Errors.FilterError, msg:
-            (m1,m2) = msg.messages()
-            ErrorDialog(m1,m2)
-        except:
-            import DisplayTrace
-            DisplayTrace.DisplayTrace()
-            
-#------------------------------------------------------------------------
-#
-# 
-#
-#------------------------------------------------------------------------
-def report(database,person):
-    DescendantReportDialog(database,person)
-
-#------------------------------------------------------------------------
-#
-# Set up sane defaults for the book_item
-#
-#------------------------------------------------------------------------
-_style_file = "descendant_graph.xml"
-_style_name = "default" 
-
-_person_handle = ""
-_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ]
-_options = ( _person_handle, _disp_format )
-
-#------------------------------------------------------------------------
-#
-# Book Item Options dialog
-#
-#------------------------------------------------------------------------
-class DescendantGraphBareDialog(Report.BareReportDialog):
-
-    def __init__(self,database,person,opt,stl):
-
-        self.options = opt
-        self.db = database
-        if self.options[0]:
-            self.person = self.db.get_person_from_handle(self.options[0])
-        else:
-            self.person = person
-        self.style_name = stl
-
-        Report.BareReportDialog.__init__(self,database,self.person)
-
-        self.disp_format = string.join(self.options[1],'\n')
-        self.new_person = None
-
-        self.extra_textbox.get_buffer().set_text(
-            self.disp_format,len(self.disp_format))
-        
-        self.window.run()
-
-    #------------------------------------------------------------------------
-    #
-    # Customization hooks
-    #
-    #------------------------------------------------------------------------
-    def get_title(self):
-        """The window title for this dialog"""
-        return "%s - GRAMPS Book" % (_("Descendant Graph"))
-
-    def get_header(self, name):
-        """The header line at the top of the dialog contents"""
-        return _("Descendant Graph for GRAMPS Book") 
-
-    def get_stylesheet_savefile(self):
-        """Where to save styles for this report."""
-        return _style_file
-    
-    def get_report_generations(self):
-        """No generations, no page breaks."""
-        return (0, 0)
-    
-    def get_report_extra_textbox_info(self):
-        """Label the textbox and provide the default contents."""
-        return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED),
+        return (_("Display Format"), self.options_dict['dispf'],
                 _("Allows you to customize the data in the boxes in the report"))
 
-    def make_default_style(self):
-        _make_default_style(self.default_style)
+    def add_user_options(self,dialog):
+        """
+        Override the base class add_user_options task to add a menu that allows
+        the user to select the sort method.
+        """
+        dialog.get_report_extra_textbox_info = self.get_textbox_info
 
-    def on_cancel(self, obj):
-        pass
-
-    def on_ok_clicked(self, obj):
-        """The user is satisfied with the dialog choices. Parse all options
-        and close the window."""
-
-        # Preparation
-        self.parse_style_frame()
-        self.parse_report_options_frame()
-        
-        if self.new_person:
-            self.person = self.new_person
-        self.options = ( self.person.get_handle(), self.report_text )
-        self.style_name = self.selected_style.get_name()
-
-#------------------------------------------------------------------------
-#
-# Function to write Book Item 
-#
-#------------------------------------------------------------------------
-def write_book_item(database,person,doc,options,newpage=0):
-    """Write the Ancestor Chart using options set.
-    All user dialog has already been handled and the output file opened."""
-    try:
-        if options[0]:
-            person = database.get_person_from_handle(options[0])
-        disp_format = options[1]
-        return DescendantReport(database, person, 
-                                   disp_format, doc, None, newpage )
-    except Errors.ReportError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except Errors.FilterError, msg:
-        (m1,m2) = msg.messages()
-        ErrorDialog(m1,m2)
-    except:
-        import DisplayTrace
-        DisplayTrace.DisplayTrace()
+    def make_default_style(self,default_style):
+        """Make the default output style for the Descendant Graph report."""
+        f = BaseDoc.FontStyle()
+        f.set_size(9)
+        f.set_type_face(BaseDoc.FONT_SANS_SERIF)
+        p = BaseDoc.ParagraphStyle()
+        p.set_font(f)
+        p.set_description(_('The basic style used for the text display.'))
+        default_style.add_style("DG-Normal",p)
 
 #------------------------------------------------------------------------
 #
 # 
 #
 #------------------------------------------------------------------------
-from Plugins import register_report, register_book_item
-
+from Plugins import register_report
 register_report(
-    report,
-    _("Descendant Graph"),
-    category=_("Graphical Reports"),
-    description=_("Generates a graph of descendants of the active person"),
-    status=(_("Alpha")),
-    author_name="Donald N. Allingham",
-    author_email="dallingham@users.sourceforge.net"
-    )
-
-# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
-register_book_item( 
-    _("Descendant Graph"), 
-    _("Graphics"),
-    DescendantGraphBareDialog,
-    write_book_item,
-    _options,
-    _style_name,
-    _style_file,
-    _make_default_style
+    name = 'descendant_graph',
+    category = const.CATEGORY_DRAW,
+    report_class = DescendantGraph,
+    options_class = DescendantGraphOptions,
+    modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
+    translated_name = _("Descendant Graph"),
+    status = _("Alpha"),
+    author_name = "Donald N. Allingham",
+    author_email = "dallingham@users.sourceforge.net",
+    description = _("Generates a graph of descendants of the active person"),
     )