diff --git a/python/box.py b/python/box.py
index cb8e7085acc5745c9a40e50f31dc7926403fb5cc..5d886b005358cf4f9a66b5630794297b4113072a 100644
--- a/python/box.py
+++ b/python/box.py
@@ -10,17 +10,10 @@ from PyQt5.QtWidgets import QMenu
 from PyQt5.QtWidgets import QAction
 from graph_constants import BOX_TYPE
 from settings_manager import emit_signal_settings_changed, preferred_pen
+from box_types import BACKGROUND_BOX
+from box_menu import show_box_menu
 from verbose import verbose
 
-BACKGROUND_BOX = 1
-TRACE_BOX = 2
-REPORT_BOX = 3
-TABLE_BOX = 4
-GRAPH_BOX = 5
-BAR_CHART_BOX = 6
-GANTT_CHART_BOX = 7
-AD_BOX = 8
-
 """box to contain QGraphicsItems children.  Optionally draw box.
 Usage:
  1) Crete box
@@ -60,7 +53,6 @@ class Box(QGraphicsItem):
         self.is_boxed = gry_box["is_boxed"]
         if "x" in gry_box:
             self.setPos(QPointF(gry_box["x"], gry_box["y"]))
-        self.menu_actions = list()
 
         # graphicsItem mode
         self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
@@ -173,89 +165,5 @@ class Box(QGraphicsItem):
     # right-click shows menu
     def contextMenuEvent(self, event):
         if event.reason() == QGraphicsSceneContextMenuEvent.Mouse:
-            self.show_box_menu()
-
-    def _add_graph_box_menu_content(self, menu):
-        menu.addSeparator()
-
-        # force directed
-        action_align_force_directed = QAction("Apply force-directed alignment",
-                                              parent=menu)
-        action_align_force_directed.setStatusTip("Straighten up node placement")
-        action_align_force_directed.triggered.connect(
-                                          self.view.align_force_directed)
-        menu.addAction(action_align_force_directed)
-
-        # force directed x10 (slow)
-        action_align_force_directed = QAction("Apply more precise force-directed alignment (slower)",
-                                              parent=menu)
-        action_align_force_directed.setStatusTip("Straighten up node placement with greater precision")
-        action_align_force_directed.triggered.connect(
-                                          self.view.align_force_directed_x10)
-        menu.addAction(action_align_force_directed)
-
-        # circular alignment
-        action_align_circular = QAction("Apply circular node alignment",
-                                              parent=menu)
-        action_align_circular.setStatusTip("Arrange graph nodes in a circle")
-        action_align_circular.triggered.connect(self.view.align_circular)
-        menu.addAction(action_align_circular)
-
-    def _add_trace_box_menu_content(self, menu):
-        menu.addSeparator()
-        graph_main_scene = self.scene()
-        menu.addAction(graph_main_scene.event_menu.action_event_menu)
-
-    # box menu
-    def show_box_menu(self):
-        menu = QMenu()
-        # action box border
-        action_set_boxed = QAction("Show border")
-        action_set_boxed.setCheckable(True)
-        action_set_boxed.setChecked(self.is_boxed)
-        @pyqtSlot(bool)
-        def _set_boxed(is_checked):
-            self.set_boxed(is_checked)
-            emit_signal_settings_changed()
-        action_set_boxed.triggered.connect(_set_boxed)
-        menu.addAction(action_set_boxed)
-
-        # action content visibility
-        action_set_visible = QAction("Show component")
-        action_set_visible.setCheckable(True)
-        action_set_visible.setChecked(self.is_visible)
-        action_set_visible.setEnabled(self.box_type != BACKGROUND_BOX)
-        @pyqtSlot(bool)
-        def _set_visible(is_checked):
-            self.set_visible(is_checked)
-            emit_signal_settings_changed()
-        action_set_visible.triggered.connect(_set_visible)
-        menu.addAction(action_set_visible)
-
-        # GRAPH_BOX menu content
-        if self.box_type == GRAPH_BOX:
-            self._add_graph_box_menu_content(menu)
-
-        # TRACE_BOX menu content
-        if self.box_type == TRACE_BOX:
-            self._add_trace_box_menu_content(menu)
-
-        # realign graph in GRAPH_BOX menu
-        if self.box_type == GRAPH_BOX:
-            @pyqtSlot()
-            def _realign_graph():
-                self._menu_action_function()
-                emit_signal_settings_changed()
-
-        # any externally added actions
-        for action in self.menu_actions:
-            menu.addAction(action)
-
-            action_realign_graph = QAction("Apply force-directed alignment")
-            action_realign_graph.setStatusTip("Straighten up node placement")
-            action_realign_graph.triggered.connect(_realign_graph)
-            menu.addAction(action_realign_graph)
-
-        # open the menu
-        _action = menu.exec(QCursor.pos())
+            show_box_menu(self)
 
diff --git a/python/box_menu.py b/python/box_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b83639f518a27954050e6d5d85a8df23fc3d191
--- /dev/null
+++ b/python/box_menu.py
@@ -0,0 +1,101 @@
+from PyQt5.QtCore import pyqtSlot # for signal/slot support
+from PyQt5.QtWidgets import QMenu, QAction
+from PyQt5.QtGui import QCursor
+from box_types import BACKGROUND_BOX, TRACE_BOX, GRAPH_BOX, AD_BOX
+from edge_angular_placer import place_edges
+
+"""
+Create and show a box_type-specific box menu.
+"""
+
+def _add_generic_menu_content(box, menu):
+
+    # action box border
+    action_set_boxed = QAction("Show border", menu)
+    action_set_boxed.setCheckable(True)
+    action_set_boxed.setChecked(box.is_boxed)
+    @pyqtSlot(bool)
+    def _set_boxed(is_checked):
+        box.set_boxed(is_checked)
+        emit_signal_settings_changed()
+    action_set_boxed.triggered.connect(_set_boxed)
+    menu.addAction(action_set_boxed)
+
+    # action content visibility
+    action_set_visible = QAction("Show component", menu)
+    action_set_visible.setCheckable(True)
+    action_set_visible.setChecked(box.is_visible)
+    action_set_visible.setEnabled(box.box_type != BACKGROUND_BOX)
+    @pyqtSlot(bool)
+    def _set_visible(is_checked):
+        box.set_visible(is_checked)
+        emit_signal_settings_changed()
+    action_set_visible.triggered.connect(_set_visible)
+    menu.addAction(action_set_visible)
+
+def _add_graph_menu_content(box, menu):
+    menu.addSeparator()
+
+    # force directed
+    action_align_force_directed = QAction("Apply force-directed alignment",
+                                          menu)
+    action_align_force_directed.setStatusTip("Straighten up node placement")
+    action_align_force_directed.triggered.connect(
+                                      box.view.align_force_directed)
+    menu.addAction(action_align_force_directed)
+
+    # force directed x10 (slow)
+    action_align_force_directed = QAction("Apply more precise "
+                   "force-directed alignment (slower)", menu)
+    action_align_force_directed.setStatusTip("Straighten up node "
+                                 "placement with greater precision")
+    action_align_force_directed.triggered.connect(
+                                      box.view.align_force_directed_x10)
+    menu.addAction(action_align_force_directed)
+
+    # circular alignment
+    action_align_circular = QAction("Apply circular node alignment", menu)
+    action_align_circular.setStatusTip("Arrange graph nodes in a circle")
+    action_align_circular.triggered.connect(box.view.align_circular)
+    menu.addAction(action_align_circular)
+
+def _add_trace_menu_content(box, menu):
+    menu.addSeparator()
+    graph_main_scene = box.scene()
+    menu.addAction(graph_main_scene.event_menu.action_event_menu)
+
+def _add_activity_diagram_menu_content(box, menu):
+    menu.addSeparator()
+
+    # place edges
+    action_place_edges = QAction("Reset edge placement", menu)
+    action_place_edges.setStatusTip("Reset edge placement based on "
+                                    "node positions")
+    @pyqtSlot(bool)
+    def _place_edges():
+        place_edges(box.view.nodes, box.view.edges)
+    action_place_edges.triggered.connect(_place_edges)
+    menu.addAction(action_place_edges)
+
+def show_box_menu(box):
+    menu = QMenu()
+    print("showboxmenu", menu)
+
+    # generic content
+    _add_generic_menu_content(box, menu)
+
+    # GRAPH_BOX menu content
+    if box.box_type == GRAPH_BOX:
+        _add_graph_menu_content(box, menu)
+
+    # TRACE_BOX menu content
+    if box.box_type == TRACE_BOX:
+        _add_trace_menu_content(box, menu)
+
+    # AD_BOX menu content
+    if box.box_type == AD_BOX:
+        _add_activity_diagram_menu_content(box, menu)
+
+    # open the menu
+    _action = menu.exec(QCursor.pos())
+
diff --git a/python/box_types.py b/python/box_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..41d1b176999bfd24a420765af4dda2bebba11ae4
--- /dev/null
+++ b/python/box_types.py
@@ -0,0 +1,9 @@
+"""the box menu provides varying services depending on box type."""
+BACKGROUND_BOX = 1
+TRACE_BOX = 2
+REPORT_BOX = 3
+TABLE_BOX = 4
+GRAPH_BOX = 5
+BAR_CHART_BOX = 6
+GANTT_CHART_BOX = 7
+AD_BOX = 8
diff --git a/python/edge_angular_placer.py b/python/edge_angular_placer.py
index 554d9e2ddc89579f74e9e0283e664d2397cd1517..4c887e548d48cbe37bf2c6191334fe7bbcf3f353 100644
--- a/python/edge_angular_placer.py
+++ b/python/edge_angular_placer.py
@@ -3,7 +3,7 @@ from PyQt5.QtCore import QLineF, QPointF
 from settings_manager import settings
 from view_ad_node import START_TYPE, END_TYPE, DECISION_TYPE, BAR_TYPE
 _CAN_H_TYPES = {START_TYPE, END_TYPE, DECISION_TYPE}
-
+_DELTA_OFFSET = 10
 
 """
 Consider node rows and columns when placing edges.
