diff --git a/ChangeLog b/ChangeLog index 8734ce086..ff6c08fb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,15 @@ 2006-03-29 Don Allingham + * src/Editors/_EditPerson.py: Fix imports of EditMediaRef, remove + specific edit image from top image window. + * src/glade/gramps.glade: remove unused dialogs, replaced by + gtk.MessageDialog + * src/AddMedia.py: clean up scale_image + * src/Utils.py: replace fork() with spawn to prevent Xlib async errors + * src/GrampsDisplay.py: replace fork() with spawn to prevent Xlib + async errors + * src/QuestionDialog.py: Simply some dialogs by using gtk.MessageDialog + * src/ImgManip.py: replace fork() with spawn to prevent Xlib async + errors * src/ViewManager.py: enable actiongroups if file loaded before the interface is initialized (command line or autoload) * src/SelectObject.py: Provide images in preview diff --git a/src/AddMedia.py b/src/AddMedia.py index fe459d933..396e5c81e 100644 --- a/src/AddMedia.py +++ b/src/AddMedia.py @@ -188,23 +188,20 @@ class AddMediaObject: # #------------------------------------------------------------------------- def scale_image(path,size): + + title_msg = _("Cannot display %s") % path + detail_msg = _('GRAMPS is not able to display the image file. ' + 'This may be caused by a corrupt file.') + try: image1 = gtk.gdk.pixbuf_new_from_file(path) - except: - WarningDialog(_("Cannot display %s") % path, - _('GRAMPS is not able to display the image file. ' - 'This may be caused by a corrupt file.')) - return gtk.gdk.pixbuf_new_from_file(const.icon) - - width = image1.get_width() - height = image1.get_height() - - scale = size / float(max(width,height)) - try: + width = image1.get_width() + height = image1.get_height() + + scale = size / float(max(width,height)) return image1.scale_simple(int(scale*width), int(scale*height), gtk.gdk.INTERP_BILINEAR) except: - WarningDialog(_("Cannot display %s") % path, - _('GRAMPS is not able to display the image file. ' - 'This may be caused by a corrupt file.')) + WarningDialog(title_msg, detail_msg) return gtk.gdk.pixbuf_new_from_file(const.icon) + diff --git a/src/DisplayTabs.py b/src/DisplayTabs.py index cc09b8049..9a64c6529 100644 --- a/src/DisplayTabs.py +++ b/src/DisplayTabs.py @@ -36,6 +36,7 @@ from gtk.gdk import ACTION_COPY, BUTTON1_MASK from TransUtils import sgettext as _ import pickle +import os try: set() @@ -62,6 +63,7 @@ import Utils import ImgManip import Spell import Errors +import Mime from DdTargets import DdTargets from GrampsWidgets import SimpleButton @@ -241,8 +243,10 @@ class ButtonTab(GrampsTab): self.tooltips.set_tip(self.del_btn, self._MSG['del']) if share_button: - self.share_btn = SimpleButton(gtk.STOCK_INDEX, self.share_button_clicked) + self.share_btn = SimpleButton(gtk.STOCK_INDEX, self.share_button_clicked) self.tooltips.set_tip(self.share_btn, self._MSG['share']) + else: + self.share_btn = None vbox = gtk.VBox() vbox.set_spacing(6) @@ -335,10 +339,46 @@ class EmbeddedList(ButtonTab): if self._DND_TYPE: self._set_dnd() + # set up right click option + self.tree.connect('button-press-event',self._on_button_press) + # build the initial data self.rebuild() self.show_all() + def _on_button_press(self, obj, event): + if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + ref = self.get_selected() + if ref: + self.right_click(obj, event) + + def right_click(self, obj, event): + + if self.share_btn: + itemlist = [ + (True, gtk.STOCK_ADD, self.add_button_clicked), + (False,_('Share'), self.edit_button_clicked), + (True, gtk.STOCK_EDIT, self.edit_button_clicked), + (True, gtk.STOCK_REMOVE, self.del_button_clicked), + ] + else: + itemlist = [ + (True, gtk.STOCK_ADD, self.add_button_clicked), + (True, gtk.STOCK_EDIT, self.edit_button_clicked), + (True, gtk.STOCK_REMOVE, self.del_button_clicked), + ] + + menu = gtk.Menu() + for (image, title, func) in itemlist: + if image: + item = gtk.ImageMenuItem(stock_id=title) + else: + item = gtk.MenuItem(title) + item.connect('activate',func) + item.show() + menu.append(item) + menu.popup(None, None, None, event.button, event.time) + def find_index(self,obj): """ returns the index of the object within the associated data @@ -1274,7 +1314,48 @@ class GalleryTab(ButtonTab): """ if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: self.edit_button_clicked(obj) + elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + reflist = self.iconlist.get_selected_items() + if len(reflist) == 1: + ref = self.media_list[reflist[0][0]] + self.right_click(ref, event) + def right_click(self, obj, event): + itemlist = [ + (True, gtk.STOCK_ADD, self.add_button_clicked), + (False,_('Share'), self.edit_button_clicked), + (True, gtk.STOCK_EDIT, self.edit_button_clicked), + (True, gtk.STOCK_REMOVE, self.del_button_clicked), + ] + + menu = gtk.Menu() + + ref_obj = self.dbstate.db.get_object_from_handle(obj.ref) + mime_type = ref_obj.get_mime_type() + if mime_type: + app = Mime.get_application(mime_type) + if app: + item = gtk.MenuItem(_('Open with %s') % app[1]) + item.connect('activate',make_launcher(app[0], + ref_obj.get_path())) + item.show() + menu.append(item) + item = gtk.SeparatorMenuItem() + item.show() + menu.append(item) + + for (image, title, func) in itemlist: + if image: + item = gtk.ImageMenuItem(stock_id=title) + else: + item = gtk.MenuItem(title) + item.connect('activate',func) + item.show() + menu.append(item) + menu.popup(None, None, None, event.button, event.time) + + + def get_icon_name(self): return 'gramps-media' @@ -1330,7 +1411,8 @@ class GalleryTab(ButtonTab): for ref in self.media_list: handle = ref.get_reference_handle() obj = self.dbstate.db.get_object_from_handle(handle) - pixbuf = ImgManip.get_thumb_from_obj(obj) + pixbuf = ImgManip.get_thumbnail_image(obj.get_path(), + obj.get_mime_type()) self.iconmodel.append(row=[pixbuf,obj.get_description(),ref]) self._connect_icon_model() self._set_label() @@ -1918,3 +2000,6 @@ class BackRefModel(gtk.ListStore): self.append(row=[dtype,gid,name,handle]) yield True yield False + +def make_launcher(prog, path): + return lambda x: os.spawnvpe(os.P_NOWAIT, prog, [ prog, path], os.environ) diff --git a/src/Editors/_EditPerson.py b/src/Editors/_EditPerson.py index d5ea92cfc..87a857fae 100644 --- a/src/Editors/_EditPerson.py +++ b/src/Editors/_EditPerson.py @@ -273,7 +273,7 @@ class EditPerson(EditPrimary): media_list = self.obj.get_media_list() if media_list: - from EditMediaRef import EditMediaRef + from Editors import EditMediaRef media_ref = media_list[0] object_handle = media_ref.get_reference_handle() @@ -300,9 +300,6 @@ class EditPerson(EditPrimary): if progname and len(progname) > 1: Utils.add_menuitem(menu,_("Open in %s") % progname[1], photo,self.popup_view_photo) - if mtype and mtype.startswith("image"): - Utils.add_menuitem(menu,_("Edit with the GIMP"), - photo,self.popup_edit_photo) Utils.add_menuitem(menu,_("Edit Object Properties"),photo, self.popup_change_description) menu.popup(None,None,None,event.button,event.time) @@ -315,20 +312,10 @@ class EditPerson(EditPrimary): object_handle = ph.get_reference_handle() Utils.view_photo(self.db.get_object_from_handle(object_handle)) - def popup_edit_photo(self, obj): - """Open this picture in a picture editor""" - media_list = self.obj.get_media_list() - if media_list: - ph = media_list[0] - object_handle = ph.get_reference_handle() - if os.fork() == 0: - obj = self.db.get_object_from_handle(object_handle) - os.execvp(const.editor,[const.editor, obj.get_path()]) - def popup_change_description(self,obj): media_list = self.obj.get_media_list() if media_list: - from EditMediaRef import EditMediaRef + from Editors import EditMediaRef media_ref = media_list[0] object_handle = media_ref.get_reference_handle() @@ -336,7 +323,6 @@ class EditPerson(EditPrimary): EditMediaRef(self.dbstate, self.uistate, self.track, media_obj, media_ref, self.image_callback) - def given_focus_out_event (self, entry, event): if not self.should_guess_gender: return False diff --git a/src/GrampsDisplay.py b/src/GrampsDisplay.py index f6cad714e..5d9e55def 100644 --- a/src/GrampsDisplay.py +++ b/src/GrampsDisplay.py @@ -44,8 +44,7 @@ def run_browser(url): for path in search: prog = os.path.join(path,browser) if os.path.isfile(prog): - if os.fork() == 0: - os.execvp(prog,[prog, url]) + os.spawnvpe(os.P_NOWAIT, prog, [prog, url], os.environ) return diff --git a/src/ImgManip.py b/src/ImgManip.py index b52d24c12..b574983ea 100644 --- a/src/ImgManip.py +++ b/src/ImgManip.py @@ -127,9 +127,7 @@ def run_thumbnailer(mtype, frm, to, size=const.thumbScale): if cmd and enable: cmdlist = map(lambda x: sublist.get(x,x),cmd.split()) - if os.fork() == 0: - os.execvp(cmdlist[0],cmdlist) - os.wait() + os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ) return True else: return False diff --git a/src/QuestionDialog.py b/src/QuestionDialog.py index 72430ab9b..4b4f40ed1 100644 --- a/src/QuestionDialog.py +++ b/src/QuestionDialog.py @@ -160,59 +160,47 @@ class OptionDialog: def get_response(self): return self.response -class ErrorDialog: +class ErrorDialog(gtk.MessageDialog): def __init__(self,msg1,msg2="",parent=None): - self.xml = gtk.glade.XML(const.gladeFile,"errdialog","gramps") - self.top = self.xml.get_widget('errdialog') - self.top.set_icon(ICON) - - label1 = self.xml.get_widget('label1') - label2 = self.xml.get_widget('label2') - label1.set_text('%s' % str(msg1)) - label1.set_use_markup(True) - label2.set_text(str(msg2)) - self.top.show() - if parent: - self.top.set_transient_for(parent) - self.top.run() - self.top.destroy() + gtk.MessageDialog.__init__(self, parent, + flags=gtk.DIALOG_MODAL, + type=gtk.MESSAGE_ERROR, + buttons=gtk.BUTTONS_CLOSE) + self.set_markup('%s' % msg1) + self.format_secondary_text(msg2) + self.set_icon(ICON) + self.show() + self.run() + self.destroy() -class WarningDialog: - def __init__(self,msg1,msg2="",parent=None): - - self.xml = gtk.glade.XML(const.gladeFile,"warndialog","gramps") - self.top = self.xml.get_widget('warndialog') - self.top.set_icon(ICON) - - label1 = self.xml.get_widget('label1') - label2 = self.xml.get_widget('label2') - label1.set_text('%s' % msg1) - label1.set_use_markup(True) - label2.set_text(msg2) - self.top.show() - if parent: - self.top.set_transient_for(parent) - self.top.run() - self.top.destroy() - -class OkDialog: +class WarningDialog(gtk.MessageDialog): def __init__(self,msg1,msg2="",parent=None): - self.xml = gtk.glade.XML(const.gladeFile,"okdialog","gramps") - self.top = self.xml.get_widget('okdialog') - self.top.set_icon(ICON) + gtk.MessageDialog.__init__(self, parent, + flags=gtk.DIALOG_MODAL, + type=gtk.MESSAGE_WARNING, + buttons=gtk.BUTTONS_CLOSE) + self.set_markup('%s' % msg1) + self.format_secondary_text(msg2) + self.set_icon(ICON) + self.show() + self.run() + self.destroy() - label1 = self.xml.get_widget('label1') - label2 = self.xml.get_widget('label2') - label1.set_text('%s' % msg1) - label1.set_use_markup(True) - label2.set_text(msg2) - self.top.show() - if parent: - self.top.set_transient_for(parent) - self.top.run() - self.top.destroy() +class OkDialog(gtk.MessageDialog): + def __init__(self,msg1,msg2="",parent=None): + + gtk.MessageDialog.__init__(self, parent, + flags=gtk.DIALOG_MODAL, + type=gtk.MESSAGE_INFO, + buttons=gtk.BUTTONS_CLOSE) + self.set_markup('%s' % msg1) + self.format_secondary_text(msg2) + self.set_icon(ICON) + self.show() + self.run() + self.destroy() class MissingMediaDialog: def __init__(self,msg1,msg2,task1,task2,task3,parent=None): diff --git a/src/Utils.py b/src/Utils.py index 0c377167c..c926dc1d4 100644 --- a/src/Utils.py +++ b/src/Utils.py @@ -596,8 +596,7 @@ def view_photo(photo): args = prog.split() args.append(photo.get_path()) - if os.fork() == 0: - os.execvp(args[0],args) + os.spawnvpe(os.P_NOWAIT, args[0], args, os.environ) def find_file( filename): # try the filename we got diff --git a/src/glade/gramps.glade b/src/glade/gramps.glade index 0484a5f50..50bf69c51 100644 --- a/src/glade/gramps.glade +++ b/src/glade/gramps.glade @@ -7491,151 +7491,6 @@ Text Beside Icons - - - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - 450 - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - False - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - 0 - False - True - GTK_PACK_END - - - - - - 12 - True - 2 - 3 - False - 0 - 0 - - - - True - - False - True - GTK_JUSTIFY_LEFT - True - False - 0 - 0.5 - 6 - 12 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 6 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 0 - 1 - expand|shrink|fill - fill - - - - - - True - gtk-dialog-error - 6 - 0.5 - 0 - 0 - 0 - - - 0 - 1 - 0 - 2 - fill - fill - - - - - 0 - False - False - - - - - - GTK_WINDOW_TOPLEVEL @@ -8144,294 +7999,6 @@ Text Beside Icons - - - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - False - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-close - True - GTK_RELIEF_NORMAL - True - -7 - - - - - 0 - False - True - GTK_PACK_END - - - - - - 12 - True - 2 - 3 - False - 0 - 0 - - - - True - - False - True - GTK_JUSTIFY_LEFT - True - False - 0 - 0.5 - 6 - 12 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - gtk-dialog-warning - 6 - 0.5 - 0 - 0 - 0 - - - 0 - 1 - 0 - 2 - fill - fill - - - - - - True - - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 6 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 0 - 1 - expand|shrink|fill - - - - - - 0 - True - True - - - - - - - - - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - True - False - True - False - False - GDK_WINDOW_TYPE_HINT_DIALOG - GDK_GRAVITY_NORTH_WEST - True - False - False - - - - True - False - 0 - - - - True - GTK_BUTTONBOX_END - - - - True - True - True - gtk-ok - True - GTK_RELIEF_NORMAL - True - -5 - - - - - 0 - False - True - GTK_PACK_END - - - - - - 12 - True - 2 - 3 - False - 0 - 0 - - - - True - - False - True - GTK_JUSTIFY_LEFT - True - False - 0 - 0.5 - 6 - 12 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 1 - 2 - fill - - - - - - - True - gtk-dialog-info - 6 - 0.5 - 0 - 0 - 0 - - - 0 - 1 - 0 - 2 - fill - fill - - - - - - True - - False - True - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 6 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 2 - 3 - 0 - 1 - expand|shrink|fill - - - - - - 0 - False - True - - - - - - GTK_WINDOW_TOPLEVEL diff --git a/src/gramps.py b/src/gramps.py index 993ea220c..5676719a9 100644 --- a/src/gramps.py +++ b/src/gramps.py @@ -47,10 +47,12 @@ except ImportError: import gtk.gdk import gtk import gtk.glade - +import gobject # setup import path +gobject.threads_init() + sys.path.append(os.path.abspath(os.path.basename(__file__))) #-------------------------------------------------------------------------