7856: Fix error when no place is selected

Check that a place has been selected when saving.
Use the standard place selection widget to be consistent.
This also implements feature request #7893.
This commit is contained in:
Nick Hall 2014-07-16 00:18:00 +01:00
parent 27fdeb65d6
commit 78e5ed05fc
3 changed files with 60 additions and 39 deletions

View File

@ -27,13 +27,11 @@
from .editsecondary import EditSecondary from .editsecondary import EditSecondary
from ..glade import Glade from ..glade import Glade
from ..widgets import MonitoredDate from ..widgets import MonitoredDate
from ..selectors import SelectorFactory from .objectentries import PlaceEntry
from ..dialog import ErrorDialog from ..dialog import ErrorDialog
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
SelectPlace = SelectorFactory('Place')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# EditPlaceRef class # EditPlaceRef class
@ -52,6 +50,9 @@ class EditPlaceRef(EditSecondary):
self.top = Glade() self.top = Glade()
self.set_window(self.top.toplevel, None, _('Place Reference Editor')) self.set_window(self.top.toplevel, None, _('Place Reference Editor'))
self.share_btn = self.top.get_object('select_place')
self.add_del_btn = self.top.get_object('add_del_place')
def _setup_fields(self): def _setup_fields(self):
self.date_field = MonitoredDate(self.top.get_object("date_entry"), self.date_field = MonitoredDate(self.top.get_object("date_entry"),
@ -60,14 +61,12 @@ class EditPlaceRef(EditSecondary):
self.uistate, self.track, self.uistate, self.track,
self.db.readonly) self.db.readonly)
self.parent = self.top.get_object('place_label') self.place_field = PlaceEntry(self.dbstate, self.uistate, self.track,
if self.obj.ref is not None: self.top.get_object("place"),
place = self.db.get_place_from_handle(self.obj.ref) self.obj.set_reference_handle,
self.parent.set_text(place.get_name()) self.obj.get_reference_handle,
else: self.add_del_btn, self.share_btn,
self.parent.set_text(_('Top level place')) skip=self.get_skip_list(self.handle))
button = self.top.get_object('place_button')
button.connect('clicked', self.select_parent)
def get_skip_list(self, handle): def get_skip_list(self, handle):
todo = [handle] todo = [handle]
@ -80,23 +79,21 @@ class EditPlaceRef(EditSecondary):
skip.append(child[1]) skip.append(child[1])
return skip return skip
def select_parent(self, button):
if self.handle:
skip = self.get_skip_list(self.handle)
else:
skip = []
sel = SelectPlace(self.dbstate, self.uistate, self.track, skip=skip)
parent = sel.run()
if parent:
self.parent.set_text(parent.get_name())
self.obj.ref = parent.get_handle()
def _connect_signals(self): def _connect_signals(self):
self.define_cancel_button(self.top.get_object('cancel_button')) self.define_cancel_button(self.top.get_object('cancel_button'))
self.define_ok_button(self.top.get_object('ok_button'), self.save) self.ok_button = self.top.get_object('ok_button')
self.define_ok_button(self.ok_button, self.save)
self.define_help_button(self.top.get_object('help_button')) self.define_help_button(self.top.get_object('help_button'))
def save(self, *obj): def save(self, *obj):
self.ok_button.set_sensitive(False)
if not self.obj.ref:
ErrorDialog(_("Cannot save place reference"),
_("No place selected. Please select a place "
" or cancel the edit."))
self.ok_button.set_sensitive(True)
return
if self.callback: if self.callback:
self.callback(self.obj) self.callback(self.obj)
self.close() self.close()

View File

@ -269,9 +269,10 @@ class PlaceEntry(ObjEntry):
DEL_STR = _('Remove place') DEL_STR = _('Remove place')
def __init__(self, dbstate, uistate, track, label, set_val, def __init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share): get_val, add_edt, share, skip=[]):
ObjEntry.__init__(self, dbstate, uistate, track, label, set_val, ObjEntry.__init__(self, dbstate, uistate, track, label, set_val,
get_val, add_edt, share) get_val, add_edt, share)
self.skip = skip
def _init_dnd(self): def _init_dnd(self):
"""connect drag and drop of places """connect drag and drop of places
@ -283,6 +284,13 @@ class PlaceEntry(ObjEntry):
self.label.drag_dest_set_target_list(tglist) self.label.drag_dest_set_target_list(tglist)
self.label.connect('drag_data_received', self.drag_data_received) self.label.connect('drag_data_received', self.drag_data_received)
def drag_data_received(self, widget, context, x, y, selection, info, time):
(drag_type, idval, obj, val) = pickle.loads(selection.get_data())
if obj not in self.skip:
data = self.get_from_handle(obj)
self.obj_added(data)
def get_from_handle(self, handle): def get_from_handle(self, handle):
""" return the object given the hande """ return the object given the hande
""" """
@ -306,7 +314,7 @@ class PlaceEntry(ObjEntry):
def call_selector(self): def call_selector(self):
cls = SelectorFactory('Place') cls = SelectorFactory('Place')
return cls(self.dbstate, self.uistate, self.track) return cls(self.dbstate, self.uistate, self.track, skip=self.skip)
class SourceEntry(ObjEntry): class SourceEntry(ObjEntry):
""" """

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-requires grampswidgets 0.0 -->
<object class="GtkDialog" id="editplaceref"> <object class="GtkDialog" id="editplaceref">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="default_width">550</property> <property name="default_width">550</property>
@ -78,7 +80,7 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">12</property> <property name="border_width">12</property>
<property name="n_rows">2</property> <property name="n_rows">2</property>
<property name="n_columns">3</property> <property name="n_columns">4</property>
<property name="column_spacing">12</property> <property name="column_spacing">12</property>
<property name="row_spacing">6</property> <property name="row_spacing">6</property>
<child> <child>
@ -111,11 +113,11 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="place_button"> <object class="GtkButton" id="select_place">
<property name="label" translatable="yes">...</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="relief">none</property>
</object> </object>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
@ -132,12 +134,6 @@
<property name="has_tooltip">True</property> <property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Invoke date editor</property> <property name="tooltip_text" translatable="yes">Invoke date editor</property>
<property name="relief">none</property> <property name="relief">none</property>
<accelerator key="d" signal="activate" modifiers="GDK_CONTROL_MASK"/>
<child internal-child="accessible">
<object class="AtkObject" id="date_stat-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Date</property>
</object>
</child>
<child> <child>
<object class="GtkImage" id="date_stat_child"> <object class="GtkImage" id="date_stat_child">
<property name="visible">True</property> <property name="visible">True</property>
@ -152,10 +148,16 @@
</child> </child>
</object> </object>
</child> </child>
<child internal-child="accessible">
<object class="AtkObject" id="date_stat-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Date</property>
</object>
</child>
<accelerator key="d" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">3</property>
<property name="right_attach">3</property> <property name="right_attach">4</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
@ -163,7 +165,7 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="place_label"> <object class="GtkLabel" id="place">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
@ -184,12 +186,26 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">3</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="y_options"/> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="add_del_place">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>