@@ -32,8 +32,8 @@ placement:
     start        round       pick right angle closest to destination
     end          round       pick right angle closest to destination
     decision     diamond     pick right angle closest to destination
-    action       rectangle   vertical only, top in, bottom out
-    bar          horizontal  vertical only, top in, bottom out
+    action       rectangle   vertical only, top center in, bottom center out
+    bar          horizontal  vertical only, top area in, bottom area out
 
 To get the snap point and approach to a node, provide from point and direction:
       snap_pint, approach = node.placer_snap_point(other_point<p>, is_to<bool>)
@@ -41,36 +41,42 @@ To get the snap point and approach to a node, provide from point and direction:
 
 class OffsetTracker():
     def __init__(self, nodes):
-        self.right_offset = settings["ad_action_width"] * 3 / 5
-        self.left_offset = -self.right_offset
+        self.right_offset = _DELTA_OFFSET
+        self.left_offset = _DELTA_OFFSET
 
-        # create a set of occupied y values for each x column
+        # create dict of list where keys are y and values are
+        # a set of (x_min, x_max) tuples representing where nodes lie.
+        # if an edge crosses a node then we should go around it using xyx.
         self.occupied_positions = defaultdict(set)
         for node in nodes:
-            self.occupied_positions[node.x()].add(node.y())
-
-    def next_offset(self, x):
-        if x == 0:
-            # shift left
-            offset = self.left_offset
-            self.left_offset -= settings["ad_action_width"] * 1 / 5
-        else:
-            offset = self.right_offset
-            self.right_offset += settings["ad_action_width"] * 1 / 5
-        return offset
-
-    # is a node with the same y in between two vertically aligned points
-    def y_in_between(self, p1, p2):
-        if p1.x() != p2.x():
-            return False, 0
-        column = self.occupied_positions[p1.x()]
-        y1, y2 = p1.y(), p2.y()
-        for y in column:
-            if (y > y1 and y < y2) or (y < y1 and y > y2):
-                if p1.x() == 0:
-                    offset = self.left_offset
-                return True
-        return False
+            x = node.x()
+            half_width = node.boundingRect().width() / 2
+            self.occupied_positions[node.y()].add((x-half_width, x+half_width))
+
+    # return a recommended x value to use for going around nodes or just x
+    def recommended_x(self, x, y_from, y_to):
+        x_new = x
+        y_min = min(y_from, y_to)
+        y_max = max(y_from, y_to)
+        should_adjust_left = False
+        should_adjust_right = False
+        for y, values in self.occupied_positions.items():
+            if y > y_min and y < y_max:
+                for x_min, x_max in values:
+                    if x >= x_min and x <= x_max:
+                        if x <= 0:
+                            should_adjust_left = True
+                            x_new = min(x_new, x_min - self.left_offset)
+                        else:
+                            should_adjust_right = True
+                            x_new = max(x_new, x_max + self.right_offset)
+        return x_new
+
+    def increase_left_offset(self):
+        self.left_offset += _DELTA_OFFSET
+
+    def increase_right_offset(self):
+        self.right_offset += _DELTA_OFFSET
 
 def _map_xyx(edge):
     edge.ep1 = QPointF(edge.ep0)
