... | ... |
@@ -50,7 +50,8 @@ class DotWidget(Gtk.DrawingArea): |
50 | 50 |
# TODO GTK3: Second argument has to be of type Gdk.EventButton instead of object. |
51 | 51 |
__gsignals__ = { |
52 | 52 |
'clicked': (GObject.SIGNAL_RUN_LAST, None, (str, object)), |
53 |
- 'error': (GObject.SIGNAL_RUN_LAST, None, (str,)) |
|
53 |
+ 'error': (GObject.SIGNAL_RUN_LAST, None, (str,)), |
|
54 |
+ 'history': (GObject.SIGNAL_RUN_LAST, None, (bool, bool)) |
|
54 | 55 |
} |
55 | 56 |
|
56 | 57 |
filter = 'dot' |
... | ... |
@@ -89,6 +90,8 @@ class DotWidget(Gtk.DrawingArea): |
89 | 90 |
self.presstime = None |
90 | 91 |
self.highlight = None |
91 | 92 |
self.highlight_search = False |
93 |
+ self.history_back = [] |
|
94 |
+ self.history_forward = [] |
|
92 | 95 |
|
93 | 96 |
def error_dialog(self, message): |
94 | 97 |
self.emit('error', message) |
... | ... |
@@ -160,6 +163,8 @@ class DotWidget(Gtk.DrawingArea): |
160 | 163 |
fp.close() |
161 | 164 |
except IOError: |
162 | 165 |
pass |
166 |
+ else: |
|
167 |
+ del self.history_back[:], self.history_forward[:] |
|
163 | 168 |
|
164 | 169 |
def update(self): |
165 | 170 |
if self.openfilename is not None: |
... | ... |
@@ -439,9 +444,39 @@ class DotWidget(Gtk.DrawingArea): |
439 | 444 |
self.zoom_to_fit() |
440 | 445 |
|
441 | 446 |
def animate_to(self, x, y): |
447 |
+ del self.history_forward[:] |
|
448 |
+ self.history_back.append(self.get_current_pos()) |
|
449 |
+ self.history_changed() |
|
450 |
+ self._animate_to(x, y) |
|
451 |
+ |
|
452 |
+ def _animate_to(self, x, y): |
|
442 | 453 |
self.animation = animation.ZoomToAnimation(self, x, y) |
443 | 454 |
self.animation.start() |
444 | 455 |
|
456 |
+ def history_changed(self): |
|
457 |
+ self.emit( |
|
458 |
+ 'history', |
|
459 |
+ bool(self.history_back), |
|
460 |
+ bool(self.history_forward)) |
|
461 |
+ |
|
462 |
+ def on_go_back(self, action=None): |
|
463 |
+ try: |
|
464 |
+ item = self.history_back.pop() |
|
465 |
+ except LookupError: |
|
466 |
+ return |
|
467 |
+ self.history_forward.append(self.get_current_pos()) |
|
468 |
+ self.history_changed() |
|
469 |
+ self._animate_to(*item) |
|
470 |
+ |
|
471 |
+ def on_go_forward(self, action=None): |
|
472 |
+ try: |
|
473 |
+ item = self.history_forward.pop() |
|
474 |
+ except LookupError: |
|
475 |
+ return |
|
476 |
+ self.history_back.append(self.get_current_pos()) |
|
477 |
+ self.history_changed() |
|
478 |
+ self._animate_to(*item) |
|
479 |
+ |
|
445 | 480 |
def window2graph(self, x, y): |
446 | 481 |
rect = self.get_allocation() |
447 | 482 |
x -= 0.5*rect.width |
... | ... |
@@ -481,6 +516,9 @@ class DotWindow(Gtk.Window): |
481 | 516 |
<toolitem action="Reload"/> |
482 | 517 |
<toolitem action="Print"/> |
483 | 518 |
<separator/> |
519 |
+ <toolitem action="Back"/> |
|
520 |
+ <toolitem action="Forward"/> |
|
521 |
+ <separator/> |
|
484 | 522 |
<toolitem action="ZoomIn"/> |
485 | 523 |
<toolitem action="ZoomOut"/> |
486 | 524 |
<toolitem action="ZoomFit"/> |
... | ... |
@@ -507,6 +545,7 @@ class DotWindow(Gtk.Window): |
507 | 545 |
|
508 | 546 |
self.dotwidget = widget or DotWidget() |
509 | 547 |
self.dotwidget.connect("error", lambda e, m: self.error_dialog(m)) |
548 |
+ self.dotwidget.connect("history", self.on_history) |
|
510 | 549 |
|
511 | 550 |
# Create a UIManager instance |
512 | 551 |
uimanager = self.uimanager = Gtk.UIManager() |
... | ... |
@@ -531,6 +570,16 @@ class DotWindow(Gtk.Window): |
531 | 570 |
('Zoom100', Gtk.STOCK_ZOOM_100, None, None, None, self.dotwidget.on_zoom_100), |
532 | 571 |
)) |
533 | 572 |
|
573 |
+ self.back_action = Gtk.Action('Back', None, None, Gtk.STOCK_GO_BACK) |
|
574 |
+ self.back_action.set_sensitive(False) |
|
575 |
+ self.back_action.connect("activate", self.dotwidget.on_go_back) |
|
576 |
+ actiongroup.add_action(self.back_action) |
|
577 |
+ |
|
578 |
+ self.forward_action = Gtk.Action('Forward', None, None, Gtk.STOCK_GO_FORWARD) |
|
579 |
+ self.forward_action.set_sensitive(False) |
|
580 |
+ self.forward_action.connect("activate", self.dotwidget.on_go_forward) |
|
581 |
+ actiongroup.add_action(self.forward_action) |
|
582 |
+ |
|
534 | 583 |
find_action = FindMenuToolAction("Find", None, |
535 | 584 |
"Find a node by name", None) |
536 | 585 |
actiongroup.add_action(find_action) |
... | ... |
@@ -658,3 +707,7 @@ class DotWindow(Gtk.Window): |
658 | 707 |
dlg.set_title(self.base_title) |
659 | 708 |
dlg.run() |
660 | 709 |
dlg.destroy() |
710 |
+ |
|
711 |
+ def on_history(self, action, has_back, has_forward): |
|
712 |
+ self.back_action.set_sensitive(has_back) |
|
713 |
+ self.forward_action.set_sensitive(has_forward) |