2007-11-25 Benny Malengier <benny.malengier@gramps-project.org>

* src/gen/lib/notetype.py: type report, citation
	* src/plugins/NarrativeWeb.py: new selection of home note & home media
	* src/GrampsWidgets.py: NoteEntry, MediaEntry
	I intend to change the other note selectors likewise next.


svn: r9403
This commit is contained in:
Benny Malengier 2007-11-25 19:07:50 +00:00
parent 5fdffbe292
commit ac82ef8754
4 changed files with 253 additions and 92 deletions

View File

@ -1,3 +1,9 @@
2007-11-25 Benny Malengier <benny.malengier@gramps-project.org>
* src/gen/lib/notetype.py: type report, citation
* src/plugins/NarrativeWeb.py: new selection of home note & home media
* src/GrampsWidgets.py: NoteEntry, MediaEntry
I intend to change the other note selectors likewise next.
2007-11-25 Douglas S. Blank <dblank@cs.brynmawr.edu>
* src/gen/lib/date.py: refer to Config values via Config.get()
* src/gen/lib/test/date_test.py: set Config values before testing

View File

@ -742,19 +742,20 @@ class ObjEntry:
to select the object.
This is the base class to create a real entry
"""
def __init__(self, dbstate, uistate, track, obj, set_val,
get_val, add_del, share):
def __init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share):
'''Pass the dbstate and uistate and present track.
obj is a gtk.Label that shows the persent value
label is a gtk.Label that shows the persent value
set_val is function that is called when handle changes, use it
to update the calling module
get_val is function that is called to obtain handle from calling
module
add_del is the gtk.Button with add or delete value
share is the gtk.Button to call the object selector
share is the gtk.Button to call the object selector or del connect
add_edt is the gtk.Button with add or edit value. Pass None if
this button should not be present.
'''
self.obj = obj
self.add_del = add_del
self.label = label
self.add_edt = add_edt
self.share = share
self.dbstate = dbstate
self.db = dbstate.db
@ -769,29 +770,39 @@ class ObjEntry:
#set the object specific code
self._init_object()
if get_val():
#check if valid object:
handle = self.get_val()
if handle:
obj = self.get_from_handle(handle)
if not obj:
#invalid val, set it to None
self.set_val(None)
if self.get_val():
self.set_button(True)
p = self.get_from_handle(self.get_val())
name = self.get_label(p)
obj = self.get_from_handle(self.get_val())
name = self.get_label(obj)
else:
name = u""
self.set_button(False)
if self.db.readonly:
self.add_del.set_sensitive(False)
if self.add_edt is not None:
self.add_edt.set_sensitive(False)
self.share.set_sensitive(False)
else:
self.add_del.set_sensitive(True)
if self.add_edt is not None:
self.add_edt.set_sensitive(True)
self.share.set_sensitive(True)
self.add_del.connect('clicked', self.add_del_clicked)
if self.add_edt is not None:
self.add_edt.connect('clicked', self.add_edt_clicked)
self.share.connect('clicked', self.share_clicked)
if not self.db.readonly and not name:
obj.set_text(self.EMPTY_TEXT)
obj.set_use_markup(True)
self.label.set_text(self.EMPTY_TEXT)
self.label.set_use_markup(True)
else:
obj.set_text(name)
self.label.set_text(name)
def _init_dnd(self):
'''inheriting objects must set this
@ -817,15 +828,14 @@ class ObjEntry:
def after_edit(self, obj):
name = self.get_label(obj)
self.obj.set_text(name)
self.label.set_text(name)
def add_del_clicked(self, obj):
''' if value, delete, if no value, call editor
def add_edt_clicked(self, obj):
''' if value, edit, if no value, call editor on new object
'''
if self.get_val():
self.set_val(None)
self.obj.set_text(u'')
self.set_button(False)
obj = self.get_from_handle(self.get_val())
self.call_editor(obj)
else:
self.call_editor()
@ -848,15 +858,16 @@ class ObjEntry:
def obj_added(self, data):
''' callback from adding an object to the entry'''
self.set_val(data.handle)
self.obj.set_text(self.get_label(data))
self.label.set_text(self.get_label(data))
self.set_button(True)
def share_clicked(self, obj):
''' if value, edit object, in no value, select existing object
''' if value, delete connect, in no value, select existing object
'''
if self.get_val():
obj = self.get_from_handle(self.get_val())
self.call_editor(obj)
self.set_val(None)
self.label.set_text(self.EMPTY_TEXT)
self.set_button(False)
else:
select = self.call_selector()
obj = select.run()
@ -864,10 +875,13 @@ class ObjEntry:
self.obj_added(obj)
def set_button(self, use_add):
''' This sets the correct image to the two buttons
''' This sets the correct image to the two buttons.
If False: select icon and add icon
If True: remove icon and edit icon
'''
for i in self.add_del.get_children():
self.add_del.remove(i)
if self.add_edt is not None:
for i in self.add_edt.get_children():
self.add_edt.remove(i)
for i in self.share.get_children():
self.share.remove(i)
@ -875,24 +889,26 @@ class ObjEntry:
image = gtk.Image()
image.set_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_BUTTON)
image.show()
self.add_del.add(image)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON)
image.show()
self.share.add(image)
self.tooltips.set_tip(self.share, self.EDIT_STR)
self.tooltips.set_tip(self.add_del, self.DEL_STR)
self.tooltips.set_tip(self.share, self.DEL_STR)
if self.add_edt is not None:
image = gtk.Image()
image.set_from_stock(gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON)
image.show()
self.add_edt.add(image)
self.tooltips.set_tip(self.add_edt, self.EDIT_STR)
else:
image = gtk.Image()
image.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
image.show()
self.add_del.add(image)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
image.show()
self.share.add(image)
self.tooltips.set_tip(self.share, self.SHARE_STR)
self.tooltips.set_tip(self.add_del, self.ADD_STR)
if self.add_edt is not None:
image = gtk.Image()
image.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
image.show()
self.add_edt.add(image)
self.tooltips.set_tip(self.add_edt, self.ADD_STR)
class PlaceEntry(ObjEntry):
"""
@ -906,17 +922,17 @@ class PlaceEntry(ObjEntry):
ADD_STR = _('Add a new place')
DEL_STR = _('Remove place')
def __init__(self, dbstate, uistate, track, obj, set_val,
get_val, add_del, share):
ObjEntry.__init__(self, dbstate, uistate, track, obj, set_val,
get_val, add_del, share)
def __init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share):
ObjEntry.__init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share)
def _init_dnd(self):
'''connect drag and drop of places
'''
self.obj.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.PLACE_LINK.target()],
self.label.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.PLACE_LINK.target()],
gtk.gdk.ACTION_COPY)
self.obj.connect('drag_data_received', self.drag_data_received)
self.label.connect('drag_data_received', self.drag_data_received)
def get_from_handle(self, handle):
''' return the object given the hande
@ -947,6 +963,59 @@ class PlaceEntry(ObjEntry):
cls = selector_factory('Place')
return cls(self.dbstate, self.uistate, self.track)
class MediaEntry(ObjEntry):
"""
Handles the selection of a existing or new media. Supports Drag and Drop
to select a media object.
"""
EMPTY_TEXT = "<i>%s</i>" % _('To select a media object, use drag-and-drop '
'or use the buttons')
EDIT_STR = _('Edit media object')
SHARE_STR = _('Select an existing media object')
ADD_STR = _('Add a new media object')
DEL_STR = _('Remove media object')
def __init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share):
ObjEntry.__init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share)
def _init_dnd(self):
'''connect drag and drop of places
'''
self.label.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.MEDIAOBJ.target()],
gtk.gdk.ACTION_COPY)
self.label.connect('drag_data_received', self.drag_data_received)
def get_from_handle(self, handle):
''' return the object given the hande
'''
return self.db.get_object_from_handle(handle)
def get_label(self, object):
return "%s [%s]" % (object.get_description(), object.gramps_id)
def call_editor(self, obj=None):
from Editors import EditMedia
if obj is None:
from gen.lib import MediaObject
object = MediaObject()
func = self.obj_added
else:
object = obj
func = self.after_edit
try:
EditMedia(self.dbstate, self.uistate, self.track,
object, func)
except WindowActiveError:
pass
def call_selector(self):
from Selectors import selector_factory
cls = selector_factory('MediaObject')
return cls(self.dbstate, self.uistate, self.track)
class NoteEntry(ObjEntry):
"""
Handles the selection of a existing or new Note. Supports Drag and Drop
@ -959,17 +1028,28 @@ class NoteEntry(ObjEntry):
ADD_STR = _('Add a new note')
DEL_STR = _('Remove note')
def __init__(self, dbstate, uistate, track, obj, set_val,
get_val, add_del, share):
ObjEntry.__init__(self, dbstate, uistate, track, obj, set_val,
get_val, add_del, share)
def __init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share):
ObjEntry.__init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share)
self.notetype = None
def set_notetype(self, type):
''' set a notetype to use in new notes
'''
self.notetype = type
def get_notetype(self):
''' return the set notetype
'''
return self.notetype
def _init_dnd(self):
'''connect drag and drop of places
'''
self.obj.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.NOTE_LINK.target()],
self.label.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.NOTE_LINK.target()],
gtk.gdk.ACTION_COPY)
self.obj.connect('drag_data_received', self.drag_data_received)
self.label.connect('drag_data_received', self.drag_data_received)
def get_from_handle(self, handle):
''' return the object given the hande
@ -977,27 +1057,27 @@ class NoteEntry(ObjEntry):
return self.db.get_note_from_handle(handle)
def get_label(self, note):
note = " ".join(note.get(markup=False).split())
if len(note) > 35:
txt = note[:35]+"..."
txt = " ".join(note.get(markup=False).split())
if len(txt) > 35:
txt = txt[:35]+"..."
else:
txt = note
return "%s [%s]" % (txt, p.gramps_id)
txt = txt
return "%s [%s]" % (txt, note.gramps_id)
def call_editor(self, obj=None):
from Editors import EditNote
if obj is None:
from gen.lib import Note, Notetype
from gen.lib import Note
note = Note()
note.set_type(NoteType.REPORT)
note.set_type(self.get_notetype())
func = self.obj_added
else:
note = obj
func = self.after_edit
try:
EditNote(self.dbstate, self.uistate, self.track,
note, func)
note, func)
except WindowActiveError:
pass