@@ -98,35 +104,37 @@ def _map_yx(edge):
     edge.ep1.setY(edge.ep3.y())
     edge.ep2.setX(edge.ep0.x())
 
-def _map_dx(edge, offset):
+def _map_over_x(edge, offset):
     edge.ep1 = QPointF(edge.ep0)
     edge.ep2 = QPointF(edge.ep3)
     dx = edge.ep0.x() + offset
     edge.ep1.setX(dx)
     edge.ep2.setX(dx)
 
-def _place_edge(edge, offset_tracker):
-    if edge.from_node.node_type in _CAN_H_TYPES \
-                      and edge.to_node.node_type in _CAN_H_TYPES \
-                      and offset_tracker.y_in_between(
-                                 edge.from_node.pos(), edge.to_node.pos()):
-
-        # place with vertical offset shift for xyx connection
-        offset = offset_tracker.next_offset(edge.from_node.x())
-        edge.ep0, _from_approach = edge.from_node.placer_snap_point(
-               QPointF(edge.from_node.x() + offset, edge.from_node.y()), False)
-        edge.ep3, _to_approach = edge.to_node.placer_snap_point(
-               QPointF(edge.to_node.x() + offset, edge.to_node.y()), True)
-        _map_dx(edge, offset)
-
-    elif edge.from_node.node_type in BAR_TYPE \
-                             and edge.to_node.node_type in BAR_TYPE:
 
