From 036eeee2c86423897eaf60ca2e7d86636a316982 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Tue, 9 Dec 2008 22:50:21 +0000 Subject: [PATCH] Add HtmlView as base for GeoView svn: r11449 --- src/DataViews/GeoView.py | 439 +++++++++++++++++++++++++++++--------- src/DataViews/__init__.py | 12 +- 2 files changed, 348 insertions(+), 103 deletions(-) diff --git a/src/DataViews/GeoView.py b/src/DataViews/GeoView.py index 0b001ff01..973ddec7e 100644 --- a/src/DataViews/GeoView.py +++ b/src/DataViews/GeoView.py @@ -4,6 +4,7 @@ # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2007-2008 Serge Noiraud +# Copyright (C) 2008 Benny Malengier # # 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 @@ -61,11 +62,10 @@ LOG = logging.getLogger(".GeoView") # #------------------------------------------------------------------------- import gen.lib -import ViewManager import PageView import Utils -import Errors import Config +from const import TEMP_DIR from BasicUtils import name_displayer as _nd #------------------------------------------------------------------------- @@ -73,23 +73,40 @@ from BasicUtils import name_displayer as _nd # Web interfaces # #------------------------------------------------------------------------- -WebKit = 0 + +NOWEB = 0 +WEBKIT = 1 +MOZIL = 2 + +WebKit = NOWEB try: import webkit - WebKit = 1 -except: - pass -try: - import gtkmozembed - WebKit = 2 + LOG.info("Using Webkit for HtmlView") + WebKit = WEBKIT except: pass + +if WebKit == NOWEB: + try: + import gtkmozembed + LOG.info("Using GtkMozembed for HtmlView") + WebKit = MOZIL + except: + pass + #no interfaces present, raise Error so that options for GeoView do not show if WebKit == 0 : Config.set(Config.GEOVIEW, False) LOG.warning(_("GeoView not enabled, no html plugin for GTK found.")) raise ImportError, 'No GTK html plugin found' +#------------------------------------------------------------------------- +# +# Gramps Modules +# +#------------------------------------------------------------------------- + + #------------------------------------------------------------------------- # # Constants @@ -97,8 +114,251 @@ if WebKit == 0 : #------------------------------------------------------------------------- # I think we should set the two following variable in const.py # They are used only with gtkmozembed. -MOZEMBED_PATH = "/tmp/" -MOZEMBED_SUBPATH = "browser-gramps" +MOZEMBED_PATH = TEMP_DIR +MOZEMBED_SUBPATH = Utils.get_empty_tempdir('mozembed_gramps') + +#------------------------------------------------------------------------- +# +# Renderer +# +#------------------------------------------------------------------------- +class Renderer(): + """ + Renderer renders the webpage. Several backend implementations are + possible + """ + def __init__(self): + self.window = None + + def get_window(self): + """ + Returns a container class with the widget that contains browser + window + """ + return self.window + + def show_all(self): + self.window.show_all() + + def open(self, url): + """ open the webpage at url + """ + raise NotImplementedError + + if (self.browser == 1): + self.m.open("file://"+htmlfile) + elif (self.browser == 2): + self.m.load_url("file://"+htmlfile) + elif (self.browser == 3): + self.m.openURL ("file://"+htmlfile); + +#------------------------------------------------------------------------- +# +# Renderer with WebKit +# +#------------------------------------------------------------------------- +class RendererWebkit(Renderer): + """ + Implementation of Renderer with Webkit + """ + def __init__(self): + Renderer.__init__(self) + self.window = webkit.WebView() + + def open(self, url): + self.window.open(url) + +class RendererMozilla(Renderer): + """ + Implementation of Renderer with gtkmozembed + """ + def __init__(self): + Renderer.__init__(self) + if hasattr(gtkmozembed, 'set_profile_path'): + set_profile_path = gtkmozembed.set_profile_path + else: + set_profile_path = gtkmozembed.gtk_moz_embed_set_profile_path + set_profile_path(MOZEMBED_PATH, MOZEMBED_SUBPATH) + self.__set_mozembed_proxy() + self.window = gtkmozembed.MozEmbed() + self.window.set_size_request(800, 600) + + def open(self, url): + self.window.load_url(url) + + def __set_mozembed_proxy(self): + """ + Try to see if we have some proxy environment variable. + http_proxy in our case. + The standard format is : http://[user:password@]proxy:port/ + """ + try: + proxy = os.environ['http_proxy'] + data = "" + if proxy: + host_port = None + parts = urlparse.urlparse(proxy) + if not parts[0] or parts[0] == 'http': + host_port = parts[1] + t = host_port.split(':') + host = t[0].strip() + if host: + try: + port = int(t[1]) + except: + user = host + u = t[1].split('@') + password = u[0] + host = u[1] + port = int(t[2]) + + if port and host: + port = str(port) + data += 'user_pref("network.proxy.type", 1);\r\n' + data += 'user_pref("network.proxy.http", "'+host+'");\r\n' + data += 'user_pref("network.proxy.http_port", '+port+');\r\n' + data += 'user_pref("network.proxy.no_proxies_on", '\ + '"127.0.0.1,localhost,localhost.localdomain");\r\n' + data += 'user_pref("network.proxy.share_proxy_settings", true);\r\n' + data += 'user_pref("network.http.proxy.pipelining", true);\r\n' + data += 'user_pref("network.http.proxy.keep-alive", true);\r\n' + data += 'user_pref("network.http.proxy.version", 1.1);\r\n' + data += 'user_pref("network.http.sendRefererHeader, 0);\r\n' + fd = file(MOZEMBED_PATH+MOZEMBED_SUBPATH+"/prefs.js","w+") + fd.write(data) + fd.close() + except: + try: # trying to remove pref.js in case of proxy change. + os.remove(MOZEMBED_PATH+MOZEMBED_SUBPATH+"/prefs.js") + except: + pass + pass # We don't use a proxy or the http_proxy variable is not set. + +#------------------------------------------------------------------------- +# +# HtmlView +# +#------------------------------------------------------------------------- +class HtmlView(PageView.PageView): + """ + HtmlView is a view showing a top widget with controls, and a bottom part + with an embedded webbrowser showing a given URL + """ + + def __init__(self, dbstate, uistate): + PageView.PageView.__init__(self, _('HtmlView'), dbstate, uistate) + + self.dbstate = dbstate + + def build_widget(self): + """ + Builds the interface and returns a gtk.Container type that + contains the interface. This containter will be inserted into + a gtk.Notebook page. + """ + global WebKit + + self.box = gtk.VBox(False, 4) + #top widget at the top + self.box.pack_start(self.top_widget(), False, False,0 ) + #web page under it in a scrolled window + self.table = gtk.Table(1, 1, False) + frame = gtk.ScrolledWindow(None, None) + frame.set_shadow_type(gtk.SHADOW_NONE) + frame.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + frame.add_with_viewport(self.table) + self.table.get_parent().set_shadow_type(gtk.SHADOW_NONE) + self.table.set_row_spacings(1) + self.table.set_col_spacings(0) + + gobject.threads_init() + self.count = 0 + + if (WebKit == WEBKIT) : + # We use webkit + self.renderer = RendererWebkit() + elif (WebKit == MOZIL) : + # We use gtkmozembed + self.renderer = RendererMozilla() + + self.table.add(self.renderer.get_window()) + self.box.pack_start(frame, True, True, 0) + + #load a welcome html page + urlhelp = self.create_start_page() + self.renderer.open(urlhelp) + self.renderer.show_all() + + return self.box + + def top_widget(self): + """ + The default class gives a widget where user can type an url + """ + hbox = gtk.HBox(False,4) + self.urlfield = gtk.Entry() + self.urlfield.connect('activate', self._on_activate); + hbox.pack_start(self.urlfield, True, True, 4) + button = gtk.Button(stock=gtk.STOCK_APPLY) + button.connect('clicked', self._on_activate) + hbox.pack_start(button, False, False, 4) + return hbox + + def _on_activate(self, object): + url = self.urlfield.get_text() + if url.find('://') == -1: + url = 'http://'+ url + self.renderer.open(url) + + def build_tree(self): + """ + Rebuilds the current display. Called from ViewManager + """ + pass #htmlview is build on click and startup + + def get_stock(self): + """ + Returns the name of the stock icon to use for the display. + This assumes that this icon has already been registered with + GNOME as a stock icon. + """ + return 'gramps-geo' + + def define_actions(self): + pass + + def create_start_page(self): + """ + This command creates a default start page, and returns the URL of this + page. + """ + tmpdir = Utils.get_empty_tempdir('htmlview') + data = """ + + + + + %(title)s + + +

