#
# Copyright (c) 2002, 2003, 2004, 2005, 2006 Art Haas
#
# This file is part of PythonCAD.
#
# PythonCAD 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 2 of the License, or
# (at your option) any later version.
#
# PythonCAD 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 PythonCAD; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#

################################################################
#
# This file contains the GTK Menu building code
#
################################################################

import os
import stat
import sys

_debug = False

if _debug:
    try:
        import gc
        gc.set_debug(gc.DEBUG_LEAK)
    except ImportError:
        pass

import pygtk
pygtk.require('2.0')
import gtk
import gtk.keysyms

from PythonCAD.Interface.Gtk.gtkimage import GTKImage
from PythonCAD.Interface.Gtk import gtkedit
from PythonCAD.Interface.Gtk import gtkentities
from PythonCAD.Interface.Gtk import gtkconobjs
from PythonCAD.Interface.Gtk import gtkprefs
from PythonCAD.Interface.Gtk import gtkmodify
from PythonCAD.Interface.Gtk import gtkmirror
from PythonCAD.Interface.Gtk import gtktext
from PythonCAD.Interface.Gtk import gtklayers
from PythonCAD.Interface.Gtk import gtkdimension
from PythonCAD.Interface.Gtk import gtkprinting
from PythonCAD.Interface.Gtk import gtkactions
from PythonCAD.Generic import globals
from PythonCAD.Generic import fileio
from PythonCAD.Generic import imageio
from PythonCAD.Generic import tools
from PythonCAD.Generic import plotfile
from PythonCAD.Generic import text
from PythonCAD.Generic import graphicobject
from PythonCAD.Generic import dimension

if not hasattr(gtk, 'Action'):
    gtk.Action = gtkactions.stdAction
    gtk.ActionGroup = gtkactions.stdActionGroup


#############################################################################
#
# callbacks for the menu items
#
#############################################################################
def file_new_cb(menuitem, data=None):
    _image = GTKImage()
    _background = globals.prefs['BACKGROUND_COLOR']
    _image.setOption('BACKGROUND_COLOR', _background)
    globals.imagelist.append(_image)
    _image.window.show_all()

#------------------------------------------------------------
def file_open_cb(menuitem, gtkimage):
    _open = False
    _fname = None
    _dialog = gtk.FileSelection("Open File ...")
    _dialog.set_transient_for(gtkimage.getWindow())
    # _dialog.hide_fileop_buttons()
    while not _open:
        _response = _dialog.run()
        if _response == gtk.RESPONSE_OK:
            _fname = _dialog.get_filename()
            if os.path.isdir(_fname):
                _fname += "/"
                _dialog.set_filename(_fname)
                _response = _dialog.run()
            else:
                _open = True
        else:
            break
    _dialog.destroy()
    if _open:
        _image = GTKImage()
        try:
            _handle = fileio.CompFile(_fname, "r")
            try:
                imageio.load_image(_image, _handle)
            finally:
                _handle.close()
        except (IOError, OSError), e:
            _errmsg = "Error opening '%s' : %s'" % (_fname, e)
            _error_dialog(gtkimage, _errmsg)
            return
        except StandardError, e:
            _errmsg = "Non-system error opening '%s' : %s'" % (_fname, e)
            _error_dialog(gtkimage, _errmsg)
            return
        globals.imagelist.append(_image)
        _image.setFilename(_fname)
        _window = _image.getWindow()
        _window.set_title(os.path.basename(_fname))
        _window.show_all()
        _image.fitImage()

#------------------------------------------------------------
def file_close_cb(menuitem, gtkimage):
    for _i in xrange(len(globals.imagelist)):
        _image = globals.imagelist[_i]
        if _image is gtkimage:
            _log = _image.getLog()
            if _log is not None:
                _log.detatch()
            del globals.imagelist[_i]
            _image.window.destroy()
            if not len(globals.imagelist):
                gtk.main_quit()
            break

#------------------------------------------------------------
def _error_dialog(gtkimage, errmsg):
    _window = gtkimage.getWindow()
    _dialog = gtk.MessageDialog( _window,
                                 gtk.DIALOG_DESTROY_WITH_PARENT,
                                 gtk.MESSAGE_ERROR,
                                 gtk.BUTTONS_CLOSE,
                                 errmsg)
    _dialog.run()
    _dialog.destroy()

#------------------------------------------------------------
def _save_file(gtkimage, filename):
    _abs = os.path.abspath(filename)
    _bname = os.path.basename(_abs)
    if _bname.endswith('.gz'):
        _bname = _bname[:-3]
    _newfile = _abs + '.new'
    _handle = fileio.CompFile(_newfile, "w", truename=_bname)
    try:
        imageio.save_image(gtkimage, _handle)
    finally:
        _handle.close()
    _backup = _abs + '~'
    if os.path.exists(_backup):
        os.unlink(_backup)
    _mode = None
    if os.path.exists(_abs):
        _st = os.stat(_abs)
        _mode = stat.S_IMODE(_st.st_mode)
        os.rename(_abs, _backup)
    try:
        os.rename(_newfile, _abs)
    except:
        os.rename(_backup, _abs)
        raise
    if _mode is not None and hasattr(os, 'chmod'):
        os.chmod(_abs, _mode)
    if gtkimage.getFilename() is None:
        gtkimage.setFilename(_abs)

#------------------------------------------------------------
def _writecopy(src, dst):
    if sys.platform == 'win32':
        _rmode = 'rb'
        _wmode = 'wb'
    else:
        _rmode = 'r'
        _wmode = 'w'
    _from = file(src, _rmode)
    try:
        _to = file(dst, _wmode)
        try:
            while True:
                _data = _from.read(8192)
                if _data == '':
                    break
                _to.write(_data)
        finally:
            _to.close()
    finally:
        _from.close()

#------------------------------------------------------------
def _save_file_by_copy(gtkimage, filename):
    _abs = os.path.abspath(filename)
    _bname = os.path.basename(_abs)
    if _bname.endswith('.gz'):
        _bname = _bname[:-3]
    _newfile = _abs + '.new'
    _handle = fileio.CompFile(_newfile, "w", truename=_bname)
    try:
        imageio.save_image(gtkimage, _handle)
    finally:
        _handle.close()
    # print "saved new file %s" % _newfile
    _backup = _abs + '~'
    if os.path.exists(_abs):
        _writecopy(_abs, _backup)
        # print "writing existing to backup %s" % _backup
    try:
        _writecopy(_newfile, _abs)
    except:
        _writecopy(_backup, _abs)
        raise
    # print "writing new file to filename %s" % _abs
    os.unlink(_newfile)
    # print "removing temporary new file %s" % _abs
    if gtkimage.getFilename() is None:
        gtkimage.setFilename(_abs)
    