-        # place bar center to bar center
+# place edge points so they go around something
+def _place_around(edge, offset_tracker, recommended_x):
+    # over to recommended_x then y then return
+    edge.ep0, _from_approach = edge.from_node.placer_snap_point(
+                           QPointF(recommended_x, edge.from_node.y()), False)
+    edge.ep3, _to_approach = edge.to_node.placer_snap_point(
+                           QPointF(recommended_x, edge.to_node.y()), True)
+    _map_over_x(edge, recommended_x)
+    if recommended_x < 0:
+        offset_tracker.increase_left_offset()
+    else:
+        offset_tracker.increase_right_offset()
+
+# place edge points without going around anything
+def _place_to(edge):
+ 
+    if edge.from_node.node_type == BAR_TYPE \
+                                and edge.to_node.node_type == BAR_TYPE:
+        # bar to bar, place yxy bar center to bar center
         edge.ep0, _from_approach = edge.from_node.placer_snap_point(
-               QPointF(edge.from_node.x(), 0), False)
+                                    QPointF(edge.from_node.x(), 0), False)
         edge.ep3, _to_approach = edge.to_node.placer_snap_point(
-               QPointF(edge.to_node.x(), 0), True)
+                                    QPointF(edge.to_node.x(), 0), True)
         _map_yxy(edge)
 
     else:
@@ -147,6 +155,81 @@ def _place_edge(edge, offset_tracker):
             raise RuntimeError("bad")
     edge.reset_appearance()
 
+def _place_edge(edge, offset_tracker):
+    from_x = edge.from_node.x()
+    from_y = edge.from_node.y()
+    to_x = edge.to_node.x()
+    to_y = edge.to_node.y()
+    print(from_x, from_y, edge.from_node.boundingRect().width(), to_x, to_y, edge.to_node.boundingRect().width())
+
+    # bar center to bar center
+    if edge.from_node.node_type == BAR_TYPE \
+                      and edge.to_node.node_type == BAR_TYPE:
+        from_x = edge.from_node.x()
+        from_y = edge.from_node.y()
+        to_x = edge.to_node.x()
+        to_y = edge.to_node.y()
+        # check for crossing with respect to from_node and to_node
+        recommended_x = offset_tracker.recommended_x(from_x, from_y, to_y)
+        if recommended_x == from_x:
+            # no crossing, how about to_node
+            recommended_x = offset_tracker.recommended_x(to_x, from_y, to_y)
+        if recommended_x == to_x:
+            # still no crossing
+            _place_to(edge)
+        else:
+            # crossing so go over, down, back
+            _place_around(edge, offset_tracker, recommended_x)
+
+    # bar to non-bar or non-bar to bar
+    elif edge.from_node.node_type == BAR_TYPE \
+                      or edge.to_node.node_type == BAR_TYPE:
+        from_x = edge.from_node.x()
+        to_x = edge.to_node.x()
+        if edge.from_node.node_type == BAR_TYPE:
+            half_width = edge.from_node.boundingRect().width() / 2
+            wide_x = from_x
+            narrow_x = to_x
+        else:
+            half_width = edge.to_node.boundingRect().width() / 2
+            wide_x = to_x
+            narrow_x = from_x
+        x_min = wide_x - half_width
+        x_max = wide_x + half_width
+
+        if narrow_x >= x_min and narrow_x <= x_max:
+            # edge would be straight down so maybe go around
+            from_y = edge.from_node.y()
+            to_y = edge.to_node.y()
+            recommended_x = offset_tracker.recommended_x(narrow_x, from_y, to_y)
+            if recommended_x == narrow_x:
+                # no crossing
+                _place_to(edge)
+            else:
+                # crossing so go over, down, back
+                _place_around(edge, offset_tracker, recommended_x)
+
+        else:
+            _place_to(edge)
+
+    # non-bar to non-bar
+    else:
+        if edge.from_node.x() == edge.to_node.x():
+            from_x = edge.from_node.x()
+            from_y = edge.from_node.y()
+            to_y = edge.to_node.y()
+            recommended_x = offset_tracker.recommended_x(from_x, from_y, to_y)
+            if recommended_x == from_x:
+                # no crossing
+                _place_to(edge)
+            else:
+                # crossing so go over, down, back
+                _place_around(edge, offset_tracker, recommended_x)
+        else:
+            _place_to(edge)
+
+    edge.reset_appearance()
+
 # place edge points for all edges
 def place_edges(nodes, edges):
     offset_tracker = OffsetTracker(nodes)
