Skip to content

Commit e623c3c

Browse files
committed
8506: Enable saving of GraphView charts
1 parent 396df8f commit e623c3c

File tree

1 file changed

+74
-6
lines changed

1 file changed

+74
-6
lines changed

GraphView/graphview.py

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
import gramps.gen.datehandler
6464
from gramps.gen.display.place import displayer as place_displayer
6565
from gramps.gen.constfunc import win
66+
from gramps.gen.config import config
67+
from gramps.gui.dialog import OptionDialog
6668

6769
if win():
6870
DETACHED_PROCESS = 8
@@ -132,10 +134,23 @@ def __init__(self, pdata, dbstate, uistate, nav_group=0):
132134
'interface.graphview-ancestor-generations')
133135

134136
self.dbstate = dbstate
137+
self.uistate = uistate
135138
self.graph_widget = None
136139
self.dbstate.connect('database-changed', self.change_db)
137140

138141
self.additional_uis.append(self.additional_ui())
142+
self.define_print_actions()
143+
144+
def define_print_actions(self):
145+
"""
146+
Associate the print button to the PrintView action.
147+
"""
148+
self._add_action('PrintView', 'document-print', _("_Print..."),
149+
accel="<PRIMARY>P",
150+
tip=_("Save the dot file for a later print.\n"
151+
"This will save a .gv file and a svg file.\n"
152+
"You must select a .gv file"),
153+
callback=self.printview)
139154

140155
def _connect_db_signals(self):
141156
"""
@@ -198,13 +213,21 @@ def additional_ui(self):
198213
<separator/>
199214
</placeholder>
200215
</menu>
216+
<menu action="EditMenu">
217+
<placeholder name="CommonEdit">
218+
<menuitem action="PrintView"/>
219+
</placeholder>
220+
</menu>
201221
</menubar>
202222
<toolbar name="ToolBar">
203223
<placeholder name="CommonNavigation">
204224
<toolitem action="Back"/>
205225
<toolitem action="Forward"/>
206226
<toolitem action="HomePerson"/>
207227
</placeholder>
228+
<placeholder name="CommonEdit">
229+
<toolitem action="PrintView"/>
230+
</placeholder>
208231
</toolbar>
209232
</ui>'''
210233

@@ -368,6 +391,51 @@ def color_config_panel(self, configdialog):
368391

369392
return _('Colors'), grid
370393

394+
#-------------------------------------------------------------------------
395+
#
396+
# Printing functionalities
397+
#
398+
#-------------------------------------------------------------------------
399+
def printview(self, obj):
400+
"""
401+
Save the dot file for a later printing with an appropriate tool.
402+
"""
403+
# Ask for the dot file name
404+
filter = Gtk.FileFilter()
405+
filter.add_pattern("*.gv")
406+
dot = Gtk.FileChooserDialog(
407+
_("Select a dot file name"),
408+
action=Gtk.FileChooserAction.OPEN,
409+
buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
410+
_('_Apply'), Gtk.ResponseType.OK))
411+
mpath = config.get('paths.report-directory')
412+
dot.set_current_folder(os.path.dirname(mpath))
413+
dot.set_filter(filter)
414+
415+
status = dot.run()
416+
if status == Gtk.ResponseType.OK:
417+
val = dot.get_filename()
418+
# selected path is an existing file and we need a file
419+
if os.path.isfile(val):
420+
aaa = OptionDialog(_('File already exists'), # parent-OK
421+
_('You can choose to either overwrite the '
422+
'file, or change the selected filename.'),
423+
_('_Overwrite'), None,
424+
_('_Change filename'), None,
425+
parent=self.uistate.window)
426+
427+
if aaa.get_response() == Gtk.ResponseType.YES:
428+
dot.destroy()
429+
self.printview(obj)
430+
return
431+
svg = val.replace('.gv', '.svg')
432+
if val:
433+
with open(val,'w') as g,\
434+
open(svg,'w') as s:
435+
g.write(self.graph_widget.dot_data.decode('utf-8'))
436+
s.write(self.graph_widget.svg_data.decode('utf-8'))
437+
dot.destroy()
438+
371439
#-------------------------------------------------------------------------
372440
#
373441
# GraphWidget
@@ -420,18 +488,18 @@ def populate(self, active_person):
420488
dot.build_graph(active_person)
421489

422490
# Build the rest of the widget by parsing SVG data from Graphviz
423-
dot_data = dot.get_dot().encode('utf8')
491+
self.dot_data = dot.get_dot().encode('utf8')
424492
if win():
425-
svg_data = Popen(['dot', '-Tsvg'],
493+
self.svg_data = Popen(['dot', '-Tsvg'],
426494
creationflags=DETACHED_PROCESS,
427495
stdin=PIPE,
428496
stdout=PIPE,
429-
stderr=PIPE).communicate(input=dot_data)[0]
497+
stderr=PIPE).communicate(input=self.dot_data)[0]
430498
else:
431-
svg_data = Popen(['dot', '-Tsvg'],
432-
stdin=PIPE, stdout=PIPE).communicate(input=dot_data)[0]
499+
self.svg_data = Popen(['dot', '-Tsvg'],
500+
stdin=PIPE, stdout=PIPE).communicate(input=self.dot_data)[0]
433501
parser = GraphvizSvgParser(self, self.view)
434-
parser.parse(svg_data)
502+
parser.parse(self.svg_data)
435503
window = self.canvas.get_parent()
436504

437505
# The scroll_to method will try and put the active person in the top

0 commit comments

Comments
 (0)