root/gaphor/tags/gaphor-0.12.5/gaphor/services/diagramexportmanager.py

Revision 1851, 6.1 kB (checked in by arj..@yirdis.nl, 1 year ago)

make diagram export work with gaphas 0.3.0's View.

Line 
1 """
2 Service dedicated to exporting diagrams to a varyity of file formats.
3 """
4
5 import os
6 from zope import interface, component
7 from gaphor.core import _, inject, action, build_action_group
8 from gaphor.interfaces import IService, IActionProvider
9
10 import cairo
11 from gaphas.view import View
12 from gaphas.painter import ItemPainter
13 from gaphas.geometry import Rectangle
14
15 class DiagramExportManager(object):
16     """
17     Service for exporting diagrams as images (SVG, PNG, PDF).
18     """
19
20     interface.implements(IService, IActionProvider)
21
22     gui_manager = inject('gui_manager')
23
24     menu_xml = """
25       <ui>
26         <menubar action="mainwindow">
27           <menu action="file">
28             <menu action="file-export">
29               <menuitem action="file-export-svg" />
30               <menuitem action="file-export-png" />
31               <menuitem action="file-export-pdf" />
32               <separator />
33             </menu>
34           </menu>
35         </menubar>
36       </ui>
37     """
38
39     def __init__(self):
40         self.action_group = build_action_group(self)
41
42     def init(self, app):
43         pass
44
45     def shutdown(self):
46         pass
47
48     def update(self):
49         tab = self.get_window().get_current_diagram_tab()
50         self.sensitive = tab and True or False
51
52
53     def save_dialog(self, diagram, title, ext):
54         import gtk
55         filename = (diagram.name or 'export') + ext
56
57         filesel = gtk.FileChooserDialog(title = title,
58             action = gtk.FILE_CHOOSER_ACTION_SAVE,
59             buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
60         filesel.set_current_name(filename)
61
62         save = False
63         while True:
64             response = filesel.run()
65             filename = filesel.get_filename()
66
67             if response == gtk.RESPONSE_OK:
68                 if os.path.exists(filename):
69                     dialog = gtk.MessageDialog(filesel,
70                         gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
71                         gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO,
72                         _("The file %s already exists. Do you want to replace it with the file you are exporting to?") % filename)
73                     answer = dialog.run()
74                     dialog.destroy()
75                     if answer == gtk.RESPONSE_YES:
76                         save = True
77                         break
78                 else:
79                     save = True
80                     break
81             else:
82                 break
83
84         filesel.destroy()
85
86         if save and filename:
87             return filename
88         return None
89
90
91     def save_svg(self, filename, canvas):
92         log.debug('Exporting SVG image to: %s' % filename)
93         view = View(canvas)
94         view.painter = ItemPainter()
95
96         # Update bounding boxes with a temporaly CairoContext
97         # (used for stuff like calculating font metrics)
98         tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
99         tmpcr = cairo.Context(tmpsurface)
100         view.update_bounding_box(tmpcr)
101         tmpcr.show_page()
102         tmpsurface.flush()
103
104         w, h = view.bounding_box.width, view.bounding_box.height
105         surface = cairo.SVGSurface(filename, w, h)
106         cr = cairo.Context(surface)
107         view.matrix.translate(-view.bounding_box.x, -view.bounding_box.y)
108         view.paint(cr)
109         cr.show_page()
110         surface.flush()
111         surface.finish()
112
113
114     def save_png(self, filename, canvas):
115         log.debug('Exporting PNG image to: %s' % filename)
116         view = View(canvas)
117         view.painter = ItemPainter()
118
119         # Update bounding boxes with a temporaly CairoContext
120         # (used for stuff like calculating font metrics)
121         tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
122         tmpcr = cairo.Context(tmpsurface)
123         view.update_bounding_box(tmpcr)
124         tmpcr.show_page()
125         tmpsurface.flush()
126
127         w, h = view.bounding_box.width, view.bounding_box.height
128         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w+1), int(h+1))
129         cr = cairo.Context(surface)
130         view.matrix.translate(-view.bounding_box.x, -view.bounding_box.y)
131         view.paint(cr)
132         cr.show_page()
133         surface.write_to_png(filename)
134
135     def save_pdf(self, filename, canvas):
136         log.debug('Exporting PDF image to: %s' % filename)
137         view = View(canvas)
138         view.painter = ItemPainter()
139
140         # Update bounding boxes with a temporaly CairoContext
141         # (used for stuff like calculating font metrics)
142         tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
143         tmpcr = cairo.Context(tmpsurface)
144         view.update_bounding_box(tmpcr)
145         tmpcr.show_page()
146         tmpsurface.flush()
147
148         w, h = view.bounding_box.width, view.bounding_box.height
149         surface = cairo.PDFSurface(filename, w, h)
150         cr = cairo.Context(surface)
151         view.matrix.translate(-view.bounding_box.x, -view.bounding_box.y)
152         view.paint(cr)
153         cr.show_page()
154         surface.flush()
155         surface.finish()
156
157     @action(name='file-export-svg', label='Export to SVG',
158             tooltip='Export the diagram to SVG')
159     def save_svg_action(self):
160         title = 'Export diagram to SVG'
161         ext = '.svg'
162         diagram = self.gui_manager.main_window.get_current_diagram()
163         filename = self.save_dialog(diagram, title, ext)
164         if filename:
165             self.save_svg(filename, diagram.canvas)
166
167
168     @action(name='file-export-png', label='Export to PNG',
169             tooltip='Export the diagram to PNG')
170     def save_png_action(self):
171         title = 'Export diagram to PNG'
172         ext = '.png'
173         diagram = self.gui_manager.main_window.get_current_diagram()
174         filename = self.save_dialog(diagram, title, ext)
175         if filename:
176             self.save_png(filename, diagram.canvas)
177
178
179     @action(name='file-export-pdf', label='Export to PDF',
180             tooltip='Export the diagram to PDF')
181     def save_pdf_action(self):
182         title = 'Export diagram to PDF'
183         ext = '.pdf'
184         diagram = self.gui_manager.main_window.get_current_diagram()
185         filename = self.save_dialog(diagram, title, ext)
186         if filename:
187             self.save_pdf(filename, diagram.canvas)
188
189
190 # vim:sw=4:et:
191
Note: See TracBrowser for help on using the browser.