diff --git a/python/graph_item.py b/python/graph_item.py
index 5c9b8dc89d073258f24be9e10765ed09d4112ee1..060554c274a6c01959a19828600b7ad87bac0ff5 100644
--- a/python/graph_item.py
+++ b/python/graph_item.py
@@ -6,7 +6,8 @@ from PyQt5.QtCore import pyqtSlot
 from tg_to_gry import empty_graph
 from node import Node
 from edge import Edge
-from box import Box, BACKGROUND_BOX
+from box_types import BACKGROUND_BOX
+from box import Box
 from view_trace import ViewTrace
 from view_report import ViewReport
 from view_table import ViewTable
diff --git a/python/gry_manager.py b/python/gry_manager.py
index 91dc4b704477f41543839cf50bcb43ee81870b5d..d1f598d52e9936621af2ef9fc98abe1802bd91c8 100644
--- a/python/gry_manager.py
+++ b/python/gry_manager.py
@@ -128,6 +128,6 @@ class GryManager(QObject):
 
             else:
                 # great, exported.
-                log("Exported Gryphon Graph file %s" % gry_file_filename)
+                log("Exported Gryphon Graph file %s" % filename)
 
 
diff --git a/python/view_ad.py b/python/view_ad.py
index 288787dc3236d4e72192305cfce06fe01d3f0be4..3a7bdc67bd5d41cd8fc3624afe80257e304f7ea7 100644
--- a/python/view_ad.py
+++ b/python/view_ad.py
@@ -1,7 +1,8 @@
 from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # for signal/slot support
 from PyQt5.QtCore import QPointF
 from settings_manager import settings
-from box import Box, AD_BOX
+from box_types import AD_BOX
+from box import Box
 from view_text import ViewText
 from view_ad_node import ViewADNode
 from view_ad_edge import ViewADEdge
diff --git a/python/view_bar_chart.py b/python/view_bar_chart.py
index 1aa2a6b62af1274d17db45227d569e4f139ce87c..90794d1b5f616e501e74075ea1c26d113c18e124 100644
--- a/python/view_bar_chart.py
+++ b/python/view_bar_chart.py
@@ -1,7 +1,8 @@
 from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # for signal/slot support
 from PyQt5.QtCore import QPointF
 from settings_manager import settings
-from box import Box, BAR_CHART_BOX
+from box_types import BAR_CHART_BOX
+from box import Box
 from view_text import ViewText
 from view_legend import ViewLegend
 from view_bar_chart_bars import ViewBarChartBars
diff --git a/python/view_gantt_chart.py b/python/view_gantt_chart.py
index 53f843e863af257c0c9778bb36c146ecc7359c6b..8394623085f3fbb85079158c614503e1f5f61295 100644
--- a/python/view_gantt_chart.py
+++ b/python/view_gantt_chart.py
@@ -1,7 +1,8 @@
 from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # for signal/slot support
 from PyQt5.QtCore import QPointF
 from settings_manager import settings