#------------------------------------------------------------
def _get_filename_and_save(gtkimage, fname=None):
    _window = gtkimage.getWindow()
    _fname = fname
    if _fname is None:
        _fname = _window.get_title()
    _fname = _window.get_title()
    _dialog = gtk.FileSelection("Save As ...")
    _dialog.set_transient_for(gtkimage.getWindow())
    _dialog.set_filename(_fname)
    _response = _dialog.run()
    _save = False
    if _response == gtk.RESPONSE_OK:
        _save = True
        _fname = _dialog.get_filename()
        if _fname == "":
            _fname = 'Untitled.xml'
        if not _fname.endswith('.xml.gz'):
            if not _fname.endswith('.xml'):
                _fname = _fname + '.xml'
        #
        # if the filename already exists see that the user
        # really wants to overwrite it ...
        #
        # test for the filename + '.gz'
        #
        if _fname.endswith('.xml.gz'):
            _gzfile = _fname
        else:
            _gzfile = _fname + '.gz'
        if os.path.exists(_gzfile):
            _save = False
            _dialog2 = gtk.Dialog("Overwrite Existing File", _window,
                                  gtk.DIALOG_MODAL,
                                  (gtk.STOCK_OK, gtk.RESPONSE_OK,
                                   gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
            _hbox = gtk.HBox(False, 10)
            _hbox.set_border_width(10)
            _dialog2.vbox.pack_start(_hbox, False, False, 0)
            _stock = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION,
                                              gtk.ICON_SIZE_DIALOG)
            _hbox.pack_start(_stock, False, False, 0)
            _label = gtk.Label("File already exists. Delete it?")
            _hbox.pack_start(_label, False, False, 0)
            _dialog2.show_all()
            _response = _dialog2.run()
            if _response == gtk.RESPONSE_OK:
                _save = True
            _dialog2.destroy()
    _dialog.destroy()
    if _save:
        # print "name: " + _gzfile
        gtkimage.setFilename(_gzfile)
        _window.set_title(os.path.basename(_gzfile))
        try:
            _save_file(gtkimage, _gzfile)
        except (IOError, OSError), _e:
            _errmsg = "Error saving '%s' : %s'" % (_gzfile, _e)
            _error_dialog(gtkimage, _errmsg)
        except StandardError, _e:
            _errmsg = "Non-system error saving '%s' : %s'" % (_gzfile, _e)
            _error_dialog(gtkimage, _errmsg)

#------------------------------------------------------------
def file_save_cb(menuitem, gtkimage):
    _fname = gtkimage.getFilename()
    if _fname is None:
        _get_filename_and_save(gtkimage)
    else:
        try:
            _save_file(gtkimage, _fname)
        except (IOError, OSError), _e:
            _errmsg = "Error saving '%s' : %s'" % (_fname, _e)
            _error_dialog(gtkimage, _errmsg)
        except StandardError, _e:
            _errmsg = "Non-system error saving '%s' : %s'" % (_fname, _e)
            _error_dialog(gtkimage, _errmsg)

#------------------------------------------------------------
def file_save_as_cb(menuitem, gtkimage):
    _fname = gtkimage.getFilename()
    if _fname is None:
        _fname = gtkimage.getWindow().get_title()
    _get_filename_and_save(gtkimage, _fname)

#------------------------------------------------------------
def file_save_layer_cb(menuitem, gtkimage):
    # print "called file_save_layer_cb()"
    active = gtkimage.getActiveLayer()
    layer_name = active.getName()
    dialog = gtk.FileSelection("Save Layer As ...")
    dialog.set_transient_for(gtkimage.getWindow())
    dialog.set_filename(layer_name)
    response = dialog.run()
    if response == gtk.RESPONSE_OK:
        fname = dialog.get_filename()
        print "Saving layer as '%s'" % fname
        #
        # fixme - add the layer saving code ...
        #
    dialog.destroy()

#------------------------------------------------------------
def file_print_screen_cb(menuitem, gtkimage):
    _plot = plotfile.Plot(gtkimage)
    _xmin, _ymin, _xmax, _ymax = gtkimage.getView()
    _plot.setBounds(_xmin, _ymin, _xmax, _ymax)
    gtkprinting.print_dialog(gtkimage, _plot)
    
#------------------------------------------------------------
def file_print_cb(menuitem, gtkimage):
    _tool = tools.PlotTool()
    gtkimage.setTool(_tool)
    gtkprinting.plot_mode_init(gtkimage, _tool)

#------------------------------------------------------------
def file_quit_cb(menuitem, gtkimage):
    gtk.main_quit()

#------------------------------------------------------------
def _select_all_cb(menuitem, gtkimage):
    _group = gtkimage.getGroup('Edit')
    if _group is not None:
        _layer = gtkimage.getActiveLayer()
        _act = _group.get_action('SelectAllPoints')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('point') > 0)
        _act = _group.get_action('SelectAllSegments')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('segment') > 0)
        _act = _group.get_action('SelectAllCircles')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('circle') > 0)
        _act = _group.get_action('SelectAllArcs')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('arc') > 0)
        _act = _group.get_action('SelectAllLeaders')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('leader') > 0)
        _act = _group.get_action('SelectAllPolylines')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('polyline') > 0)
        _act = _group.get_action('SelectAllChamfers')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('chamfer') > 0)
        _act = _group.get_action('SelectAllFillets')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('fillet') > 0)
        _act = _group.get_action('SelectAllHCLines')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('hcline') > 0)
        _act = _group.get_action('SelectAllVCLines')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('vcline') > 0)
        _act = _group.get_action('SelectAllACLines')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('acline') > 0)
        _act = _group.get_action('SelectAllCLines')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('cline') > 0)
        _act = _group.get_action('SelectAllCCircles')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('ccircle') > 0)
        _act = _group.get_action('SelectAllTextBlocks')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('textblock') > 0)
        _act = _group.get_action('SelectAllLDims')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('linear_dimension') > 0)
        _act = _group.get_action('SelectAllHDims')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('horizontal_dimension') > 0)
        _act = _group.get_action('SelectAllVDims')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('vertical_dimension') > 0)
        _act = _group.get_action('SelectAllRDims')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('radial_dimension') > 0)
        _act = _group.get_action('SelectAllADims')
        if _act is not None:
            _act.set_property('sensitive', _layer.getEntityCount('angular_dimension') > 0)

#------------------------------------------------------------
def edit_undo_cb(menuitem, gtkimage):
    gtkimage.doUndo()
    gtkimage.redraw()

#------------------------------------------------------------
def edit_redo_cb(menuitem, gtkimage):
    gtkimage.doRedo()
    gtkimage.redraw()

#------------------------------------------------------------
def edit_copy_cb(menuitem, gtkimage):
    for _obj in gtkimage.getSelectedObjects():
        if _obj.getParent() is not None:
            globals.selectobj.storeObject(_obj)

#------------------------------------------------------------
def edit_cut_cb(menuitem, gtkimage):
    gtkimage.startAction()
    try:
        for _obj in gtkimage.getSelectedObjects():
            globals.selectobj.storeObject(_obj)
            #
            # check that the object parent is not None - if it
            # is then the object was deleted as a result of the
            # deletion of an earlier object (i.e. dimension)
            #
            _layer = _obj.getParent()
            if _layer is not None:
                _layer.delObject(_obj)
    finally:
        gtkimage.endAction()
    gtkimage.redraw()

#------------------------------------------------------------
def edit_paste_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click where you want to paste the objects")
    gtkedit.paste_mode_init(_tool)

#------------------------------------------------------------
def edit_select_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the items you want to select.")
    gtkedit.select_mode_init(_tool)

#------------------------------------------------------------
def edit_deselect_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the items you want to deselect.")
    gtkedit.deselect_mode_init(_tool)
        
#------------------------------------------------------------
def select_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the items you want to select.")
    gtkedit.select_mode_init(_tool)

#------------------------------------------------------------
def select_all_points_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _point in _active_layer.getLayerEntities("point"):
        gtkimage.selectObject(_point)

#------------------------------------------------------------
def select_all_segments_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _segment in _active_layer.getLayerEntities("segment"):
        gtkimage.selectObject(_segment)

#------------------------------------------------------------
def select_all_circles_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _circle in _active_layer.getLayerEntities("circle"):
        gtkimage.selectObject(_circle)

#------------------------------------------------------------
def select_all_arcs_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _arc in _active_layer.getLayerEntities("arc"):
        gtkimage.selectObject(_arc)

#------------------------------------------------------------
def select_all_hclines_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _hcl in _active_layer.getLayerEntities("hcline"):
        gtkimage.selectObject(_hcl)

#------------------------------------------------------------
def select_all_vclines_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _vcl in _active_layer.getLayerEntities("vcline"):
        gtkimage.selectObject(_vcl)

#------------------------------------------------------------
def select_all_aclines_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _acl in _active_layer.getLayerEntities("acline"):
        gtkimage.selectObject(_acl)

#------------------------------------------------------------
def select_all_clines_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _cline in _active_layer.getLayerEntities("cline"):
        gtkimage.selectObject(_cline)

#------------------------------------------------------------
def select_all_ccircles_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _ccircle in _active_layer.getLayerEntities("ccircle"):
        gtkimage.selectObject(_ccircle)

#------------------------------------------------------------
def select_all_leaders_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _leader in _active_layer.getLayerEntities("leader"):
        gtkimage.selectObject(_leader)

#------------------------------------------------------------
def select_all_polylines_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _pline in _active_layer.getLayerEntities("polyline"):
        gtkimage.selectObject(_pline)

#------------------------------------------------------------
def select_all_ldims_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _ldim in _active_layer.getLayerEntities("linear_dimension"):
        gtkimage.selectObject(_ldim)

#------------------------------------------------------------
def select_all_hdims_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _hdim in _active_layer.getLayerEntities("horizontal_dimension"):
        gtkimage.selectObject(_hdim)

#------------------------------------------------------------
def select_all_vdims_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _vdim in _active_layer.getLayerEntities("vertical_dimension"):
        gtkimage.selectObject(_vdim)

def select_all_rdims_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _rdim in _active_layer.getLayerEntities("radial_dimension"):
        gtkimage.selectObject(_rdim)

def select_all_adims_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _adim in _active_layer.getLayerEntities("angular_dimension"):
        gtkimage.selectObject(_adim)

def select_all_tblocks_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _tb in _active_layer.getLayerEntities("textblock"):
        gtkimage.selectObject(_tb)

def select_all_chamfers_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _ch in _active_layer.getLayerEntities("chamfer"):
        gtkimage.selectObject(_ch)

def select_all_fillets_cb(menuitem, gtkimage):
    _active_layer = gtkimage.getActiveLayer()
    for _f in _active_layer.getLayerEntities("fillet"):
        gtkimage.selectObject(_f)

def prefs_cb(menuitem, gtkimage):
    gtkprefs.prefs_dialog(gtkimage)

def draw_point_cb(menuitem, gtkimage):
    _tool = tools.PointTool()
    gtkimage.setTool(_tool)
    gtkentities.point_mode_init(gtkimage, _tool)

def draw_segment_cb(menuitem, gtkimage):
    _tool = tools.SegmentTool()
    gtkimage.setTool(_tool)
    gtkentities.segment_mode_init(gtkimage, _tool)

def draw_rectangle_cb(menuitem, gtkimage):
    _tool = tools.RectangleTool()
    gtkimage.setTool(_tool)
    gtkentities.rectangle_mode_init(gtkimage, _tool)

def draw_circle_center_cb(menuitem, gtkimage):
    _tool = tools.CircleTool()
    gtkimage.setTool(_tool)
    gtkentities.circle_center_mode_init(gtkimage, _tool)

def draw_circle_tp_cb(menuitem, gtkimage):
    _tool = tools.TwoPointCircleTool()
    gtkimage.setTool(_tool)
    gtkentities.circle_tp_mode_init(gtkimage, _tool)

def draw_arc_center_cb(menuitem, gtkimage):
    _tool = tools.ArcTool()
    gtkimage.setTool(_tool)
    gtkentities.arc_center_mode_init(gtkimage, _tool)

