3914: Add a new markup for creating links to URLs and for gramps objects
svn: r15340
This commit is contained in:
parent
ef002c54ad
commit
40b8c2d9a2
@ -213,6 +213,7 @@ src/gui/editors/editeventref.py
|
||||
src/gui/editors/editfamily.py
|
||||
src/gui/editors/editldsord.py
|
||||
src/gui/editors/editlocation.py
|
||||
src/gui/editors/editlink.py
|
||||
src/gui/editors/editmedia.py
|
||||
src/gui/editors/editmediaref.py
|
||||
src/gui/editors/editname.py
|
||||
@ -839,6 +840,7 @@ src/glade/editrepository.glade
|
||||
src/glade/editreporef.glade
|
||||
src/glade/editpersonref.glade
|
||||
src/glade/editlocation.glade
|
||||
src/glade/editlink.glade
|
||||
src/glade/editfamily.glade
|
||||
src/glade/editchildref.glade
|
||||
src/glade/editattribute.glade
|
||||
|
@ -56,6 +56,7 @@ class StyledTextTagType(GrampsType):
|
||||
FONTCOLOR = 5
|
||||
HIGHLIGHT = 6
|
||||
SUPERSCRIPT = 7
|
||||
LINK = 8
|
||||
|
||||
_CUSTOM = NONE_TYPE
|
||||
_DEFAULT = NONE_TYPE
|
||||
@ -69,6 +70,7 @@ class StyledTextTagType(GrampsType):
|
||||
(FONTCOLOR, _("Fontcolor"), "fontcolor"),
|
||||
(HIGHLIGHT, _("Highlight"), "highlight"),
|
||||
(SUPERSCRIPT, _("Superscript"), "superscript"),
|
||||
(LINK, _("Link"), "link"),
|
||||
]
|
||||
|
||||
STYLE_TYPE = {
|
||||
@ -80,6 +82,7 @@ class StyledTextTagType(GrampsType):
|
||||
FONTFACE: str,
|
||||
FONTSIZE: int,
|
||||
SUPERSCRIPT: bool,
|
||||
LINK: str,
|
||||
}
|
||||
|
||||
STYLE_DEFAULT = {
|
||||
@ -91,6 +94,7 @@ class StyledTextTagType(GrampsType):
|
||||
FONTFACE: 'Sans',
|
||||
FONTSIZE: 10,
|
||||
SUPERSCRIPT: False,
|
||||
LINK: '',
|
||||
}
|
||||
|
||||
def __init__(self, value=None):
|
||||
|
@ -99,6 +99,7 @@ class DocBackend(object):
|
||||
FONTCOLOR = 5
|
||||
HIGHLIGHT = 6
|
||||
SUPERSCRIPT = 7
|
||||
LINK = 8
|
||||
|
||||
SUPPORTED_MARKUP = []
|
||||
|
||||
@ -115,6 +116,7 @@ class DocBackend(object):
|
||||
ITALIC : ("", ""),
|
||||
UNDERLINE : ("", ""),
|
||||
SUPERSCRIPT : ("", ""),
|
||||
LINK : ("", ""),
|
||||
}
|
||||
|
||||
def __init__(self, filename=None):
|
||||
@ -216,7 +218,7 @@ class DocBackend(object):
|
||||
if not self.STYLETYPE_MAP or \
|
||||
self.CLASSMAP != tagtype.__class__.__name__ :
|
||||
self.CLASSMAP == tagtype.__class__.__name__
|
||||
self.STYLETYPE_MAP[tagtype.__class__.BOLD] = self.BOLD
|
||||
self.STYLETYPE_MAP[tagtype.BOLD] = self.BOLD
|
||||
self.STYLETYPE_MAP[tagtype.ITALIC] = self.ITALIC
|
||||
self.STYLETYPE_MAP[tagtype.UNDERLINE] = self.UNDERLINE
|
||||
self.STYLETYPE_MAP[tagtype.FONTFACE] = self.FONTFACE
|
||||
@ -224,7 +226,10 @@ class DocBackend(object):
|
||||
self.STYLETYPE_MAP[tagtype.FONTCOLOR] = self.FONTCOLOR
|
||||
self.STYLETYPE_MAP[tagtype.HIGHLIGHT] = self.HIGHLIGHT
|
||||
self.STYLETYPE_MAP[tagtype.SUPERSCRIPT] = self.SUPERSCRIPT
|
||||
self.STYLETYPE_MAP[tagtype.LINK] = self.LINK
|
||||
|
||||
if s_tag.name == 'link':
|
||||
return self.format_link(s_tag.value)
|
||||
typeval = int(s_tag.name)
|
||||
s_tagvalue = s_tag.value
|
||||
tag_name = None
|
||||
@ -351,3 +356,13 @@ class DocBackend(object):
|
||||
otext += opentag[1]
|
||||
|
||||
return otext
|
||||
|
||||
def format_link(self, value):
|
||||
"""
|
||||
Default format for links. Override for better support.
|
||||
|
||||
value is: "TYPE DATA" where TYPE is 'url' or 'ref'.
|
||||
|
||||
"""
|
||||
return self.STYLETAG_MARKUP[DocBackend.UNDERLINE]
|
||||
|
||||
|
@ -28,6 +28,7 @@ dist_pkgdata_DATA = \
|
||||
editreporef.glade \
|
||||
editpersonref.glade \
|
||||
editlocation.glade \
|
||||
editlink.glade \
|
||||
editfamily.glade \
|
||||
editchildref.glade \
|
||||
editattribute.glade \
|
||||
|
212
src/glade/editlink.glade
Normal file
212
src/glade/editlink.glade
Normal file
@ -0,0 +1,212 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkDialog" id="editurl">
|
||||
<property name="modal">True</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox29">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox37">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table27">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label219">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Gramps item:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label220">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Web Address:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="mnemonic_widget">entry1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label591">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Type:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-index</property>
|
||||
<property name="icon-size">2</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="x_options"></property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area29">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button125">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button124">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="tooltip_markup">Accept changes and close window</property>
|
||||
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button130">
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">button125</action-widget>
|
||||
<action-widget response="-5">button124</action-widget>
|
||||
<action-widget response="-11">button130</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
@ -19,6 +19,7 @@ pkgdata_PYTHON = \
|
||||
editfamily.py \
|
||||
editldsord.py \
|
||||
editlocation.py \
|
||||
editlink.py \
|
||||
editmedia.py \
|
||||
editmediaref.py \
|
||||
editname.py \
|
||||
|
@ -38,8 +38,9 @@ from editreporef import EditRepoRef
|
||||
from editsource import EditSource, DeleteSrcQuery
|
||||
from editsourceref import EditSourceRef
|
||||
from editurl import EditUrl
|
||||
from editlink import EditLink
|
||||
|
||||
# Map from gen.obj name to Editor:
|
||||
# Map from gen.lib name to Editor:
|
||||
EDITORS = {
|
||||
'Person': EditPerson,
|
||||
'Event': EditEvent,
|
||||
@ -58,18 +59,23 @@ def EditObject(dbstate, uistate, track, obj_class, prop, value):
|
||||
prop is 'handle' or 'gramps_id'
|
||||
value is string handle or string gramps_id
|
||||
"""
|
||||
import logging
|
||||
LOG = logging.getLogger(".Edit")
|
||||
if obj_class in dbstate.db.get_table_names():
|
||||
if prop in ("gramps_id", "handle"):
|
||||
obj = dbstate.db.get_table_metadata(obj_class)[prop + "_func"](value)
|
||||
if obj:
|
||||
EDITORS[obj_class](dbstate, uistate, track, obj)
|
||||
try:
|
||||
EDITORS[obj_class](dbstate, uistate, track, obj)
|
||||
except Exception as msg:
|
||||
LOG.warn(str(msg))
|
||||
else:
|
||||
raise AttributeError("gramps://%s/%s/%s not found" %
|
||||
(obj_class, prop, value))
|
||||
LOG.warn("gramps://%s/%s/%s not found" %
|
||||
(obj_class, prop, value))
|
||||
else:
|
||||
raise AttributeError("unknown property to edit '%s'; "
|
||||
"should be 'gramps_id' or 'handle'" % prop)
|
||||
LOG.warn("unknown property to edit '%s'; "
|
||||
"should be 'gramps_id' or 'handle'" % prop)
|
||||
else:
|
||||
raise AttributeError("unknown object to edit '%s'; "
|
||||
"should be one of %s" % (obj_class, EDITORS.keys()))
|
||||
LOG.warn("unknown object to edit '%s'; "
|
||||
"should be one of %s" % (obj_class, EDITORS.keys()))
|
||||
|
||||
|
219
src/gui/editors/editlink.py
Normal file
219
src/gui/editors/editlink.py
Normal file
@ -0,0 +1,219 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2010 Doug Blank <doug.blank@gmail.com>
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id: $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
import ManagedWindow
|
||||
import GrampsDisplay
|
||||
from glade import Glade
|
||||
from Simple import SimpleAccess
|
||||
|
||||
WEB, EVENT, FAMILY, MEDIA, NOTE, PERSON, PLACE, REPOSITORY, SOURCE = range(9)
|
||||
OBJECT_MAP = {
|
||||
EVENT: "Event",
|
||||
FAMILY: "Family",
|
||||
MEDIA: "Media",
|
||||
NOTE: "Note",
|
||||
PERSON: "Person",
|
||||
PLACE: "Place",
|
||||
REPOSITORY: "Repository",
|
||||
SOURCE: "Source",
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EditUrl class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class EditLink(ManagedWindow.ManagedWindow):
|
||||
|
||||
def __init__(self, dbstate, uistate, track, url, callback):
|
||||
self.url = url
|
||||
self.dbstate = dbstate
|
||||
self.simple_access = SimpleAccess(self.dbstate.db)
|
||||
self.callback = callback
|
||||
|
||||
ManagedWindow.ManagedWindow.__init__(self, uistate, track, url)
|
||||
|
||||
self._local_init()
|
||||
self._connect_signals()
|
||||
self.show()
|
||||
|
||||
def _local_init(self):
|
||||
self.top = Glade()
|
||||
self.set_window(self.top.toplevel,
|
||||
self.top.get_object("title"),
|
||||
_('Link Editor'))
|
||||
self.table = self.top.get_object('table27')
|
||||
self.uri_list = gtk.combo_box_new_text()
|
||||
for text in [_("Web Address"), # 0 this order range above
|
||||
_("Gramps Event"), # 1
|
||||
_("Gramps Family"), # 2
|
||||
_("Gramps Media"), # 3
|
||||
_("Gramps Note"), # 4
|
||||
_("Gramps Person"), # 5
|
||||
_("Gramps Place"), # 6
|
||||
_("Gramps Repository"), # 7
|
||||
_("Gramps Source"), # 8
|
||||
]:
|
||||
self.uri_list.append_text(text)
|
||||
self.table.attach(self.uri_list, 1, 2, 0, 1)
|
||||
self.pick_item = self.top.get_object('button1')
|
||||
#self.edit_item = self.top.get_object('button2')
|
||||
self.selected = self.top.get_object('label1')
|
||||
self.url_link = self.top.get_object('entry1')
|
||||
self.uri_list.connect("changed", self._on_type_changed)
|
||||
self.pick_item.connect("clicked", self._on_pick_one)
|
||||
#self.edit_item.connect("clicked", self._on_edit_one)
|
||||
if self.url.startswith("gramps://"):
|
||||
object_class, prop, value = self.url[9:].split("/", 2)
|
||||
if object_class == "Event":
|
||||
self.uri_list.set_active(EVENT)
|
||||
elif object_class == "Family":
|
||||
self.uri_list.set_active(FAMILY)
|
||||
elif object_class == "Media":
|
||||
self.uri_list.set_active(MEDIA)
|
||||
elif object_class == "Note":
|
||||
self.uri_list.set_active(NOTE)
|
||||
elif object_class == "Person":
|
||||
self.uri_list.set_active(PERSON)
|
||||
elif object_class == "Place":
|
||||
self.uri_list.set_active(PLACE)
|
||||
elif object_class == "Repository":
|
||||
self.uri_list.set_active(REPOSITORY)
|
||||
elif object_class == "Source":
|
||||
self.uri_list.set_active(SOURCE)
|
||||
# set texts:
|
||||
self.selected.set_text(self.display_link(
|
||||
object_class, prop, value))
|
||||
self.url_link.set_text("gramps://%s/%s/%s" %
|
||||
(object_class, prop, value))
|
||||
else:
|
||||
self.uri_list.set_active(WEB)
|
||||
self.url_link.set_text(self.url)
|
||||
self.url_link.connect("changed", self.update_ui)
|
||||
|
||||
def update_ui(self, widget):
|
||||
url = self.url_link.get_text()
|
||||
# text needs to have 3 or more chars://and at least one char
|
||||
match = re.match("\w{3,}://\w+", url)
|
||||
if match:
|
||||
self.ok_button.set_sensitive(True)
|
||||
else:
|
||||
self.ok_button.set_sensitive(False)
|
||||
|
||||
def display_link(self, obj_class, prop, value):
|
||||
return self.simple_access.display(obj_class, prop, value)
|
||||
|
||||
def _on_edit_one(self, widget):
|
||||
from gui.editors import EditObject
|
||||
uri = self.url_link.get_text()
|
||||
if uri.startswith("gramps://"):
|
||||
obj_class, prop, value = uri[9:].split("/", 2)
|
||||
EditObject(self.dbstate,
|
||||
self.uistate,
|
||||
self.track,
|
||||
obj_class, prop, value)
|
||||
|
||||
def _on_pick_one(self, widget):
|
||||
from gui.selectors import SelectorFactory
|
||||
object_class = OBJECT_MAP[self.uri_list.get_active()]
|
||||
Select = SelectorFactory(object_class)
|
||||
uri = self.url_link.get_text()
|
||||
default = None
|
||||
if uri.startswith("gramps://"):
|
||||
obj_class, prop, value = uri[9:].split("/", 2)
|
||||
if object_class == obj_class:
|
||||
if prop == "handle":
|
||||
default = value
|
||||
elif (prop == "gramps_id" and
|
||||
object_class in self.dbstate.db.get_table_names()):
|
||||
person = self.dbstate.db.get_table_metadata(object_class)["gramps_id_func"](value)
|
||||
if person:
|
||||
default = person.handle
|
||||
d = Select(self.dbstate, self.uistate, self.track,
|
||||
default=default)
|
||||
|
||||
result = d.run()
|
||||
if result:
|
||||
prop = "handle"
|
||||
value = result.handle
|
||||
self.selected.set_text(self.display_link(
|
||||
object_class, prop, value))
|
||||
self.url_link.set_text("gramps://%s/%s/%s" %
|
||||
(object_class, prop, value))
|
||||
|
||||
def _on_type_changed(self, widget):
|
||||
self.selected.set_text("")
|
||||
if self.uri_list.get_active() == WEB:
|
||||
self.url_link.set_sensitive(True)
|
||||
self.pick_item.set_sensitive(False)
|
||||
else:
|
||||
self.url_link.set_sensitive(False)
|
||||
self.pick_item.set_sensitive(True)
|
||||
|
||||
def get_uri(self):
|
||||
if self.uri_list.get_active() == WEB:
|
||||
return self.url_link.get_text()
|
||||
else:
|
||||
#object_class = OBJECT_MAP[self.uri_list.get_active()]
|
||||
#prop = "handle"
|
||||
#value = ""
|
||||
#return "gramps://%s/%s/%s" % (object_class, prop, value)
|
||||
return self.url_link.get_text()
|
||||
|
||||
def _connect_signals(self):
|
||||
self.define_cancel_button(self.top.get_object('button125'))
|
||||
self.ok_button = self.top.get_object('button124')
|
||||
self.define_ok_button(self.ok_button, self.save)
|
||||
self.define_help_button(self.top.get_object('button130'))
|
||||
self.update_ui(self.url_link)
|
||||
|
||||
def build_menu_names(self, obj):
|
||||
etitle =_('Link Editor')
|
||||
return (etitle, etitle)
|
||||
|
||||
def define_ok_button(self,button,function):
|
||||
button.connect('clicked',function)
|
||||
|
||||
def save(self, widget):
|
||||
self.callback(self.get_uri())
|
||||
self.close()
|
||||
|
||||
def define_cancel_button(self,button):
|
||||
button.connect('clicked',self.close)
|
||||
|
||||
def define_help_button(self, button, webpage='', section=''):
|
||||
button.connect('clicked', lambda x: GrampsDisplay.help(webpage,
|
||||
section))
|
@ -44,8 +44,8 @@ from baseselector import BaseSelector
|
||||
#-------------------------------------------------------------------------
|
||||
class SelectPerson(BaseSelector):
|
||||
|
||||
def __init__(self, dbstate, uistate, track=[], title = None, filter = None,
|
||||
skip=set(), show_search_bar = False):
|
||||
def __init__(self, dbstate, uistate, track=[], title=None, filter=None,
|
||||
skip=set(), show_search_bar=False, default=None):
|
||||
|
||||
# SelectPerson may have a title passed to it which should be used
|
||||
# instead of the default defined for get_window_title()
|
||||
@ -53,7 +53,7 @@ class SelectPerson(BaseSelector):
|
||||
self.title = title
|
||||
|
||||
BaseSelector.__init__(self, dbstate, uistate, track, filter,
|
||||
skip, show_search_bar)
|
||||
skip, show_search_bar, default)
|
||||
|
||||
def _local_init(self):
|
||||
"""
|
||||
|
@ -82,6 +82,25 @@ STYLE_TO_PROPERTY = {
|
||||
MATCH_FLAVOR,
|
||||
MATCH_STRING,) = range(4)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# LinkTag class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class LinkTag(gtk.TextTag):
|
||||
"""
|
||||
Class for keeping track of link data.
|
||||
"""
|
||||
lid = 0
|
||||
def __init__(self, buffer, data, **properties):
|
||||
LinkTag.lid += 1
|
||||
self.data = data
|
||||
gtk.TextTag.__init__(self, "link-%d" % LinkTag.lid)
|
||||
tag_table = buffer.get_tag_table()
|
||||
for property in properties:
|
||||
self.set_property(property, properties[property])
|
||||
tag_table.add(self)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GtkSpellState class
|
||||
@ -432,6 +451,29 @@ class StyledTextBuffer(gtk.TextBuffer):
|
||||
self.remove_tag_by_name(tag_name,
|
||||
self.get_iter_at_offset(start),
|
||||
self.get_iter_at_offset(end+1))
|
||||
|
||||
def clear_selection(self):
|
||||
"""
|
||||
Clear tags from selection.
|
||||
"""
|
||||
start, end = self._get_selection()
|
||||
tags = self._get_tag_from_range(start.get_offset(), end.get_offset())
|
||||
removed_something = False
|
||||
for tag_name, tag_data in tags.iteritems():
|
||||
if tag_name.startswith("link"):
|
||||
for start_pos, end_pos in tag_data:
|
||||
self.remove_tag_by_name(tag_name,
|
||||
self.get_iter_at_offset(start_pos),
|
||||
self.get_iter_at_offset(end_pos+1))
|
||||
removed_something = True
|
||||
|
||||
for style in ALLOWED_STYLES:
|
||||
value = self.style_state[style]
|
||||
if value and (value != StyledTextTagType.STYLE_DEFAULT[style]):
|
||||
self.remove_tag(self._find_tag_by_name(style, value),
|
||||
start, end)
|
||||
removed_something = True
|
||||
return removed_something
|
||||
|
||||
def _get_tag_from_range(self, start=None, end=None):
|
||||
"""Extract gtk.TextTags from buffer.
|
||||
@ -474,7 +516,9 @@ class StyledTextBuffer(gtk.TextBuffer):
|
||||
If TextTag does not exist yet, it is created.
|
||||
|
||||
"""
|
||||
if StyledTextTagType.STYLE_TYPE[style] == bool:
|
||||
if style not in StyledTextTagType.STYLE_TYPE:
|
||||
return None
|
||||
elif StyledTextTagType.STYLE_TYPE[style] == bool:
|
||||
tag_name = str(style)
|
||||
elif StyledTextTagType.STYLE_TYPE[style] == str:
|
||||
tag_name = "%d %s" % (style, value)
|
||||
@ -507,7 +551,12 @@ class StyledTextBuffer(gtk.TextBuffer):
|
||||
|
||||
s_tags = s_text.get_tags()
|
||||
for s_tag in s_tags:
|
||||
g_tag = self._find_tag_by_name(int(s_tag.name), s_tag.value)
|
||||
if s_tag.name == 'Link':
|
||||
g_tag = LinkTag(self, s_tag.value,
|
||||
foreground="blue",
|
||||
underline=UNDERLINE_SINGLE)
|
||||
else:
|
||||
g_tag = self._find_tag_by_name(int(s_tag.name), s_tag.value)
|
||||
if g_tag is not None:
|
||||
for (start, end) in s_tag.ranges:
|
||||
start_iter = self.get_iter_at_offset(start)
|
||||
@ -533,23 +582,30 @@ class StyledTextBuffer(gtk.TextBuffer):
|
||||
s_tags = []
|
||||
|
||||
for g_tagname, g_ranges in g_tags.items():
|
||||
style_and_value = g_tagname.split(' ', 1)
|
||||
if g_tagname.startswith('link'):
|
||||
tag = self.get_tag_table().lookup(g_tagname)
|
||||
s_ranges = [(start, end+1) for (start, end) in g_ranges]
|
||||
s_value = tag.data
|
||||
s_tag = StyledTextTag('Link', s_value, s_ranges)
|
||||
s_tags.append(s_tag)
|
||||
else:
|
||||
style_and_value = g_tagname.split(' ', 1)
|
||||
|
||||
try:
|
||||
style = int(style_and_value[0])
|
||||
if len(style_and_value) == 1:
|
||||
s_value = None
|
||||
else:
|
||||
s_value = StyledTextTagType.STYLE_TYPE[style]\
|
||||
(style_and_value[1])
|
||||
|
||||
if style in ALLOWED_STYLES:
|
||||
s_ranges = [(start, end+1) for (start, end) in g_ranges]
|
||||
s_tag = StyledTextTag(style, s_value, s_ranges)
|
||||
|
||||
s_tags.append(s_tag)
|
||||
except ValueError:
|
||||
_LOG.debug("silently skipping gtk.TextTag '%s'" % g_tagname)
|
||||
try:
|
||||
style = int(style_and_value[0])
|
||||
if len(style_and_value) == 1:
|
||||
s_value = None
|
||||
else:
|
||||
s_value = StyledTextTagType.STYLE_TYPE[style]\
|
||||
(style_and_value[1])
|
||||
|
||||
if style in ALLOWED_STYLES:
|
||||
s_ranges = [(start, end+1) for (start, end) in g_ranges]
|
||||
s_tag = StyledTextTag(style, s_value, s_ranges)
|
||||
|
||||
s_tags.append(s_tag)
|
||||
except ValueError:
|
||||
_LOG.debug("silently skipping gtk.TextTag '%s'" % g_tagname)
|
||||
|
||||
return StyledText(txt, s_tags)
|
||||
|
||||
|
@ -50,8 +50,9 @@ from pango import UNDERLINE_SINGLE
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.lib import StyledTextTagType
|
||||
from gui.widgets.styledtextbuffer import (StyledTextBuffer, ALLOWED_STYLES,
|
||||
MATCH_START, MATCH_END,
|
||||
MATCH_FLAVOR, MATCH_STRING)
|
||||
MATCH_START, MATCH_END,
|
||||
MATCH_FLAVOR, MATCH_STRING,
|
||||
LinkTag)
|
||||
from gui.widgets.valueaction import ValueAction
|
||||
from gui.widgets.toolcomboentry import ToolComboEntry
|
||||
from gui.widgets.springseparator import SpringSeparatorAction
|
||||
@ -76,6 +77,7 @@ FORMAT_TOOLBAR = '''
|
||||
<toolitem action="%d"/>
|
||||
<toolitem action="%d"/>
|
||||
<toolitem action="%d"/>
|
||||
<toolitem action="%d"/>
|
||||
<toolitem action="spring"/>
|
||||
<toolitem action="clear"/>
|
||||
</toolbar>
|
||||
@ -87,6 +89,7 @@ FORMAT_TOOLBAR = '''
|
||||
StyledTextTagType.FONTSIZE,
|
||||
StyledTextTagType.FONTCOLOR,
|
||||
StyledTextTagType.HIGHLIGHT,
|
||||
StyledTextTagType.LINK,
|
||||
)
|
||||
|
||||
FONT_SIZES = [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22,
|
||||
@ -101,7 +104,18 @@ SCHEME = "(file:/|https?:|ftps?:|webcal:)"
|
||||
USER = "[" + USERCHARS + "]+(:[" + PASSCHARS + "]+)?"
|
||||
URLPATH = "/[" + PATHCHARS + "]*[^]'.}>) \t\r\n,\\\"]"
|
||||
|
||||
(GENURL, HTTP, MAIL) = range(3)
|
||||
(GENURL, HTTP, MAIL, LINK) = range(4)
|
||||
|
||||
def find_parent_with_attr(self, attr="dbstate"):
|
||||
"""
|
||||
"""
|
||||
# Find a parent with attr:
|
||||
obj = self
|
||||
while obj:
|
||||
if hasattr(obj, attr):
|
||||
break
|
||||
obj = obj.get_parent()
|
||||
return obj
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -204,6 +218,9 @@ class StyledTextEditor(gtk.TextView):
|
||||
self.textbuffer.apply_tag_by_name('hyperlink', start, end)
|
||||
window.set_cursor(HAND_CURSOR)
|
||||
self.url_match = match
|
||||
elif match and (match[MATCH_FLAVOR] in (LINK,)):
|
||||
window.set_cursor(HAND_CURSOR)
|
||||
self.url_match = match
|
||||
else:
|
||||
window.set_cursor(REGULAR_CURSOR)
|
||||
self.url_match = None
|
||||
@ -256,15 +273,37 @@ class StyledTextEditor(gtk.TextView):
|
||||
int(event.x), int(event.y))
|
||||
iter_at_location = self.get_iter_at_location(x, y)
|
||||
self.match = self.textbuffer.match_check(iter_at_location.get_offset())
|
||||
tooltip = None
|
||||
if not self.match:
|
||||
for tag in (tag for tag in iter_at_location.get_tags()
|
||||
if tag.get_property('name').startswith("link")):
|
||||
self.match = (x, y, LINK, tag.data, tag)
|
||||
tooltip = self.make_tooltip_from_link(tag)
|
||||
break
|
||||
|
||||
if self.match != self.last_match:
|
||||
self.emit('match-changed', self.match)
|
||||
|
||||
self.last_match = self.match
|
||||
|
||||
self.window.get_pointer()
|
||||
self.set_tooltip_text(tooltip)
|
||||
return False
|
||||
|
||||
def make_tooltip_from_link(self, link_tag):
|
||||
"""
|
||||
Return a string useful for a tooltip given a LinkTag object.
|
||||
"""
|
||||
from Simple import SimpleAccess
|
||||
win_obj = find_parent_with_attr(self, attr="dbstate")
|
||||
display = link_tag.data
|
||||
if win_obj:
|
||||
simple_access = SimpleAccess(win_obj.dbstate.db)
|
||||
url = link_tag.data
|
||||
if url.startswith("gramps://"):
|
||||
obj_class, prop, value = url[9:].split("/")
|
||||
display = simple_access.display(obj_class, prop, value) or url
|
||||
return display
|
||||
|
||||
def on_button_release_event(self, widget, event):
|
||||
"""
|
||||
Copy selection to clipboard for left click if selection given
|
||||
@ -325,6 +364,14 @@ class StyledTextEditor(gtk.TextView):
|
||||
open_menu = gtk.MenuItem(_('_Open Link'))
|
||||
copy_menu = gtk.MenuItem(_('Copy _Link Address'))
|
||||
|
||||
if flavor == LINK:
|
||||
edit_menu = gtk.MenuItem(_('_Edit Link'))
|
||||
edit_menu.connect('activate', self._edit_url_cb,
|
||||
self.url_match[-1], # tag
|
||||
)
|
||||
edit_menu.show()
|
||||
menu.prepend(edit_menu)
|
||||
|
||||
copy_menu.connect('activate', self._copy_url_cb, url, flavor)
|
||||
copy_menu.show()
|
||||
menu.prepend(copy_menu)
|
||||
@ -373,6 +420,8 @@ class StyledTextEditor(gtk.TextView):
|
||||
_('Font Color'), self._on_action_activate),
|
||||
(str(StyledTextTagType.HIGHLIGHT), 'gramps-font-bgcolor', None, None,
|
||||
_('Background Color'), self._on_action_activate),
|
||||
(str(StyledTextTagType.LINK), gtk.STOCK_JUMP_TO, None, None,
|
||||
_('Link'), self._on_link_activate),
|
||||
('clear', gtk.STOCK_CLEAR, None, None,
|
||||
_('Clear Markup'), self._format_clear_cb),
|
||||
]
|
||||
@ -487,6 +536,34 @@ class StyledTextEditor(gtk.TextView):
|
||||
_LOG.debug("applying style '%d' with value '%s'" % (style, str(value)))
|
||||
self.textbuffer.apply_style(style, value)
|
||||
|
||||
def _on_link_activate(self, action):
|
||||
"""
|
||||
Create a link of a selected region of text.
|
||||
"""
|
||||
# Send in a default link. Could be based on active person.
|
||||
selection_bounds = self.textbuffer.get_selection_bounds()
|
||||
if selection_bounds:
|
||||
uri_dialog(self, None, self.setlink_callback)
|
||||
|
||||
def setlink_callback(self, uri, tag=None):
|
||||
"""
|
||||
Callback for setting or editing a link's object.
|
||||
"""
|
||||
if uri:
|
||||
_LOG.debug("applying style 'link' with value '%s'" % uri)
|
||||
if not tag:
|
||||
tag = LinkTag(self.textbuffer,
|
||||
data=uri,
|
||||
underline=UNDERLINE_SINGLE,
|
||||
foreground="blue")
|
||||
selection_bounds = self.textbuffer.get_selection_bounds()
|
||||
self.textbuffer.apply_tag(tag,
|
||||
selection_bounds[0],
|
||||
selection_bounds[1])
|
||||
else:
|
||||
tag.data = uri
|
||||
|
||||
|
||||
def _on_action_activate(self, action):
|
||||
"""Apply a format set from a gtk.Action type of action."""
|
||||
style = int(action.get_name())
|
||||
@ -533,14 +610,27 @@ class StyledTextEditor(gtk.TextView):
|
||||
(text, StyledTextTagType.STYLE_TYPE[style]))
|
||||
|
||||
def _format_clear_cb(self, action):
|
||||
"""Remove all formats from the selection.
|
||||
"""
|
||||
Remove all formats from the selection or from all.
|
||||
|
||||
Remove only our own tags without touching other ones (e.g. gtk.Spell),
|
||||
thus remove_all_tags() can not be used.
|
||||
|
||||
"""
|
||||
for style in ALLOWED_STYLES:
|
||||
self.textbuffer.remove_style(style)
|
||||
clear_anything = self.textbuffer.clear_selection()
|
||||
if not clear_anything:
|
||||
for style in ALLOWED_STYLES:
|
||||
self.textbuffer.remove_style(style)
|
||||
|
||||
start, end = self.textbuffer.get_bounds()
|
||||
tags = self.textbuffer._get_tag_from_range(start.get_offset(),
|
||||
end.get_offset())
|
||||
for tag_name, tag_data in tags.iteritems():
|
||||
if tag_name.startswith("link"):
|
||||
for start, end in tag_data:
|
||||
self.textbuffer.remove_tag_by_name(tag_name,
|
||||
self.textbuffer.get_iter_at_offset(start),
|
||||
self.textbuffer.get_iter_at_offset(end+1))
|
||||
|
||||
def _on_buffer_style_changed(self, buffer, changed_styles):
|
||||
"""Synchronize actions as the format changes at the buffer's cursor."""
|
||||
@ -574,9 +664,23 @@ class StyledTextEditor(gtk.TextView):
|
||||
url = 'mailto:' + url
|
||||
elif flavor == GENURL:
|
||||
pass
|
||||
elif flavor == LINK:
|
||||
# gramps://person/id/VALUE
|
||||
# gramps://person/handle/VALUE
|
||||
if url.startswith("gramps://"):
|
||||
# if in a window:
|
||||
win_obj = find_parent_with_attr(self, attr="dbstate")
|
||||
if win_obj:
|
||||
obj_class, prop, value = url[9:].split("/")
|
||||
from gui.editors import EditObject
|
||||
EditObject(win_obj.dbstate,
|
||||
win_obj.uistate,
|
||||
win_obj.track,
|
||||
obj_class, prop, value)
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
||||
# If ok, then let's open
|
||||
display_url(url)
|
||||
|
||||
def _copy_url_cb(self, menuitem, url, flavor):
|
||||
@ -586,6 +690,14 @@ class StyledTextEditor(gtk.TextView):
|
||||
|
||||
clipboard = gtk.Clipboard(selection="PRIMARY")
|
||||
clipboard.set_text(url)
|
||||
|
||||
|
||||
def _edit_url_cb(self, menuitem, link_tag):
|
||||
"""
|
||||
Edit the URI of the link.
|
||||
"""
|
||||
uri_dialog(self, link_tag.data,
|
||||
lambda uri: self.setlink_callback(uri, link_tag))
|
||||
|
||||
# public methods
|
||||
|
||||
@ -617,6 +729,24 @@ class StyledTextEditor(gtk.TextView):
|
||||
"""
|
||||
return self.toolbar
|
||||
|
||||
def uri_dialog(self, uri, callback):
|
||||
"""
|
||||
Function to spawn the link editor.
|
||||
"""
|
||||
from gui.editors.editlink import EditLink
|
||||
obj = find_parent_with_attr(self, attr="dbstate")
|
||||
if obj:
|
||||
if uri is None:
|
||||
# make a default link
|
||||
uri = "http://"
|
||||
# Check in order for an open page:
|
||||
for object_class in ["Person", "Place", "Event", "Family",
|
||||
"Repository", "Source", "Media"]:
|
||||
handle = obj.uistate.get_active(object_class)
|
||||
if handle:
|
||||
uri = "gramps://%s/handle/%s" % (object_class, handle)
|
||||
EditLink(obj.dbstate, obj.uistate, obj.track, uri, callback)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Module functions
|
||||
|
@ -75,7 +75,9 @@ class HtmlBackend(DocBackend):
|
||||
DocBackend.FONTSIZE,
|
||||
DocBackend.FONTCOLOR,
|
||||
DocBackend.HIGHLIGHT,
|
||||
DocBackend.SUPERSCRIPT ]
|
||||
DocBackend.SUPERSCRIPT,
|
||||
DocBackend.LINK,
|
||||
]
|
||||
|
||||
STYLETAG_MARKUP = {
|
||||
DocBackend.BOLD : ("<strong>", "</strong>"),
|
||||
@ -85,7 +87,7 @@ class HtmlBackend(DocBackend):
|
||||
DocBackend.SUPERSCRIPT : ("<sup>", "</sup>"),
|
||||
}
|
||||
|
||||
ESCAPE_FUNC = lambda x: escape
|
||||
ESCAPE_FUNC = lambda self: escape
|
||||
|
||||
def __init__(self, filename=None):
|
||||
"""
|
||||
@ -97,6 +99,7 @@ class HtmlBackend(DocBackend):
|
||||
self.html_body = None
|
||||
self._subdir = None
|
||||
self.title = None
|
||||
self.build_link = None
|
||||
|
||||
def _create_xmltag(self, tagtype, value):
|
||||
"""
|
||||
@ -111,7 +114,6 @@ class HtmlBackend(DocBackend):
|
||||
elif tagtype == DocBackend.FONTFACE:
|
||||
#fonts can have strange symbols in them, ' needs to be escaped
|
||||
value = value.replace("'", "\\'")
|
||||
|
||||
return ('<span style="%s">' % (self.STYLETAG_TO_PROPERTY[tagtype] %
|
||||
(value)),
|
||||
'</span>')
|
||||
@ -172,3 +174,22 @@ class HtmlBackend(DocBackend):
|
||||
full path of the datadir directory
|
||||
"""
|
||||
return os.path.join(os.path.dirname(self.getf()), self.datadir())
|
||||
|
||||
def format_link(self, value):
|
||||
"""
|
||||
Override of base method.
|
||||
"""
|
||||
if value.startswith("gramps://"):
|
||||
if self.build_link:
|
||||
obj_class, prop, handle = value[9:].split("/", 3)
|
||||
if prop in ["handle", "gramps_id"]:
|
||||
value = self.build_link(prop, handle, obj_class, up=True)
|
||||
if not value:
|
||||
return self.STYLETAG_MARKUP[DocBackend.UNDERLINE]
|
||||
else:
|
||||
return self.STYLETAG_MARKUP[DocBackend.UNDERLINE]
|
||||
else:
|
||||
return self.STYLETAG_MARKUP[DocBackend.UNDERLINE]
|
||||
return ('<a href="%s">' % self.ESCAPE_FUNC()(value),
|
||||
'</a>')
|
||||
|
||||
|
@ -81,7 +81,9 @@ class OdfBackend(DocBackend):
|
||||
DocBackend.FONTSIZE,
|
||||
DocBackend.FONTCOLOR,
|
||||
DocBackend.HIGHLIGHT,
|
||||
DocBackend.SUPERSCRIPT ]
|
||||
DocBackend.SUPERSCRIPT,
|
||||
DocBackend.LINK,
|
||||
]
|
||||
|
||||
STYLETAG_MARKUP = {
|
||||
DocBackend.BOLD :
|
||||
@ -129,3 +131,14 @@ class OdfBackend(DocBackend):
|
||||
return ('<text:span text:style-name=\"FontHighlight__%s__\">' %
|
||||
self.ESCAPE_FUNC()(value),
|
||||
'</text:span>')
|
||||
|
||||
def format_link(self, value):
|
||||
"""
|
||||
Override of base method.
|
||||
"""
|
||||
if value.startswith("gramps://"):
|
||||
return self.STYLETAG_MARKUP[DocBackend.UNDERLINE]
|
||||
else:
|
||||
return ('<text:a xlink:href="%s">' % self.ESCAPE_FUNC()(value),
|
||||
'</text:a>')
|
||||
|
||||
|
@ -304,6 +304,7 @@ class BasePage(object):
|
||||
self.up = False
|
||||
# class to do conversion of styled notes to html markup
|
||||
self._backend = HtmlBackend()
|
||||
self._backend.build_link = report.build_link
|
||||
|
||||
self.report = report
|
||||
self.title_str = title
|
||||
@ -5557,6 +5558,41 @@ class NavWebReport(Report):
|
||||
def build_url_fname_html(self, fname, subdir = None, up = False):
|
||||
return self.build_url_fname(fname, subdir, up) + self.ext
|
||||
|
||||
def build_link(self, prop, handle, obj_class, up = False):
|
||||
"""
|
||||
Build a link to an item.
|
||||
"""
|
||||
if prop == "gramps_id":
|
||||
if obj_class in self.database.get_table_names():
|
||||
obj = self.database.get_table_metadata(obj_class)["gramps_id_func"](handle)
|
||||
if obj:
|
||||
handle = obj.handle
|
||||
else:
|
||||
raise AttributeError("gramps_id '%s' not found in '%s'" %
|
||||
handle, obj_class)
|
||||
else:
|
||||
raise AttributeError("invalid gramps_id lookup "
|
||||
"in table name '%s'" % obj_class)
|
||||
# handle, ppl
|
||||
if obj_class == "Person":
|
||||
if handle in self.person_handles:
|
||||
return self.build_url_fname(handle, "ppl", up) + self.ext
|
||||
else:
|
||||
return None
|
||||
elif obj_class == "Source":
|
||||
subdir = "src"
|
||||
elif obj_class == "Place":
|
||||
subdir = "plc"
|
||||
elif obj_class == "Event":
|
||||
subdir = "evt"
|
||||
elif obj_class == "Media":
|
||||
subdir = "img"
|
||||
elif obj_class == "Repository":
|
||||
subdir = "repo"
|
||||
else:
|
||||
raise AttributeError("unknown object type '%s'" % obj_class)
|
||||
return self.build_url_fname(handle, subdir, up) + self.ext
|
||||
|
||||
def build_url_fname(self, fname, subdir = None, up = False):
|
||||
"""
|
||||
Create part of the URL given the filename and optionally the subdirectory.
|
||||
|
Loading…
Reference in New Issue
Block a user