| ... | ... |
@@ -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) |