%(content)s

+ + + + """ % { 'height' : 600, + 'title' : _('Start page for the Html View'), + 'content': _('Type an webpage address at the top, and hit' + ' the execute button to load a webpage in this' + ' page\n
\n' + 'For example: http://gramps-project.org

') + } + filename = os.path.join(tmpdir, 'startpage') + fd = file(filename,"w+") + fd.write(data) + fd.close() + return 'file://'+filename + #------------------------------------------------------------------------- # @@ -111,8 +371,6 @@ class GeoView(PageView.PersonNavView): PageView.PersonNavView.__init__(self, _('GeoView'), dbstate, uistate) global WebKit - if (WebKit == 1): LOG.info("GeoView uses WebKit") - elif (WebKit == 2): LOG.info("GeoView uses gtkmozembed") self.dbstate = dbstate self.usedmap = "openstreetmap" @@ -123,7 +381,7 @@ class GeoView(PageView.PersonNavView): # Create a temporary dot file (handle,self.htmlfile) = tempfile.mkstemp(".html","GeoV", MOZEMBED_PATH ) - # needed to be solved. where to remove it ? + # needs to be solved. where to remove it ? def __del__(self): """ @@ -242,11 +500,10 @@ class GeoView(PageView.PersonNavView): self.m = gtkmozembed.MozEmbed() self.m.set_size_request(800, 600) - if (WebKit != 0) : - self.table_2.add(self.m) - self.geo_places(None,self.displaytype) - - self.m.show_all() + self.table_2.add(self.m) + self.geo_places(None,self.displaytype) + + self.m.show_all() return self.notebook @@ -255,37 +512,28 @@ class GeoView(PageView.PersonNavView): Specifies the UIManager XML code that defines the menus and buttons associated with the interface. """ - global WebKit - if (WebKit != 0 ): - if Config.get(Config.GEOVIEW_GOOGLEMAPS): - alternate_map = "GoogleMaps" - elif Config.get(Config.GEOVIEW_OPENLAYERS): - alternate_map = "OpenLayersMaps" - elif Config.get(Config.GEOVIEW_YAHOO): - alternate_map = "YahooMaps" - elif Config.get(Config.GEOVIEW_MICROSOFT): - alternate_map = "MicrosoftMaps" - return ''' - - - - - - - - - - - - ''' % alternate_map - else: - return ''' - - - - - - ''' + + if Config.get(Config.GEOVIEW_GOOGLEMAPS): + alternate_map = "GoogleMaps" + elif Config.get(Config.GEOVIEW_OPENLAYERS): + alternate_map = "OpenLayersMaps" + elif Config.get(Config.GEOVIEW_YAHOO): + alternate_map = "YahooMaps" + elif Config.get(Config.GEOVIEW_MICROSOFT): + alternate_map = "MicrosoftMaps" + return ''' + + + + + + + + + + + + ''' % alternate_map def define_actions(self): """ @@ -300,53 +548,48 @@ class GeoView(PageView.PersonNavView): be able to toggle these when you are at the end of the history or at the beginning of the history. """ - global WebKit - if (WebKit != 0 ): - self._add_action('OpenStreetMap', 'gramps-openstreetmap', _('_OpenStreetMap'), - callback=self.select_OpenStreetMap_map, - tip=_("Select OpenStreetMap Maps")) - if Config.get(Config.GEOVIEW_GOOGLEMAPS): - self._add_action('GoogleMaps', 'gramps-alternate-map', - _('_Google Maps'), - callback=self.select_google_map, - tip=_("Select Google Maps. If possible, " - "choose OpenStreetMap!")) - elif Config.get(Config.GEOVIEW_OPENLAYERS): - self._add_action('OpenLayersMaps', 'gramps-alternate-map', - _('_OpenLayers Maps'), - callback=self.select_openlayers_map, - tip=_("Select OpenLayers Maps. If possible," - " choose OpenStreetMap")) - elif Config.get(Config.GEOVIEW_YAHOO): - self._add_action('YahooMaps', 'gramps-alternate-map', - _('_Yahoo! Maps'), - callback=self.select_yahoo_map, - tip=_("Select Yahoo Maps. If possible, choose" - " OpenStreetMap")) - elif Config.get(Config.GEOVIEW_MICROSOFT): - self._add_action('MicrosoftMaps', 'gramps-alternate-map', - _('_Microsoft Maps'), - callback=self.select_microsoft_map, - tip=_("Select Microsoft Maps. If possible," - " choose OpenStreetMap")) - - self._add_action('AllPlacesMaps', gtk.STOCK_HOME, _('_AllPlacesMaps'), - callback=self.all_places, - tip=_("Attempt to view all database places on the Map.")) - self._add_action('PersonMaps', 'gramps-person', _('_Person'), - callback=self.person_places, - tip=_("Attempt to view all the places where lived the selected people.")) - self._add_action('FamilyMaps', 'gramps-parents-add', _('_Family'), - callback=self.family_places, - tip=_("Attempt to view places on the Map of the selected people's family.")) - self._add_action('EventMaps', 'gramps-event', _('_Event'), - callback=self.event_places, - tip=_("Attempt to view places on the Map for all events.")) - else: - self._add_action('MissingKit', gtk.STOCK_REMOVE, _('_MissingKit'), - callback=None, - tip=_("You can't use GeoView: webkit, gtkmozembed or gtkhtml missing")) + self._add_action('OpenStreetMap', 'gramps-openstreetmap', _('_OpenStreetMap'), + callback=self.select_OpenStreetMap_map, + tip=_("Select OpenStreetMap Maps")) + if Config.get(Config.GEOVIEW_GOOGLEMAPS): + self._add_action('GoogleMaps', 'gramps-alternate-map', + _('_Google Maps'), + callback=self.select_google_map, + tip=_("Select Google Maps. If possible, " + "choose OpenStreetMap!")) + elif Config.get(Config.GEOVIEW_OPENLAYERS): + self._add_action('OpenLayersMaps', 'gramps-alternate-map', + _('_OpenLayers Maps'), + callback=self.select_openlayers_map, + tip=_("Select OpenLayers Maps. If possible," + " choose OpenStreetMap")) + elif Config.get(Config.GEOVIEW_YAHOO): + self._add_action('YahooMaps', 'gramps-alternate-map', + _('_Yahoo! Maps'), + callback=self.select_yahoo_map, + tip=_("Select Yahoo Maps. If possible, choose" + " OpenStreetMap")) + elif Config.get(Config.GEOVIEW_MICROSOFT): + self._add_action('MicrosoftMaps', 'gramps-alternate-map', + _('_Microsoft Maps'), + callback=self.select_microsoft_map, + tip=_("Select Microsoft Maps. If possible," + " choose OpenStreetMap")) + + self._add_action('AllPlacesMaps', gtk.STOCK_HOME, _('_AllPlacesMaps'), + callback=self.all_places, + tip=_("Attempt to view all database places on the Map.")) + self._add_action('PersonMaps', 'gramps-person', _('_Person'), + callback=self.person_places, + tip=_("Attempt to view all the places where lived the selected people.")) + self._add_action('FamilyMaps', 'gramps-parents-add', _('_Family'), + callback=self.family_places, + tip=_("Attempt to view places on the Map of the selected people's family.")) + self._add_action('EventMaps', 'gramps-event', _('_Event'), + callback=self.event_places, + tip=_("Attempt to view places on the Map for all events.")) + PageView.PersonNavView.define_actions(self) def goto_active_person(self,handle=None): @@ -391,9 +634,9 @@ class GeoView(PageView.PersonNavView): self.createMapstraction(htmlfile,displaytype) LOG.debug("geo_places : in appel page") if (self.browser == 1): - self.m.open("file://"+htmlfile) + self.m.open("file://"+htmlfile) elif (self.browser == 2): - self.m.load_url("file://"+htmlfile) + self.m.load_url("file://"+htmlfile) elif (self.browser == 3): self.m.openURL ("file://"+htmlfile); diff --git a/src/DataViews/__init__.py b/src/DataViews/__init__.py index 520b2d8bd..dba34318b 100644 --- a/src/DataViews/__init__.py +++ b/src/DataViews/__init__.py @@ -37,14 +37,18 @@ from NoteView import NoteView geopresent = True try: - from GeoView import GeoView + from GeoView import HtmlView, GeoView except: geopresent = False try: import Config - DATA_VIEWS = eval("["+Config.get(Config.DATA_VIEWS)+"]") - #add GeoView if in config and present + dv = Config.get(Config.DATA_VIEWS) + #remove GeoView so we do not try to eval it if import fails + if not geopresent and not dv.find('GeoView') == -1: + dv = dv.replace('GeoView','').replace(',,',',') + DATA_VIEWS = eval("["+dv+"]") + #add or remove GeoView if config says so if geopresent and Config.get(Config.GEOVIEW) and \ not GeoView in DATA_VIEWS: DATA_VIEWS.append(GeoView) @@ -58,9 +62,7 @@ try: if newval[-1] == ',': newval = newval[:-1] Config.set(Config.DATA_VIEWS, newval) - print Config.get(Config.DATA_VIEWS) except AttributeError: - print 'exep' # Fallback if bad config line, or if no Config system DATA_VIEWS = [ GrampletView,