-from box import Box, GANTT_CHART_BOX
+from box_types import GANTT_CHART_BOX
+from box import Box
 from view_text import ViewText
 from view_legend import ViewLegend
 from view_gantt_chart_bars import ViewGanttChartBars
diff --git a/python/view_graph.py b/python/view_graph.py
index 3ca7d80890d59cc816afbe473ff11d62a2f131ff..77a0f0f2f570b8e009e5f89da6ba745aa7c443e3 100644
--- a/python/view_graph.py
+++ b/python/view_graph.py
@@ -1,7 +1,8 @@
 from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # for signal/slot support
 from PyQt5.QtCore import QPointF
 from settings_manager import settings
-from box import Box, GRAPH_BOX
+from box_types import GRAPH_BOX
+from box import Box
 from view_text import ViewText
 from view_graph_node import ViewGraphNode
 from view_graph_edge import ViewGraphEdge
diff --git a/python/view_report.py b/python/view_report.py
index 2450c2222c650578053e902e316e9faac0f7c68b..2a1e7f9a6edde38da5c750d7aca3f76048827c66 100644
--- a/python/view_report.py
+++ b/python/view_report.py
@@ -1,4 +1,5 @@
-from box import Box, REPORT_BOX
+from box_types import REPORT_BOX
+from box import Box
 from view_report_report import ViewReportReport
 
 class ViewReport():
diff --git a/python/view_report_report.py b/python/view_report_report.py
index a8d44cc87ab82431520994b3a49d32e8223ed454..34aa73465ea85bb5ab4d4ab07daa653f4cda70d6 100644
--- a/python/view_report_report.py
+++ b/python/view_report_report.py
@@ -6,6 +6,7 @@ from graph_constants import VIEW_REPORT_TYPE
 from font_helper import text_width, widest_text, \
                         HORIZONTAL_PADDING, LEFT_PADDING, cell_height
 from settings_manager import preferred_pen
+from box_menu import show_box_menu
 
 # text looks bad in renderable so we render text in paint
 
@@ -109,5 +110,5 @@ class ViewReportReport(QGraphicsItem):
 
     def contextMenuEvent(self, event):
         if event.reason() == QGraphicsSceneContextMenuEvent.Mouse:
-            self.report_box.show_box_menu()
+            show_box_menu(self.report_box)
 
diff --git a/python/view_table.py b/python/view_table.py
index d060ca16321a26efe5d698467a68ecea3dea474f..e6f5f75d0f88cf5e260dea81091ab09d89e2b413 100644
--- a/python/view_table.py
+++ b/python/view_table.py
@@ -1,4 +1,5 @@
-from box import Box, TABLE_BOX
+from box_types import TABLE_BOX
+from box import Box
 from view_table_table import ViewTableTable
 
 class ViewTable():
diff --git a/python/view_table_table.py b/python/view_table_table.py
index 6030ecdb44713a4d37ed11692ee1e4d991161c3b..a206b80959019ee6ac9dbf70d85c205cf05bf4a3 100644
--- a/python/view_table_table.py
+++ b/python/view_table_table.py
@@ -2,11 +2,11 @@ from PyQt5.QtCore import QPoint, QRectF, Qt
 from PyQt5.QtGui import QPainterPath, QPen
 from PyQt5.QtWidgets import QGraphicsItem
 from PyQt5.QtWidgets import QGraphicsSceneContextMenuEvent
-from box import Box, TABLE_BOX
 from graph_constants import VIEW_TABLE_TYPE
 from font_helper import cell_height, text_widths, column_text_widths, \
                         LEFT_PADDING, HORIZONTAL_PADDING
 from settings_manager import preferred_pen
+from box_menu import show_box_menu
 
 # text looks bad in renderable so we render text in paint
 
@@ -142,5 +142,5 @@ class ViewTableTable(QGraphicsItem):
 
     def contextMenuEvent(self, event):
         if event.reason() == QGraphicsSceneContextMenuEvent.Mouse:
-            self.table_box.show_box_menu()
+            show_box_menu(self.table_box)
 
diff --git a/python/view_trace.py b/python/view_trace.py
index d774e7dd35f9324e9144dc6727460c69c0a62d8f..869480bba856c1dbe72d556be86d2706b353436f 100644
--- a/python/view_trace.py
+++ b/python/view_trace.py
@@ -1,5 +1,6 @@
 from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # for signal/slot support
-from box import Box, TRACE_BOX
+from box_types import TRACE_BOX
+from box import Box
 from node import Node
 from edge import Edge
 from trace_collapse_helpers import collapse_below, uncollapse_below, \