def draw_hcl_cb(menuitem, gtkimage):
    _tool = tools.HCLineTool()
    gtkimage.setTool(_tool)
    gtkconobjs.hcline_mode_init(gtkimage, _tool)

def draw_vcl_cb(menuitem, gtkimage):
    _tool = tools.VCLineTool()
    gtkimage.setTool(_tool)
    gtkconobjs.vcline_mode_init(gtkimage, _tool)

def draw_acl_cb(menuitem, gtkimage):
    _tool = tools.ACLineTool()
    gtkimage.setTool(_tool)
    gtkconobjs.acline_mode_init(gtkimage, _tool)

def draw_cl_cb(menuitem, gtkimage):
    _tool = tools.CLineTool()
    gtkimage.setTool(_tool)
    gtkconobjs.cline_mode_init(gtkimage, _tool)

def draw_perpendicular_cline_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the object you want a perpendicular to")
    gtkconobjs.perpendicular_cline_mode_init(_tool)

def draw_tangent_cline_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the circle object you want a tangent to")
    gtkconobjs.tangent_cline_mode_init(_tool)

def draw_tangent_two_ccircles_cb(menuitem, gtkimage):
    _tool = tools.CCircleTangentLineTool()
    gtkimage.setTool(_tool)
    gtkconobjs.two_circle_tangent_line_mode_init(gtkimage, _tool)

def draw_poffset_cline_cb(menuitem, gtkimage):
    _tool = tools.ParallelOffsetTool()
    gtkimage.setTool(_tool)
    gtkconobjs.parallel_offset_mode_init(gtkimage, _tool)

def draw_ccirc_cp_cb(menuitem, gtkimage):
    _tool = tools.CCircleTool()
    gtkimage.setTool(_tool)
    # gtkimage.setPrompt("Click in the drawing area or enter a Point")
    gtkconobjs.ccircle_cpmode_init(gtkimage, _tool)

def draw_ccirc_tp_cb(menuitem, gtkimage):
    _tool = tools.TwoPointCCircleTool()
    gtkimage.setTool(_tool)
    # gtkimage.setPrompt("Click in the drawing area or enter a Point")
    gtkconobjs.ccircle_tpmode_init(gtkimage, _tool)

def draw_tangent_single_conobj_cb(menuitem, gtkimage):
    _tool = tools.TangentCCircleTool()
    gtkimage.setTool(_tool)
    gtkconobjs.tangent_ccircle_mode_init(gtkimage, _tool)

def draw_tangent_two_conobjs_cb(menuitem, gtkimage):
    # print "two_conobjs_cb() ..."
    _tool = tools.TwoPointTangentCCircleTool()
    gtkimage.setTool(_tool)
    gtkconobjs.two_cline_tancc_mode_init(gtkimage, _tool)

def draw_chamfer_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the points where you want a chamfer.")
    gtkentities.chamfer_mode_init(_tool)

def draw_fillet_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the points where you want a fillet.")
    gtkentities.fillet_mode_init(_tool)

def draw_leader_cb(menuitem, gtkimage):
    _tool = tools.LeaderTool()
    gtkimage.setTool(_tool)
    gtkentities.leader_mode_init(gtkimage, _tool)

def draw_polyline_cb(menuitem, gtkimage):
    _tool = tools.PolylineTool()
    gtkimage.setTool(_tool)
    gtkentities.polyline_mode_init(gtkimage, _tool)

