Browse code

Introduce "Export to other format" feature

Meier, Moritz authored on 08/10/2021 16:42:39 • José Fonseca committed on 27/11/2021 15:12:34
Showing 2 changed files

... ...
@@ -36,6 +36,7 @@ Shortcuts:
36 36
   F                         find
37 37
   Q                         quit
38 38
   P                         print
39
+  T                         toggle show/hide toolbar
39 40
   Escape                    halt animation
40 41
   Ctrl-drag                 zoom in/out
41 42
   Shift-drag                zooms an area
... ...
@@ -133,6 +133,7 @@ class DotWidget(Gtk.DrawingArea):
133 133
         # By default DOT language is UTF-8, but it accepts other encodings
134 134
         assert isinstance(dotcode, bytes)
135 135
         xdotcode = self.run_filter(dotcode)
136
+            
136 137
         if xdotcode is None:
137 138
             return False
138 139
         try:
... ...
@@ -155,6 +156,7 @@ class DotWidget(Gtk.DrawingArea):
155 156
 
156 157
     def set_xdotcode(self, xdotcode, center=True):
157 158
         assert isinstance(xdotcode, bytes)
159
+
158 160
         if self.graphviz_version is None:
159 161
             stdout = subprocess.check_output([self.filter, '-V'], stderr=subprocess.STDOUT)
160 162
             stdout = stdout.rstrip()
... ...
@@ -537,6 +539,7 @@ class DotWindow(Gtk.Window):
537 539
     <ui>
538 540
         <toolbar name="ToolBar">
539 541
             <toolitem action="Open"/>
542
+            <toolitem action="Export"/>
540 543
             <toolitem action="Reload"/>
541 544
             <toolitem action="Print"/>
542 545
             <separator/>
... ...
@@ -590,6 +593,7 @@ class DotWindow(Gtk.Window):
590 593
         # Create actions
591 594
         actiongroup.add_actions((
592 595
             ('Open', Gtk.STOCK_OPEN, None, None, None, self.on_open),
596
+            ('Export', Gtk.STOCK_SAVE_AS, None, None, "Save graph as picture.", self.on_export),
593 597
             ('Reload', Gtk.STOCK_REFRESH, None, None, None, self.on_reload),
594 598
             ('Print', Gtk.STOCK_PRINT, None, None,
595 599
              "Prints the currently visible part of the graph", self.dotwidget.on_print),
... ...
@@ -749,6 +753,55 @@ class DotWindow(Gtk.Window):
749 753
             self.open_file(filename)
750 754
         else:
751 755
             chooser.destroy()
756
+   
757
+    def export_file(self, filename, format_):
758
+        if not filename.endswith("." + format_):
759
+            filename += '.' + format_
760
+        cmd = [
761
+            self.dotwidget.filter, # program name, usually "dot"
762
+            '-T' + format_,
763
+            '-o', filename,
764
+            self.dotwidget.openfilename,
765
+        ]
766
+        subprocess.check_call(cmd)
767
+
768
+    def on_export(self, action):
769
+        output_formats = {
770
+            "PNG image": "png",
771
+            "SVG image": "svg",
772
+            "PDF image": "pdf",
773
+            "GIF image": "gif",
774
+            "PDF image": "pdf",
775
+        }
776
+        buttons = (
777
+            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
778
+            Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
779
+        chooser = Gtk.FileChooserDialog(
780
+            parent=self,
781
+            title="Export to other file format.",
782
+            action=Gtk.FileChooserAction.SAVE,
783
+            buttons=buttons) 
784
+        chooser.set_default_response(Gtk.ResponseType.OK)
785
+        chooser.set_current_folder(self.last_open_dir)
786
+        
787
+        openfilename = os.path.basename(self.dotwidget.openfilename)
788
+        openfileroot = os.path.splitext(openfilename)[0]
789
+        chooser.set_current_name(openfileroot)
790
+
791
+        for name, ext in output_formats.items():
792
+            filter_ = Gtk.FileFilter()
793
+            filter_.set_name(name)
794
+            filter_.add_pattern('*.' + ext)
795
+            chooser.add_filter(filter_)
796
+        
797
+        if chooser.run() == Gtk.ResponseType.OK:
798
+            filename = chooser.get_filename()
799
+            format_ = output_formats[chooser.get_filter().get_name()]
800
+            chooser.destroy()
801
+            self.export_file(filename, format_)
802
+        else:
803
+            chooser.destroy()
804
+	
752 805
 
753 806
     def on_reload(self, action):
754 807
         self.dotwidget.reload()