7991: Enhance style sheet editor to include table styles

This commit is contained in:
Nick Hall 2014-08-18 22:48:47 +01:00
parent 136fabfc16
commit da2023b3f8
3 changed files with 345 additions and 68 deletions

View File

@ -6,6 +6,7 @@
# Copyright (C) 2007 Brian G. Matherly
# Copyright (C) 2009 Benny Malengier
# Copyright (C) 2009 Gary Burton
# Copyright (C) 2014 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -155,52 +156,78 @@ class StyleSheetList(object):
continue
sheet = self.map[name]
xml_file.write('<sheet name="%s">\n' % escxml(name))
for p_name in sheet.get_paragraph_style_names():
# Get variables for substitutions
para = sheet.get_paragraph_style(p_name)
font = para.get_font()
rmargin = float(para.get_right_margin())
lmargin = float(para.get_left_margin())
findent = float(para.get_first_indent())
tmargin = float(para.get_top_margin())
bmargin = float(para.get_bottom_margin())
padding = float(para.get_padding())
bg_color = para.get_background_color()
# Write out style definition
xml_file.write(
'<style name="%s">\n' % escxml(p_name) +
'<font face="%d" ' % font.get_type_face() +
'size="%d" ' % font.get_size() +
'italic="%d" ' % font.get_italic() +
'bold="%d" ' % font.get_bold() +
'underline="%d" ' % font.get_underline() +
'color="#%02x%02x%02x" ' % font.get_color() +
'/>\n' +
'<para ' +
'description="%s" ' %
escxml(para.get_description()) +
'rmargin="%.3f" ' % rmargin +
'lmargin="%.3f" ' % lmargin +
'first="%.3f" ' % findent +
'tmargin="%.3f" ' % tmargin +
'bmargin="%.3f" ' % bmargin +
'pad="%.3f" ' % padding +
'bgcolor="#%02x%02x%02x" ' % bg_color +
'level="%d" ' % para.get_header_level() +
'align="%d" ' % para.get_alignment() +
'tborder="%d" ' % para.get_top_border() +
'lborder="%d" ' % para.get_left_border() +
'rborder="%d" ' % para.get_right_border() +
'bborder="%d" ' % para.get_bottom_border() +
'/>\n' +
'</style>\n'
)
for p_name in sheet.get_paragraph_style_names():
self.write_paragraph_style(xml_file, sheet, p_name)
for t_name in sheet.get_table_style_names():
self.write_table_style(xml_file, sheet, t_name)
xml_file.write('</sheet>\n')
xml_file.write('</stylelist>\n')
xml_file.close()
def write_paragraph_style(self, xml_file, sheet, p_name):
para = sheet.get_paragraph_style(p_name)
# Get variables for substitutions
font = para.get_font()
rmargin = float(para.get_right_margin())
lmargin = float(para.get_left_margin())
findent = float(para.get_first_indent())
tmargin = float(para.get_top_margin())
bmargin = float(para.get_bottom_margin())
padding = float(para.get_padding())
bg_color = para.get_background_color()
# Write out style definition
xml_file.write(
'<style name="%s">\n' % escxml(p_name) +
'<font face="%d" ' % font.get_type_face() +
'size="%d" ' % font.get_size() +
'italic="%d" ' % font.get_italic() +
'bold="%d" ' % font.get_bold() +
'underline="%d" ' % font.get_underline() +
'color="#%02x%02x%02x" ' % font.get_color() +
'/>\n' +
'<para ' +
'description="%s" ' % escxml(para.get_description()) +
'rmargin="%.3f" ' % rmargin +
'lmargin="%.3f" ' % lmargin +
'first="%.3f" ' % findent +
'tmargin="%.3f" ' % tmargin +
'bmargin="%.3f" ' % bmargin +
'pad="%.3f" ' % padding +
'bgcolor="#%02x%02x%02x" ' % bg_color +
'level="%d" ' % para.get_header_level() +
'align="%d" ' % para.get_alignment() +
'tborder="%d" ' % para.get_top_border() +
'lborder="%d" ' % para.get_left_border() +
'rborder="%d" ' % para.get_right_border() +
'bborder="%d" ' % para.get_bottom_border() +
'/>\n' +
'</style>\n'
)
def write_table_style(self, xml_file, sheet, t_name):
t_style = sheet.get_table_style(t_name)
# Write out style definition
xml_file.write(
'<style name="%s">\n' % escxml(t_name) +
'<table width="%d" ' % t_style.get_width() +
'columns="%d"' % t_style.get_columns() +
'>\n')
for col in range(t_style.get_columns()):
column_width = t_style.get_column_width(col)
xml_file.write('<column width="%d" />\n' % column_width)
xml_file.write('</table>\n')
xml_file.write('</style>\n')
def parse(self):
"""
Loads the StyleSheets from the associated file, if it exists.
@ -385,8 +412,10 @@ class SheetParser(handler.ContentHandler):
self.f = None
self.p = None
self.s = None
self.sname = None
self.pname = None
self.t = None
self.columns_widths = []
self.sheet_name = None
self.style_name = None
def startElement(self, tag, attrs):
"""
@ -394,7 +423,7 @@ class SheetParser(handler.ContentHandler):
"""
if tag == "sheet":
self.s = StyleSheet(self.sheetlist.map["default"])
self.sname = attrs['name']
self.sheet_name = attrs['name']
elif tag == "font":
self.f = FontStyle()
self.f.set_type_face(int(attrs['face']))
@ -404,6 +433,7 @@ class SheetParser(handler.ContentHandler):
self.f.set_underline(int(attrs['underline']))
self.f.set_color(cnv2color(attrs['color']))
elif tag == "para":
self.p = ParagraphStyle()
if 'description' in attrs:
self.p.set_description(attrs['description'])
self.p.set_right_margin(glocale.float(attrs['rmargin']))
@ -424,14 +454,23 @@ class SheetParser(handler.ContentHandler):
self.p.set_top_border(int(attrs['tborder']))
self.p.set_bottom_border(int(attrs['bborder']))
self.p.set_background_color(cnv2color(attrs['bgcolor']))
self.p.set_font(self.f)
elif tag == "style":
self.p = ParagraphStyle()
self.pname = attrs['name']
self.style_name = attrs['name']
elif tag == "table":
self.t = TableStyle()
self.t.set_width(int(attrs['width']))
self.t.set_columns(int(attrs['columns']))
self.column_widths = []
elif tag == "column":
self.column_widths.append(int(attrs['width']))
def endElement(self, tag):
"Overridden class that handles the start of a XML element"
if tag == "style":
self.p.set_font(self.f)
self.s.add_paragraph_style(self.pname, self.p)
elif tag == "sheet":
self.sheetlist.set_style_sheet(self.sname, self.s)
"Overridden class that handles the end of a XML element"
if tag == "sheet":
self.sheetlist.set_style_sheet(self.sheet_name, self.s)
elif tag == "para":
self.s.add_paragraph_style(self.style_name, self.p)
elif tag == "table":
self.t.set_column_widths(self.column_widths)
self.s.add_table_style(self.style_name, self.t)

View File

@ -45,6 +45,11 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment8">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkDialog" id="editor">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
@ -129,7 +134,7 @@
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Style n_ame:</property>
<property name="label" translatable="yes">Style sheet n_ame:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">style_name</property>
@ -680,6 +685,7 @@
<property name="ypad">3</property>
<property name="label" translatable="yes">Alignment</property>
<property name="justify">center</property>
<property name="ellipsize">end</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
@ -1219,6 +1225,153 @@
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="n_rows">6</property>
<property name="n_columns">4</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Width</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="right_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Column widths</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkBox" id="column_widths">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="table_width">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">etched-out</property>
<property name="adjustment">adjustment8</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">%</property>
<property name="justify">center</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Table options</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>

View File

@ -6,6 +6,7 @@
# Copyright (C) 2008 Peter Landgren
# Copyright (C) 2010 Jakim Friant
# Copyright (C) 2012 Paul Franklin
# Copyright (C) 2014 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -42,7 +43,7 @@ import re
# GNOME/GTK modules
#
#------------------------------------------------------------------------
from gi.repository import Gdk
from gi.repository import Gtk, Gdk
#------------------------------------------------------------------------
#
@ -51,7 +52,7 @@ from gi.repository import Gdk
#------------------------------------------------------------------------
from gramps.gen.plug.docgen import (StyleSheet, FONT_SERIF, FONT_SANS_SERIF,
PARA_ALIGN_RIGHT, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
PARA_ALIGN_JUSTIFY)
PARA_ALIGN_JUSTIFY, ParagraphStyle, TableStyle)
from gramps.gen.constfunc import cuni
from ...listmodel import ListModel
from ...managedwindow import set_titles
@ -188,7 +189,7 @@ class StyleEditor(object):
style - style object that is to be edited
parent - StyleListDisplay object that called the editor
"""
self.current_p = None
self.current_style = None
self.current_name = None
self.style = StyleSheet(style)
@ -209,11 +210,14 @@ class StyleEditor(object):
self.pname = self.top.get_object('pname')
self.pdescription = self.top.get_object('pdescription')
self.notebook = self.top.get_object('notebook1')
self.vbox = self.top.get_object('column_widths')
set_titles(self.window, self.top.get_object('title'),
_('Style editor'))
self.top.get_object("label6").set_text(_("point size|pt"))
titles = [(_('Paragraph'), 0, 130)]
titles = [(_('Style'), 0, 130)]
self.plist = ListModel(self.top.get_object("ptree"), titles,
self.change_display)
@ -230,6 +234,9 @@ class StyleEditor(object):
names = _alphanumeric_sort(self.style.get_paragraph_style_names())
for p_name in names:
self.plist.add([p_name], self.style.get_paragraph_style(p_name))
names = _alphanumeric_sort(self.style.get_table_style_names())
for t_name in names:
self.plist.add([t_name], self.style.get_table_style(t_name))
self.plist.select_row(0)
if self.parent:
@ -240,10 +247,64 @@ class StyleEditor(object):
def __close(self, obj):
self.window.destroy()
def draw(self):
"""Updates the display with the selected paragraph."""
def show_pages(self, show_pages):
"""
Make the given pages visible.
"""
for page_num in range(self.notebook.get_n_pages()):
page = self.notebook.get_nth_page(page_num)
if page_num in show_pages:
page.show()
else:
page.hide()
p = self.current_p
def draw(self):
"""
Updates the display with the selected style.
"""
if isinstance(self.current_style, ParagraphStyle):
self.show_pages([0, 1, 2])
self.draw_paragraph()
elif isinstance(self.current_style, TableStyle):
self.show_pages([0, 3])
self.draw_table()
def draw_table(self):
"""
Updates the display with the selected table style.
"""
t = self.current_style
self.pname.set_text( '<span size="larger" weight="bold">%s</span>' %
self.current_name)
self.pname.set_use_markup(True)
self.pdescription.set_text(_("No description available") )
self.top.get_object("table_width").set_value(t.get_width())
self.column = []
for widget in self.vbox.get_children():
self.vbox.remove(widget)
for i in range(t.get_columns()):
hbox = Gtk.HBox()
label = Gtk.Label(_('Column %d:') % (i + 1))
hbox.pack_start(label, False, False, 6)
spin = Gtk.SpinButton()
spin.set_range(0, 100)
spin.set_increments(1, 10)
spin.set_numeric(True)
spin.set_value(t.get_column_width(i))
self.column.append(spin)
hbox.pack_start(spin, False, False, 6)
hbox.pack_start(Gtk.Label('%'), False, False, 6)
hbox.show_all()
self.vbox.pack_start(hbox, False, False, 3)
def draw_paragraph(self):
"""
Updates the display with the selected paragraph style.
"""
p = self.current_style
self.pname.set_text( '<span size="larger" weight="bold">%s</span>' %
self.current_name)
self.pname.set_use_markup(True)
@ -307,9 +368,31 @@ class StyleEditor(object):
self.top.get_object('color_code').set_text(
"#%02X%02X%02X" % self.fg_color)
def save(self):
"""
Saves the current style displayed on the dialog.
"""
if isinstance(self.current_style, ParagraphStyle):
self.save_paragraph()
elif isinstance(self.current_style, TableStyle):
self.save_table()
def save_table(self):
"""
Saves the current table style displayed on the dialog.
"""
t = self.current_style
t.set_width(self.top.get_object("table_width").get_value_as_int())
for i in range(t.get_columns()):
t.set_column_width(i, self.column[i].get_value_as_int())
self.style.add_table_style(self.current_name, self.current_style)
def save_paragraph(self):
"""Saves the current paragraph displayed on the dialog"""
p = self.current_p
"""
Saves the current paragraph style displayed on the dialog.
"""
p = self.current_style
font = p.get_font()
font.set_size(self.top.get_object("size").get_value_as_int())
@ -344,7 +427,7 @@ class StyleEditor(object):
font.set_color(self.fg_color)
p.set_background_color(self.bg_color)
self.style.add_paragraph_style(self.current_name, self.current_p)
self.style.add_paragraph_style(self.current_name, self.current_style)
def on_save_style_clicked(self, obj):
"""
@ -353,24 +436,26 @@ class StyleEditor(object):
"""
name = cuni(self.top.get_object("style_name").get_text())
self.save_paragraph()
self.save()
self.style.set_name(name)
self.parent.sheetlist.set_style_sheet(name, self.style)
self.parent.redraw()
self.window.destroy()
def change_display(self, obj):
"""Called when the paragraph selection has been changed. Saves the
old paragraph, then draws the newly selected paragraph"""
"""
Called when the paragraph selection has been changed. Saves the
old paragraph, then draws the newly selected paragraph.
"""
# Don't save until current_name is defined
# If it's defined, save under the current paragraph name
if self.current_name:
self.save_paragraph()
self.save()
# Then change to new paragraph
objs = self.plist.get_selected_objects()
store, node = self.plist.get_selected()
self.current_name = store.get_value(node, 0)
self.current_p = objs[0]
self.current_style = objs[0]
self.draw()
def dummy_callback(obj):