View File

@ -67,18 +67,22 @@ class NoteType(GrampsType):
PERSONNAME = 20
# other common types
SOURCE_TEXT = 21 # this is used for verbatim source text in SourceRef
CITATION = 22
REPORT_TEXT = 23 # this is used for notes used for reports
_CUSTOM = CUSTOM
_DEFAULT = GENERAL
_DATAMAPREAL = [
(UNKNOWN, _("Unknown"), "Unknown"),
(CUSTOM, _("Custom"), "Custom"),
(GENERAL, _("General"), "General"),
(RESEARCH, _("Research"), "Research"),
(TRANSCRIPT, _("Transcript"), "Transcript"),
(UNKNOWN, _("Unknown"), "Unknown"),
(CUSTOM, _("Custom"), "Custom"),
(GENERAL, _("General"), "General"),
(RESEARCH, _("Research"), "Research"),
(TRANSCRIPT, _("Transcript"), "Transcript"),
(SOURCE_TEXT, _("Source text"), "Source text"),
(CITATION, _('Citation'), "Citation"),
(REPORT_TEXT, _("Report"), "Report"),
]
_DATAMAPIGNORE = [

View File

@ -80,6 +80,7 @@ import Utils
import ThumbNails
import ImgManip
import GrampsLocale
import GrampsWidgets
import Mime
from QuestionDialog import ErrorDialog, WarningDialog
from BasicUtils import name_displayer as _nd
@ -174,7 +175,8 @@ class BasePage:
self.photo_list = photo_list
self.usegraph = options.handler.options_dict['NWEBgraph']
self.graphgens = options.handler.options_dict['NWEBgraphgens']
self.use_home = self.options.handler.options_dict['NWEBhomenote'] != ""
self.use_home = self.options.handler.options_dict['NWEBhomenote'] != "" or \
self.options.handler.options_dict['NWEBhomepic'] != ""
self.page_title = ""
self.warn_dir = True
@ -1398,20 +1400,21 @@ class HomePage(BasePage):
BasePage.__init__(self, title, options, archive, media_list, "")
note_id = options.handler.options_dict['NWEBhomenote']
pic_id = options.handler.options_dict['NWEBhomepic']
of = self.create_file("index")
author = get_researcher().get_name()
self.display_header(of,db,_('Home'),author)
of.write('<h3>%s</h3>\n' % _('Home'))
if note_id:
obj = db.get_object_from_handle(note_id)
if pic_id:
obj = db.get_object_from_handle(pic_id)
mime_type = obj.get_mime_type()
if mime_type and mime_type.startswith("image"):
try:
(newpath,thumb_path) = self.copy_media(obj,False)
self.store_file(archive,self.html_dir,obj.get_path(),
self.store_file(archive, self.html_dir, obj.get_path(),
newpath)
of.write('<div class="centered">\n')
of.write('<img ')
@ -1419,18 +1422,17 @@ class HomePage(BasePage):
of.write('alt="%s" />' % obj.get_description())
of.write('</div>\n')
except (IOError,OSError),msg:
WarningDialog(_("Could not add photo to page"),str(msg))
WarningDialog(_("Could not add photo to page"), str(msg))
notelist = obj.get_note_list()
if notelist:
note_obj = db.get_note_from_handle(notelist[0])
text = note_obj.get(markup=True)
if note_obj.get_format():
of.write('<pre>\n%s\n</pre>\n' % text)
else:
of.write('<p>')
of.write('</p><p>'.join(text.split('\n')))
of.write('</p>')
if note_id:
note_obj = db.get_note_from_handle(note_id)
text = note_obj.get(markup=True)
if note_obj.get_format():
of.write('<pre>\n%s\n</pre>\n' % text)
else:
of.write('<p>')
of.write('</p><p>'.join(text.split('\n')))
of.write('</p>')
self.display_footer(of,db)
self.close_file(of)
@ -2359,6 +2361,7 @@ class WebReport(Report):
NWEBencoding
NWEBintronote
NWEBhomenote
NWEBhomepic
NWEBnoid
NWEBlinkhome
NWEBshowbirth
@ -2415,7 +2418,8 @@ class WebReport(Report):
self.user_footer = options.handler.options_dict['NWEBfooter']
self.use_archive = options.handler.options_dict['NWEBarchive']
self.use_intro = options.handler.options_dict['NWEBintronote'] != u""
self.use_home = options.handler.options_dict['NWEBhomenote'] != u""
self.use_home = options.handler.options_dict['NWEBhomenote'] != u"" or\
options.handler.options_dict['NWEBhomepic'] != u""
def write_report(self):
if not self.use_archive:
@ -2702,12 +2706,13 @@ class WebReportOptions(ReportOptions):
'NWEBcss' : 'main0.css',
'NWEBintronote' : '',
'NWEBhomenote' : '',
'NWEBhomepic' : '',
}
self.options_help = {
}
def add_user_options(self,dialog):
def add_user_options(self, dialog):
priv_msg = _("Do not include records marked private")
living_msg = _("Living People")
death_msg = _("Years from death to consider living")
@ -2851,12 +2856,14 @@ class WebReportOptions(ReportOptions):
media_list = [['','']]
html_list = [['','']]
#Page Generation tab
if self.db:
cursor = self.db.get_media_cursor()
data = cursor.first()
while data:
(handle, value) = data
if not value[3]:
#no mime type
html_list.append([value[4],handle])
media_list.append([value[4],handle])
@ -2865,14 +2872,29 @@ class WebReportOptions(ReportOptions):
media_list.sort(lambda x, y: locale.strcoll(x[0], y[0]))
html_list.sort(lambda x, y: locale.strcoll(x[0], y[0]))
self.home_note = mk_combobox(media_list,self.options_dict['NWEBhomenote'])
self.home_nt_box, self.home_nt_label, self.home_nt_share_btn \
= mk_object_entry()
self.home_note = GrampsWidgets.NoteEntry(dialog.dbstate,
dialog.uistate, dialog.track,
self.home_nt_label,
self.set_home_nt_val, self.get_home_nt_val,
None, self.home_nt_share_btn)
self.home_pic_box, self.home_pic_label, self.home_pic_share_btn \
= mk_object_entry()
self.home_pic = GrampsWidgets.MediaEntry(dialog.dbstate,
dialog.uistate, dialog.track,
self.home_pic_label,
self.set_home_pic_val, self.get_home_pic_val,
None, self.home_pic_share_btn)
self.intro_note = mk_combobox(media_list,self.options_dict['NWEBintronote'])
self.contact = mk_combobox(media_list,self.options_dict['NWEBcontact'])
self.header = mk_combobox(html_list,self.options_dict['NWEBheader'])
self.footer = mk_combobox(html_list,self.options_dict['NWEBfooter'])
dialog.add_frame_option(title,_('Home Media/Note ID'),
self.home_note)
dialog.add_frame_option(title,_('Home Page note'),
self.home_nt_box)
dialog.add_frame_option(title,_('Home Page image'),
self.home_pic_box)
dialog.add_frame_option(title,_('Introduction Media/Note ID'),
self.intro_note)
dialog.add_frame_option(title,contact_msg,self.contact)
@ -2895,7 +2917,41 @@ class WebReportOptions(ReportOptions):
dialog.add_frame_option(title,None,self.showparents)
dialog.add_frame_option(title,None,self.showhalfsiblings)
def parse_user_options(self,dialog):
def set_home_nt_val(self, val):
''' store the note handle in options
'''
if val is None:
self.options_dict['NWEBhomenote'] = u''
else:
self.options_dict['NWEBhomenote'] = unicode(val)
def get_home_nt_val(self):
''' obtain note handle
'''
val = self.options_dict['NWEBhomenote']
if val == "":
return None
else:
return val
def set_home_pic_val(self, val):
''' store the media handle in options
'''
if val is None:
self.options_dict['NWEBhomepic'] = u''
else:
self.options_dict['NWEBhomepic'] = unicode(val)
def get_home_pic_val(self):
''' obtain note handle
'''
val = self.options_dict['NWEBhomepic']
if val == "":
return None
else:
return val
def parse_user_options(self, dialog):
"""Parse the privacy options frame of the dialog. Save the
user selected choices for later use."""
@ -2918,7 +2974,6 @@ class WebReportOptions(ReportOptions):
self.options_dict['NWEBdownload'] = int(self.inc_download.get_active())
self.options_dict['NWEBtitle'] = unicode(self.title.get_text())
self.options_dict['NWEBintronote'] = unicode(self.intro_note.get_handle())
self.options_dict['NWEBhomenote'] = unicode(self.home_note.get_handle())
self.options_dict['NWEBgraph'] = int(self.inc_graph.get_active())
index = self.graph_gens.get_active()
@ -2959,25 +3014,30 @@ class WebReportDialog(ReportDialog):
HELP_TOPIC = "rep-web"
def __init__(self,dbstate,uistate,person):
def __init__(self, dbstate, uistate, person):
self.database = dbstate.db
self.person = person
name = "navwebpage"
translated_name = _("Generate Web Site")
self.options = WebReportOptions(name,self.database)
self.category = CATEGORY_WEB
ReportDialog.__init__(self,dbstate,uistate,person,self.options,
name,translated_name)
ReportDialog.__init__(self, dbstate, uistate, person, self.options,
name, translated_name)
self.style_name = None
while True:
response = self.window.run()
if response == gtk.RESPONSE_OK:
self.close()
self.make_report()
break
elif response != gtk.RESPONSE_HELP:
elif (response == gtk.RESPONSE_DELETE_EVENT or
response == gtk.RESPONSE_CANCEL):
# the buttons generating this already call close via connect
break
self.close()
def on_cancel(self, *obj):
self.close(*obj)
def setup_style_frame(self):
"""The style frame is not used in this dialog."""
@ -3129,6 +3189,7 @@ class EmptyDoc:
def init(self):
pass
#-------------------------------------------------------------------------
#
# GrampsNoteComboBox
@ -3181,6 +3242,16 @@ def mk_combobox(media_list,select_value):
widget.set_sensitive(False)
return widget
def mk_object_entry():
''' return a vbox widget with fields for object selection
'''
box = gtk.HBox()
label = gtk.Label()
button_sel = gtk.Button()
box.pack_start(label)
box.pack_start(button_sel, expand=False, fill=False)
return (box, label, button_sel)
#-------------------------------------------------------------------------
#
#