def _get_polygon_side_count(gtkimage):
    _sides = 0
    _window = gtkimage.getWindow()
    _dialog = gtk.Dialog("Polygon Sides", _window,
                         gtk.DIALOG_MODAL,
                         (gtk.STOCK_OK, gtk.RESPONSE_OK,
                          gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
    _hbox = gtk.HBox(False, 10)
    _hbox.set_border_width(10)
    _dialog.vbox.pack_start(_hbox, False, False, 0)
    _stock = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION,
                                      gtk.ICON_SIZE_DIALOG)
    _hbox.pack_start(_stock, False, False, 0)
    _label = gtk.Label("Number of sides:")
    _hbox.pack_start(_label, False, False, 0)
    _adj = gtk.Adjustment(3, 3, 3600, 1, 1, 1) # arbitrary max ...
    _sb = gtk.SpinButton(_adj)
    _sb.set_numeric(True)
    _hbox.pack_start(_sb, True, True, 0)
    _dialog.show_all()
    _response = _dialog.run()
    if _response == gtk.RESPONSE_OK:
        _sides = _sb.get_value()
    _dialog.destroy()
    return _sides

def draw_polygon_cb(menuitem, gtkimage):
    _sides = _get_polygon_side_count(gtkimage)
    if _sides > 0:
        _tool = tools.PolygonTool()
        _tool.setSideCount(_sides)
        gtkimage.setTool(_tool)
        gtkentities.polygon_mode_init(gtkimage, _tool)

def draw_ext_polygon_cb(menuitem, gtkimage):
    _sides = _get_polygon_side_count(gtkimage)
    if _sides > 0:
        _tool = tools.PolygonTool()
        _tool.setExternal()
        _tool.setSideCount(_sides)
        gtkimage.setTool(_tool)
        gtkentities.polygon_mode_init(gtkimage, _tool)

def draw_set_style_cb(menuitem, gtkimage):
    gtkentities.set_active_style(gtkimage)

def draw_set_linetype_cb(menuitem, gtkimage):
    gtkentities.set_active_linetype(gtkimage)

def draw_set_color_cb(menuitem, gtkimage):
    gtkentities.set_active_color(gtkimage)

def draw_set_thickness_cb(menuitem, gtkimage):
    gtkentities.set_line_thickness(gtkimage)

def draw_text_cb(menuitem, gtkimage):
    _text = gtktext.text_add_dialog(gtkimage)
    if _text is not None:
        _tool = tools.TextTool()
        _tool.setText(_text)
        gtkimage.setTool(_tool)
        gtktext.text_add_init(gtkimage, _tool)

def move_horizontal_cb(menuitem, gtkimage):
    _tool = tools.HorizontalMoveTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the drawing area or enter the distance.")
    gtkmodify.move_horizontal_init(_tool)

def move_vertical_cb(menuitem, gtkimage):
    _tool = tools.VerticalMoveTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the drawing area or enter the distance.")
    gtkmodify.move_vertical_init(_tool)

def move_twopoint_cb(menuitem, gtkimage):
    _tool = tools.MoveTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the drawing area or enter the x and y distances.")
    gtkmodify.move_twopoint_init(_tool)

def stretch_horiz_cb(menuitem, gtkimage):
    _tool = tools.HorizontalStretchTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on a point or enter the horizontal distance.")
    gtkmodify.stretch_horizontal_init(_tool)

def stretch_vert_cb(menuitem, gtkimage):
    _tool = tools.VerticalStretchTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the drawing area or enter the distance.")
    gtkmodify.stretch_vertical_init(_tool)

def stretch_twopoint_cb(menuitem, gtkimage):
    _tool = tools.StretchTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the drawing area or enter the x and y distances.")
    gtkmodify.stretch_xy_init(_tool)

def transfer_object_cb(menuitem, gtkimage):
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    prompt = "Click on the objects you want to transfer to the active layer"
    gtkimage.setPrompt(prompt)
    gtkmodify.transfer_object_init(_tool)

def split_object_cb(menuitem, gtkimage):
    _tool = tools.SplitTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the objects you want to split")
    gtkmodify.split_object_init(gtkimage, _tool)

def mirror_object_cb(menuitem, gtkimage):
    _tool = tools.MirrorTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the mirroring construction line.")
    gtkmirror.mirror_mode_init(_tool)

def delete_cb(menuitem, gtkimage):
    _tool = tools.DeleteTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the items you want to delete.")
    gtkmodify.delete_mode_init(_tool)

def change_style_cb(menuitem, gtkimage):
    _st = gtkmodify.change_style_dialog(gtkimage)
    if _st is not None:
        _tool = tools.GraphicObjectTool()
        _tool.setAttribute('setStyle')
        _tool.setValue(_st)
        _tool.setObjtype(graphicobject.GraphicObject)
        gtkimage.setTool(_tool)
        gtkmodify.change_style_init(gtkimage, _tool)

def change_color_cb(menuitem, gtkimage):
    _color = gtkmodify.change_color_dialog(gtkimage)
    if _color is not None:
        _tool = tools.GraphicObjectTool()
        _tool.setAttribute('setColor')
        _tool.setValue(_color)
        _tool.setObjtype(graphicobject.GraphicObject)
        gtkimage.setTool(_tool)
        gtkmodify.change_color_init(gtkimage, _tool)

def change_linetype_cb(menuitem, gtkimage):
    _lt = gtkmodify.change_linetype_dialog(gtkimage)
    if _lt is not None:
        _tool = tools.GraphicObjectTool()
        _tool.setAttribute('setLinetype')
        _tool.setValue(_lt)
        _tool.setObjtype(graphicobject.GraphicObject)
        gtkimage.setTool(_tool)
        gtkmodify.change_linetype_init(gtkimage, _tool)

def change_thickness_cb(menuitem, gtkimage):
    _t = gtkmodify.change_thickness_dialog(gtkimage)
    if _t is not None:
        _tool = tools.GraphicObjectTool()
        _tool.setAttribute('setThickness')
        _tool.setValue(_t)
        _tool.setObjtype(graphicobject.GraphicObject)
        gtkimage.setTool(_tool)
        gtkmodify.change_thickness_init(gtkimage, _tool)

def change_textblock_style_cb(menuitem, gtkimage):
    _st = gtkmodify.change_textblock_style_dialog(gtkimage, 'FONT_STYLE')
    if _st is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setStyle')
        _tool.setValue(_st)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_style_init(gtkimage, _tool)

def change_textblock_weight_cb(menuitem, gtkimage):
    _w = gtkmodify.change_textblock_weight_dialog(gtkimage, 'FONT_WEIGHT')
    if _w is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setWeight')
        _tool.setValue(_w)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_weight_init(gtkimage, _tool)

def change_textblock_alignment_cb(menuitem, gtkimage):
    _align = gtkmodify.change_textblock_alignment_dialog(gtkimage, 'TEXT_ALIGNMENT')
    if _align is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setAlignment')
        _tool.setValue(_align)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_alignment_init(gtkimage, _tool)

def change_textblock_size_cb(menuitem, gtkimage):
    _size = gtkmodify.change_textblock_size_dialog(gtkimage, 'TEXT_SIZE')
    if _size is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setSize')
        _tool.setValue(_size)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_size_init(gtkimage, _tool)

def change_textblock_family_cb(menuitem, gtkimage):
    _family = gtkmodify.change_textblock_family_dialog(gtkimage, 'FONT_FAMILY')
    if _family is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setFamily')
        _tool.setValue(_family)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_family_init(gtkimage, _tool)

def change_textblock_color_cb(menuitem, gtkimage):
    _color = gtkmodify.change_textblock_color_dialog(gtkimage, 'FONT_COLOR')
    if _color is not None:
        _tool = tools.TextTool()
        _tool.setAttribute('setColor')
        _tool.setValue(_color)
        _tool.setObjtype(text.TextBlock)
        gtkimage.setTool(_tool)
        gtkmodify.change_textblock_color_init(gtkimage, _tool)

def change_dim_endpoint_cb(menuitem, gtkimage):
    _et = gtkmodify.change_dim_endpoint_dialog(gtkimage)
    if _et is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setEndpointType')
        _tool.setValue(_et)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_endpoint_init(gtkimage, _tool)

def change_dim_endpoint_size_cb(menuitem, gtkimage):
    _es = gtkmodify.change_dim_endpoint_size_dialog(gtkimage)
    if _es is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setEndpointSize')
        _tool.setValue(_es)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_endpoint_size_init(gtkimage, _tool)

def change_dim_offset_cb(menuitem, gtkimage):
    _offset = gtkmodify.change_dim_offset_dialog(gtkimage)
    if _offset is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setOffset')
        _tool.setValue(_offset)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_offset_init(gtkimage, _tool)

def change_dim_extension_cb(menuitem, gtkimage):
    _ext = gtkmodify.change_dim_extension_dialog(gtkimage)
    if _ext is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setExtension')
        _tool.setValue(_ext)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_extension_init(gtkimage, _tool)

def change_dim_dual_mode_cb(menuitem, gtkimage):
    _ddm = gtkmodify.change_dim_dual_mode_dialog(gtkimage)
    if _ddm is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setDualDimMode')
        _tool.setValue(_ddm)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_dual_mode_init(gtkimage, _tool)

def change_dim_dual_mode_offset_cb(menuitem, gtkimage):
    _dmo = gtkmodify.change_dim_dual_mode_offset_dialog(gtkimage)
    if _dmo is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setDualModeOffset')
        _tool.setValue(_dmo)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_dual_mode_offset_init(gtkimage, _tool)

def change_dim_thickness_cb(menuitem, gtkimage):
    _t = gtkmodify.change_dim_thickness_dialog(gtkimage)
    if _t is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setThickness')
        _tool.setValue(_t)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_thickness_init(gtkimage, _tool)

def change_dim_color_cb(menuitem, gtkimage):
    _color = gtkmodify.change_dim_color_dialog(gtkimage)
    if _color is not None:
        _tool = tools.EditDimensionTool()
        _tool.setAttribute('setColor')
        _tool.setValue(_color)
        _tool.setObjtype(dimension.Dimension)
        gtkimage.setTool(_tool)
        gtkmodify.change_dim_color_init(gtkimage, _tool)

def _change_dimstring_style_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setStyle')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_style_init(gtkimage, _tool)

def change_dim_primary_style_cb(menuitem, gtkimage):
    _st = gtkmodify.change_textblock_style_dialog(gtkimage, 'DIM_PRIMARY_FONT_STYLE')
    if _st is not None:
        _change_dimstring_style_cb(gtkimage, _st, True)

def change_dim_secondary_style_cb(menuitem, gtkimage):
    _st = gtkmodify.change_textblock_style_dialog(gtkimage, 'DIM_SECONDARY_FONT_STYLE')
    if _st is not None:
        _change_dimstring_style_cb(gtkimage, _st, False)

def _change_dimstring_family_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setFamily')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_family_init(gtkimage, _tool)

def change_dim_primary_family_cb(menuitem, gtkimage):
    _family = gtkmodify.change_textblock_family_dialog(gtkimage, 'DIM_PRIMARY_FONT_FAMILY')
    if _family is not None:
        _change_dimstring_family_cb(gtkimage, _family, True)

def change_dim_secondary_family_cb(menuitem, gtkimage):
    _family = gtkmodify.change_textblock_family_dialog(gtkimage, 'DIM_SECONDARY_FONT_FAMILY')
    if _family is not None:
        _change_dimstring_family_cb(gtkimage, _family, False)

def _change_dimstring_weight_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setWeight')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_weight_init(gtkimage, _tool)

def change_dim_primary_weight_cb(menuitem, gtkimage):
    _weight = gtkmodify.change_textblock_weight_dialog(gtkimage, 'DIM_PRIMARY_FONT_WEIGHT')
    if _weight is not None:
        _change_dimstring_weight_cb(gtkimage, _weight, True)

def change_dim_secondary_weight_cb(menuitem, gtkimage):
    _weight = gtkmodify.change_textblock_weight_dialog(gtkimage, 'DIM_SECONDARY_FONT_WEIGHT')
    if _weight is not None:
        _change_dimstring_weight_cb(gtkimage, _weight, False)

def _change_dimstring_size_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setSize')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_size_init(gtkimage, _tool)

def change_dim_primary_size_cb(menuitem, gtkimage):
    _size = gtkmodify.change_textblock_size_dialog(gtkimage, 'DIM_PRIMARY_TEXT_SIZE')
    if _size is not None:
        _change_dimstring_size_cb(gtkimage, _size, True)

def change_dim_secondary_size_cb(menuitem, gtkimage):
    _size = gtkmodify.change_textblock_size_dialog(gtkimage, 'DIM_SECONDARY_TEXT_SIZE')
    if _size is not None:
        _change_dimstring_size_cb(gtkimage, _size, False)

def _change_dimstring_color_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setColor')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_color_init(gtkimage, _tool)

def change_dim_primary_color_cb(menuitem, gtkimage):
    _color = gtkmodify.change_textblock_color_dialog(gtkimage, 'DIM_PRIMARY_FONT_COLOR')
    if _color is not None:
        _change_dimstring_color_cb(gtkimage, _color, True)

def change_dim_secondary_color_cb(menuitem, gtkimage):
    _color = gtkmodify.change_textblock_color_dialog(gtkimage, 'DIM_SECONDARY_FONT_COLOR')
    if _color is not None:
        _change_dimstring_color_cb(gtkimage, _color, False)

def _change_dimstring_alignment_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setAlignment')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_alignment_init(gtkimage, _tool)

def change_dim_primary_alignment_cb(menuitem, gtkimage):
    _align = gtkmodify.change_textblock_alignment_dialog(gtkimage, 'DIM_PRIMARY_TEXT_ALIGNMENT')
    if _align is not None:
        _change_dimstring_alignment_cb(gtkimage, _align, True)

def change_dim_secondary_alignment_cb(menuitem, gtkimage):
    _align = gtkmodify.change_textblock_alignment_dialog(gtkimage, 'DIM_SECONDARY_TEXT_ALIGNMENT')
    if _align is not None:
        _change_dimstring_alignment_cb(gtkimage, _align, False)

def _change_dimstring_prefix_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setPrefix')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)

def change_ldim_pds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'DIM_PRIMARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, True)
        gtkmodify.change_ldimstr_prefix_init(gtkimage, gtkimage.getTool())

def change_ldim_sds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'DIM_SECONDARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, False)
        gtkmodify.change_ldimstr_prefix_init(gtkimage, gtkimage.getTool())

def change_rdim_pds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'RADIAL_DIM_PRIMARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, True)
        gtkmodify.change_rdimstr_prefix_init(gtkimage, gtkimage.getTool())

def change_rdim_sds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'RADIAL_DIM_SECONDARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, False)
        gtkmodify.change_rdimstr_prefix_init(gtkimage, gtkimage.getTool())

def change_adim_pds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'ANGULAR_DIM_PRIMARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, True)
        gtkmodify.change_adimstr_prefix_init(gtkimage, gtkimage.getTool())

def change_adim_sds_prefix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_prefix_dialog(gtkimage, 'ANGULAR_DIM_SECONDARY_PREFIX')
    if _text is not None:
        _change_dimstring_prefix_cb(gtkimage, _text, False)
        gtkmodify.change_adimstr_prefix_init(gtkimage, gtkimage.getTool())

def _change_dimstring_suffix_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setSuffix')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)

def change_ldim_pds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'DIM_PRIMARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, True)
        gtkmodify.change_ldimstr_suffix_init(gtkimage, gtkimage.getTool())

def change_ldim_sds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'DIM_SECONDARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, False)
        gtkmodify.change_ldimstr_suffix_init(gtkimage, gtkimage.getTool())

def change_rdim_pds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'RADIAL_DIM_PRIMARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, True)
        gtkmodify.change_rdimstr_suffix_init(gtkimage, gtkimage.getTool())

def change_rdim_sds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'RADIAL_DIM_SECONDARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, False)
        gtkmodify.change_rdimstr_suffix_init(gtkimage, gtkimage.getTool())

def change_adim_pds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'ANGULAR_DIM_PRIMARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, True)
        gtkmodify.change_adimstr_suffix_init(gtkimage, gtkimage.getTool())

def change_adim_sds_suffix_cb(menuitem, gtkimage):
    _text = gtkmodify.change_dimstr_suffix_dialog(gtkimage, 'ANGULAR_DIM_SECONDARY_SUFFIX')
    if _text is not None:
        _change_dimstring_suffix_cb(gtkimage, _text, False)
        gtkmodify.change_adimstr_suffix_init(gtkimage, gtkimage.getTool())

def _change_dimstring_precision_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setPrecision')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_precision_init(gtkimage, _tool)

def change_dim_primary_precision_cb(menuitem, gtkimage):
    _prec = gtkmodify.change_dimstr_precision_dialog(gtkimage, 'DIM_PRIMARY_PRECISION')
    if _prec is not None:
        _change_dimstring_precision_cb(gtkimage, _prec, True)

def change_dim_secondary_precision_cb(menuitem, gtkimage):
    _prec = gtkmodify.change_dimstr_precision_dialog(gtkimage, 'DIM_SECONDARY_PRECISION')
    if _prec is not None:
        _change_dimstring_precision_cb(gtkimage, _prec, False)

def _change_dimstring_units_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setUnits')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_precision_init(gtkimage, _tool)

def change_dim_primary_units_cb(menuitem, gtkimage):
    _unit = gtkmodify.change_dimstr_units_dialog(gtkimage, 'DIM_PRIMARY_UNITS')
    if _unit is not None:
        _change_dimstring_units_cb(gtkimage, _unit, True)

def change_dim_secondary_units_cb(menuitem, gtkimage):
    _unit = gtkmodify.change_dimstr_units_dialog(gtkimage, 'DIM_SECONDARY_UNITS')
    if _unit is not None:
        _change_dimstring_units_cb(gtkimage, _unit, False)

def _change_dimstring_print_zero_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setPrintZero')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_print_zero_init(gtkimage, _tool)

def change_dim_primary_print_zero_cb(menuitem, gtkimage):
    _flag = gtkmodify.change_dimstr_print_zero_dialog(gtkimage, 'DIM_PRIMARY_LEADING_ZERO')
    if _flag is not None:
        _change_dimstring_print_zero_cb(gtkimage, _flag, True)

def change_dim_secondary_print_zero_cb(menuitem, gtkimage):
    _flag = gtkmodify.change_dimstr_print_zero_dialog(gtkimage, 'DIM_SECONDARY_LEADING_ZERO')
    if _flag is not None:
        _change_dimstring_print_zero_cb(gtkimage, _flag, False)

def _change_dimstring_print_decimal_cb(gtkimage, val, flag):
    _tool = tools.EditDimStringTool()
    _tool.setAttribute('setPrintDecimal')
    _tool.setValue(val)
    _tool.setPrimary(flag)
    _tool.setObjtype(dimension.DimString)
    gtkimage.setTool(_tool)
    gtkmodify.change_dimstr_print_decimal_init(gtkimage, _tool)

def change_dim_primary_print_decimal_cb(menuitem, gtkimage):
    _flag = gtkmodify.change_dimstr_print_decimal_dialog(gtkimage, 'DIM_PRIMARY_TRAILING_DECIMAL')
    if _flag is not None:
        _change_dimstring_print_decimal_cb(gtkimage, _flag, True)

def change_dim_secondary_print_decimal_cb(menuitem, gtkimage):
    _flag = gtkmodify.change_dimstr_print_decimal_dialog(gtkimage, 'DIM_SECONDARY_TRAILING_DECIMAL')
    if _flag is not None:
        _change_dimstring_print_decimal_cb(gtkimage, _flag, False)

def change_rdim_dia_mode_cb(menuitem, gtkimage):
    _tool = tools.EditDimensionTool()
    _tool.setObjtype(dimension.RadialDimension)
    gtkimage.setTool(_tool)
    gtkmodify.change_rdim_dia_mode_init(gtkimage, _tool)

def change_adim_invert_cb(menuitem, gtkimage):
    _tool = tools.EditDimensionTool()
    _tool.setObjtype(dimension.AngularDimension)
    gtkimage.setTool(_tool)
    gtkmodify.invert_adim_init(gtkimage, _tool)

    
def zoom_cb(menuitem, gtkimage):
    # print "in zoom_cb()"
    _tool = tools.Tool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click in the window.")
    gtkmodify.zoom_init(_tool)

def zoom_in_cb(menuitem, gtkimage):
    _xmin, _ymin, _xmax, _ymax = gtkimage.getView()
    _scale = gtkimage.getUnitsPerPixel()
    _xdiff = abs(_xmax - _xmin)
    _ydiff = abs(_ymax - _ymin)
    _xmin = (_xmin + _xmax)/2.0 - _xdiff/4.0
    _ymin = (_ymin + _ymax)/2.0 - _ydiff/4.0
    gtkimage.setView(_xmin, _ymin, (_scale/2.0))
    gtkimage.redraw()

def zoom_out_cb(menuitem, gtkimage):
    _xmin, _ymin, _xmax, _ymax = gtkimage.getView()
    _scale = gtkimage.getUnitsPerPixel()
    _xdiff = abs(_xmax - _xmin)
    _ydiff = abs(_ymax - _ymin)
    _xmin = (_xmin + _xmax)/2.0 - _xdiff
    _ymin = (_ymin + _ymax)/2.0 - _ydiff
    gtkimage.setView(_xmin, _ymin, (_scale * 2.0))
    gtkimage.redraw()

def zoom_fit_cb(menuitem, gtkimage):
    gtkimage.fitImage()

def dimension_linear_cb(menuitem, gtkimage):
    _tool = tools.LinearDimensionTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the first point for the dimension.")
    gtkdimension.linear_mode_init(_tool)

def dimension_horizontal_cb(menuitem, gtkimage):
    _tool = tools.HorizontalDimensionTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the first point for the dimension.")
    gtkdimension.horizontal_mode_init(_tool)

def dimension_vertical_cb(menuitem, gtkimage):
    _tool = tools.VerticalDimensionTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the first point for the dimension.")
    gtkdimension.vertical_mode_init(_tool)

def dimension_radial_cb(menuitem, gtkimage):
    _tool = tools.RadialDimensionTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on an arc or a circle to dimension.")
    gtkdimension.radial_mode_init(_tool)

def dimension_angular_cb(menuitem, gtkimage):
    _tool = tools.AngularDimensionTool()
    gtkimage.setTool(_tool)
    gtkimage.setPrompt("Click on the angle vertex point or an arc.")
    gtkdimension.angular_mode_init(_tool)

def get_focus_widget_cb(menuitem, gtkimage):
    _widget = gtkimage.getWindow().get_focus()
    print "Focus widget: " + str(_widget)

def get_undo_stack_cb(menuitem, gtkimage):
    _layer = gtkimage.getActiveLayer()
    _log = _layer.getLog()
    if _log is not None:
        _log.printUndoData()

def get_redo_stack_cb(menuitem, gtkimage):
    _layer = gtkimage.getActiveLayer()
    _log = _layer.getLog()
    if _log is not None:
        _log.printRedoData()

def get_image_undo_cb(menuitem, gtkimage):
    gtkimage.printStack(True)

def get_image_redo_cb(menuitem, gtkimage):
    gtkimage.printStack(False)

def collect_garbage_cb(menuitem, gtkimage):
    if 'gc' in sys.modules:
        _lost = gc.collect()
        print "%d lost objects: " % _lost


def _debug_cb(action, *args):
    print "_debug_cb()"
    print "action: " + `action`
    print "args: " + str(args)
    _group = action.get_property('action-group')
    if _group is not None:
        for _act in _group.list_actions():
            _name = _act.get_name()
            print "Action name: %s" % _name

def _std_cb(action, *args):
    print "_std_cb()"
    _name = action.get_name()
    print "Action name: %s" % _name

def _add_accelerators(action, menuitem, accelgroup):
    _path = action.get_accel_path()
    if _path is not None:
        _data = gtk.accel_map_lookup_entry(_path)
        if _data is not None:
            _k, _m = _data
            if gtk.accelerator_valid(_k, _m):
                menuitem.add_accelerator('activate', accelgroup,
                                         _k, _m, gtk.ACCEL_VISIBLE)



#############################################################################
#
# Menu item definitions -- These define the individual menu items,
# and the actions taken (callbacks invoked) when they are selected.
#
#############################################################################

######################  File menu  ##########################
def _file_menu_init(menuitem, gtkimage):
    _group = gtkimage.getGroup('File')
    if _group is not None:
        _act = _group.get_action('SaveLayerAs')
        if _act is not None:
            _act.set_property('sensitive', False)
            
#------------------------------------------------------------
def _make_file_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    #
    _act = gtk.Action('New', '_New', None, gtk.STOCK_NEW)
    _act.connect('activate', file_new_cb)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Open', '_Open', None, gtk.STOCK_OPEN)
    _act.connect('activate', file_open_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Close', '_Close', None, gtk.STOCK_CLOSE)
    _act.connect('activate', file_close_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Save', '_Save', None, gtk.STOCK_SAVE)
    _act.connect('activate', file_save_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('SaveAs', 'Save _As ...', None, None)
    _act.connect('activate', file_save_as_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SaveLayerAs', 'Save _Layer As ...', None, None)
    _act.connect('activate', file_save_layer_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('PrintScreen', 'Print Screen', None, None)
    _act.connect('activate', file_print_screen_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Print', '_Print', None, gtk.STOCK_PRINT)
    _act.connect('activate', file_print_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, '<control>P')
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Quit', '_Quit', None, gtk.STOCK_QUIT)
    _act.connect('activate', file_quit_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    return _menu

#######################  Edit menu  ###########################
def _edit_menu_init(menuitem, gtkimage):
    _group = gtkimage.getGroup('Edit')
    if _group is not None:
        _act = _group.get_action('Undo')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.canUndo())
        _act = _group.get_action('Redo')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.canRedo())
        _act = _group.get_action('Cut')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.hasSelection())
        _act = _group.get_action('Copy')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.hasSelection())
        _act = _group.get_action('Paste')
        if _act is not None:
            _act.set_property('sensitive', globals.selectobj.hasObjects())
        _act = _group.get_action('Select')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.getActiveLayer().hasEntities())
        _act = _group.get_action('SelectAll')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.getActiveLayer().hasEntities())
        _act = _group.get_action('Deselect')
        if _act is not None:
            _act.set_property('sensitive', gtkimage.hasSelection())
            

#############################################################################
#  Edit -> select all submenu
#############################################################################
def _make_select_all_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    #
    _act = gtk.Action('SelectAllPoints', '_Points', None, None)
    _act.connect('activate', select_all_points_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllSegments', '_Segments', None, None)
    _act.connect('activate', select_all_segments_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllCircles', '_Circles', None, None)
    _act.connect('activate', select_all_circles_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllArcs', '_Arcs', None, None)
    _act.connect('activate', select_all_arcs_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllLeaders', '_Leaders', None, None)
    _act.connect('activate', select_all_leaders_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllPolylines', '_Polylines', None, None)
    _act.connect('activate', select_all_polylines_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllChamfers', 'Cha_mfers', None, None)
    _act.connect('activate', select_all_chamfers_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllFillets', '_Fillets', None, None)
    _act.connect('activate', select_all_fillets_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('SelectAllHCLines', '_HCLines', None, None)
    _act.connect('activate', select_all_hclines_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllVCLines', '_VCLines', None, None)
    _act.connect('activate', select_all_vclines_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllACLines', '_ACLines', None, None)
    _act.connect('activate', select_all_aclines_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllCLines', 'C_Lines', None, None)
    _act.connect('activate', select_all_clines_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllCCircles', 'CCircles', None, None)
    _act.connect('activate', select_all_ccircles_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('SelectAllTextBlocks', 'TextBlocks', None, None)
    _act.connect('activate', select_all_tblocks_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('SelectAllLDims', 'Linear Dim.', None, None)
    _act.connect('activate', select_all_ldims_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllHDims', 'Horiz. Dim.', None, None)
    _act.connect('activate', select_all_hdims_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllVDims', 'Vert. Dim.', None, None)
    _act.connect('activate', select_all_vdims_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllRDims', 'Radial Dim.', None, None)
    _act.connect('activate', select_all_rdims_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAllADims', 'Angular Dim.', None, None)
    _act.connect('activate', select_all_adims_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu


#############################################################################
#  Edit menu
#############################################################################
def _make_edit_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    #
    _act = gtk.Action('Undo', '_Undo', None, gtk.STOCK_UNDO)
    _act.connect('activate', edit_undo_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, '<control>Z')
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Redo', '_Redo', None, gtk.STOCK_REDO)
    _act.connect('activate', edit_redo_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, '<control><shift>Z')
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Cut', 'Cut', None, gtk.STOCK_CUT)
    _act.connect('activate', edit_cut_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Copy', 'Copy', None, gtk.STOCK_COPY)
    _act.connect('activate', edit_copy_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Paste', 'Paste', None, gtk.STOCK_PASTE)
    _act.connect('activate', edit_paste_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('Select', '_Select', None, None)
    _act.connect('activate', edit_select_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SelectAll', 'Select _All', None, None)
    _act.connect('activate', _select_all_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _submenu = _make_select_all_menu(actiongroup, gtkimage)
    _item.set_submenu(_submenu)
    _menu.append(_item)
    #
    _act = gtk.Action('Deselect', '_Deselect', None, None)
    _act.connect('activate', edit_deselect_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Prefs', '_Preferences', None, gtk.STOCK_PREFERENCES)
    _act.connect('activate', prefs_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    return _menu

#############################################################################
#  Draw -> basic sub-menu
#############################################################################
def _make_draw_basic_menu(actiongroup, gtkimage):
    # _accel = gtkimage.accel
    _menu = gtk.Menu()
    #
    _act = gtk.Action('Points', '_Point', None, None)
    _act.connect('activate', draw_point_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Segments', '_Segment', None, None)
    _act.connect('activate', draw_segment_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Rectangles', '_Rectangle', None, None)
    _act.connect('activate', draw_rectangle_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Circles', '_Circle', None, None)
    _act.connect('activate', draw_circle_center_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('CirclesTwoPoints', 'Circle (_2 Pts)', None, None)
    _act.connect('activate', draw_circle_tp_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Arcs', '_Arc', None, None)
    _act.connect('activate', draw_arc_center_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Draw -> lines sub-menu
#############################################################################
def _make_draw_conlines_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('HCLines', '_Horizontal', None, None)
    _act.connect('activate', draw_hcl_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('VCLines', '_Vertical', None, None)
    _act.connect('activate', draw_vcl_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ACLines', '_Angled', None, None)
    _act.connect('activate', draw_acl_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('CLines', '_Two-Point', None, None)
    _act.connect('activate', draw_cl_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('PerpConLines', 'Per_pendicular', None, None)
    _act.connect('activate', draw_perpendicular_cline_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ParallelConLines', 'Para_llel', None, None)
    _act.connect('activate', draw_poffset_cline_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('TangentConLines', '_Tangent', None, None)
    _act.connect('activate', draw_tangent_cline_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('TangentTwoCirclesConLines', 'Tangent _2 Circ',
                      None, None)
    _act.connect('activate', draw_tangent_two_ccircles_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Draw -> concentric circles sub-menu
#############################################################################
def _make_draw_concircs_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('CCircles', '_Center Pt.', None, None)
    _act.connect('activate', draw_ccirc_cp_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('CCirclesTwoPoints', '_Two Pts.', None, None)
    _act.connect('activate', draw_ccirc_tp_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #    
    _act = gtk.Action('CCircleTangentSingle', '_Single Tangency', None, None)
    _act.connect('activate', draw_tangent_single_conobj_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #    
    _act = gtk.Action('CCircleTangentDual', '_Dual Tangency', None, None)
    _act.connect('activate', draw_tangent_two_conobjs_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Draw set style sub-menu
#############################################################################
def _make_draw_set_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('SetStyle', '_Style', None, None)
    _act.connect('activate', draw_set_style_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SetLinetype', '_Linetype', None, None)
    _act.connect('activate', draw_set_linetype_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SetColor', '_Color', None, None)
    _act.connect('activate', draw_set_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('SetThickness', '_Thickness', None, None)
    _act.connect('activate', draw_set_thickness_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Draw . . .  .
#############################################################################
def _make_add_new_menu(actiongroup, gtkimage):
    #
    # These currently do nothing but are present to encourage
    # the development of code to make the ability to add and
    # save new styles and linetypes in drawings ...
    #
    _menu = gtk.Menu()
    #
    _act = gtk.Action('AddStyle', 'Style', None, None)
    _act.set_property('sensitive', False)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('AddLinetype', 'Linetype', None, None)
    _act.set_property('sensitive', False)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu
    
#############################################################################
#  Top level draw menu
#############################################################################
def _make_draw_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('Basic', '_Basic', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_draw_basic_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('ConLines', 'Con. _Lines', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_draw_conlines_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('ConCircs', 'Con. _Circs.', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_draw_concircs_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('Chamfers', 'Cha_mfer', None, None)
    _act.connect('activate', draw_chamfer_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Fillets', '_Fillet', None, None)
    _act.connect('activate', draw_fillet_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Leaders', 'Lea_der', None, None)
    _act.connect('activate', draw_leader_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Polylines', '_Polyline', None, None)
    _act.connect('activate', draw_polyline_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('InternalPolygon', 'Poly_gon (Int.)', None, None)
    _act.connect('activate', draw_polygon_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ExternalPolygon', 'Polygon (E_xt.)', None, None)
    _act.connect('activate', draw_ext_polygon_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Textblocks', '_Text', None, None)
    _act.connect('activate', draw_text_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('SetProperties', '_Set ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_draw_set_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('AddNew', 'Add _New ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_add_new_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    return _menu

#############################################################################
#  Modify -> move sub-menu
#############################################################################
def _make_modify_move_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('MoveHoriz', '_Horizontal', None, None)
    _act.connect('activate', move_horizontal_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('MoveVert', '_Vertical', None, None)
    _act.connect('activate', move_vertical_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('MoveTwoPt', '_Two-Point Move', None, None)
    _act.connect('activate', move_twopoint_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> stretch sub-menu
#############################################################################
def _make_modify_stretch_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('StretchHoriz', '_Horizontal', None, None)
    _act.connect('activate', stretch_horiz_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('StretchVert', '_Vertical', None, None)
    _act.connect('activate', stretch_vert_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('StretchTwoPt', '_Two-Point Stretch', None, None)
    _act.connect('activate', stretch_twopoint_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> change sub-sub-menu 
#############################################################################
def _make_change_text_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeTextBlockFamily', '_Family', None, None)
    _act.connect('activate', change_textblock_family_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeTextBlockWeight', '_Weight', None, None)
    _act.connect('activate', change_textblock_weight_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeTextBlockStyle', '_Style', None, None)
    _act.connect('activate', change_textblock_style_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeTextBlockColor', '_Color', None, None)
    _act.connect('activate', change_textblock_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeTextBlockSize', 'Si_ze', None, None)
    _act.connect('activate', change_textblock_size_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeTextBlockAlignment', '_Alignment', None, None)
    _act.connect('activate', change_textblock_alignment_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> change -> Dimension -> Primary DimString sub-sub-menu 
#############################################################################
def _make_change_primary_dimstring_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangePDimStringFamily', 'Family', None, None)
    _act.connect('activate', change_dim_primary_family_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringWeight', 'Weight', None, None)
    _act.connect('activate', change_dim_primary_weight_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringStyle', 'Style', None, None)
    _act.connect('activate', change_dim_primary_style_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringSize', 'Size', None, None)
    _act.connect('activate', change_dim_primary_size_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringColor', 'Color', None, None)
    _act.connect('activate', change_dim_primary_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringAlignment', 'Alignment', None, None)
    _act.connect('activate', change_dim_primary_alignment_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringPrefix', 'Prefix', None, None)
    _act.connect('activate', change_ldim_pds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringSuffix', 'Suffix', None, None)
    _act.connect('activate', change_ldim_pds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringPrecision', 'Precision', None, None)
    _act.connect('activate', change_dim_primary_precision_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringUnits', 'Units', None, None)
    _act.connect('activate', change_dim_primary_units_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringPrintZero', 'Print Zero', None, None)
    _act.connect('activate', change_dim_primary_print_zero_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangePDimStringPrintDecimal', 'Print Decimal', None, None)
    _act.connect('activate', change_dim_primary_print_decimal_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> change -> Dimension -> Secondary DimString sub-sub-menu 
#############################################################################
def _make_change_secondary_dimstring_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeSDimStringFamily', 'Family', None, None)
    _act.connect('activate', change_dim_secondary_family_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringWeight', 'Weight', None, None)
    _act.connect('activate', change_dim_secondary_weight_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringStyle', 'Style', None, None)
    _act.connect('activate', change_dim_secondary_style_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringSize', 'Size', None, None)
    _act.connect('activate', change_dim_secondary_size_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringColor', 'Color', None, None)
    _act.connect('activate', change_dim_secondary_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringAlignment', 'Alignment', None, None)
    _act.connect('activate', change_dim_secondary_alignment_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringPrefix', 'Prefix', None, None)
    _act.connect('activate', change_ldim_sds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringSuffix', 'Suffix', None, None)
    _act.connect('activate', change_ldim_sds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringPrecision', 'Precision', None, None)
    _act.connect('activate', change_dim_secondary_precision_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringPrecision', 'Units', None, None)
    _act.connect('activate', change_dim_secondary_units_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringPrintZero', 'Print Zero', None, None)
    _act.connect('activate', change_dim_secondary_print_zero_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeSDimStringPrintDecimal', 'Print Decimal', None, None)
    _act.connect('activate', change_dim_secondary_print_decimal_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

def _make_change_rdim_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeRDimPDSPrefix', 'Primary Prefix', None, None)
    _act.connect('activate', change_rdim_pds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeRDimPDSSuffix', 'Primary Suffix', None, None)
    _act.connect('activate', change_rdim_pds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeRDimSDSPrefix', 'Secondary Prefix', None, None)
    _act.connect('activate', change_rdim_sds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeRDimSDSSuffix', 'Secondary Suffix', None, None)
    _act.connect('activate', change_rdim_sds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeRDimDiaMode', 'Dia. Mode', None, None)
    _act.connect('activate', change_rdim_dia_mode_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

def _make_change_adim_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeADimPDSPrefix', 'Primary Prefix', None, None)
    _act.connect('activate', change_adim_pds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeADimPDSSuffix', 'Primary Suffix', None, None)
    _act.connect('activate', change_adim_pds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeADimSDSPrefix', 'Secondary Prefix', None, None)
    _act.connect('activate', change_adim_sds_prefix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeADimSDSSuffix', 'Secondary Suffix', None, None)
    _act.connect('activate', change_adim_sds_suffix_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeADimInvert', 'Invert', None, None)
    _act.connect('activate', change_adim_invert_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> change -> dimension sub-sub-menu 
#############################################################################
def _make_change_dimension_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeDimEndpointType', 'Endpoint _Type', None, None)
    _act.connect('activate', change_dim_endpoint_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimEndpointSize', 'Endpoint _Size', None, None)
    _act.connect('activate', change_dim_endpoint_size_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimOffset', '_Offset Length', None, None)
    _act.connect('activate', change_dim_offset_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimExtension', 'E_xtension Length', None, None)
    _act.connect('activate', change_dim_extension_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimDualMode', '_Dual Mode', None, None)
    _act.connect('activate', change_dim_dual_mode_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimDualModeOffset', 'Dual Mode O_ffset', None, None)
    _act.connect('activate', change_dim_dual_mode_offset_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimThickness', '_Thickness', None, None)
    _act.connect('activate', change_dim_thickness_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeDimColor', '_Color', None, None)
    _act.connect('activate', change_dim_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangePDimStrMenu', '_Primary DimString', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_primary_dimstring_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeSDimStrMenu', '_Secondary DimString', None, None)
    actiongroup.add_action(_act)

    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_secondary_dimstring_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeRDimMenu', 'RadialDim ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_rdim_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeADimMenu', 'AngularDim ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_adim_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    # _act = gtk.Action('ChangeDimPrimaryDS', '_Primary DimString', None, None)
    # _act.connect('activate', change_primary_dim_cb, gtkimage)
    # actiongroup.add_action(_act)
    # _menu.append(_act.create_menu_item())
    #
    # _act = gtk.Action('ChangeDimSecondaryDS', '_Secondary DimString', None, None)
    # _act.connect('activate', change_secondary_dim_cb, gtkimage)
    # actiongroup.add_action(_act)
    # _menu.append(_act.create_menu_item())
    #
    return _menu

#############################################################################
#  Modify -> change sub-menu 
#############################################################################
def _make_modify_change_menu(actiongroup, gtkimage):
    _menu = gtk.Menu()
    #
    _act = gtk.Action('ChangeStyle', '_Style', None, None)
    _act.connect('activate', change_style_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeLinetype', '_Linetype', None, None)
    _act.connect('activate', change_linetype_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeColor', '_Color', None, None)
    _act.connect('activate', change_color_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('ChangeThickness', '_Thickness', None, None)
    _act.connect('activate', change_thickness_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeTextMenu', 'Text_Block ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_text_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ChangeDimMenu', '_Dimension ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_change_dimension_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    return _menu

#############################################################################
#  Initialize Modify -> change sub menu
#############################################################################
def _change_menu_init(menuitem, gtkimage):
    # print "_change_menu_init()"
    _group = gtkimage.getGroup('Modify')
    if _group is not None:
        _objlist = []
        _active = gtkimage.getActiveLayer()
        _gflag = _tflag = _dflag = False
        for _obj in gtkimage.getSelectedObjects(False):
            if isinstance(_obj, graphicobject.GraphicObject):
                _goflag = True
                continue
            if isinstance(_obj, text.TextBlock):
                _tflag = True
                continue
            if isinstance(_obj, dimension.Dimension):
                _dflag = True
            if _gflag and _tflag and _dflag:
                break
        if not _gflag or not _tflag or not _dflag:
            for _obj in _active.getChildren():
                if not _gflag and isinstance(_obj,
                                             graphicobject.GraphicObject):
                    _gflag = True
                    continue
                if not _tflag and isinstance(_obj, text.TextBlock):
                    _tflag = True
                    continue
                if not _dflag and isinstance(_obj, dimension.Dimension):
                    _dflag = True
                if _gflag and _tflag and _dflag:
                    break
        _act = _group.get_action('ChangeStyle')
        if _act is not None:
            _act.set_property('sensitive', _gflag)
        _act = _group.get_action('ChangeLinetype')
        if _act is not None:
            _act.set_property('sensitive', _gflag)
        _act = _group.get_action('ChangeColor')
        if _act is not None:
            _act.set_property('sensitive', _gflag)
        _act = _group.get_action('ChangeThickness')
        if _act is not None:
            _act.set_property('sensitive', _gflag)
        _act = _group.get_action('ChangeTextMenu')
        if _act is not None:
            _act.set_property('sensitive', _tflag)
        _act = _group.get_action('ChangeDimMenu')
        if _act is not None:
            _act.set_property('sensitive', _dflag)
        
#############################################################################
#  Initialize top level modify menu -- this handles greying out non-active items.
#############################################################################
def _modify_menu_init(menuitem, gtkimage):
    _group = gtkimage.getGroup('Modify')
    if _group is not None:
        _active = gtkimage.getActiveLayer()
        _act = _group.get_action('Move')
        if _act is not None:
            _act.set_property('sensitive', (_active.hasEntities() or
                                            gtkimage.hasSelection()))
        _act = _group.get_action('Stretch')
        if _act is not None:
            _act.set_property('sensitive', _active.hasEntities())
        _act = _group.get_action('Split')
        if _act is not None:
            _flag = ((_active.getEntityCount('segment') > 0) or
                     (_active.getEntityCount('circle') > 0) or
                     (_active.getEntityCount('arc') > 0) or
                     (_active.getEntityCount('polyline') > 0))
            _act.set_property('sensitive', _flag)
        _act = _group.get_action('Mirror')
        if _act is not None:
            _flag = ((_active.hasEntities() or gtkimage.hasSelection()) and
                     ((_active.getEntityCount('hcline') > 0) or
                      (_active.getEntityCount('vcline') > 0) or
                      (_active.getEntityCount('acline') > 0) or
                      (_active.getEntityCount('cline') > 0)))
            _act.set_property('sensitive', _flag)
        _act = _group.get_action('Transfer')
        if _act is not None:
            _flag = False
            _layers = [gtkimage.getTopLayer()]
            while len(_layers):
                _layer = _layers.pop()
                if _layer is not _active:
                    _flag = _layer.hasEntities()
                if _flag:
                    break
                _layers.extend(_layer.getSublayers())
            _act.set_property('sensitive', _flag)
        _act = _group.get_action('Delete')
        if _act is not None:
            _act.set_property('sensitive', _active.hasEntities())
        _act = _group.get_action('Change')
        if _act is not None:
            _act.set_property('sensitive', (gtkimage.hasSelection() or
                                            _active.hasEntities()))
        _act = _group.get_action('ZoomFit')
        if _act is not None:
            _act.set_property('sensitive', _active.hasEntities())


#############################################################################
#  Top level modify menu
#############################################################################
def _make_modify_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    #
    _act = gtk.Action('Move', '_Move ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_modify_move_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('Stretch', 'S_tretch ...', None, None)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_modify_stretch_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _act = gtk.Action('Split', 'S_plit', None, None)
    _act.connect('activate', split_object_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Mirror', '_Mirror', None, None)
    _act.connect('activate', mirror_object_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('Transfer', 'Trans_fer', None, None)
    _act.connect('activate', transfer_object_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Delete', '_Delete', None, None)
    _act.connect('activate', delete_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('Change', '_Change', None, None)
    _act.connect('activate', _change_menu_init, gtkimage)
    actiongroup.add_action(_act)
    _item = _act.create_menu_item()
    _item.set_submenu(_make_modify_change_menu(actiongroup, gtkimage))
    _menu.append(_item)
    #
    _item = gtk.SeparatorMenuItem()
    _item.show()
    _menu.append(_item)
    #
    _act = gtk.Action('ZoomWindow', 'Zoom _Window', None, None)
    _act.connect('activate', zoom_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    ############  SDB notes:  Create separate "view" menu with zoom
    ############  and option to move viewing center.
    _act = gtk.Action('ZoomIn', '_Zoom In', None, gtk.STOCK_ZOOM_IN)
    _act.connect('activate', zoom_in_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('ZoomOut', 'Zoom _Out', None, gtk.STOCK_ZOOM_OUT)
    _act.connect('activate', zoom_out_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('ZoomFit', 'Zoom _Fit', None, gtk.STOCK_ZOOM_FIT)
    _act.connect('activate', zoom_fit_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, None)
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    return _menu

#############################################################################
#  Init top level Dimensions menu
#############################################################################
def _dimension_menu_init(menuitem, gtkimage):
    _group = gtkimage.getGroup('Dimension')
    if _group is not None:
        _ldim = _hdim = _vdim = _rdim = _adim = False
        _count = 0
        _layers = [gtkimage.getTopLayer()]
        for _layer in _layers:
            _pc = _layer.getEntityCount('point')
            if _pc > 0:
                _count = _count + _pc
                if _count > 1:
                    _ldim = _hdim = _vdim = True
                if _count > 2:
                    _adim = True
            if _layer.getEntityCount('circle') > 0:
                _rdim = True
            if _layer.getEntityCount('arc') > 0:
                _rdim = _adim = True
            if _ldim and _hdim and _vdim and _rdim and _adim:
                break
            _layers.extend(_layer.getSublayers())
        _act = _group.get_action('Linear')
        if _act is not None:
            _act.set_property('sensitive', _ldim)
        _act = _group.get_action('Horizontal')
        if _act is not None:
            _act.set_property('sensitive', _hdim)
        _act = _group.get_action('Vertical')
        if _act is not None:
            _act.set_property('sensitive', _vdim)
        _act = _group.get_action('Radial')
        if _act is not None:
            _act.set_property('sensitive', _rdim)
        _act = _group.get_action('Angular')
        if _act is not None:
            _act.set_property('sensitive', _adim)

#############################################################################
#  Top level Dimensions menu
#############################################################################
def _make_dimension_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    _act = gtk.Action('Linear', '_Linear', None, None)
    _act.connect('activate', dimension_linear_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('Horizontal', '_Horizontal', None, None)
    _act.connect('activate', dimension_horizontal_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('Vertical', '_Vertical', None, None)
    _act.connect('activate', dimension_vertical_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('Radial', '_Radial', None, None)
    _act.connect('activate', dimension_radial_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('Angular', '_Angular', None, None)
    _act.connect('activate', dimension_angular_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    return _menu

#############################################################################
#  Top level debug menu
#############################################################################
def _make_debug_menu(actiongroup, gtkimage):
    _accel = gtkimage.accel
    _menu = gtk.Menu()
    _act = gtk.Action('Focus', 'Focus', None, None)
    _act.connect('activate', get_focus_widget_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    #
    _act = gtk.Action('UndoStack', 'Undo Stack', None, None)
    _act.connect('activate', get_undo_stack_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, '<alt>Z')
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('RedoStack', 'Redo Stack', None, None)
    _act.connect('activate', get_redo_stack_cb, gtkimage)
    _act.set_accel_group(_accel)
    actiongroup.add_action_with_accel(_act, '<alt><shift>Z')
    _item = _act.create_menu_item()
    if isinstance(_act, gtkactions.stdAction):
        _add_accelerators(_act, _item, _accel)
    _menu.append(_item)
    #
    _act = gtk.Action('ImageUndo', 'Image Undo', None, None)
    _act.connect('activate', get_image_undo_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('ImageRedo', 'Image Redo', None, None)
    _act.connect('activate', get_image_redo_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    _act = gtk.Action('GC', 'GC', None, None)
    _act.connect('activate', collect_garbage_cb, gtkimage)
    actiongroup.add_action(_act)
    _menu.append(_act.create_menu_item())
    return _menu
    
#############################################################################
#  Fill out top menubar with menu items.
#############################################################################
def fill_menubar(mb, gtkimage):
    if not isinstance(mb, gtk.MenuBar):
        raise TypeError, "Invalid gtk.MenuBar object: " + `mb`
    # File menu
    _group = gtk.ActionGroup('File')
    gtkimage.addGroup(_group)
    _act = gtk.Action('FileMenu', '_File', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    _act.connect('activate', _file_menu_init, gtkimage)
    _menu = _make_file_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
    # Edit menu
    _group = gtk.ActionGroup('Edit')
    gtkimage.addGroup(_group)
    _act = gtk.Action('EditMenu', '_Edit', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    _act.connect('activate', _edit_menu_init, gtkimage)
    _menu = _make_edit_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
    # Draw menu
    _group = gtk.ActionGroup('Draw')
    gtkimage.addGroup(_group)
    _act = gtk.Action('DrawMenu', '_Draw', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    _menu = _make_draw_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
    # Modifying
    _group = gtk.ActionGroup('Modify')
    gtkimage.addGroup(_group)
    _act = gtk.Action('ModifyMenu', '_Modify', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    _act.connect('activate', _modify_menu_init, gtkimage)
    _menu = _make_modify_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
    # Dimensioning
    _group = gtk.ActionGroup('Dimension')
    gtkimage.addGroup(_group)
    _act = gtk.Action('DimensionMenu', 'Dime_nsions', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    _act.connect('activate', _dimension_menu_init, gtkimage)
    _menu = _make_dimension_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
    # Debug
    _group = gtk.ActionGroup('Debug')
    gtkimage.addGroup(_group)
    _act = gtk.Action('DebugMenu', 'De_bug', None, None)
    _group.add_action(_act)
    _item = gtk.MenuItem()
    _act.connect_proxy(_item)
    # _act.connect('activate', _debug_cb)
    _menu = _make_debug_menu(_group, gtkimage)
    _item.set_submenu(_menu)
    mb.append(_item)
