[GRASS-SVN] r65871 - in grass-addons/grass7/gui/wxpython/wx.metadata: . config db.csw.admin db.csw.harvest db.csw.run g.gui.cswbrowser g.gui.metadata mdlib profiles t.info.iso

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Aug 10 06:13:38 PDT 2015


Author: krejcmat
Date: 2015-08-10 06:13:38 -0700 (Mon, 10 Aug 2015)
New Revision: 65871

Added:
   grass-addons/grass7/gui/wxpython/wx.metadata/config/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/config/connections_resources.xml
   grass-addons/grass7/gui/wxpython/wx.metadata/config/default-sample.cfg
   grass-addons/grass7/gui/wxpython/wx.metadata/config/g.gui.cswbrowser.html
   grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md.txt
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts.txt
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups.txt
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes.txt
   grass-addons/grass7/gui/wxpython/wx.metadata/config/record_metadata_dc.html
   grass-addons/grass7/gui/wxpython/wx.metadata/config/service_metadata.html
   grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_highlight.html
   grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_render.html
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.html
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.py
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.html
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.py
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.html
   grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.py
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.html
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.py
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlRequest.html
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlResponse.html
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswlib.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswutil.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdeditorfactory.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdjinjaparser.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdffactory.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdftheme.py
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/
   grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.html
   grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.py
Removed:
   grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups
   grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/jinjainfo.py
   grass-addons/grass7/gui/wxpython/wx.metadata/pdf/
Modified:
   grass-addons/grass7/gui/wxpython/wx.metadata/Makefile
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml
Log:
GSOC2015 improved metadata

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/Makefile	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -4,20 +4,15 @@
 	mdlib \
 	r.info.iso \
 	v.info.iso \
-	pdf\
-	g.gui.metadata
+	t.info.iso \
+	db.csw.admin \
+	db.csw.run \
+	db.csw.harvest \
+	g.gui.cswbrowser \
+	g.gui.metadata \
+    profiles \
+    config
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 
-default:
-	$(MAKE) parsubdirs
-	@cp -r profiles $(ETC)
-	@cp -r config $(ETC)
-
-install:
-	@cd mdlib ; $(MAKE) install
-	@cd r.info.iso ; $(MAKE) install
-	@cd v.info.iso ; $(MAKE) install
-	@cd pdf ; $(MAKE) install
-	@cd g.gui.metadata ; $(MAKE) install
-	@cp -r etc/* $(INST_DIR)/etc
+default: parsubdirs

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,6 @@
+MODULE_TOPDIR = ..
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default:
+	$(INSTALL_DATA) *.??? *.html  $(ETC)


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/connections_resources.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/connections_resources.xml	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/connections_resources.xml	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,17 @@
+<qgsCSWConnections version="1.0">
+    <csw name="Danmark: National CSW" url="http://www.geodata-info.dk/registrant/srv/en/csw?" />
+    <csw name="Data.gov CSW" url="http://catalog.data.gov/csw-all" />
+    <csw name="Finland: National CSW (Paikkatietohakemisto)" url="http://www.paikkatietohakemisto.fi/geonetwork/srv/fi/csw?" />
+    <csw name="Geonorge - National CSW service for Norway" url="http://www.geonorge.no/geonetwork/srv/eng/csw" />
+    <csw name="Geoportale Nazionale - Servizio di ricerca Italiano" url="http://www.pcn.minambiente.it/geoportal/csw" />
+    <csw name="Iceland: National CSW (Iceland Service)" url="http://gatt.lmi.is/geoportal122/csw?" />
+    <csw name="Italy: National CSW (Geoportale Nazionale - Servizio di ricerca Italiano)" url="http://www.pcn.minambiente.it/geoportal/csw" />
+    <csw name="Italy: RNDT - Repertorio Nazionale dei Dati Territoriali - Servizio di ricerca" url="http://www.rndt.gov.it/RNDT/CSW" />
+    <csw name="LINZ Data Service" url="http://data.linz.govt.nz/feeds/csw" />
+    <csw name="Nationaal Georegister (Nederland)" url="http://www.nationaalgeoregister.nl/geonetwork/srv/eng/csw" />
+    <csw name="New Zealand: LINZ Data Service" url="http://data.linz.govt.nz/feeds/csw" />
+    <csw name="RNDT - Repertorio Nazionale dei Dati Territoriali - Servizio di ricerca" url="http://www.rndt.gov.it/RNDT/CSW" />
+    <csw name="UK Location Catalogue Publishing Service" url="http://csw.data.gov.uk/geonetwork/srv/en/csw" />
+    <csw name="UNEP GRID-Geneva Metadata Catalog" url="http://metadata.grid.unep.ch:8080/geonetwork/srv/eng/csw" />
+    <csw name="USA: Data.gov CSW" url="http://catalog.data.gov/csw-all" />
+<csw name="localhost" url="http://localhost:8000/" /><csw name="den" url="http://www.geodata-info.dk/registrant/srv/en/csw" /></qgsCSWConnections>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/connections_resources.xml
___________________________________________________________________
Added: svn:mime-type
   + text/xml
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/default-sample.cfg
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/default-sample.cfg	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/default-sample.cfg	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,98 @@
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#
+# Copyright (c) 2015 Tom Kralidis
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+[server]
+home=/var/www/html/pycsw
+url=http://localhost/pycsw/csw.py
+mimetype=application/xml; charset=UTF-8
+encoding=UTF-8
+language=en-US
+maxrecords=10
+#loglevel=DEBUG
+#logfile=/tmp/pycsw.log
+#ogc_schemas_base=http://foo
+#federatedcatalogues=http://catalog.data.gov/csw
+#pretty_print=true
+#gzip_compresslevel=8
+#domainquerytype=range
+#domaincounts=true
+#spatial_ranking=true
+profiles=apiso
+
+[manager]
+transactions=false
+allowed_ips=127.0.0.1
+#csw_harvest_pagesize=10
+
+[metadata:main]
+identification_title=pycsw Geospatial Catalogue
+identification_abstract=pycsw is an OGC CSW server implementation written in Python
+identification_keywords=catalogue,discovery,metadata
+identification_keywords_type=theme
+identification_fees=None
+identification_accessconstraints=None
+provider_name=Organization Name
+provider_url=http://pycsw.org/
+contact_name=Lastname, Firstname
+contact_position=Position Title
+contact_address=Mailing Address
+contact_city=City
+contact_stateorprovince=Administrative Area
+contact_postalcode=Zip or Postal Code
+contact_country=Country
+contact_phone=+xx-xxx-xxx-xxxx
+contact_fax=+xx-xxx-xxx-xxxx
+contact_email=Email Address
+contact_url=Contact URL
+contact_hours=Hours of Service
+contact_instructions=During hours of service.  Off on weekends.
+contact_role=pointOfContact
+
+[repository]
+# sqlite
+database=sqlite:////var/www/pycsw/tests/suites/cite/data/records.db
+# postgres
+#database=postgresql://username:password@localhost/pycsw
+# mysql
+#database=mysql://username:password@localhost/pycsw?charset=utf8
+#mappings=path/to/mappings.py
+table=records
+#filter=type = 'http://purl.org/dc/dcmitype/Dataset'
+
+[metadata:inspire]
+enabled=true
+languages_supported=eng,gre
+default_language=eng
+date=YYYY-MM-DD
+gemet_keywords=Utility and governmental services
+conformity_service=notEvaluated
+contact_name=Organization Name
+contact_email=Email Address
+temp_extent=YYYY-MM-DD/YYYY-MM-DD
+

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/g.gui.cswbrowser.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/g.gui.cswbrowser.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/g.gui.cswbrowser.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <title></title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/g.gui.cswbrowser.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1,5 +0,0 @@
-self.md.identification = mdutil.MD_DataIdentification_MOD()
-self.md.dataquality = DQ_DataQuality()
-self.md.distribution = MD_Distribution()
-self.md.identification.extent = EX_Extent()
-self.md.identification.extent.boundingBox = EX_GeographicBoundingBox()

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md.txt
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md.txt	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md.txt	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,6 @@
+self.md.identification = mdutil.MD_DataIdentification_MOD()
+self.md.dataquality = DQ_DataQuality()
+self.md.distribution = MD_Distribution()
+self.md.identification.extent = EX_Extent()
+self.md.identification.extent.boundingBox = EX_GeographicBoundingBox()
+self.md.referencesystem=MD_ReferenceSystem(None)
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1 +0,0 @@
-keywords=[{"preferredLabel": {"string": "accident", "language": "en"}, "definition": {"string": "An unexpected occurrence, failure or loss with the potential for harming human life, property or the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/25", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "administration", "language": "en"}, "definition": {"string": "The management or direction of the affairs of a public or private office, business or organization.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/95", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "agriculture", "language": "en"}, "definition": {"string": "The production of plants and animals useful to man, involving soil cultivation and the breeding and management of crops and livestock.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/232", "thesaurus": "http:
 //www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "analysis", "language": "en"}, "definition": {"string": "Examination or determination.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/397", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "animal husbandry", "language": "en"}, "definition": {"string": "A branch of agriculture concerned with the breeding and feeding of domestic animals.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/429", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "atmosphere", "language": "en"}, "definition": {"string": "The gaseous envelope surrounding the Earth in a several kilometers-thick layer.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/617", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "biochemical process", "language": "en"}, "defini
 tion": {"string": "Chemical processes occurring in living organisms.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/812", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "biosphere", "language": "en"}, "definition": {"string": "That part of the Earth and atmosphere capable of supporting living organisms.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/892", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "border", "language": "en"}, "definition": {"string": "The dividing line or frontier between political or geographic regions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/963", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "built environment", "language": "en"}, "definition": {"string": "That part of the physical surroundings which are people-made or people-organized, such as buildings
  and other major structures, roads, bridges and the like, down to lesser objects such as traffic lights, telephone and pillar boxes.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1063", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "business", "language": "en"}, "definition": {"string": "The activity, position or site associated with commerce or the earning of a livelihood.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1084", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical", "language": "en"}, "definition": {"string": "Any substance used in or resulting from a reaction involving changes to atoms or molecules.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1327", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical element", "language": "en"}, "definition": {"string": "A
  substance made up of atoms with the same atomic number; common examples are hydrogen, gold, and iron.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2643", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical process", "language": "en"}, "definition": {"string": "The particular method of manufacturing or making a chemical usually involving a number of steps or operations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1320", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical property", "language": "en"}, "definition": {"string": "Properties of a substance depending on the arrangement of the atoms in the molecule, e.g. bio-availability, degradability, persistence, etc.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1322", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "climat
 e", "language": "en"}, "definition": {"string": "The average weather condition in a region of the world. Many aspects of the Earth's geography affect the climate. Equatorial, or low, latitudes are hotter than the polar latitudes because of the angle at which the rays of sunlight arrive at the Earth's surface. The difference in temperature at the equator and at the poles has an influence on the global circulation of huge masses of air. Cool air at the poles sinks and spreads along the surface of the Earth towards the equator. Cool air forces its way under the lower density warmer air in the lower regions, pushing the lighter air up and toward the poles, where it will cool and descend.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1462", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "craft", "language": "en"}, "definition": {"string": "An occupation or trade requiring manual dexterity or skilled artistry.", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1850", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "culture (society)", "language": "en"}, "definition": {"string": "The body of customary beliefs, social forms, and material traits constituting a distinct complex of tradition of a racial or social group.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1921", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "demography", "language": "en"}, "definition": {"string": "The statistical study of human vital statistics and population dynamics.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2060", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "disaster", "language": "en"}, "definition": {"string": "The result of a vast ecological breakdown in the relations between man and his environment, a serious and sudd
 en event (or slow, as in drought) on such a scale that the stricken community needs extraordinary efforts to cope with it, often with outside help or international aid.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2215", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "disease", "language": "en"}, "definition": {"string": "A definite pathological process having a characteristic set of signs and symptoms which are detrimental to the well-being of the individual.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2232", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "economy", "language": "en"}, "definition": {"string": "The system of activities and administration through which a society uses its resources to produce wealth.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2516", "thesaurus": "http://www.eionet.europa.eu/gemet/concept
 /"}, {"preferredLabel": {"string": "education", "language": "en"}, "definition": {"string": "The act or process of imparting or acquiring knowledge or skills.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2547", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "effect", "language": "en"}, "definition": {"string": "Effects include: a) direct effects, which are caused by the action and occur at the same time and place, b) indirect effects, which are caused by the action and are later in time or farther removed in distance, that are still reasonably foreseeable.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2562", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "energy", "language": "en"}, "definition": {"string": "The capacity to do work; involving thermal energy (heat), radiant energy (light), kinetic energy (motion) or chemical energy; measured in joul
 es.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2712", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environment", "language": "en"}, "definition": {"string": "A concept which includes all aspects of the surroundings of humanity, affecting individuals and social groupings. The European Union has defined the environment as \"the combination of elements whose complex interrelationships make up the settings, the surroundings and the conditions of life of the individual and of society, as they are or as they are felt\". The environment thus includes the built environment, the natural environment and all natural resources, including air, land and water. It also includes the surroundings of the workplace.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2944", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental assessment", "language": "en"}, "
 definition": {"string": "The evaluation or appraisal of ecological or natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2774", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental awareness", "language": "en"}, "definition": {"string": "The growth and development of awareness, understanding and consciousness toward the biophysical environment and its problems, including human interactions and effects. Thinking \"ecologically\" or in terms of an ecological consciousness.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2778", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental control", "language": "en"}, "definition": {"string": "Protection of the environment through policies concerning the control of wastes, the improvement of the human-made environment, the protection of heritage values, the institution of national p
 arks and reserves, the protection of fauna and flora, the conservation of forests and landscapes, etc.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2795", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental data", "language": "en"}, "definition": {"string": "Information concerning the state or condition of the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2803", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental economy issue", "language": "en"}, "definition": {"string": "A matter of public importance involving both a community's or a country's management of financial resources and its protection of natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2810", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental impact", "languag
 e": "en"}, "definition": {"string": "Any alteration of environmental conditions or creation of a new set of environmental conditions, adverse or beneficial, caused or induced by the action or set of actions under consideration.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2829", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental management", "language": "en"}, "definition": {"string": "Measures and controls which are directed at environmental conservation, the rational and sustainable allocation and utilization of natural resources, the optimization of interrelations between society and the environment, and the improvement of human welfare for present and future generations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2877", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental planning", "language": "en"}, "definition": {"stri
 ng": "The identification of desirable objectives for the physical environment, including social and economic objectives, and the creation of administrative procedures and programmes to meet those objectives.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2889", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental policy", "language": "en"}, "definition": {"string": "Official statements of principles, intentions, values, and objective which are based on legislation and the governing authority of a state and which serve as a guide for the operations of governmental and private activities in environmental affairs.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2892", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental problem solving", "language": "en"}, "definition": {"string": "The activity of finding solutions for troublesome or per
 plexing situations involving ecological or natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/13187", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental protection", "language": "en"}, "definition": {"string": "Measures and controls to prevent damage and degradation of the environment, including the sustainability of its living resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2900", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "equipment", "language": "en"}, "definition": {"string": "Any collection of materials, supplies or apparatuses stored, furnished or provided for an undertaking or activity.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2956", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "evaluation", "language": "en"}, "definition": {"strin
 g": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3011", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "experiment", "language": "en"}, "definition": {"string": "A test under controlled conditions that is made to demonstrate a known truth, examine the validity of a hypothesis, or determine the efficacy of something previously untried.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3050", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "finances", "language": "en"}, "definition": {"string": "The monetary resources or revenue of a government, company, organization or individual.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3194", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "firm", "language": "en"}, "definition": {"string": "A commercial partnership of two or
  more persons, especially when incorporated.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3232", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "fishery", "language": "en"}, "definition": {"string": "The industry of catching, processing and selling fish.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3237", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "forestry", "language": "en"}, "definition": {"string": "The management of forest lands for wood, forages, water, wildlife, and recreation.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3439", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "geological process", "language": "en"}, "definition": {"string": "Dynamic actions or events that occur at the Earth's surface due to application of natural forces resulting from gravity, temperatu
 re changes, freezing and thawing, chemical reactions, seismic shaking, and the agencies of wind and moving water, ice and snow. Where and when a force exceeds the strength of the earth material, the material is changed by deformation, translocation, or chemical reactions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3648", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "hazard", "language": "en"}, "definition": {"string": "A physical or chemical agent capable of causing harm to persons, property, animals, plants or other natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3852", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "health", "language": "en"}, "definition": {"string": "A state of dynamic equilibrium between an organism and its environment in which all functions of mind and body are normal.", "language": "en"}, "uri": "http://
 www.eionet.europa.eu/gemet/concept/3865", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "health-environment relationship", "language": "en"}, "definition": {"string": "Relationship between the quality of the environment and the health conditions of individuals.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3869", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "hydrosphere", "language": "en"}, "definition": {"string": "The waters of the Earth, as distinguished from the rocks (lithosphere), living things (biosphere), and the air (atmosphere). Includes the waters of the ocean; rivers, lakes, and other bodies of surface water in liquid form on the continents; snow, ice, and glaciers; and liquid water, ice, and water vapour in both the unsaturated and saturated zones below the land surface. Included by some, but excluded by others, is water in the atmosphere , which includes wa
 ter vapour, clouds, and all forms of precipitation while still in the atmosphere.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4124", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "impact source", "language": "en"}, "definition": {"string": "Elements of an action which cause damage to the surrounding environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4163", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "industrial process", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4257", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "industry", "language": "en"}, "definition": {"string": "An industry is a group of establishments engaged in the same or similar kinds of economic activities. Industries produce commoditi
 es that are sold with the expectation of recovering the total cost of production. A single industry can produce many different commodities.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4279", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "information", "language": "en"}, "definition": {"string": "All facts, ideas or imaginative works of the mind which have been communicated, published or distributed formally or informally in any format, or the knowledge that is  communicated or received.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4303", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "institutional structure", "language": "en"}, "definition": {"string": "An organization's complex system of mutually connected and dependent elements or parts, which make up a definite manner of arrangement.", "language": "en"}, "uri": "http://www.eionet.europa.eu/g
 emet/concept/13292", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "international relations", "language": "en"}, "definition": {"string": "The political or diplomatic interaction or dealings between independent nations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4438", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "justice", "language": "en"}, "definition": {"string": "The correct application of law as opposed to arbitrariness.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11583", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "labour", "language": "en"}, "definition": {"string": "One of the factors of production. It includes all the exertions - manual, physical or mental - by individuals, directed towards the production of wealth.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/
 4577", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "land", "language": "en"}, "definition": {"string": "A specified geographical tract of the Earth's surface including all its attributes, comprising its geology, superficial deposits, topography, hydrology, soils, flora and fauna, together with the results of past and present human activity, to the extent that these attributes exert a significant influence on the present and future land utilization.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4599", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "land setup", "language": "en"}, "definition": {"string": "The formulation of regional objectives, plans and programmes and the harmonization of the regional effects of sectorial planning.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4666", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"p
 referredLabel": {"string": "law (corpus of rules)", "language": "en"}, "definition": {"string": "A body of rules of action or conduct prescribed by controlling authority, and having binding legal force.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11499", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "law (individual)", "language": "en"}, "definition": {"string": "One of the rules making up the body of law.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4707", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "legal form of organisations", "language": "en"}, "definition": {"string": "The type, structure or purpose of an institution as arranged, required and defined by local or national laws to determine the appropriate governmental regulations, privileges and tax status applicable to that institution.", "language": "en"}, "uri": "http://www.eionet.eur
 opa.eu/gemet/concept/13161", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "legislation", "language": "en"}, "definition": {"string": "The act or process of making laws.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4749", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "lithosphere", "language": "en"}, "definition": {"string": "The solid portion of the Earth, as compared with the atmosphere and the hydrosphere.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4855", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "management", "language": "en"}, "definition": {"string": "Government, control, superintendence, physical or manual handling or guidance; act of managing by direction or regulation, or administration, as management of family, or of household, etc.", "language": "en"}, "uri": "http://www.eionet.europa.
 eu/gemet/concept/4985", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "material", "language": "en"}, "definition": {"string": "The substance of which a product is made or composed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5086", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "medicine (practice)", "language": "en"}, "definition": {"string": "The science and art of treating and healing.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5144", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "methodology", "language": "en"}, "definition": {"string": "The system of methods and principles used in a particular discipline.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5203", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "military activities", "l
 anguage": "en"}, "definition": {"string": "Actions and movements pertaining to or conducted by the armed forces.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5243", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "military aspects", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5241", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "monitoring", "language": "en"}, "definition": {"string": "To check regularly in order to perceive change in some quality or quantity.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5346", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "nutrition", "language": "en"}, "definition": {"string": "A process in animals and plants involving the intake of nutrient materials and their subsequent assimilation into the tissues.", "language": "en"}, "uri": "http://www.ei
 onet.europa.eu/gemet/concept/5765", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "organisation of the legal system", "language": "en"}, "definition": {"string": "The specific manner, form and institutions by which a government's ability to make, enforce and interpret laws are brought together into a coordinated whole.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/13146", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "overburden", "language": "en"}, "definition": {"string": "The material such as soil and rock lying above a mineral deposit that must be removed in order to work the deposit.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5956", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "parameter", "language": "en"}, "definition": {"string": "1) A quantity in an equation which must be specified beside th
 e independent variables to obtain the solution for the dependent variables. \n2) A quantity which is constant under a given set of conditions, but may be different under other conditions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6033", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pedosphere", "language": "en"}, "definition": {"string": "That shell or layer of the Earth in which soil-forming processes occur.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6094", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physical process", "language": "en"}, "definition": {"string": "A continuous action or series of changes which alters the material form of matter.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6228", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physical property", "lang
 uage": "en"}, "definition": {"string": "Property of a compound that can change without involving a change in chemical composition.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6229", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physicochemical process", "language": "en"}, "definition": {"string": "Processes involving changes in the physical properties and chemical structure of substances.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6233", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "planning", "language": "en"}, "definition": {"string": "The act of making a detailed scheme for attaining an objective.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6287", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "policy", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/conce
 pt/6370", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "politics", "language": "en"}, "definition": {"string": "The theory and practice of acquiring and exercising the power to govern in a society in order to arbitrate values, allocate resources and establish and enforce rules.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6371", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pollutant", "language": "en"}, "definition": {"string": "Any substance, usually a residue of human activity, which has an undesirable effect upon the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6395", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pollution", "language": "en"}, "definition": {"string": "The indirect or direct alteration of the biological, thermal, physical, or radioactive properties of any medium in 
 such a way as to create a hazard or potential hazard to human health or to the health, safety or welfare of any living species.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6445", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "product", "language": "en"}, "definition": {"string": "Something produced by human or mechanical effort or by a natural process.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6660", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "radiation", "language": "en"}, "definition": {"string": "Emission of any rays from either natural or man-made origins, such as radio waves, the sun's rays, medical X-rays and the fall-out and nuclear wastes produced by nuclear weapons and nuclear energy production. Radiation is usually divided between non-ionizing radiation, such as thermal radiation (heat) and light, and nuclear radiation. Non-ioni
 zing radiation includes ultraviolet radiation from the sun which, although it can damage cells and tissues, does not involve the ionization events of nuclear radiation.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6884", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "recreation", "language": "en"}, "definition": {"string": "Activities that promote refreshment of health or spirits by relaxation and enjoyment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7001", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "research", "language": "en"}, "definition": {"string": "Scientific investigation aimed at discovering and applying new facts, techniques and natural laws.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7127", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "resource", "language":
  "en"}, "definition": {"string": "Any component of the environment that can be utilized by an organism.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7168", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "resource utilisation", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8879", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "risk", "language": "en"}, "definition": {"string": "The expected number of lives lost, persons injured, damage to property and disruption of economic activity due to a particular natural phenomenon, and consequently the product of the probability of occurrence and the expected magnitude of damage.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7233", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string"
 : "safety", "language": "en"}, "definition": {"string": "The state of being secure from harm, injury, danger or risk, often as a result of planned measures or preparations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7362", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "science", "language": "en"}, "definition": {"string": "The study of the physical universe and its contents by means of reproducible observations, measurements, and experiments to establish, verify, or modify general laws to explain its nature and behaviour.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7472", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "services", "language": "en"}, "definition": {"string": "The carrying out of work for which there is a constant public demand by the provision of labor and the utilization of tools.", "language": "en"}, "uri": "http://www.eionet.
 europa.eu/gemet/concept/7621", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "society", "language": "en"}, "definition": {"string": "Human group of people, more or less large and complex, associated for some common interest and characterized by distinctive hierarchical relationships.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7823", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "space (interplanetary)", "language": "en"}, "definition": {"string": "Space extending between the sun and the planets of the solar system. Interplanetary space is not empty, but contains dust, particles with an electric charge, and the magnetic field of the sun (also called the IMF, or Interplanetary Magnetic Field).", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7962", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "state of ma
 tter", "language": "en"}, "definition": {"string": "One of the three fundamental conditions of matter: the solid, the liquid, and gaseous states.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8072", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "statistics", "language": "en"}, "definition": {"string": "A branch of mathematics dealing with the collection, analysis, interpretation, and presentation of masses of numerical data.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8076", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "subject", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/14848", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "technical regulation", "language": "en"}, "definition": {"string": "A government or
  management prescribed rule that provides detailed or stringent requirements, either directly or by referring to or incorporating the content of a standard, technical specification or code of practice.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11433", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "technology", "language": "en"}, "definition": {"string": "Systematic knowledge of and its application to industrial processes; closely related to engineering and science.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8339", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "tourism", "language": "en"}, "definition": {"string": "The temporary movement of people to destinations outside their normal places or work and residence, the activities undertaken during their stay in those destinations and the facilities created to cater for their needs.", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8522", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "trade (services)", "language": "en"}, "definition": {"string": "The act or process of buying, selling or exchanging goods and services at either wholesale or retail, within a country or between countries.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8563", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "trade activity", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11089", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "traffic", "language": "en"}, "definition": {"string": "1) The movement of vehicles, ships, aircraft, persons, etc., in an area or over a route.\n2) The vehicles, persons, etc., moving in an area or over a route.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/conce
 pt/8582", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "transportation", "language": "en"}, "definition": {"string": "The act or means of moving tangible objects (persons or goods) from place to place. Often involves the use of some type of vehicle.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8641", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "transportation mean", "language": "en"}, "definition": {"string": "Vehicles used for transferring people or goods from one place to another.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5116", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "vibration", "language": "en"}, "definition": {"string": "A periodic motion of small amplitude and high frequency, characteristic of elastic bodies.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8959
 ", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "waste", "language": "en"}, "definition": {"string": "Material, often unusable, left over from any manufacturing, industrial, agricultural or other human process; Material damaged or altered during a manufacturing process and subsequently left useless.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/9041", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}]

Copied: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts.txt (from rev 65870, grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts)
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts.txt	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts.txt	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1 @@
+keywords=[{"preferredLabel": {"string": "accident", "language": "en"}, "definition": {"string": "An unexpected occurrence, failure or loss with the potential for harming human life, property or the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/25", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "administration", "language": "en"}, "definition": {"string": "The management or direction of the affairs of a public or private office, business or organization.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/95", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "agriculture", "language": "en"}, "definition": {"string": "The production of plants and animals useful to man, involving soil cultivation and the breeding and management of crops and livestock.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/232", "thesaurus": "http:
 //www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "analysis", "language": "en"}, "definition": {"string": "Examination or determination.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/397", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "animal husbandry", "language": "en"}, "definition": {"string": "A branch of agriculture concerned with the breeding and feeding of domestic animals.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/429", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "atmosphere", "language": "en"}, "definition": {"string": "The gaseous envelope surrounding the Earth in a several kilometers-thick layer.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/617", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "biochemical process", "language": "en"}, "defini
 tion": {"string": "Chemical processes occurring in living organisms.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/812", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "biosphere", "language": "en"}, "definition": {"string": "That part of the Earth and atmosphere capable of supporting living organisms.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/892", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "border", "language": "en"}, "definition": {"string": "The dividing line or frontier between political or geographic regions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/963", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "built environment", "language": "en"}, "definition": {"string": "That part of the physical surroundings which are people-made or people-organized, such as buildings
  and other major structures, roads, bridges and the like, down to lesser objects such as traffic lights, telephone and pillar boxes.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1063", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "business", "language": "en"}, "definition": {"string": "The activity, position or site associated with commerce or the earning of a livelihood.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1084", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical", "language": "en"}, "definition": {"string": "Any substance used in or resulting from a reaction involving changes to atoms or molecules.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1327", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical element", "language": "en"}, "definition": {"string": "A
  substance made up of atoms with the same atomic number; common examples are hydrogen, gold, and iron.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2643", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical process", "language": "en"}, "definition": {"string": "The particular method of manufacturing or making a chemical usually involving a number of steps or operations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1320", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "chemical property", "language": "en"}, "definition": {"string": "Properties of a substance depending on the arrangement of the atoms in the molecule, e.g. bio-availability, degradability, persistence, etc.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1322", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "climat
 e", "language": "en"}, "definition": {"string": "The average weather condition in a region of the world. Many aspects of the Earth's geography affect the climate. Equatorial, or low, latitudes are hotter than the polar latitudes because of the angle at which the rays of sunlight arrive at the Earth's surface. The difference in temperature at the equator and at the poles has an influence on the global circulation of huge masses of air. Cool air at the poles sinks and spreads along the surface of the Earth towards the equator. Cool air forces its way under the lower density warmer air in the lower regions, pushing the lighter air up and toward the poles, where it will cool and descend.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1462", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "craft", "language": "en"}, "definition": {"string": "An occupation or trade requiring manual dexterity or skilled artistry.", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1850", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "culture (society)", "language": "en"}, "definition": {"string": "The body of customary beliefs, social forms, and material traits constituting a distinct complex of tradition of a racial or social group.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/1921", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "demography", "language": "en"}, "definition": {"string": "The statistical study of human vital statistics and population dynamics.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2060", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "disaster", "language": "en"}, "definition": {"string": "The result of a vast ecological breakdown in the relations between man and his environment, a serious and sudd
 en event (or slow, as in drought) on such a scale that the stricken community needs extraordinary efforts to cope with it, often with outside help or international aid.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2215", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "disease", "language": "en"}, "definition": {"string": "A definite pathological process having a characteristic set of signs and symptoms which are detrimental to the well-being of the individual.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2232", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "economy", "language": "en"}, "definition": {"string": "The system of activities and administration through which a society uses its resources to produce wealth.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2516", "thesaurus": "http://www.eionet.europa.eu/gemet/concept
 /"}, {"preferredLabel": {"string": "education", "language": "en"}, "definition": {"string": "The act or process of imparting or acquiring knowledge or skills.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2547", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "effect", "language": "en"}, "definition": {"string": "Effects include: a) direct effects, which are caused by the action and occur at the same time and place, b) indirect effects, which are caused by the action and are later in time or farther removed in distance, that are still reasonably foreseeable.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2562", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "energy", "language": "en"}, "definition": {"string": "The capacity to do work; involving thermal energy (heat), radiant energy (light), kinetic energy (motion) or chemical energy; measured in joul
 es.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2712", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environment", "language": "en"}, "definition": {"string": "A concept which includes all aspects of the surroundings of humanity, affecting individuals and social groupings. The European Union has defined the environment as \"the combination of elements whose complex interrelationships make up the settings, the surroundings and the conditions of life of the individual and of society, as they are or as they are felt\". The environment thus includes the built environment, the natural environment and all natural resources, including air, land and water. It also includes the surroundings of the workplace.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2944", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental assessment", "language": "en"}, "
 definition": {"string": "The evaluation or appraisal of ecological or natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2774", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental awareness", "language": "en"}, "definition": {"string": "The growth and development of awareness, understanding and consciousness toward the biophysical environment and its problems, including human interactions and effects. Thinking \"ecologically\" or in terms of an ecological consciousness.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2778", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental control", "language": "en"}, "definition": {"string": "Protection of the environment through policies concerning the control of wastes, the improvement of the human-made environment, the protection of heritage values, the institution of national p
 arks and reserves, the protection of fauna and flora, the conservation of forests and landscapes, etc.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2795", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental data", "language": "en"}, "definition": {"string": "Information concerning the state or condition of the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2803", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental economy issue", "language": "en"}, "definition": {"string": "A matter of public importance involving both a community's or a country's management of financial resources and its protection of natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2810", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental impact", "languag
 e": "en"}, "definition": {"string": "Any alteration of environmental conditions or creation of a new set of environmental conditions, adverse or beneficial, caused or induced by the action or set of actions under consideration.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2829", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental management", "language": "en"}, "definition": {"string": "Measures and controls which are directed at environmental conservation, the rational and sustainable allocation and utilization of natural resources, the optimization of interrelations between society and the environment, and the improvement of human welfare for present and future generations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2877", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental planning", "language": "en"}, "definition": {"stri
 ng": "The identification of desirable objectives for the physical environment, including social and economic objectives, and the creation of administrative procedures and programmes to meet those objectives.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2889", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental policy", "language": "en"}, "definition": {"string": "Official statements of principles, intentions, values, and objective which are based on legislation and the governing authority of a state and which serve as a guide for the operations of governmental and private activities in environmental affairs.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2892", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental problem solving", "language": "en"}, "definition": {"string": "The activity of finding solutions for troublesome or per
 plexing situations involving ecological or natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/13187", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "environmental protection", "language": "en"}, "definition": {"string": "Measures and controls to prevent damage and degradation of the environment, including the sustainability of its living resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2900", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "equipment", "language": "en"}, "definition": {"string": "Any collection of materials, supplies or apparatuses stored, furnished or provided for an undertaking or activity.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/2956", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "evaluation", "language": "en"}, "definition": {"strin
 g": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3011", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "experiment", "language": "en"}, "definition": {"string": "A test under controlled conditions that is made to demonstrate a known truth, examine the validity of a hypothesis, or determine the efficacy of something previously untried.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3050", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "finances", "language": "en"}, "definition": {"string": "The monetary resources or revenue of a government, company, organization or individual.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3194", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "firm", "language": "en"}, "definition": {"string": "A commercial partnership of two or
  more persons, especially when incorporated.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3232", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "fishery", "language": "en"}, "definition": {"string": "The industry of catching, processing and selling fish.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3237", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "forestry", "language": "en"}, "definition": {"string": "The management of forest lands for wood, forages, water, wildlife, and recreation.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3439", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "geological process", "language": "en"}, "definition": {"string": "Dynamic actions or events that occur at the Earth's surface due to application of natural forces resulting from gravity, temperatu
 re changes, freezing and thawing, chemical reactions, seismic shaking, and the agencies of wind and moving water, ice and snow. Where and when a force exceeds the strength of the earth material, the material is changed by deformation, translocation, or chemical reactions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3648", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "hazard", "language": "en"}, "definition": {"string": "A physical or chemical agent capable of causing harm to persons, property, animals, plants or other natural resources.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3852", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "health", "language": "en"}, "definition": {"string": "A state of dynamic equilibrium between an organism and its environment in which all functions of mind and body are normal.", "language": "en"}, "uri": "http://
 www.eionet.europa.eu/gemet/concept/3865", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "health-environment relationship", "language": "en"}, "definition": {"string": "Relationship between the quality of the environment and the health conditions of individuals.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/3869", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "hydrosphere", "language": "en"}, "definition": {"string": "The waters of the Earth, as distinguished from the rocks (lithosphere), living things (biosphere), and the air (atmosphere). Includes the waters of the ocean; rivers, lakes, and other bodies of surface water in liquid form on the continents; snow, ice, and glaciers; and liquid water, ice, and water vapour in both the unsaturated and saturated zones below the land surface. Included by some, but excluded by others, is water in the atmosphere , which includes wa
 ter vapour, clouds, and all forms of precipitation while still in the atmosphere.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4124", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "impact source", "language": "en"}, "definition": {"string": "Elements of an action which cause damage to the surrounding environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4163", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "industrial process", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4257", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "industry", "language": "en"}, "definition": {"string": "An industry is a group of establishments engaged in the same or similar kinds of economic activities. Industries produce commoditi
 es that are sold with the expectation of recovering the total cost of production. A single industry can produce many different commodities.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4279", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "information", "language": "en"}, "definition": {"string": "All facts, ideas or imaginative works of the mind which have been communicated, published or distributed formally or informally in any format, or the knowledge that is  communicated or received.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4303", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "institutional structure", "language": "en"}, "definition": {"string": "An organization's complex system of mutually connected and dependent elements or parts, which make up a definite manner of arrangement.", "language": "en"}, "uri": "http://www.eionet.europa.eu/g
 emet/concept/13292", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "international relations", "language": "en"}, "definition": {"string": "The political or diplomatic interaction or dealings between independent nations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4438", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "justice", "language": "en"}, "definition": {"string": "The correct application of law as opposed to arbitrariness.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11583", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "labour", "language": "en"}, "definition": {"string": "One of the factors of production. It includes all the exertions - manual, physical or mental - by individuals, directed towards the production of wealth.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/
 4577", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "land", "language": "en"}, "definition": {"string": "A specified geographical tract of the Earth's surface including all its attributes, comprising its geology, superficial deposits, topography, hydrology, soils, flora and fauna, together with the results of past and present human activity, to the extent that these attributes exert a significant influence on the present and future land utilization.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4599", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "land setup", "language": "en"}, "definition": {"string": "The formulation of regional objectives, plans and programmes and the harmonization of the regional effects of sectorial planning.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4666", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"p
 referredLabel": {"string": "law (corpus of rules)", "language": "en"}, "definition": {"string": "A body of rules of action or conduct prescribed by controlling authority, and having binding legal force.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11499", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "law (individual)", "language": "en"}, "definition": {"string": "One of the rules making up the body of law.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4707", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "legal form of organisations", "language": "en"}, "definition": {"string": "The type, structure or purpose of an institution as arranged, required and defined by local or national laws to determine the appropriate governmental regulations, privileges and tax status applicable to that institution.", "language": "en"}, "uri": "http://www.eionet.eur
 opa.eu/gemet/concept/13161", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "legislation", "language": "en"}, "definition": {"string": "The act or process of making laws.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4749", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "lithosphere", "language": "en"}, "definition": {"string": "The solid portion of the Earth, as compared with the atmosphere and the hydrosphere.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/4855", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "management", "language": "en"}, "definition": {"string": "Government, control, superintendence, physical or manual handling or guidance; act of managing by direction or regulation, or administration, as management of family, or of household, etc.", "language": "en"}, "uri": "http://www.eionet.europa.
 eu/gemet/concept/4985", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "material", "language": "en"}, "definition": {"string": "The substance of which a product is made or composed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5086", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "medicine (practice)", "language": "en"}, "definition": {"string": "The science and art of treating and healing.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5144", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "methodology", "language": "en"}, "definition": {"string": "The system of methods and principles used in a particular discipline.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5203", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "military activities", "l
 anguage": "en"}, "definition": {"string": "Actions and movements pertaining to or conducted by the armed forces.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5243", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "military aspects", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5241", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "monitoring", "language": "en"}, "definition": {"string": "To check regularly in order to perceive change in some quality or quantity.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5346", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "nutrition", "language": "en"}, "definition": {"string": "A process in animals and plants involving the intake of nutrient materials and their subsequent assimilation into the tissues.", "language": "en"}, "uri": "http://www.ei
 onet.europa.eu/gemet/concept/5765", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "organisation of the legal system", "language": "en"}, "definition": {"string": "The specific manner, form and institutions by which a government's ability to make, enforce and interpret laws are brought together into a coordinated whole.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/13146", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "overburden", "language": "en"}, "definition": {"string": "The material such as soil and rock lying above a mineral deposit that must be removed in order to work the deposit.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5956", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "parameter", "language": "en"}, "definition": {"string": "1) A quantity in an equation which must be specified beside th
 e independent variables to obtain the solution for the dependent variables. \n2) A quantity which is constant under a given set of conditions, but may be different under other conditions.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6033", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pedosphere", "language": "en"}, "definition": {"string": "That shell or layer of the Earth in which soil-forming processes occur.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6094", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physical process", "language": "en"}, "definition": {"string": "A continuous action or series of changes which alters the material form of matter.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6228", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physical property", "lang
 uage": "en"}, "definition": {"string": "Property of a compound that can change without involving a change in chemical composition.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6229", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "physicochemical process", "language": "en"}, "definition": {"string": "Processes involving changes in the physical properties and chemical structure of substances.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6233", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "planning", "language": "en"}, "definition": {"string": "The act of making a detailed scheme for attaining an objective.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6287", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "policy", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/conce
 pt/6370", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "politics", "language": "en"}, "definition": {"string": "The theory and practice of acquiring and exercising the power to govern in a society in order to arbitrate values, allocate resources and establish and enforce rules.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6371", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pollutant", "language": "en"}, "definition": {"string": "Any substance, usually a residue of human activity, which has an undesirable effect upon the environment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6395", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "pollution", "language": "en"}, "definition": {"string": "The indirect or direct alteration of the biological, thermal, physical, or radioactive properties of any medium in 
 such a way as to create a hazard or potential hazard to human health or to the health, safety or welfare of any living species.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6445", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "product", "language": "en"}, "definition": {"string": "Something produced by human or mechanical effort or by a natural process.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6660", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "radiation", "language": "en"}, "definition": {"string": "Emission of any rays from either natural or man-made origins, such as radio waves, the sun's rays, medical X-rays and the fall-out and nuclear wastes produced by nuclear weapons and nuclear energy production. Radiation is usually divided between non-ionizing radiation, such as thermal radiation (heat) and light, and nuclear radiation. Non-ioni
 zing radiation includes ultraviolet radiation from the sun which, although it can damage cells and tissues, does not involve the ionization events of nuclear radiation.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/6884", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "recreation", "language": "en"}, "definition": {"string": "Activities that promote refreshment of health or spirits by relaxation and enjoyment.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7001", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "research", "language": "en"}, "definition": {"string": "Scientific investigation aimed at discovering and applying new facts, techniques and natural laws.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7127", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "resource", "language":
  "en"}, "definition": {"string": "Any component of the environment that can be utilized by an organism.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7168", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "resource utilisation", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8879", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "risk", "language": "en"}, "definition": {"string": "The expected number of lives lost, persons injured, damage to property and disruption of economic activity due to a particular natural phenomenon, and consequently the product of the probability of occurrence and the expected magnitude of damage.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7233", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string"
 : "safety", "language": "en"}, "definition": {"string": "The state of being secure from harm, injury, danger or risk, often as a result of planned measures or preparations.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7362", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "science", "language": "en"}, "definition": {"string": "The study of the physical universe and its contents by means of reproducible observations, measurements, and experiments to establish, verify, or modify general laws to explain its nature and behaviour.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7472", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "services", "language": "en"}, "definition": {"string": "The carrying out of work for which there is a constant public demand by the provision of labor and the utilization of tools.", "language": "en"}, "uri": "http://www.eionet.
 europa.eu/gemet/concept/7621", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "society", "language": "en"}, "definition": {"string": "Human group of people, more or less large and complex, associated for some common interest and characterized by distinctive hierarchical relationships.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7823", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "space (interplanetary)", "language": "en"}, "definition": {"string": "Space extending between the sun and the planets of the solar system. Interplanetary space is not empty, but contains dust, particles with an electric charge, and the magnetic field of the sun (also called the IMF, or Interplanetary Magnetic Field).", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/7962", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "state of ma
 tter", "language": "en"}, "definition": {"string": "One of the three fundamental conditions of matter: the solid, the liquid, and gaseous states.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8072", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "statistics", "language": "en"}, "definition": {"string": "A branch of mathematics dealing with the collection, analysis, interpretation, and presentation of masses of numerical data.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8076", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "subject", "language": "en"}, "definition": {"string": "No definition needed.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/14848", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "technical regulation", "language": "en"}, "definition": {"string": "A government or
  management prescribed rule that provides detailed or stringent requirements, either directly or by referring to or incorporating the content of a standard, technical specification or code of practice.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11433", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "technology", "language": "en"}, "definition": {"string": "Systematic knowledge of and its application to industrial processes; closely related to engineering and science.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8339", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "tourism", "language": "en"}, "definition": {"string": "The temporary movement of people to destinations outside their normal places or work and residence, the activities undertaken during their stay in those destinations and the facilities created to cater for their needs.", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8522", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "trade (services)", "language": "en"}, "definition": {"string": "The act or process of buying, selling or exchanging goods and services at either wholesale or retail, within a country or between countries.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8563", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "trade activity", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/11089", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "traffic", "language": "en"}, "definition": {"string": "1) The movement of vehicles, ships, aircraft, persons, etc., in an area or over a route.\n2) The vehicles, persons, etc., moving in an area or over a route.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/conce
 pt/8582", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "transportation", "language": "en"}, "definition": {"string": "The act or means of moving tangible objects (persons or goods) from place to place. Often involves the use of some type of vehicle.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8641", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "transportation mean", "language": "en"}, "definition": {"string": "Vehicles used for transferring people or goods from one place to another.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/5116", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "vibration", "language": "en"}, "definition": {"string": "A periodic motion of small amplitude and high frequency, characteristic of elastic bodies.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/8959
 ", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}, {"preferredLabel": {"string": "waste", "language": "en"}, "definition": {"string": "Material, often unusable, left over from any manufacturing, industrial, agricultural or other human process; Material damaged or altered during a manufacturing process and subsequently left useless.", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/concept/9041", "thesaurus": "http://www.eionet.europa.eu/gemet/concept/"}]


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordConcepts.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1 +0,0 @@
-keywords=[{"preferredLabel": {"string": "ADMINISTRATION, MANAGEMENT, POLICY, POLITICS, INSTITUTIONS, PLANNING", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/96", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "AGRICULTURE, FORESTRY; ANIMAL HUSBANDRY; FISHERY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/234", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ANTHROPOSPHERE (built environment, human settlements, land setup)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1062", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ATMOSPHERE (air, climate)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/618", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "BIOSPHERE (organisms, ecosystems)", "language": "en"}, "uri": "http://www.eionet.europa.eu
 /gemet/group/893", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "CHEMISTRY, SUBSTANCES, PROCESSES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1349", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ECONOMICS, FINANCE", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/2504", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "EFFECTS, IMPACTS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10114", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENERGY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/2711", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENVIRONMENT (natural environment, anthropic environment)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10111", "thesaurus": "http
 ://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENVIRONMENTAL POLICY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/13109", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "FUNCTIONAL TERMS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/14980", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "GENERAL TERMS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10117", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "HEALTH, NUTRITION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/3875", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "HYDROSPHERE (freshwater, marine water, waters)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4125", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredL
 abel": {"string": "INDUSTRY, CRAFTS; TECHNOLOGY; EQUIPMENTS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4281", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "INFORMATION, EDUCATION, CULTURE, ENVIRONMENTAL AWARENESS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1922", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LAND (landscape, geography)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4630", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LEGISLATION, NORMS, CONVENTIONS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4750", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LITHOSPHERE (soil, geological processes)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4856", "thesaurus": "http://www.eionet.europa.eu/g
 emet/group/"}, {"preferredLabel": {"string": "PHYSICAL ASPECTS, NOISE, VIBRATIONS, RADIATIONS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/6237", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "PRODUCTS, MATERIALS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10112", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RECREATION, TOURISM", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7007", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RESEARCH, SCIENCES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7136", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RESOURCES (utilisation of resources)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10118", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferred
 Label": {"string": "RISKS, SAFETY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7243", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "SOCIETY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7779", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "SPACE", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7956", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TIME (chronology)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/14979", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TRADE, SERVICES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/8575", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TRAFFIC, TRANSPORTATION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/gr
 oup/8603", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "WASTES, POLLUTANTS, POLLUTION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/9117", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}]

Copied: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups.txt (from rev 65870, grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups)
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups.txt	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups.txt	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1 @@
+keywords=[{"preferredLabel": {"string": "ADMINISTRATION, MANAGEMENT, POLICY, POLITICS, INSTITUTIONS, PLANNING", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/96", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "AGRICULTURE, FORESTRY; ANIMAL HUSBANDRY; FISHERY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/234", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ANTHROPOSPHERE (built environment, human settlements, land setup)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1062", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ATMOSPHERE (air, climate)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/618", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "BIOSPHERE (organisms, ecosystems)", "language": "en"}, "uri": "http://www.eionet.europa.eu
 /gemet/group/893", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "CHEMISTRY, SUBSTANCES, PROCESSES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1349", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ECONOMICS, FINANCE", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/2504", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "EFFECTS, IMPACTS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10114", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENERGY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/2711", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENVIRONMENT (natural environment, anthropic environment)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10111", "thesaurus": "http
 ://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "ENVIRONMENTAL POLICY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/13109", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "FUNCTIONAL TERMS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/14980", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "GENERAL TERMS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10117", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "HEALTH, NUTRITION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/3875", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "HYDROSPHERE (freshwater, marine water, waters)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4125", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredL
 abel": {"string": "INDUSTRY, CRAFTS; TECHNOLOGY; EQUIPMENTS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4281", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "INFORMATION, EDUCATION, CULTURE, ENVIRONMENTAL AWARENESS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/1922", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LAND (landscape, geography)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4630", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LEGISLATION, NORMS, CONVENTIONS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4750", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "LITHOSPHERE (soil, geological processes)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/4856", "thesaurus": "http://www.eionet.europa.eu/g
 emet/group/"}, {"preferredLabel": {"string": "PHYSICAL ASPECTS, NOISE, VIBRATIONS, RADIATIONS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/6237", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "PRODUCTS, MATERIALS", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10112", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RECREATION, TOURISM", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7007", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RESEARCH, SCIENCES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7136", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "RESOURCES (utilisation of resources)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/10118", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferred
 Label": {"string": "RISKS, SAFETY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7243", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "SOCIETY", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7779", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "SPACE", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/7956", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TIME (chronology)", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/14979", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TRADE, SERVICES", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/8575", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "TRAFFIC, TRANSPORTATION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/gr
 oup/8603", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}, {"preferredLabel": {"string": "WASTES, POLLUTANTS, POLLUTION", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/group/9117", "thesaurus": "http://www.eionet.europa.eu/gemet/group/"}]


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordGroups.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1 +0,0 @@
-keywords=[{"preferredLabel": {"string": "administration", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/1", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "agriculture", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/2", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "air", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/3", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "animal husbandry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/18", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "biology", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/4", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "building", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/5", "thesau
 rus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "chemistry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/6", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "climate", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/7", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "disasters, accidents, risk", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/32", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "economics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/9", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "energy", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/10", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "environmental policy", "language": "en"},
  "uri": "http://www.eionet.europa.eu/gemet/theme/11", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "fishery", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/12", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "food, drinking water", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/13", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "forestry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/14", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "general", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/15", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "geography", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/16", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLab
 el": {"string": "human health", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/17", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "industry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/19", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "information", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/20", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "legislation", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/21", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "materials", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/27", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "military aspects", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/22", "thesaurus": "http
 ://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "natural areas, landscape, ecosystems", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/23", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "natural dynamics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/8", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "noise, vibrations", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/24", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "physics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/25", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "pollution", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/26", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "radiations", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/28", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "research", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/30", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "resources", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/31", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "social aspects, population", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/34", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "soil", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/35", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "space", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/36", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"pr
 eferredLabel": {"string": "tourism", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/29", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "trade, services", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/33", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "transport", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/37", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "urban environment, urban stress", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/38", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "waste", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/39", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "water", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/40", "th
 esaurus": "http://www.eionet.europa.eu/gemet/theme/"}]

Copied: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes.txt (from rev 65870, grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes)
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes.txt	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes.txt	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1 @@
+keywords=[{"preferredLabel": {"string": "administration", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/1", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "agriculture", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/2", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "air", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/3", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "animal husbandry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/18", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "biology", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/4", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "building", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/5", "thesau
 rus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "chemistry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/6", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "climate", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/7", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "disasters, accidents, risk", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/32", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "economics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/9", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "energy", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/10", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "environmental policy", "language": "en"},
  "uri": "http://www.eionet.europa.eu/gemet/theme/11", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "fishery", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/12", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "food, drinking water", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/13", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "forestry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/14", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "general", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/15", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "geography", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/16", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLab
 el": {"string": "human health", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/17", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "industry", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/19", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "information", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/20", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "legislation", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/21", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "materials", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/27", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "military aspects", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/22", "thesaurus": "http
 ://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "natural areas, landscape, ecosystems", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/23", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "natural dynamics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/8", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "noise, vibrations", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/24", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "physics", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/25", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "pollution", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/26", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "radiations", "language
 ": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/28", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "research", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/30", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "resources", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/31", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "social aspects, population", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/34", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "soil", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/35", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "space", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/36", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"pr
 eferredLabel": {"string": "tourism", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/29", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "trade, services", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/33", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "transport", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/37", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "urban environment, urban stress", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/38", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "waste", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/39", "thesaurus": "http://www.eionet.europa.eu/gemet/theme/"}, {"preferredLabel": {"string": "water", "language": "en"}, "uri": "http://www.eionet.europa.eu/gemet/theme/40", "th
 esaurus": "http://www.eionet.europa.eu/gemet/theme/"}]


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/keywordThemes.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/record_metadata_dc.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/record_metadata_dc.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/record_metadata_dc.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html lang="{{ language }}">
+<head>
+    <meta charset="utf-8"/>
+    <title>{{ gettext('Record Metadata') }}</title>
+    <style type="text/css">
+        body, h3 {
+            background-color: #ffffff;
+            font-family: arial, verdana, sans-serif;
+            text-align: left;
+            float: left;
+        }
+
+        header {
+            display: inline-block;
+        }
+    </style>
+</head>
+<body>
+<header>
+    <h3>{{ gettext('Record Metadata') }} (<a href="{{ obj.xml_url }}">{{ gettext('View XML') }}</a>)</h3>
+</header>
+<section id="record-metadata">
+    <table>
+        <tr>
+            <td>{{ gettext('Identifier') }}</td>
+            <td>{{ obj.identifier }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Title') }}</td>
+            <td>{{ obj.title }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Abstract') }}</td>
+            <td>{{ obj.abstract }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Subjects') }}</td>
+            <td>{{ obj.subjects|join(',') }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Creator') }}</td>
+            <td>{{ obj.creator }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Contributor') }}</td>
+            <td>{{ obj.contributor}}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Publisher') }}</td>
+            <td>{{ obj.publisher}}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Contributor') }}</td>
+            <td>{{ obj.contributor}}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Modified') }}</td>
+            <td>{{ obj.modified }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Language') }}</td>
+            <td>{{ obj.language }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Format') }}</td>
+            <td>{{ obj.format }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Rights') }}</td>
+            <td>{{ obj.rights|join(',') }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Bounding Box') }}</td>
+            <td>{{ [obj.bbox.minx, obj.bbox.miny, obj.bbox.maxx, obj.bbox.maxy]|join(',') }}</td>
+        </tr>
+    </table>
+</section>
+<section id="links">
+    <h4>Links</h4>
+    <ul>
+        {% for link in obj.references %}
+        <li><a href="{{ link['url'] }}">{{ link['scheme'] if link['scheme'] not in [None, 'None', ''] else
+            gettext('Access Link') }}</a></li>
+        {% endfor %}
+        {% for link in obj.uris %}
+        <li><a href="{{ link['url'] }}">{{ link['protocol'] if link['protocol'] not in [None, 'None', ''] else
+            gettext('Access Link') }}</a></li>
+        {% endfor %}
+    </ul>
+</section>
+</body>
+</html>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/record_metadata_dc.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/service_metadata.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/service_metadata.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/service_metadata.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="{{ language }}">
+<head>
+    <meta charset="utf-8"/>
+    <title>{{ gettext('Service Metadata') }}</title>
+    <style type="text/css">
+        body, h3, h4 {
+            background-color: #ffffff;
+            font-family: arial, verdana, sans-serif;
+            text-align: left;
+            float: left;
+        }
+
+        header {
+            display: inline-block;
+        }
+    </style>
+</head>
+<body>
+<header>
+    <h3>{{ gettext('Service Metadata') }}</h3>
+</header>
+<section id="service-metadata">
+    <h4>{{ gettext('Service Identification') }}</h4>
+    <table>
+        <tr>
+            <td>{{ gettext('Title') }}</td>
+            <td>{{ obj.identification.title }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Abstract') }}</td>
+            <td>{{ obj.identification.abstract }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Keywords') }}</td>
+            <td>{{ obj.identification.keywords|join(',') }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Type') }}</td>
+            <td>{{ obj.identification.type }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Version') }}</td>
+            <td>{{ obj.identification.version }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Fees') }}</td>
+            <td>{{ obj.identification.fees }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Access Constraints') }}</td>
+            <td>{{ obj.identification.accessconstraints }}</td>
+        </tr>
+    </table>
+</section>
+<section id="service-provider">
+    <h4>{{ gettext('Service URL') }}</h4>
+
+    <p><a href="{{ obj.url }}">{{ obj.url}}</a></p>
+</section>
+<section id="service-provider">
+    <h4>{{ gettext('Service Provider') }}</h4>
+    <table>
+        <tr>
+            <td>{{ gettext('Name') }}</td>
+            <td>{{ obj.provider.name }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Site') }}</td>
+            <td><a href="{{ obj.provider.url }}">{{ obj.provider.url }}</a></td>
+        </tr>
+    </table>
+</section>
+<section id="service-contact">
+    <h4>{{ gettext('Service Contact') }}</h4>
+    <table>
+        <tr>
+            <td>{{ gettext('Name') }}</td>
+            <td>{{ obj.provider.contact.name }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Position') }}</td>
+            <td>{{ obj.provider.contact.position}}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Role') }}</td>
+            <td>{{ obj.provider.contact.role }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Address') }}</td>
+            <td>
+                {{ obj.provider.contact.address }}<br/>
+                {{ obj.provider.contact.city }}, {{ obj.provider.contact.region }}<br/>
+                {{ obj.provider.contact.postcode }}<br/>
+                {{ obj.provider.contact.country }}
+            </td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Email') }}</td>
+            <td><a href="mailto:{{ obj.provider.contact.email  }}">{{ obj.provider.contact.email }}</a></td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Phone') }}</td>
+            <td>{{ obj.provider.contact.phone }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Fax') }}</td>
+            <td>{{ obj.provider.contact.fax }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Url') }}</td>
+            <td><a href="{{ obj.provider.contact.url }}">{{ obj.provider.contact.url }}</a></td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Hours of Service') }}</td>
+            <td>{{ obj.provider.contact.hours }}</td>
+        </tr>
+        <tr>
+            <td>{{ gettext('Contact Instructions') }}</td>
+            <td>{{ obj.provider.contact.instructions }}</td>
+        </tr>
+    </table>
+</section>
+</body>
+</html>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/service_metadata.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_highlight.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_highlight.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_highlight.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <title>XML</title>
+    <style type="text/css">
+        {
+        {
+            css
+        }
+        }
+    </style>
+</head>
+<body>
+{{ body }}
+</body>
+</html>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_highlight.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_render.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_render.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_render.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <title>XML</title>
+
+</head>
+<body>
+{{ body }}
+</body>
+</html>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/config/xml_render.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = db.csw.admin
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,49 @@
+<h2>DESCRIPTION</h2>
+
+Module <em>db.csw.admin</em> allows to handle csw server.
+
+<h2>NOTES</h2>
+For dependencies and installation instructions see
+<a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+<h2>USAGE</h2>
+
+For using this module must be installed pycsw libraries. Default path to configure folder is setup to pycsw install
+folder(LINUX) /var/www/html/pycsw in another case, path to config file must by set by user.
+
+<h3>Configure file</h3>
+
+In configure file must be setup few parameters for proper work of pycsw library.
+<ul>
+<li>server.home<br>
+Path to folder with installed pycsw</li>
+<li>database.homez<br>
+Path to database with data of catalog. By default is set to SQLite database. E.g GRASS GIS sqlite database.</li>
+<li>server.url<br>
+For using local serever this parameter should by set to <a href="http://localhost:8000/">http://localhost:8000/</a></li>
+</ul>
+
+
+<div class="code"><pre>
+v.harvest.iso source=http://www.rndt.gov.it/RNDT/CSW destionantion=http://localhost:8000/
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="r.info.html">r.info</a>,
+  <a href="v.info.iso.html">v.info.iso</a>,
+  <a href="g.gui.metadata.html">g.gui.metadata</a>
+  <a href="g.gui.cswbrowser.html">g.gui.cswbrowser</a>
+  <a href="db.csw.harvest">db.csw.harvest</a>
+  <a href="db.csw.run">db.csw.run</a>
+</em>
+
+<p>
+See also related <a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+<h2>AUTHOR</h2>
+Matej Krejci, <a href="http://geo.fsv.cvut.cz/gwiki/osgeorel">OSGeoREL</a>
+at the Czech Technical University in Prague, developed
+during <a href="http://trac.osgeo.org/grass/wiki/GSoC/2014/MetadataForGRASS">Google
+Summer of Code 2015</a> (mentors: Martin Landa)


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,399 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+ at module  db.csw.admin
+ at brief   Module for creating metadata based on ISO for vector maps
+
+(C) 2015 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2015)
+used and modified original pycsw-admin.py from pycsw lib(
+https://github.com/geopython/pycsw/blob/master/bin/pycsw-admin.py)
+"""
+
+
+#%module
+#% description: CSW database manager
+#% keyword: csw
+#% keyword: metadata
+#%end
+
+#%option G_OPT_F_INPUT
+#% key: configure
+#% description: path to configure file (default.cfg)
+#% required : yes
+#% answer : /var/www/html/pycsw/default.cfg
+#%end
+
+#%option
+#% key: load_records
+#% label: Load metadata(folder)
+#% description: Loads metadata records from directory into repository
+#% guisection: Records
+#%end
+
+#%flag
+#% key: r
+#% label: Load records recursively
+#% description: Load records from directory recursively
+#% guisection: Records
+#%end
+
+#%flag
+#% key: s
+#% label: Setup database
+#% description: Creates repository tables and indexes
+#% guisection: Commands
+#%end
+
+#%option
+#% key: export_records
+#% label: Create db dump(folder)
+#% description: Dump metadata records from repository into directory
+#% guisection: Commands
+#%end
+
+#%flag
+#% key: i
+#% label: Database indexes
+#% description: Rebuild repository database indexes
+#% guisection: Commands
+#%end
+
+#%flag
+#% key: o
+#% label: Optimize db
+#% description: Optimize repository database
+#% guisection: Commands
+#%end
+
+#%flag
+#% key: h
+#% label: Refresh harvested records
+#% description: Optimize repository database
+#% guisection: Commands
+#%end
+
+#%option G_OPT_F_OUTPUT
+#% key: gen_sitemap
+#% label: Sitemap
+#% description: Generate XML Sitemap
+#% guisection: Commands
+#% required: NO
+#%end
+
+#%flag
+#% key: d
+#% label: Delete all records(!!)
+#% description: Delete all records without prompting
+#% guisection: Commands
+#%end
+
+#%flag
+#% key: f
+#% label: Force confirmation
+#% description: Force confirmation of task
+#% guisection: Commands
+#%end
+
+#%option
+#% key: url_csw
+#% label: Url of CSW
+#% description: Execute a CSW request via HTTP POST: URL of CSW
+#% guisection: Execute request
+#%end
+
+#%option G_OPT_F_INPUT
+#% key: file_xml
+#% label: XML file
+#% description: Execute a CSW request via HTTP POST: XML FILE
+#% guisection: Execute request
+#% required: NO
+#%end
+
+
+import sys
+import os
+import ConfigParser
+
+from grass.pygrass.modules import Module
+from grass.script import parse_key_val
+from grass.script import core as grass
+
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'mdlib'))
+from subprocess import PIPE
+import getopt
+from cswutil import *
+import shutil
+from pycsw.core import admin, config
+
+
+class CswAdmin():
+    def __init__(self):
+        self.COMMAND = None
+        self.XML_DIRPATH = None
+        self.CFG = None
+        self.RECURSIVE = False
+        self.OUTPUT_FILE = None
+        self.CSW_URL = None
+        self.XML = None
+        self.XSD = None
+        self.TIMEOUT = 30
+        self.FORCE_CONFIRM = False
+        self.METADATA = None
+        self.DATABASE = None
+        self.URL = None
+        self.HOME = None
+        self.TABLE = None
+        self.CONTEXT = config.StaticContext()
+
+
+    def argParser(self, defaultConf, load_records,
+                  loadRecurs, setupDB,
+                  exportRecord, indexes,
+                  optimize, harvest,
+                  siteOut, deleteAll,
+                  cswURL, cswXML, force):
+        if defaultConf is None:
+            grass.error('Configure file is not exist')
+        args = []
+        args.append('-c')
+
+        if load_records:
+            args.append('load_records')
+            args.append('-p')
+            args.append(load_records)
+            if loadRecurs:
+                args.append('-r')
+            if force:
+                args.append('y')
+            return args
+
+        if setupDB:
+            args.append('setup_db')
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if exportRecord:
+            args.append('export_records')
+            args.append('-p')
+            args.append(exportRecord)
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if indexes:
+            args.append('rebuild_db_indexes')
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if optimize:
+            args.append('optimize_db')
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if harvest:
+            args.append('refresh_harvested_records')
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if siteOut:
+            args.append('gen_sitemaps')
+            args.append('-o')
+            args.append(siteOut)
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        if deleteAll:
+            args.append('delete_records')
+            args.append('-f')
+            args.append(defaultConf)
+            if force:
+                args.append('y')
+            return args
+
+        if cswURL and cswXML:
+            args.append('post_xml')
+            args.append('-u')
+            args.append(cswURL)
+            args.append('-x')
+            args.append(cswXML)
+            args.append('-f')
+            args.append(defaultConf)
+            return args
+
+        return False
+
+
+    def run(self, argv):
+
+        if len(argv) == 0:
+            grass.error('Nothing to do. Set args')
+            return
+        print argv
+        try:
+            OPTS, ARGS = getopt.getopt(argv, 'c:f:ho:p:ru:x:s:t:y')
+        except getopt.GetoptError as err:
+            grass.error( '\nERROR: %s' % err)
+            #print usage()
+
+        for o, a in OPTS:
+            if o == '-c':
+                self.COMMAND = a
+            if o == '-f':
+                self.CFG = a
+            if o == '-o':
+                self.OUTPUT_FILE = a
+            if o == '-p':
+                self.XML_DIRPATH = a
+            if o == '-r':
+                self.RECURSIVE = True
+            if o == '-u':
+                self.CSW_URL = a
+            if o == '-x':
+                self.XML = a
+            if o == '-t':
+                self.TIMEOUT = int(a)
+            if o == '-y':
+                self.FORCE_CONFIRM = True
+
+        if self.CFG is None and self.COMMAND not in ['post_xml']:
+            print 'ERROR: -f <cfg> is a required argument'
+
+        if self.COMMAND not in ['post_xml']:
+            SCP = ConfigParser.SafeConfigParser()
+            SCP.readfp(open(self.CFG))
+
+            self.DATABASE = SCP.get('repository', 'database')
+            self.URL = SCP.get('server', 'url')
+            self.HOME = SCP.get('server', 'home')
+            self.METADATA = dict(SCP.items('metadata:main'))
+            try:
+                self.TABLE = SCP.get('repository', 'table')
+            except ConfigParser.NoOptionError:
+                self.TABLE = 'records'
+
+        if self.COMMAND == 'setup_db':
+            try:
+                admin.setup_db(self.DATABASE, self.TABLE, self.HOME)
+            except Exception as err:
+                print err
+                print 'ERROR: DB creation error.  Database tables already exist'
+                print 'Delete tables or database to reinitialize'
+
+        elif self.COMMAND == 'load_records':
+            admin.load_records(self.CONTEXT, self.DATABASE, self.TABLE, self.XML_DIRPATH, self.RECURSIVE,
+                               self.FORCE_CONFIRM)
+        elif self.COMMAND == 'export_records':
+            admin.export_records(self.CONTEXT, self.DATABASE, self.TABLE, self.XML_DIRPATH)
+        elif self.COMMAND == 'rebuild_db_indexes':
+            admin.rebuild_db_indexes(self.DATABASE, self.TABLE)
+        elif self.COMMAND == 'optimize_db':
+            admin.optimize_db(self.CONTEXT, self.DATABASE, self.TABLE)
+        elif self.COMMAND == 'refresh_harvested_records':
+            admin.refresh_harvested_records(self.CONTEXT, self.DATABASE, self.TABLE, self.URL)
+        elif self.COMMAND == 'gen_sitemap':
+            admin.gen_sitemap(self.CONTEXT, self.DATABASE, self.TABLE, self.URL, self.OUTPUT_FILE)
+        elif self.COMMAND == 'post_xml':
+            grass.message(admin.post_xml(self.CSW_URL, self.XML, self.TIMEOUT))
+
+        elif self.COMMAND == 'delete_records':
+            admin.delete_records(self.CONTEXT, self.DATABASE, self.TABLE)
+'''#TODO
+    def initDatabase(self):
+        driverDB = Module('db.connect',
+                          flags='pg',
+                          quiet=True,
+                          stdout_=PIPE)
+        self.database = parse_key_val(driverDB.outputs.stdout, sep=': ')
+        conf = 'default.cfg'
+        modif = os.path.join(os.getenv('GRASS_ADDON_BASE') ,'etc','config','default.cfg')
+        defaultConf = os.path.join(os.getenv('GRASS_ADDON_BASE') ,'etc','config','default-sample.cfg')
+        print self.database
+
+        SCP = ConfigParser.SafeConfigParser()
+        try:
+            SCP.readfp(open(conf))
+        except:
+            shutil.copy2(defaultConf, conf)
+            SCP.readfp(open(conf))
+
+        DATABASE = SCP.get('repository', 'database')
+        #URL = SCP.get('server', 'url')
+        HOME = SCP.get('server', 'home')
+
+
+        #currPython=os.path.dirname(os.path.realpath(__file__))
+        if not os.path.isdir(HOME):
+            grass.message('Cannot find server home folder < %s >' % HOME)
+            grass.error('Move pycsw(install foder) to <%s> or set server.home in <default.cfg >'%HOME)
+
+        if not os.access(defaultConf, os.W_OK):
+            try:
+                shutil.copy2(defaultConf, HOME)
+                grass.message('Configure file created in < %s/default.cfg >' % HOME)
+            except:
+                grass.error('Cannot duplicate <default-sample.cfg> to <default.cfg> ' )
+                return
+
+        if not os.access(defaultConf, os.W_OK):
+            grass.error('Cannot acces configure file < %s >' % defaultConf)
+            return
+
+        if self.database['driver'] == 'sqlite':
+            if not os.access(DATABASE, os.W_OK):
+                grass.error('Cannot acces databaase < %s >'%DATABASE)
+'''
+'''
+#%flag
+#% key: a
+#% label: Automatic configuration
+#% description: Set database according GRASS default and confugure server
+#% guisection: Auto Config
+#%end
+'''
+def main():
+    defaultConf = options['configure']
+    load_records = options['load_records']
+    loadRecurs = flags['r']
+    setupDB = flags['s']
+    exportRecord = options['export_records']
+    indexes = flags['i']
+    optimize = flags['o']
+    harvest = flags['h']
+    siteOut = options['gen_sitemap']
+    deleteAll = flags['d']
+    cswURL = options['url_csw']
+    cswXML = options['file_xml']
+    force = flags['f']
+
+    csw = CswAdmin()
+    #if flags['a']:
+        #csw.initDatabase()
+    args = csw.argParser(defaultConf,
+                         load_records,
+                         loadRecurs,
+                         setupDB,
+                         exportRecord,
+                         indexes,
+                         optimize,
+                         harvest,
+                         siteOut,
+                         deleteAll,
+                         cswURL,
+                         cswXML,
+                         force)
+    if args:
+        csw.run(args)
+
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    main()


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.admin/db.csw.admin.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = db.csw.harvest
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,37 @@
+<h2>DESCRIPTION</h2>
+
+Module <em>db.csw.harvest</em> allows to harvest metadata between two catalogs.
+
+<p>
+<h2>NOTES</h2>
+For dependencies and installation instructions see
+<a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+For importing metadata to local server transactions must be allowed. The parameter "transactions" is stored in configure file "default.cfq"(by default in pycsw installation foleder ).
+
+<h2>EXAMPLES</h2>
+<p>
+Harvesting of remote cataloge to local:
+
+<div class="code"><pre>
+db.csw.harvest source=http://www.rndt.gov.it/RNDT/CSW destionantion=http://localhost:8000/
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="r.info.html">r.info</a>,
+  <a href="v.info.iso.html">v.info.iso</a>,
+  <a href="g.gui.metadata.html">g.gui.metadata</a>
+  <a href="g.gui.cswbrowser.html">g.gui.cswbrowser</a>
+  <a href="db.csw.admin">db.csw.admin</a>
+  <a href="db.csw.run">db.csw.run</a>
+</em>
+
+<p>
+See also related <a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+<h2>AUTHOR</h2>
+Matej Krejci, <a href="http://geo.fsv.cvut.cz/gwiki/osgeorel">OSGeoREL</a>
+at the Czech Technical University in Prague, developed
+during <a href="http://trac.osgeo.org/grass/wiki/GSoC/2014/MetadataForGRASS">Google
+Summer of Code 2015</a> (mentors: Martin Landa)


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+# -*- coding: ISO-8859-15 -*-
+"""
+ at module  db.csw.harvest
+ at brief   Module for creating metadata based on ISO for vector maps
+
+(C) 2015 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at modified for GRASS GIS by Matej Krejci <matejkrejci gmail.com> (GSoC 2015)
+ at originaly crated by  "# Copyright (c) 2010 Tom Kralidis"
+
+
+
+# simple process to harvest CSW catalogues via Harvest operations
+
+
+"""
+
+#%module
+#% description: CSW database manager
+#% keyword: csw
+#% keyword: metadata
+#% keyword: harvesting
+#%end
+
+#%option
+#% key: source
+#% label: uri source
+#% description: uri to csw source
+#% required : yes
+#%end
+
+#%option
+#% key: destination
+#% label: uri destination
+#% description: uri to csw destination
+#% required : yes
+#%end
+
+#%option
+#% key: max
+#% label: max records
+#% description: uri to csw destination
+#% type: integer
+#%end
+
+import sys,os
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'mdlib'))
+from grass.script import core as grass
+from owslib.csw import CatalogueServiceWeb
+from owslib.ows import ExceptionReport
+#from __future__ import absolute_import
+#from __future__ import print_function
+
+
+def harvest(source,dst):
+    maxrecords=options['max']
+    if options['max']==0 or None:
+        maxrecords=10
+    stop = 0
+    flag = 0
+
+    src = CatalogueServiceWeb(source)
+    dest = CatalogueServiceWeb(dst)
+
+    while stop == 0:
+        if flag == 0:  # first run, start from 0
+            startposition = 0
+        else:  # subsequent run, startposition is now paged
+            startposition = src.results['nextrecord']
+
+        src.getrecords(esn='brief', startposition=startposition, maxrecords=maxrecords)
+
+        print(src.results)
+
+        if src.results['nextrecord'] == 0 \
+            or src.results['returned'] == 0 \
+            or src.results['nextrecord'] > src.results['matches']:  # end the loop, exhausted all records
+            stop = 1
+            break
+
+        # harvest each record to destination CSW
+        for i in list(src.records):
+            source = '%s?service=CSW&version=2.0.2&request=GetRecordById&id=%s' % \
+                (sys.argv[1], i)
+            dest.harvest(source=source, \
+                resourcetype='http://www.isotc211.org/2005/gmd')
+            #print dest.request
+            #print dest.response
+
+        flag = 1
+
+
+def _get_csw(catalog_url,timeout=10):
+    """function to init owslib.csw.CatalogueServiceWeb"""
+    # connect to the server
+    try:
+        catalog = CatalogueServiceWeb(catalog_url,timeout=timeout)
+        return catalog
+    except ExceptionReport, err:
+        msg = 'Error connecting to service: %s' % err
+    except ValueError, err:
+        msg = 'Value Error: %s' % err
+    except Exception, err:
+        msg = 'Unknown Error: %s' % err
+    grass.error( 'CSW Connection error: %s' % msg)
+
+    return False
+
+def main():
+
+    if not _get_csw(options['source']):
+        return
+
+    harvest(options['source'],options['destination'])
+
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    main()


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.harvest/db.csw.harvest.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = db.csw.run
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,32 @@
+<h2>DESCRIPTION</h2>
+
+...
+
+<h2>NOTES</h2>
+...
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="r.info.html">r.info</a>,
+  <a href="v.info.iso.html">v.info.iso</a>,
+  <a href="g.gui.metadata.html">g.gui.metadata</a>
+  <a href="db.csw.harvest">db.csw.harvest</a>
+  <a href="db.csw.admin">db.csw.admin</a>
+  <a href="db.csw.run">db.csw.run</a>
+</em>
+
+<p>
+See also related <a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+
+<h2>AUTHOR</h2>
+
+Matej
+Krejci, <a href="http://geo.fsv.cvut.cz/gwiki/osgeorel">OSGeoREL</a>
+at the Czech Technical University in Prague, developed
+during <a href="http://trac.osgeo.org/grass/wiki/GSoC/2014/MetadataForGRASS">Google
+Summer of Code 2014</a> (mentors: Margherita Di Leo, Martin Landa)
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+# =================================================================
+#
+# Authors: Adam Hinz <hinz.adam at gmail.com>
+#
+# Copyright (c) 2015 Adam Hinz
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+# WSGI wrapper for pycsw
+#
+# Apache mod_wsgi configuration
+#
+# ServerName host1
+# WSGIDaemonProcess host1 home=/var/www/pycsw processes=2
+# WSGIProcessGroup host1
+#
+# WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/csw.wsgi
+#
+# <Directory /var/www/pycsw>
+#  Order deny,allow
+#  Allow from all
+# </Directory>
+#
+# or invoke this script from the command line:
+#
+# $ python ./csw.wsgi
+#
+# which will publish pycsw to:
+#
+# http://localhost:8000/
+#
+
+#%module
+#% description: Csw wsgi handler
+#% keyword: csw
+#% keyword: metadata
+#%end
+
+#%option
+#% key: path
+#% description: path to pycsw instal folder
+#% required : yes
+#% answer : /var/www/html/pycsw
+#%end
+
+#%option
+#% key: port
+#% type: integer
+#% description: server port
+#% required : yes
+#% answer: 8000
+#%end
+
+from StringIO import StringIO
+import os, sys
+
+from grass.script import core as grass
+import contextlib
+
+
+from pycsw import server
+app_path=None
+
+ at contextlib.contextmanager
+def application(env, start_response):
+    """WSGI wrapper"""
+    config = 'default.cfg'
+
+    if 'PYCSW_CONFIG' in env:
+        config = env['PYCSW_CONFIG']
+
+    if env['QUERY_STRING'].lower().find('config') != -1:
+        for kvp in env['QUERY_STRING'].split('&'):
+            if kvp.lower().find('config') != -1:
+                config = kvp.split('=')[1]
+
+    if not os.path.isabs(config):
+        config = os.path.join(app_path, config)
+
+    if 'HTTP_HOST' in env and ':' in env['HTTP_HOST']:
+        env['HTTP_HOST'] = env['HTTP_HOST'].split(':')[0]
+
+    env['local.app_root'] = app_path
+
+    csw = server.Csw(config, env)
+
+    gzip = False
+    if ('HTTP_ACCEPT_ENCODING' in env and
+            env['HTTP_ACCEPT_ENCODING'].find('gzip') != -1):
+        # set for gzip compressed response
+        gzip = True
+
+    # set compression level
+    if csw.config.has_option('server', 'gzip_compresslevel'):
+        gzip_compresslevel = \
+            int(csw.config.get('server', 'gzip_compresslevel'))
+    else:
+        gzip_compresslevel = 0
+
+    status, contents = csw.dispatch_wsgi()
+
+    headers = {}
+
+    if gzip and gzip_compresslevel > 0:
+        import gzip
+
+        buf = StringIO()
+        gzipfile = gzip.GzipFile(mode='wb', fileobj=buf,
+                                 compresslevel=gzip_compresslevel)
+        gzipfile.write(contents)
+        gzipfile.close()
+
+        contents = buf.getvalue()
+
+        headers['Content-Encoding'] = 'gzip'
+
+    headers['Content-Length'] = str(len(contents))
+    headers['Content-Type'] = csw.contenttype
+
+    start_response(status, headers.items())
+
+    return [contents]
+
+def main():
+    path=options['path']
+    port = int(options['port'])
+    path=os.path.dirname(path)
+
+    app_path = os.path.dirname(path)
+    sys.path.append(app_path)
+
+    from wsgiref.simple_server import make_server
+
+    try:
+        httpd = make_server('', port, application)
+        grass.message( "Serving on port %d..." % port)
+    except Exception,e:
+        grass.error(str(e))
+        sys.stdout.flush()
+        sys.exit()
+
+    httpd.serve_forever()
+    sys.stdout.flush()
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    main()


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/db.csw.run/db.csw.run.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,8 @@
+MODULE_TOPDIR = ../..
+
+PGM= g.gui.cswbrowser
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
+
+default: script


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,80 @@
+<h2>DESCRIPTION</h2>
+
+<em>g.gui.cswbrowser</em> support searching and browsing metadata catalog based on
+ <a href="http://www.opengeospatial.org/standards/cat">Catalogue Service(CSW)</a> standard .
+
+<p>
+The module allows to setting up connection to csw by uri and search metadata with using advanced filter.
+
+<h2>NOTES</h2>
+
+For dependencies and installation instructions see
+<a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+<h3>Setting up connection</h3>
+
+After start g.gui.cswbrowser the connection manager is initialized by default connection file  which includes some well
+known catalogs. Connection manager allows to add, to delete and to load connection from xml file.
+
+<h3>Search and browse catalog</h3>
+
+Searching and browsing panel allows to setup request with using custom filter.
+
+<h2>EXAMPLES</h2>
+
+<h3>Query filter</h3>
+The filter can be defined by limitation of area by bounding box which can be set by GRASS region or manualy.
+
+<h3>Bounding box</h3>
+
+<ul>
+  <li>Bounding box<br>
+    Bounding box defined spatial extent for limitation of area. Button "Map extends" allows to set up values from current GRASS region.</li>
+  <li>Keywords<br>
+    This filter allows to use basic or advance keyword filtering. In the simple case user can define single keywords or
+      multiple keywords with button "+". Logic operator between keywords is AND(&&).
+    Second, advanced is based on OGC list of expressions which means that can be set filtr with logic relations between
+      keywords or sets of keywords. Dialog for settings kewords text string is under "Advanced" checkbox. Syntax of
+      constraints is based on python list syntax. Each keywords must be in braces<'>or<">.</li>
+    <li><ul>
+    <li>OR condition<br>
+    a || b || c
+    ["a","b","c"]</li>
+    <li>AND condition<br>
+        a && b && c
+        [[a,b,c]]</li>
+    <li>MORE condition<br>
+         (a && b) || c || d || e
+        [[a,b],[c],[d],[e]] or [[a,b],c,d,e]</li>
+    </ul></li>
+</ul>
+
+<h3>Browsing of metadata</h3>
+In case of successful request, user can browse through results and show request and response in xml format. If services
+contains uri of WMS, WFS or WMS, module allows to add them directly with using upper toolbar.
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="r.info.html">r.info</a>,
+  <a href="v.info.iso.html">v.info.iso</a>,
+  <a href="g.gui.metadata.html">g.gui.metadata</a>,
+  <a href="db.csw.harvest">db.csw.harvest</a>,
+  <a href="db.csw.admin">db.csw.admin</a>,
+  <a href="db.csw.run">db.csw.run</a>
+</em>
+
+<p>
+See also related <a href="http://grasswiki.osgeo.org/wiki/ISO/INSPIRE_Metadata_Support">wiki page</a>.
+
+
+<h2>AUTHOR</h2>
+
+Matej Krejci, <a href="http://geo.fsv.cvut.cz/gwiki/osgeorel">OSGeoREL</a>
+at the Czech Technical University in Prague, developed
+during <a href="http://trac.osgeo.org/grass/wiki/GSoC/2014/MetadataForGRASS">Google
+Summer of Code 2015</a> (mentors: Martin Landa)
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+import sys, os
+import grass.script as grass
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'mdlib'))
+from cswlib import *
+import wx
+class CswBrowserMainDialog(wx.Frame):
+    def __init__(self):
+        wx.Frame.__init__(self, None, title="Metadata browser", size=(1024, 760))
+
+        self.mainNotebook = wx.Notebook(self, wx.ID_ANY)
+        self.config = wx.Config("g.gui.cswbrowser")
+
+        self.BrowserPanel = CSWBrowserPanel(self.mainNotebook, self)
+        self.connectionPanel = CSWConnectionPanel(self.mainNotebook, self)
+        # self.dirpath = os.path.join(os.getenv('GRASS_ADDON_BASE'), 'g.gui.cswbrowser')
+        self.mainNotebook.AddPage(self.BrowserPanel, text='Find')
+        self.mainNotebook.AddPage(self.connectionPanel, text='Configure')
+        self._layout()
+
+    def _layout(self):
+        self.mainsizer = wx.BoxSizer(wx.VERTICAL)
+        self.mainsizer.Add(self.mainNotebook, 1, wx.EXPAND, )
+        self.SetSizer(self.mainsizer)
+
+def main():
+    app = wx.App()
+    a = CswBrowserMainDialog()
+    a.Show()
+    app.MainLoop()
+
+if __name__ == '__main__':
+    grass.parser()
+    main()
+


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/g.gui.cswbrowser.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlRequest.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlRequest.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlRequest.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <title>XML</title>
+    <style type="text/css">
+        {
+        {
+            css
+        }
+        }
+    </style>
+</head>
+<body>
+<div class="highlight"><pre><span class="cp"><?xml version="1.0" ?></span>
+<span class="nt"><csw:GetRecords</span> <span class="na">maxRecords=</span><span class="s">"20"</span> <span class="na">outputFormat=</span><span class="s">"application/xml"</span> <span class="na">outputSchema=</span><span class="s">"http://www.opengis.net/cat/csw/2.0.2"</span> <span class="na">resultType=</span><span class="s">"results"</span> <span class="na">service=</span><span class="s">"CSW"</span> <span class="na">version=</span><span class="s">"2.0.2"</span> <span class="na">xmlns:csw=</span><span class="s">"http://www.opengis.net/cat/csw/2.0.2"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"</span><span class="nt">></span>
+	<span class="nt"><csw:Query</span> <span class="na">typeNames=</span><span class="s">"csw:Record"</span><span class="nt">></span>
+		<span class="nt"><csw:ElementSetName></span>full<span class="nt"></csw:ElementSetName></span>
+	<span class="nt"></csw:Query></span>
+<span class="nt"></csw:GetRecords></span>
+</pre></div>
+
+</body>
+</html>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlRequest.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlResponse.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlResponse.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlResponse.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,485 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <title>XML</title>
+    <style type="text/css">
+        {
+        {
+            css
+        }
+        }
+    </style>
+</head>
+<body>
+<div class="highlight"><pre><span class="cp"><?xml version="1.0" encoding="utf-8"?></span>
+<span class="nt"><csw:GetRecordsResponse</span> <span class="na">xmlns:csw=</span><span class="s">"http://www.opengis.net/cat/csw/2.0.2"</span> <span class="na">xmlns:dc=</span><span class="s">"http://purl.org/dc/elements/1.1/"</span> <span class="na">xmlns:ogc=</span><span class="s">"http://www.opengis.net/ogc"</span> <span class="na">xmlns:dct=</span><span class="s">"http://purl.org/dc/terms/"</span> <span class="na">xmlns:ows=</span><span class="s">"http://www.opengis.net/ows"</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span><span class="nt">></span>
+<span class="nt"><csw:RequestId</span> <span class="nt">/></span>
+<span class="nt"><csw:SearchStatus</span> <span class="nt">/></span>
+<span class="nt"><csw:SearchResults</span> <span class="na">elementSet=</span><span class="s">"full"</span> <span class="na">recordSchema=</span><span class="s">"http://schemas.opengis.net/csw/2.0.2/record.xsd"</span> <span class="na">numberOfRecordsMatched=</span><span class="s">"17527"</span> <span class="na">numberOfRecordsReturned=</span><span class="s">"20"</span> <span class="na">nextRecord=</span><span class="s">"40"</span><span class="nt">></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>p_AR:00001:20120112:171634<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>PFVP Provincia di Arezzo - Zone di rispetto venatorio<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2005-12-28<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Istituite dalle Province su richiesta delle ATC sul territorio destinato alla caccia programmata possono essere previste in due tipologie:<span class="ni">&#xd;</span>
+									- zone vaste in cui  prevista la possibilit di prelievo sulle specie non in indirizzo:<span class="ni">&#xd;</span>
+									- zone di limitata estensione istituite soprattutto con riguardo alla piccola selvaggina stanziale.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>pianificazione<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>gestione ambientale<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>legislazione regionale<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>zona controllata di caccia<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Utilizzo del territorio<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>planningCadastre<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Altri vincoli<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.4196653333 43.10020904<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.3714 43.513237<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.4196653333 43.10020904<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.3714 43.513237<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_molise:{E1CCB7E3-AE4F-48E0-A418-A6205DB72B83}<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>MOLISEDB.GIS.W_G_S381114<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2012-04-03<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>La feature class rappresenta un foglio della Carta Tecnica Regionale 1:5000. Il dato  stato ricevuto dalla Regione Molise in formato shapefile.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>map<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Utilizzo del territorio<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Nomi geografici<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>imageryBaseMapsEarthCover<span class="nt"></dc:subject></span>
+<span class="nt"><dc:format></span>SDE Feature Class<span class="nt"></dc:format></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Altri vincoli<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.832482 41.874003<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>14.874149 41.899003<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.832482 41.874003<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>14.874149 41.899003<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_molise:{B9315A15-C9C8-4080-A42B-D8998B24DD31}<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>MOLISEDB.GIS.W_G_S394083<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2012-04-06<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>La feature class rappresenta un foglio della Carta Tecnica Regionale 1:5000. Il dato  stato ricevuto dalla Regione Molise in formato shapefile.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>map<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Utilizzo del territorio<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Nomi geografici<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>imageryBaseMapsEarthCover<span class="nt"></dc:subject></span>
+<span class="nt"><dc:format></span>SDE Feature Class<span class="nt"></dc:format></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Altri vincoli<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.91582 41.698862<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>14.957496 41.724031<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.91582 41.698862<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>14.957496 41.724031<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_molise:{677D9AFF-0950-4067-B9A3-AFD8371C5FFA}<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>MOLISEDB.GIS.MO_DBP01G_Centri_Molise<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2012-03-08<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Feature Class dei centri abitati DBPrior 10k livello 2 per intera Regione Molise. Dato consegnato dalla Regione Molise.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>land use classification<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Utilizzo del territorio<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>boundaries<span class="nt"></dc:subject></span>
+<span class="nt"><dc:format></span>SDE Feature Class<span class="nt"></dc:format></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Altri vincoli<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.00283 41.397792<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.080393 42.034867<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.00283 41.397792<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.080393 42.034867<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_umbria:00019:20100607:143032<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Rete geodetica Regione Umbria<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2010-06-07<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>La rete geodetica planoaltimetrica della Regione Umbria<span class="ni">&#xd;</span>
+Costituisce un raffittimento della rete fondamentale IGM95 e nella sua configurazione definitiva  costituita da 294 nuovi vertici che si aggiungono agli 87 vertici IGM95 esistenti, per un totale di 381 punti uniformemente distribuiti sul territorio regionale.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Sistemi di coordinate<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>geoscientificInformation<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.8918873189186 42.3644489025728<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.2641895503866 43.6173443846477<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.8918873189186 42.3644489025728<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.2641895503866 43.6173443846477<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_molise:{F9F2F9E0-3898-4C3E-AE17-FE276C809F4E}<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>MOLISEDB.GIS.MM_Tmax_Ottobre<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2012-03-14<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>La feature class MM_Tmax_Ottobre,  una feature class poligonale che rappresenta le aree con temperature massime misurate nel mese di Ottobre omogenee. Delle Temperature Massime sono considerati la massima, la media e la minima mensile. Ogni area  stata calcolata per interpolazione a partire dai dati rilevati dalle singole stazioni di misura.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Condizioni atmosferiche<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>climatologyMeteorologyAtmosphere<span class="nt"></dc:subject></span>
+<span class="nt"><dc:format></span>SDE Feature Class<span class="nt"></dc:format></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Dato a conoscibilit limitata<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>13.941193 41.363275<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.161064 42.069535<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>13.941193 41.363275<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.161064 42.069535<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_umbria:00001:20091013:152425<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Carta fitoclimatica<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-12-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Contiene le unit fitoclimatiche dell'Umbria che rientrano in due Regioni (Temperata Semioceanica di Transizione e Temperata Semioceanica) con l'individuazione sul territorio regionale dei 7 Piani bioclimatici (Collinare Submediterraneo, Basso-Collinare, Alto-Collinare, Collinare Subcontinentale, Basso-Montano, Alto-Montano, Subalpino-Alpino) e delle relative varianti.<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Regioni biogeografiche<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>biota<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.8918873189186 42.3644489025728<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.2641895503866 43.6173443846477<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.8918873189186 42.3644489025728<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.2641895503866 43.6173443846477<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"><dc:URI</span> <span class="na">protocol=</span><span class="s">"WWW:DOWNLOAD-1.0-http--download"</span><span class="nt">></span>http://www.umbriaterritorio.it/CarteTematichePDF/004_.pdf<span class="nt"></dc:URI></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:403:20091007:081436<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Refresh Provincia Belluno 2009<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>copertura del suolo per usi agricoli della Provincia Belluno  rappresentata nella proiezione conforme di Gauss-Boaga<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>copertura del suolo per usi agricoli<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.66603804 45.88049788<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.74959784 46.68037467<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.66603804 45.88049788<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.74959784 46.68037467<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:386:20090911:093825<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Mantova 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Mantova alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>10.30927983 44.90828099<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>11.42766438 45.42804199<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>10.30927983 44.90828099<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>11.42766438 45.42804199<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:329:20090911:084441<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Alessandria 2009<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Alessandria alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>8.10847121 44.46487886<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>9.21425034 45.20541861<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>8.10847121 44.46487886<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>9.21425034 45.20541861<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00389:20090911:094023<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Vibo Valentia 2009<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Vibo Valentia alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>15.82719408 38.4289221<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>16.43470805 38.82446257<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>15.82719408 38.4289221<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>16.43470805 38.82446257<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>r_campan:16050018:20090527:103952<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Parchi Nazionali<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-31<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Perimetrazioni dei Parchi Regionali presenti in Regione Campania<span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Siti protetti<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>parchi nazionali<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>environment<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>Dato a conoscibilit limitata<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.364741 39.98938<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.698097 40.873218<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.364741 39.98938<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.698097 40.873218<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00377:20090911:093144<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Trento 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Trento alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>10.45230853 45.6730803<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>11.96285745 46.53297967<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>10.45230853 45.6730803<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>11.96285745 46.53297967<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00373:20090911:092903<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Terni 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Terni alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.89188729 42.36443703<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.89633447 42.94310311<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>11.89188729 42.36443703<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>12.89633447 42.94310311<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00342:20090911:090542<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Piacenza 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Piacenza alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>9.19792713 44.55582795<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>10.08347854 45.13907144<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>9.19792713 44.55582795<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>10.08347854 45.13907144<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00330:20090911:084602<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Novara 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Novara alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>8.37667885 39.54914737<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>9.82710733 40.86492774<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>8.37667885 39.54914737<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>9.82710733 40.86492774<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:332:20090911:085547<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Asti 2009<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Asti alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>7.88367392 44.51951501<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>8.51258103 45.13293242<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>7.88367392 44.51951501<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>8.51258103 45.13293242<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:377:20090911:093146<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Gorizia 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Gorizia alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>13.23754532 45.67415462<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.64284038 46.05129914<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>13.23754532 45.67415462<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>13.64284038 46.05129914<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:00367:20090911:092454<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Ortofotocarta Salerno 2008<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2008-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>Ortofotocarta della Provincia Salerno alla scala 1:10.000 rappresentata nella proiezione conforme di Gauss-Boaga. Una sezione rappresenta la sedicesima parte di un foglio della serie IGM 1:50.000<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>ortofoto<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>fotografia aerea (immagine)<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.42872224 39.9905913<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.80638769 40.84875212<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>14.42872224 39.9905913<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>15.80638769 40.84875212<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"><csw:Record</span> <span class="na">xmlns:ns2=</span><span class="s">"http://www.cnipa.gov.it/RNDT/Service"</span> <span class="na">xmlns:srv=</span><span class="s">"http://www.isotc211.org/2005/srv"</span> <span class="na">xmlns:gmd=</span><span class="s">"http://www.isotc211.org/2005/gmd"</span> <span class="na">xmlns:gco=</span><span class="s">"http://www.isotc211.org/2005/gco"</span><span class="nt">></span>
+<span class="nt"><dc:identifier></span>agea:419:20091012:090325<span class="nt"></dc:identifier></span>
+<span class="nt"><dc:title></span>Refresh Provincia Cuneo 2009<span class="nt"></dc:title></span>
+<span class="nt"><dct:modified></span>2009-07-01<span class="nt"></dct:modified></span>
+<span class="nt"><dct:abstract></span>copertura del suolo per usi agricoli della Provincia Cuneo  rappresentata nella proiezione conforme di Gauss-Boaga<span class="ni">&#xd;</span>
+                                       <span class="nt"></dct:abstract></span>
+<span class="nt"><dc:type></span>Dataset<span class="nt"></dc:type></span>
+<span class="nt"><dc:subject></span>copertura del suolo per usi agricoli<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>Orto immagini<span class="nt"></dc:subject></span>
+<span class="nt"><dc:subject></span>farming<span class="nt"></dc:subject></span>
+<span class="nt"><dc:language></span>ita<span class="nt"></dc:language></span>
+<span class="nt"><dc:rights></span>
+							Altri vincoli
+						<span class="nt"></dc:rights></span>
+<span class="nt"><ows:WGS84BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>6.85344523 44.06006515<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>8.26856826 44.85647935<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:WGS84BoundingBox></span>
+<span class="nt"><ows:BoundingBox></span>
+<span class="nt"><ows:LowerCorner></span>6.85344523 44.06006515<span class="nt"></ows:LowerCorner></span>
+<span class="nt"><ows:UpperCorner></span>8.26856826 44.85647935<span class="nt"></ows:UpperCorner></span>
+<span class="nt"></ows:BoundingBox></span>
+<span class="nt"></csw:Record></span>
+<span class="nt"></csw:SearchResults></span>
+<span class="nt"></csw:GetRecordsResponse></span>
+</pre></div>
+
+</body>
+</html>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.cswbrowser/htmlResponse.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1,1637 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8
-"""
- at package editor
- at module g.gui.metadata
- at brief base editor, read/write ISO metadata, generator of widgets in editor
-
-Classes:
- - editor::MdFileWork
- - editor::MdBox
- - editor::MdWxDuplicator
- - editor::MdItem
- - editor::MdNotebookPage
- - editor::MdMainEditor
-
-(C) 2014 by the GRASS Development Team
-This program is free software under the GNU General Public License
-(>=v2). Read the file COPYING that comes with GRASS for details.
-
- at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
-"""
-import re
-import os
-import sys
-import tempfile
-import contextlib
-from lxml import etree
-
-import wx
-from wx import ID_ANY
-from wx import EVT_BUTTON
-import wx.lib.scrolledpanel as scrolled
-
-from owslib.iso import *
-from jinjainfo import JinjaTemplateParser
-from jinja2 import Environment, FileSystemLoader
-
-from core.gcmd import RunCommand, GError, GMessage
-from gui_core.widgets import IntegerValidator, NTCValidator, SimpleValidator,\
-    TimeISOValidator, EmailValidator  # ,EmptyValidator
-import mdutil
-
-from core.gcmd import RunCommand
-from subprocess import PIPE
-from grass.pygrass.modules import Module
-#=========================================================================
-# MD filework
-#=========================================================================
-
-
-class MdFileWork():
-
-    ''' initializer of metadata in OWSLib and export OWSLib object to xml by jinja template system
-    '''
-
-    def __init__(self, pathToXml=None):
-        self.path = pathToXml
-        self.owslibInfo = None
-
-    def initMD(self, path=None):
-        '''
-        @brief initialize metadata
-        @param path: path to xml
-        @return: initialized md object by input xml
-        '''
-        if path is None:
-            self.md = mdutil.MD_MetadataMOD(md=None)
-            return self.md
-        else:
-            io = open(path, 'r')
-            str1 = ''
-            for line in io.readlines():
-                str1 += mdutil.removeNonAscii(line)
-            io.close()
-            io1 = open(path, 'w')
-            io1.write(str1)
-            io1.close()
-
-            try:
-                tree = etree.parse(path)
-                root = tree.getroot()
-                self.md = mdutil.MD_MetadataMOD(root)
-
-                return self.md
-
-            except Exception, e:
-                GError('Error loading xml:\n' + str(e))
-
-    def saveToXML(self, md, owsTagList, jinjaPath, outPath=None, xmlOutName=None, msg=True, rmTeplate=False):
-        '''
-        @note creator of xml with using OWSLib md object and jinja template
-        @param md: owslib.iso.MD_Metadata
-        @param owsTagList: in case if user is defining template
-        @param jinjaPath: path to jinja template
-        @param outPath: path of exported xml
-        @param xmlOutName: name of exported xml
-        @param msg: gmesage info after export
-        @param rmTeplate: remove template after use
-        @return: initialized md object by input xml
-        '''
-    # if  output file name is None, use map name and add postfix
-        self.dirpath = os.path.dirname(os.path.realpath(__file__))
-        self.md = md
-        self.owsTagList = owsTagList
-
-        if xmlOutName is None:
-            xmlOutName = 'RANDExportMD'  # TODO change to name of map
-        if not xmlOutName.lower().endswith('.xml'):
-            xmlOutName += '.xml'
-        # if path is None, use lunch. dir
-        # TODO change default folder to mapset location
-        if not outPath:
-            outPath = os.path.join(self.dirpath, xmlOutName)
-        else:
-            outPath = os.path.join(outPath, xmlOutName)
-        xml = open(jinjaPath, 'r')
-
-        str1 = ''
-        for line in xml.readlines():
-            line = mdutil.removeNonAscii(line)
-            str1 += line
-        xml.close
-        io = open(jinjaPath, 'w')
-        io.write(str1)
-        io.close()
-
-        # generating xml using jinja templates
-        head, tail = os.path.split(jinjaPath)
-        env = Environment(loader=FileSystemLoader(head))
-        env.globals.update(zip=zip)
-        template = env.get_template(tail)
-        if self.owsTagList is None:
-            iso_xml = template.render(md=self.md)
-        else:
-            iso_xml = template.render(md=self.md, owsTagList=self.owsTagList)
-        xml_file = xmlOutName
-
-        try:
-            xml_file = open(outPath, "w")
-            xml_file.write(iso_xml)
-            xml_file.close()
-
-            if msg:
-                GMessage('File is exported to: %s' % outPath)
-
-            if rmTeplate:
-                os.remove(jinjaPath)
-
-            return outPath
-
-        except Exception, e:
-            GError('Error writing xml:\n' + str(e))
-
-#=========================================================================
-# CREATE BOX (staticbox+button(optional)
-#=========================================================================
-
-    
-
-class MdBox(wx.Panel):
-
-    '''widget(static box) which include metadata items (MdItem)
-    '''
-
-    def __init__(self, parent, label='label'):
-        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
-        self.label = label
-        self.mdItems = list()
-        self.stbox = wx.StaticBox(self, label=label, id=ID_ANY, style=wx.RAISED_BORDER)
-        self.stbox.SetForegroundColour((0, 0, 0))
-        self.stbox.SetBackgroundColour((200, 200, 200))
-        self.stbox.SetFont(wx.Font(12, wx.NORMAL, wx.NORMAL, wx.NORMAL))
-
-    def addItems(self, items, multi=True, rmMulti=False, isFirstNum=-1):
-        '''
-        @param items: editor::MdItems
-        @param multi: true in case when box has button for duplicating box and included items
-        @param rmMulti: true in case when box has button for removing box and included items
-        @param isFirstNum: handling with 'add' and 'remove' button of box.
-                            this param is necessary for generating editor in editor::MdEditor.generateGUI.inBlock()
-                            note: just first generated box has 'add' button (because being mandatory) and next others has
-                            'remove' button
-        '''
-        if isFirstNum != 1:
-            multi = False
-            rmMulti = True
-
-        # if not initialize in jinja template (default is true)
-        if multi is None:
-            multi = True
-
-        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
-        self.SetSizer(self.panelSizer)
-
-        self.boxButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        self.panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
-        self.panelSizer.Add(self.boxButtonSizer, flag=wx.EXPAND, proportion=1)
-
-        self.stBoxSizer = wx.StaticBoxSizer(self.stbox, orient=wx.VERTICAL)
-        self.boxButtonSizer.Add(self.stBoxSizer, flag=wx.EXPAND, proportion=1)
-
-        for item in items:
-            self.mdItems.append(item)
-            self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
-            self.stBoxSizer.AddSpacer(5, 5, 1, wx.EXPAND)
-
-        if multi:
-            self.addBoxButt = wx.Button(self, id=ID_ANY, size=(30, 30), label='+')
-            self.boxButtonSizer.Add(self.addBoxButt, 0)
-            self.addBoxButt.Bind(EVT_BUTTON, self.duplicateBox)
-
-        if rmMulti:
-            self.rmBoxButt = wx.Button(self, id=ID_ANY, size=(30, 30), label='-')
-            self.boxButtonSizer.Add(self.rmBoxButt, 0)
-            self.rmBoxButt.Bind(EVT_BUTTON, self.removeBox)
-
-
-        
-    def addDuplicatedItem(self, item):
-        self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
-        self.stBoxSizer.AddSpacer(5, 5, 1, wx.EXPAND)
-        self.GetParent().Layout()
-
-    def getCtrlID(self):
-        return self.GetId()
-
-    def removeBox(self, evt):
-        for item in self.mdItems:
-            item.mdDescription.removeMdItem(item)
-        self.GetParent().removeBox(self)
-
-    def removeMdItem(self, mdItem, items):
-        '''
-        @param mdItem: object editor::MdItem
-        @param items: widgets to destroy
-        '''
-        mdItem.mdDescription.removeMdItem(mdItem)
-        for item in items:
-            try:
-                item.Destroy()
-            except:
-                pass
-        self.stBoxSizer.RemovePos(-1)  # remove wxSpacer
-        self.stBoxSizer.Remove(mdItem)
-        self.GetParent().Layout()
-
-    def duplicateBox(self, evt):
-        duplicator = MdWxDuplicator(self.mdItems, self.GetParent(), self.label)
-        clonedBox = duplicator.mdBox
-        self.GetParent().addDuplicatedItem(clonedBox, self.GetId())
-
-
-#===============================================================================
-# Handling keywords from database
-#===============================================================================
-class MdBoxKeywords(MdBox):
-    def __init__(self,parent,parent2,label):
-        super(MdBoxKeywords, self).__init__(parent,label)
-        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
-        self.SetSizer(self.panelSizer)
-        self.boxButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.parent2=parent2
-
-        self.panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
-        self.panelSizer.Add(self.boxButtonSizer, flag=wx.EXPAND, proportion=1)
-        self.parent=parent
-        self.stBoxSizer = wx.StaticBoxSizer(self.stbox, orient=wx.VERTICAL)
-        self.boxButtonSizer.Add(self.stBoxSizer, flag=wx.EXPAND, proportion=1)
-        self.itemHolder=[]
-        self.textTMP=None
-
-    def addKeywordItem(self,item):
-        self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
-
-    def removeKeywordItem(self,item):
-        self.parent2.removeKeyfromBox(item,self.textTMP)
-        self.stBoxSizer.Remove(item)
-        self.parent.Fit()
-
-
-#===============================================================================
-# DUPLICATOR OF WIDGETS-mditem
-#===============================================================================
-
-class MdWxDuplicator():
-
-    '''duplicator of MdBox and MdItem object
-    '''
-
-    def __init__(self, mdItems, parent, boxlabel=None, mdItemOld=None, template=None):
-        '''
-        @param mdItems:  list of editor::MdItem
-        @param parent: parent of new duplicated box
-        @param boxlabel: label of static box
-        @param mdItemOld: object which will be duplicated
-        @param template: in case if 'template mode' is on in editor
-        '''
-        # duplicate box of items
-        if boxlabel:
-            itemList = list()
-            self.mdBox = MdBox(parent, boxlabel)
-            for i in mdItems:
-                try:  # check if item has multiple button
-                    i.addItemButt.GetLabel()
-                    multi = True
-                except:
-                    multi = False
-                try:  # check if chckBoxEdit exists
-                    i.chckBoxEdit.GetValue()
-                    template = True
-                except:
-                    template = False
-
-                i = i.mdDescription  # var mdDescription is  jinjainfo::MdDescription
-                mdItem1 = MdItem(parent=self.mdBox,
-                                 item=i,
-                                 multiplicity=multi,
-                                 isFirstNum=1,
-                                 chckBox=template)
-
-                itemList.append(mdItem1)
-
-                i.addMdItem(mdItem1)  # add item with using jinjainfo::MDescription
-            self.mdBox.addItems(itemList, False, True)  # fill box
-
-        else:  # duplicate only MdItem
-            self.mdItem = MdItem(parent=parent,
-                                 item=mdItems,
-                                 multiplicity=False,
-                                 rmMulti=True,
-                                 isFirstNum=-1,
-                                 chckBox=template)
-
-            try:
-                if mdItems.inbox is not None:
-                    mdItems.addMdItem(self.mdItem, mdItemOld)
-                else:
-                    mdItems.addMdItem(self.mdItem)
-            except:
-                mdItems.addMdItem(self.mdItem)
-
-#=========================================================================
-# METADATA ITEM (label+ctrlText+button(optional)+chckbox(template)
-#=========================================================================
-class MdItem(wx.BoxSizer):
-
-    '''main building blocks of generated GUI of editor
-    '''
-
-    def __init__(self, parent, item, multiplicity=None, rmMulti=False, isFirstNum=-1, chckBox=False):
-        '''
-        @param item: jinjainfo::MdDescription(initialized by parsing information from jinja template)
-        @param multiplicity: if true- widget has button for duplicate self
-        @param rmMulti: if true- widget has button for remove self
-        @param isFirstNum: handling with 'add' and 'remove' button of box.
-                            this param is necessary for generating editor in editor::MdEditor.generateGUI.inBlock()
-                            note: just first generated box has 'add' button (because being mandatory) and next others has
-                            'remove' button
-        @param chckBox: in case-True  'template editor' is on and widget has checkbox
-        '''
-        wx.BoxSizer.__init__(self, wx.VERTICAL)
-        self.isValid = False
-        self.isChecked = False
-        self.mdDescription = item
-        self.chckBox = chckBox
-        self.multiple = multiplicity
-        self.parent=parent
-        added=False
-        if multiplicity is None:
-            self.multiple = item.multiplicity
-
-        if isFirstNum != 1:
-            self.multiple = False
-
-        if isFirstNum != 1 and item.multiplicity:
-            rmMulti = True
-        self.tagText = wx.StaticText(parent=parent, id=ID_ANY, label=item.name)
-        if self.mdDescription.databaseAttr =='language':
-            self.fillComboDB('language')
-            added=True
-        elif self.mdDescription.databaseAttr =='topicCategory':
-            self.fillComboDB('topicCategory')
-            added=True
-        elif self.mdDescription.databaseAttr =='degree':
-            self.fillComboDB('degree')
-            added=True
-        elif self.mdDescription.databaseAttr =='dateType':
-            self.fillComboDB('dateType')
-            added=True
-        elif self.mdDescription.databaseAttr =='role':
-            self.fillComboDB('role')
-            added=True
-
-        if self.chckBox is False and not added:
-            if item.multiline is True:
-                self.valueCtrl = wx.TextCtrl(parent, id=ID_ANY, size=(0, 70),
-                                             validator=self.validators(item.type),
-                                             style=wx.VSCROLL |
-                                             wx.TE_MULTILINE | wx.TE_WORDWRAP |
-                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER)
-            else:
-                self.valueCtrl = wx.TextCtrl(parent, id=wx.ID_ANY,
-                                             validator=self.validators(item.type),
-                                             style=wx.VSCROLL | wx.TE_DONTWRAP |
-                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER | wx.HSCROLL)
-        elif self.chckBox is True and not added:
-            if item.multiline is True:
-                self.valueCtrl = wx.TextCtrl(parent, id=ID_ANY, size=(0, 70),
-                                             style=wx.VSCROLL |
-                                             wx.TE_MULTILINE | wx.TE_WORDWRAP |
-                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER)
-            else:
-                self.valueCtrl = wx.TextCtrl(parent, id=wx.ID_ANY,
-                                             style=wx.VSCROLL | wx.TE_DONTWRAP |
-                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER | wx.HSCROLL)
-
-
-        self.valueCtrl.Bind(wx.EVT_MOTION, self.onMove)
-        self.valueCtrl.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY)
-
-        if self.multiple:
-            self.addItemButt = wx.Button(parent, -1, size=(30, 30), label='+')
-            self.addItemButt.Bind(EVT_BUTTON, self.duplicateItem)
-
-        if rmMulti:
-            self.rmItemButt = wx.Button(parent, -1, size=(30, 30), label='-')
-            self.rmItemButt.Bind(EVT_BUTTON, self.removeItem)
-
-        if self.chckBox:
-            self.chckBoxEdit = wx.CheckBox(parent, -1, size=(30, 30))
-            self.chckBoxEdit.Bind(wx.EVT_CHECKBOX, self.onChangeChckBox)
-            self.chckBoxEdit.SetValue(False)
-            self.isChecked = False
-            self.valueCtrl.Disable()
-
-        self.createInfo()
-        self.tip = wx.ToolTip(self.infoTip)
-
-        self._addItemLay(item.multiline, rmMulti)
-
-    def fillComboDB(self,label):
-        if label == 'language':
-            lang=["Afrikaans","Albanian","Arabic","Armenian","Basque","Bengali",
-                  "Bulgarian","Catalan","Cambodian","Chinese","Croatian","Czech",
-                  "Danish","Dutch","English","Estonian","Fiji","Finnish","French",
-                  "Georgian","German","Greek","Gujarati","Hebrew","Hindi","Hungarian",
-                  "Icelandic","Indonesian","Irish","Italian","Japanese","Javanese","Korean",
-                  "Latin","Latvian","Lithuanian","Macedonian","Malay","Malayalam","Maltese",
-                  "Maori","Marathi","Mongolian","Nepali","Norwegian","Persian","Polish","Portuguese",
-                  "Punjabi","Quechua","Romanian","Russian","Samoan","Serbian","Slovak","Slovenian",
-                  "Spanish","Swahili","Swedish","Tamil","Tatar","Telugu","Thai","Tibetan","Tonga",
-                  "Turkish","Ukrainian","Urdu","Uzbek","Vietnamese","Welsh","Xhosa"]
-            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
-            for lng in lang:
-                self.valueCtrl.Append(lng)
-        if label == 'topicCategory':
-            lang= ['farming','biota','boundaries','climatologyMeteorologyAtmosphere','economy',
-                   'elevation','enviroment','geoscientificInformation','health','imageryBaseMapsEarthCover',
-                   'intelligenceMilitary','inlandWaters','location','planningCadastre','society','structure',
-                   'transportation','utilitiesCommunication']
-            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
-            for lng in lang:
-                self.valueCtrl.Append(lng)
-        if label == 'degree':
-            lang=['Not evaluated','Not conformant','Conformant']
-            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
-            for lng in lang:
-                self.valueCtrl.Append(lng)
-        if label == 'dateType':
-            lang=['Date of creation','Date of last revision', 'Date of publication']
-            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
-            for lng in lang:
-                self.valueCtrl.Append(lng)
-        if label == 'role':
-            lang=['Author','Custodian','Distributor','Originator','Owner','Point of contact','Principal Investigation',
-                  'Processor','Publisher','Resource provider','User']
-            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
-            for lng in lang:
-                self.valueCtrl.Append(lng)
-    def validators(self, validationStyle):
-
-        if validationStyle == 'email':
-            return EmailValidator()
-
-        if validationStyle == 'integer':
-            return NTCValidator('DIGIT_ONLY')
-
-        if validationStyle == 'decimal':
-            return NTCValidator('DIGIT_ONLY')
-
-        if validationStyle == 'date':
-            return TimeISOValidator()
-
-        # return EmptyValidator()
-        return SimpleValidator('')
-
-    def onChangeChckBox(self, evt):
-        '''current implementation of editor mode for defining templates not allowed to check
-        only single items in static box. There are two cases:  all items in box are checked or not.
-        '''
-        if self.mdDescription.inbox:  # MdItems are in box
-            try:
-                items = self.valueCtrl.GetParent().mdItems
-                if self.isChecked:
-                    self.valueCtrl.Disable()
-                    self.isChecked = False
-                else:
-                    self.valueCtrl.Enable()
-                    self.isChecked = True
-
-                for item in items:
-                    if self.isChecked:
-                        item.valueCtrl.Enable()
-                        item.chckBoxEdit.SetValue(True)
-                        item.isChecked = True
-                    else:
-                        item.valueCtrl.Disable()
-                        item.chckBoxEdit.SetValue(False)
-                        item.isChecked = False
-            except:
-                pass
-        else:
-            if self.isChecked:
-                self.valueCtrl.Disable()
-                self.isChecked = False
-            else:
-                self.valueCtrl.Enable()
-                self.isChecked = True
-
-    def onMove(self, evt=None):
-        self.valueCtrl.SetToolTip(self.tip)
-
-    def createInfo(self):
-        """Feed for tooltip
-        """
-        string = ''
-        if self.mdDescription.ref is not None:
-            string += self.mdDescription.ref + '\n\n'
-        if self.mdDescription.name is not None:
-            string += 'NAME: \n' + self.mdDescription.name + '\n\n'
-        if self.mdDescription.desc is not None:
-            string += 'DESCRIPTION: \n' + self.mdDescription.desc + '\n\n'
-        if self.mdDescription.example is not None:
-            string += 'EXAMPLE: \n' + self.mdDescription.example + '\n\n'
-        if self.mdDescription.type is not None:
-            string += 'DATA TYPE: \n' + self.mdDescription.type + '\n\n'
-        string += '*' + '\n'
-        if self.mdDescription.statements is not None:
-            string += 'Jinja template info: \n' + self.mdDescription.statements + '\n'
-
-        if self.mdDescription.statements1 is not None:
-            string += self.mdDescription.statements1 + '\n'
-        string += 'OWSLib info:\n' + self.mdDescription.tag
-        self.infoTip = string
-
-    def removeItem(self, evt):
-        """adding all items in self(mdItem) to list and call parent remover
-        """
-        ilist = [self.valueCtrl, self.tagText]
-        try:
-            ilist.append(self.rmItemButt)
-        except:
-            pass
-        try:
-            ilist.append(self.chckBoxEdit)
-        except:
-            pass
-        self.valueCtrl.GetParent().removeMdItem(self, ilist)
-
-    def duplicateItem(self, evt):
-        '''add Md item to parent(box or notebook page)
-        '''
-        parent = self.valueCtrl.GetParent()
-        # if parent is box
-        if self.mdDescription.inbox:
-            duplicator = MdWxDuplicator(mdItems=self.mdDescription,
-                                        parent=parent,
-                                        mdItemOld=self,
-                                        template=self.chckBox)
-        else:
-            duplicator = MdWxDuplicator(mdItems=self.mdDescription,
-                                        parent=parent,
-                                        template=self.chckBox)
-
-        clonedMdItem = duplicator.mdItem
-        # call parent "add" function
-        self.valueCtrl.GetParent().addDuplicatedItem(clonedMdItem, self.valueCtrl.GetId())
-
-    def setValue(self, value):
-        '''Set value & color of widgets
-        in case if is template creator 'on':
-            yellow: in case if value is marked by $NULL(by mdgrass::GrassMD)
-            red:    if value is '' or object is not initialized. e.g. if user
-                    read non fully valid INSPIRE xml with INSPIRE jinja template,
-                    the GUI generating mechanism will create GUI according to template
-                    and all missing tags(xml)-gui(TextCtrls) will be marked by red
-        '''
-        if value is None or value is '':
-            if self.chckBox:
-                self.chckBoxEdit.SetValue(True)
-                self.isChecked = True
-                try:
-                    self.onChangeChckBox(None)
-                    self.onChangeChckBox(None)
-                except:
-                    pass
-                self.valueCtrl.SetBackgroundColour((245, 204, 230))  # red
-
-            self.valueCtrl.SetValue('')
-            self.valueCtrl.Enable()
-
-        elif self.chckBox and value == '$NULL':
-            self.valueCtrl.SetBackgroundColour((255, 255, 82))  # yellow
-            self.valueCtrl.SetValue('')
-
-            if self.chckBox:
-                self.chckBoxEdit.SetValue(True)
-                self.isChecked = True
-                self.valueCtrl.Enable()
-                try:
-                    self.onChangeChckBox(None)
-                    self.onChangeChckBox(None)
-                except:
-                    pass
-
-        elif value == '$NULL':
-            self.valueCtrl.SetValue('')
-
-        else:
-            self.isValid = True
-            self.valueCtrl.SetValue(value)
-
-    def getValue(self):
-
-        value = mdutil.replaceXMLReservedChar(self.valueCtrl.GetValue())
-        value = value.replace('\n', '')
-        value = value.replace('"', '')
-        value = value.replace("'", '')
-        return value
-
-    def getCtrlID(self):
-        return self.valueCtrl.GetId()
-
-    def _addItemLay(self, multiline, rmMulti):
-        self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)
-        if multiline is True:
-            self.textFieldSizer.Add(self.valueCtrl, proportion=1, flag=wx.EXPAND)
-        else:
-            self.textFieldSizer.Add(self.valueCtrl, proportion=1)
-
-        if self.multiple:
-            self.textFieldSizer.Add(self.addItemButt, 0)
-
-        if rmMulti:
-            self.textFieldSizer.Add(self.rmItemButt, 0)
-
-        if self.chckBox:
-            self.textFieldSizer.Add(self.chckBoxEdit, 0)
-
-        self.Add(item=self.tagText, proportion=0)
-        self.Add(item=self.textFieldSizer, proportion=0, flag=wx.EXPAND)
-
-
-class MdItemKeyword(wx.BoxSizer):
-    def __init__(self, parent, text,keyword,title, keywordObj):
-        wx.BoxSizer.__init__(self, wx.VERTICAL)
-        self.isValid = False
-        self.isChecked = False
-        self.keywordObj=keywordObj
-        self.text = wx.StaticText(parent=parent, id=ID_ANY, label=text)
-        self.parent=parent
-        self.rmItemButt = wx.Button(parent, -1, size=(30, 30), label='-')
-        self.rmItemButt.Bind(EVT_BUTTON, self.removeItem)
-        self.keyword=keyword
-        self.title=title
-        #self.createInfo()
-        #self.tip = wx.ToolTip(self.infoTip)
-        self.layout()
-
-    def getVal(self):
-        return  self.text.GetLabel()
-
-    def getKyewordObj(self):
-        self.keywordObj['keywords']=self.keyword
-        self.keywordObj['title']=self.title
-        return self.keywordObj
-
-    def removeItem(self,evt):
-        self.parent.textTMP=self.text.GetLabel()
-        self.textFieldSizer.Clear()
-        #self.textFieldSizer.Destroy()
-
-        self.rmItemButt.Destroy()
-        self.text.Destroy()
-        self.parent.removeKeywordItem(self)
-
-    def layout(self):
-        self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        self.textFieldSizer.Add(self.rmItemButt, 0,flag=wx.LEFT)
-        self.textFieldSizer.Add(self.text, 0,flag=wx.RIGHT)
-        self.Add(item=self.textFieldSizer, proportion=0, flag=wx.EXPAND)
-#=========================================================================
-#=========================================================================
-# ADD NOTEBOOK PAGE
-#=========================================================================
-
-class MdNotebookPage(scrolled.ScrolledPanel):
-
-    """
-    every notebook page is initialized by jinjainfo::MdDescription.group (label)
-    """
-
-    def __init__(self, parent):
-        scrolled.ScrolledPanel.__init__(self, parent=parent, id=wx.ID_ANY)
-        self.items = []
-        self.SetupScrolling()
-        self._addNotebookPageLay()
-        self.sizerIndexDict = {}
-        self.sizerIndex = 0
-
-    def _addNotebookPageLay(self):
-        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
-        self.SetSizer(self.mainSizer)
-
-    def _getIndex(self):
-        '''
-        index for handling position of editor::MdBox,MdItem in editor::MdNotebookPage(self).
-        Primary for correct duplicating Boxes or items on notebook page
-        '''
-        self.sizerIndex += 1
-        return self.sizerIndex
-
-    def addKeywordObj(self,item):
-        self.mainSizer.Add(item, proportion=0, flag=wx.EXPAND)
-
-    def addItem(self, item):
-        '''
-        @param item: can be editor::MdBox or editor::MDItem
-        '''
-        if isinstance(item, list):
-            for i in item:
-                if isinstance(i, list):
-                    for ii in i:
-                        self.sizerIndexDict[ii.getCtrlID()] = self._getIndex()
-                        self.mainSizer.Add(ii, proportion=0, flag=wx.EXPAND)
-                else:
-                    self.sizerIndexDict[i.getCtrlID()] = self._getIndex()
-                    self.mainSizer.Add(i, proportion=0, flag=wx.EXPAND)
-        else:
-            self.sizerIndexDict[item.getCtrlID()] = self._getIndex()
-            self.mainSizer.Add(item, proportion=0, flag=wx.EXPAND)
-
-    def addDuplicatedItem(self, item, mId):
-        '''adding duplicated object to sizer to position after parent
-        '''
-        self.items.append(item)
-        posIndex = self.sizerIndexDict[mId]
-        self.mainSizer.Insert(posIndex, item, proportion=0, flag=wx.EXPAND)
-        self.SetSizerAndFit(self.mainSizer)
-        self.GetParent().Refresh()
-
-    def removeBox(self, box):
-        box.Destroy()
-        self.SetSizerAndFit(self.mainSizer)
-
-    def removeMdItem(self, mdDes, items):
-        '''Remove children
-        @param mdDes: editor::MdItem.mdDescription
-        @param items: all widgets to remove of MdItem
-        '''
-        mdDes.mdDescription.removeMdItem(mdDes)  # remove from jinjainfi:MdDEscription object
-        for item in items:
-            item.Destroy()
-        self.SetSizerAndFit(self.mainSizer)
-
-#class MdItemKyewords
-class MdKeywords(wx.BoxSizer):
-    def __init__(self,parent,mdObject,mdOWS):
-        wx.BoxSizer.__init__(self, wx.VERTICAL)
-        self.itemHolder=set()
-        self.parent=parent
-        self.keywordsOWSObject=mdOWS
-
-        self.comboKeysLabel=wx.StaticText(parent=self.parent,id=ID_ANY,label='Keywords from repositories')
-        self.comboKeys=wx.ComboBox(parent=self.parent, id=ID_ANY)
-
-        self.keysList=wx.TreeCtrl(parent=self.parent, id=ID_ANY,size=(0, 120),style=wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_DEFAULT_STYLE)
-        self.box=MdBoxKeywords(parent=parent,parent2=self,label='Keywords')
-        self.memKeys=set()
-        self.comboKeys.Bind(wx.EVT_COMBOBOX,self.onSetVocabulary)
-        self.keysList.Bind(wx.EVT_TREE_ITEM_ACTIVATED,self.addItemsToBox)
-        self.layout()
-        Module('db.connect',flags='d')
-        self.fillDb()
-        self.fillKeywordsList()
-
-    def removeKeyfromBox(self,item,text):
-        self.memKeys.remove(text)
-        self.itemHolder.remove(item)
-
-    def addItemsToBox(self,evt):
-        item = evt.GetItem()
-        if item == self.keysList.GetRootItem():
-            return
-
-        keyword=self.keysList.GetItemText(item)
-        currKeyword=self.titles[self.comboKeys.GetValue()]
-        out=self.comboKeys.GetValue()+', '+ keyword+', '+ currKeyword['type']+', '+ currKeyword['date']
-        if keyword in self.memKeys:
-            return
-        self.memKeys.add(out)
-
-        kItem=MdItemKeyword(self.box,out,keyword,self.comboKeys.GetValue(),currKeyword)
-        self.itemHolder.add(kItem)
-        self.box.addKeywordItem(kItem)
-        self.box.Fit()
-        self.parent.Fit()
-
-    def dbSelect(self,sql):
-        res = Module('db.select',
-                sql=sql,
-                flags='c',
-                stdout_=PIPE)
-        return res.outputs.stdout
-
-    def dbExecute(self,sql):
-        res = Module('db.execute',
-                sql=sql)
-
-    def GetKws(self):
-        return self.itemHolder# dict is in var keywordObj
-
-    def fillDb(self):
-
-
-
-        if not mdutil.isTableExists('metadata_themes'):
-            sql='create table if not exists metadata_themes (title TEXT, keyword TEXT, date_iso TEXT ,date_type TEXT)'
-            self.dbExecute(sql)
-            p1=os.path.join(sys.path[0],'..')
-
-            titles = [['keywordConcepts','GEMET - Concepts, version 2.4'],
-                     ['keywordThemes','GEMET - Themes, version 2.4'],
-                     ['keywordGroups','GEMET - Groups, version 2.4']]
-            for title in titles:
-                path = os.path.join(p1, 'config', title[0])
-                str=''
-                with open(path, "r") as inp :
-                    exec(inp.read())
-
-                    for item in keywords:
-                            str+="('%s','%s','%s','%s'),"%(title[1],item['preferredLabel']['string'],'2010-01-13','publication')
-                    str=str[:-1]
-                    sql="INSERT INTO 'metadata_themes' ('title', 'keyword', 'date_iso' ,'date_type' ) VALUES"+str
-                inp.close()
-                self.dbExecute(sql)
-
-    def fillKeywordsList(self):
-        sql='SELECT title,keyword,date_iso,date_type FROM metadata_themes'
-
-        #TODO check if database exist
-        self.keysDict=None
-        metaRepository=self.dbSelect(sql)
-        self.titles={}
-        theme=''
-        titleTmp=None
-        lines=metaRepository.splitlines()
-        #lines.pop()
-        for line in lines:
-            line=line.split('|')
-            if theme != line[0]: #if new theme found
-                if titleTmp is not None:#first loop
-                    self.titles[titleTmp]=self.keysDict
-                theme=line[0]
-                self.keysDict={}
-                self.keysDict['date']=line[2]
-                self.keysDict['type']=line[3]
-                self.keysDict['keywords']=[1]
-            self.keysDict['keywords'].append(str(line[1]))
-            titleTmp=line[0]
-
-        if self.keysDict is None:
-            GMessage('Predefined values of metadata are missing in database')
-            return
-        self.titles[titleTmp]=self.keysDict
-
-        for key in self.titles.keys():
-            self.comboKeys.Append(key)
-
-    def onSetVocabulary(self,evt):
-        self.keysList.DeleteAllItems()
-        self.root=self.keysList.AddRoot('Keywords')
-        title=self.comboKeys.GetValue()
-
-        keywords=self.titles[title]['keywords']
-        keywords.pop(0)
-        for keyword in keywords:
-            self.keysList.AppendItem(parent=self.root,text=str(keyword))
-        self.keysList.ExpandAll()
-
-    def layout(self):
-        self.Add(self.box,flag=wx.EXPAND)
-        self.Add(self.comboKeysLabel,flag=wx.EXPAND)
-        self.Add(self.comboKeys,flag=wx.EXPAND)
-        self.AddSpacer(10, 10, 1, wx.EXPAND)
-
-        self.Add(self.keysList,proportion=1,flag=wx.EXPAND)
-
-
-#=========================================================================
-# MAIN FRAME
-#=========================================================================
-class MdMainEditor(wx.Panel):
-
-    '''
-    main functions : self.generateGUI(): generating GUI from: editor:MdItem,MdBox,MdNotebookPage
-                     self.createNewMD(): filling OWSLib.iso.MD_Metadata by values from generated GUI
-                     self.defineTemplate(): creator of predefined templates in template editor mode
-    '''
-
-    def __init__(self, parent, profilePath, xmlMdPath, templateEditor=False):
-        '''
-        @param profilePath: path to jinja template for generating GUI of editor
-        @param xmlMdPath: path of xml for init Editor
-        @param templateEditor: mode-creator of template
-        '''
-        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
-        self.mdo = MdFileWork()
-        self.md = self.mdo.initMD(xmlMdPath)
-        self.templateEditor = templateEditor
-        self.profilePath = profilePath
-
-        self.jinj = JinjaTemplateParser(self.profilePath)
-        # list of object MdDescription
-        self.mdDescription = self.jinj.mdDescription
-        # string of tags from jinja template (loops and OWSLib objects)
-        self.mdOWSTagStr = self.jinj.mdOWSTagStr
-        self.mdOWSTagStrList = self.jinj.mdOWSTagStrList  #
-        self.keywords=None
-        self.nbPage=None
-        self.generateGUI()
-        self._layout()
-
- #----------------------------------------------------------- GUI GENERATOR START
-    def executeStr(self, stri, mdDescrObj):
-        '''note- exec cannot be in sub function
-        for easy understanding to product of self.generateGUI()- print stri
-        '''
-        #print stri
-        exec stri
-
-    def plusC(self, num=None):
-        '''iterator for handling jinja teplate items in self.generateGUI and self.createNewMD
-
-        '''
-        if num is None:
-            num = 1
-        self.c += num
-        if self.c >= self.max:
-            self.c -= 1  # ensure to 'list out of bounds'
-            self.stop = True
-
-    def minusC(self, num=None):
-        '''iterator for handling jinja template items in self.generateGUI and self.createNewMD
-        '''
-        if num is None:
-            num = 1
-        self.c -= num
-        if self.c <= self.max:
-            self.stop = False
-
-    def generateGUI(self):
-        '''
-        @var tagStringLst:  tagStringLst is self.mdOWSTagStr in list.
-                            Item=line from jinja template(only lines with owslib objects and loops)
-        @var mdDescrObj:    list of MdDescription() objects initialized\
-                            by information from jinja t.
-        @var self.c:        index of var: tagStringLst and var: self.mdDescription
-        @var markgroup:     markers of created list in GUI notebook
-        @var self.max:      length of tagStringLst and mdDescrObj
-        @var self.stop:     index self.c is increasing  by function plusC(),\
-                            that care about not exceeding the index
-        HINT: print param stri in self.executeStr()
-        '''
-        def prepareStatements():
-            '''in jinja template are defining some py-function specifically:
-            e.g. |length=len
-            also statements with pythonic 'zip' must be prepare specifically for generator of GUI
-            '''
-            for c in range(self.max):
-                if '|length' in str(tagStringLst[c]):
-                    a = tagStringLst[c]
-                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
-                    tagStringLst[c] = a
-                if 'zip(' in tagStringLst[c]:
-                    sta = tagStringLst[c]
-                    tagStringLst[c] = sta.replace('md.', 'self.md.')
-
-        def chckIfJumpToLoop(sta):
-            '''if loaded xml not include tags(OWSLib object) from jinja template, this function will
-                    generate sample of item(marked by red in GUI-template mode).
-            @note: in case of sub statements e.g. metadata-keywords is need to check booth statements
-            @param sta: statements of the loop
-            for understanding print param for self.executeStr()
-            '''
-            self.isValidS = False
-            staTMP = sta
-            if not '\t'in staTMP:
-                tab = '\t'
-                tab1 = ''
-                staTMP = staTMP + ":\n" + tab + 'self.isValidS=True'
-            else:
-                tab = '\t'
-                tab1 = '\t'
-                staTMP = staTMP.replace('\t', '') + ":\n" + tab + 'self.isValidS=True'
-
-            try:  # if loop for in for
-                self.executeStr(staTMP, False)
-            except:
-                staTMP = self.staTMP.replace('self.isValidS=True', '') + '\n\t' + staTMP.replace('\t', '\t\t')
-                self.executeStr(staTMP, False)
-
-            self.staTMP = staTMP
-            if self.isValidS:
-                return sta
-            else:
-                return tab1 + 'for n in range(1)'
-
-        def inBlock():
-            '''This part of code build string-code for executing. This can happend if is necassary to use statements
-                to generate gui(OWSLib objects in list). The block of code is building from "statement" which is represended by OWSLib object.
-                In case if OWSLib object is non initialized(metadata missing), function chckIfJumpToLoop() replace statements by "for n in range(1)".
-            @var IFStatements: True= string is IF statements
-            @var loop: current statements, mostly loop FOR
-            @var str1: final string for execute
-            @var box:  True if editor::MdItems is in editor::MdBox
-            @var isValid: True in case if OWSLib object in statement is initialized. False= statements is 'for n in range(1)'
-            '''
-            IFStatements = False
-            statements = tagStringLst[self.c - 1]
-            if 'if' in statements.split():
-                IFStatements = True
-            loop = statements.replace(' md.', ' self.md.')
-            looptmp = chckIfJumpToLoop(loop)
-            str2 = 'numOfSameBox=0\n'
-            str2 += looptmp
-
-            str2 += ':\n'
-            str2 += '\t' + 'self.ItemList=list()\n'  # initialize list
-            str2 += '\t' + 'numOfSameBox+=1\n'
-
-            box = False
-            if self.mdDescription[self.c].inbox:
-                box = True
-                str2 += '\t' + 'box=MdBox(self.nbPage,mdDescrObj[' + str(self.c) + '].inbox)\n'  # add box
-
-            str1 = str2
-            while '\t' in tagStringLst[self.c] and self.stop is False:
-                if  'for' not in str(tagStringLst[self.c]).split()\
-                        and 'if' not in str(tagStringLst[self.c]).split():
-
-                    value = str(self.mdOWSTagStrList[self.c])
-                    str1 += '\t' + 'self.mdDescription[' + str(self.c) + "].addStatements('" + loop + "')\n"
-
-                    if box:
-                        str1 +=     '\t' + \
-                            'it=MdItem(parent=box,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameBox,chckBox=self.templateEditor)\n'
-                    else:
-                        str1 +=     '\t' + \
-                            'it=MdItem(parent=self.nbPage,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameBox,chckBox=self.templateEditor)\n'
-
-                    if self.isValidS:  # if metadata are loaded to owslib
-                        if IFStatements:
-                            str1 += '\t' + 'it.setValue(self.' + str(value) + ')\n'
-                        else:
-                            str1 += '\t' + 'it.setValue(' + str(value) + ')\n'
-                    else:
-                        if IFStatements:
-                            str1 += '\t' + 'it.setValue("")\n'
-                        else:
-                            str1 += '\t' + 'it.setValue("")\n'
-
-                    str1 += '\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(it)\n'
-                    str1 += '\t' + 'self.ItemList.append(it)\n'
-                    tab = '\t'
-                    self.plusC()
-
-                else:  # if statements in statements
-                    statements = tagStringLst[self.c]
-                    str2 = ''
-                    keyword = False
-
-                    if '["keywords"]' in statements:
-                        keyword = True
-                        str2 += '\t' + 'self.keywordsList=[]\n'
-
-                    str2 += '\t' + 'numOfSameItem=0\n'
-                    loop2 = statements.replace(' md.', ' self.md.')
-                    looptmp1 = chckIfJumpToLoop(loop2)
-                    str2 += looptmp1 + ':\n'
-                    self.plusC()
-                    str1 += str2
-                    while '\t\t' in tagStringLst[self.c] and self.stop is False:
-                        value = str(self.mdOWSTagStrList[self.c])
-                        # save information about loops
-                        str1 += '\t\t' + 'numOfSameItem+=1\n'
-                        str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + "].addStatements('" + loop + "')\n"
-                        str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + "].addStatements1('" + loop2 + "')\n"
-
-                        if box:
-                            str1 += '\t\t' + \
-                                'it=MdItem(parent=box,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameItem,chckBox=self.templateEditor)\n'
-                        else:
-                            str1 += '\t\t' + \
-                                'it=MdItem(self.nbPage,mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameItem,chckBox=self.templateEditor)\n'
-
-                        if self.isValidS:
-                            str1 += '\t\t' + 'it.setValue(' + str(value) + ')\n'
-                        else:
-                            str1 += '\t\t' + 'it.setValue("")\n'
-
-                        str1 += '\t\t' + 'self.ItemList.append(it)\n'
-                        if keyword:
-                            str1 += '\t\t' + 'self.keywordsList.append(it)\n'
-                            str1 += '\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(self.keywordsList)\n'
-                        else:
-                            str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(it)\n'
-
-                        tab = '\t\t'
-                        self.plusC()
-            if box:
-                str1 += tab +\
-                    'box.addItems(items=self.ItemList,multi=mdDescrObj[self.c].inboxmulti,isFirstNum=numOfSameBox)\n'
-                str1 += tab + 'self.nbPage.addItem(box)\n'
-            else:
-                str1 += tab + 'self.nbPage.addItem(self.ItemList)\n'
-
-            self.executeStr(str1, mdDescrObj)
-
-    #--------------------------------------------------------------------- INIT VARS
-        self.notebook = wx.Notebook(self)
-        markedgroup = []  # notebook panel marker
-        tagStringLst = self.mdOWSTagStrList
-        mdDescrObj = self.mdDescription  # from jinja
-        self.c = 0
-        self.stop = False
-        self.max = len(mdDescrObj)
-        prepareStatements()
-        self.notebokDict = {}
-    # --------------------------------------------- #START of the loop of generator
-        while self.stop is False:  # self.stop is managed by def plusC(self):
-            group = mdDescrObj[self.c].group
-
-            if group not in markedgroup:  # if group is not created
-                markedgroup.append(group)  # mark group
-                self.nbPage = MdNotebookPage(self.notebook)
-                self.notebook.AddPage(self.nbPage, mdDescrObj[self.c].group)
-                if mdDescrObj[self.c].group=='Keywords':
-                    self.keywords=MdKeywords(parent=self.nbPage,mdObject=mdDescrObj[self.c],mdOWS=self.md.identification.keywords)
-                    self.nbPage.addKeywordObj(self.keywords)
-                self.notebokDict[mdDescrObj[self.c].group] = self.nbPage
-            else:
-                self.nbPage = self.notebokDict[mdDescrObj[self.c].group]
-
-            # if  statements started
-            if '\t' in tagStringLst[self.c] and self.stop is False:
-                inBlock()
-            # if is just single item without statements
-            elif 'for' not in str(tagStringLst[self.c]).split() and 'if' not in str(tagStringLst[self.c]).split():
-                it = MdItem(parent=self.nbPage, item=mdDescrObj[self.c], chckBox=self.templateEditor)
-                value = 'self.' + str(self.mdOWSTagStrList[self.c]).replace('\n', '')
-                print value
-                value = eval(value)
-                if value is None:
-                    value = ''
-
-                it.setValue(value)
-                self.mdDescription[self.c].addMdItem(it)
-                self.nbPage.addItem(it)
-                self.plusC()
-            else:
-                self.plusC()
-        if self.templateEditor:
-            self.refreshChkboxes()
-
-    def refreshChkboxes(self):
-        '''In case if template editor is on, after generating GUI it is
-         obligatory to refresh checkboxes
-        '''
-        for item in self.mdDescription:
-            for i in item.mdItem:
-                try:
-                    i.onChangeChckBox(None)
-                    i.onChangeChckBox(None)
-                except:
-                    pass
-    #----------------------------------------------------------- GUI GENERATOR END
-
-    def defineTemplate(self):
-        '''Main function for generating jinja template in mode "template editor"
-        Every widget MdItem is represented by 'jinja tag'. Not checked widget= tag in jinja template will be replaced by
-        list of string with string of replaced tag. In rendering template this produces holding(non removing) jinja-tag from template.
-        In case if widget is checked= rendering will replace OWSLib object by filled values( like in normal editing mode)
-        @var finalTemplate:    string included final jinja template
-        '''
-        try:
-            template = open(self.profilePath, 'r')
-        except Exception, e:
-            GError('Error loading template:\n' + str(e))
-
-        owsTagList = list()
-        indexowsTagList = 0
-        finalTemplate = ''
-        chcked = False
-        forSTS = False
-        ifSTS = False
-
-        for line in template.readlines():
-            if '{% for' in line:
-                forSTS = True
-
-            if '{% if' in line:
-                ifSTS = True
-
-            for r, item in enumerate(self.mdDescription):
-                str1 = item.selfInfoString
-                if str1 in line:  # owslib definition in line
-                    try:
-                        if item.mdItem[0].isChecked == False:
-                            chcked = False
-                    except:
-                        try:
-                            if self.mdDescription[r + 1].mdItem[0].isChecked == False:
-                                chcked = False
-                        except:
-                            try:
-                                if self.mdDescription[r + 2].mdItem[0].isChecked == False:
-                                    chcked = False
-                            except:
-                                try:
-                                    if self.mdDescription[r + 3].mdItem[0].isChecked == False:
-                                        chcked = False
-                                except:
-                                    pass
-                    if not chcked:  # chckbox in gui
-
-                        if forSTS:
-                            forSTS = False
-
-                        if ifSTS:
-                            ifSTS = False
-
-                        owsTagList.append(str1)
-                        templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
-                        indexowsTagList += 1
-
-                        line = line.replace(str1, templateStr)
-                        tag = '{{ ' + item.tag + ' }}'
-                        line = line.replace(tag, templateStr)
-
-                        finalTemplate += line
-                        continue
-
-            if chcked:
-                if '{% endfor -%}' in line and forSTS == 0:
-                    str1 = '{% endfor -%}'
-                    owsTagList.append(str1)
-                    templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
-                    indexowsTagList += 1
-
-                    line = line.replace(str1, templateStr)
-                    tag = '{{' + item.tag + '}}'
-                    line = line.replace(tag, templateStr)
-                    finalTemplate += line
-
-                elif '{% endif -%}' in line and ifSTS == 0:
-                    str1 = '{% endif -%}'
-                    owsTagList.append(str1)
-                    templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
-                    indexowsTagList += 1
-
-                    line = line.replace(str1, templateStr)
-                    tag = '{{' + item.tag + '}}'
-                    line = line.replace(tag, templateStr)
-                    finalTemplate += line
-
-                else:
-                    finalTemplate += line
-            chcked = True
-
-        head, tail = os.path.split(self.profilePath)
-        tail = 'EXPT' + tail
-        self.profilePath = os.path.join(head, tail)
-        templateOut = open(self.profilePath, 'w')
-        templateOut.write(finalTemplate)
-        templateOut.close()
-
-
-        return owsTagList
-    #----------------------------------------- FILL OWSLib BY EDITED METADATA IN GUI
-
-    def executeStr1(self, stri, item):
-        '''note- exec cannot be in sub function
-        for easier understanding to product of self.createNewMD()- print stri
-        '''
-        # print stri
-        exec stri
-
-    def getKeywordsFromRepositoryWidget(self,md):
-        if  self.keywords is not None:
-            for item in self.keywords.GetKws():
-                titles=item.getKyewordObj()
-
-                kw = {}
-                kw['keywords'] = []
-                kw['keywords'].append(titles['keywords'])
-                kw['type'] = None
-                kw['thesaurus'] = {}
-                kw['thesaurus']['title']=titles['title']
-                kw['thesaurus']['date']=titles['date']
-                kw['thesaurus']['datetype']=titles['type']
-                md.identification.keywords.append(kw)
-        return md
-
-    def saveMDfromGUI(self, evt=None):
-        '''Main function for exporting metadata from filled widgets.
-           Initializing owslib object by metadata from gui(export of metadata)
-        '''
-        def prepareStatements():
-            '''replacing some specific declaration of python function in jinja template
-            '''
-            for c in range(self.max):
-                if '|length' in str(mdDes[c].tag):
-                    a = mdDes[c].tag
-                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
-                    mdDes[c].tag = a
-                if '|length' in str(mdDes[c].statements):
-                    a = mdDes[c].statements
-                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
-                    mdDes[c].statements = a
-                if '|length' in str(mdDes[c].statements1):
-                    a = mdDes[c].statements1
-                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
-                    mdDes[c].statements1 = a
-
-        def chckIf1Statements():
-            '''Return true if next item in jinjainfo::MdDescription is statement
-            '''
-            try:
-                if mdDes[self.c + 1].statement:
-                    return True
-                else:
-                    return False
-            except:
-                return False
-
-        def chckIf2xStatements():
-            '''Return true if next two items in jinjainfo::MdDescription are representing statements
-            '''
-            if 'if'in mdDes[self.c].tag.split() or 'for' in mdDes[self.c].tag.split():
-                try:
-                    if 'if'in mdDes[self.c + 1].tag.split() or 'for'in mdDes[self.c + 1].tag.split():
-                        return True
-                    else:
-                        return False
-                except:
-                    return False
-
-        def noneStatements():
-            '''Without condition or loop
-            '''
-            str1 = ''
-            for wxCtrl in mdDes[self.c].mdItem:
-                if wxCtrl.getValue() is not None:
-                    str1 += 'self.' + mdDes[self.c].tag + '="' + str(wxCtrl.getValue()) + '"\n'
-                    self.executeStr1(str1, mdDes[self.c])
-                    str1 = ''
-            self.plusC()
-
-        def inStatements():
-            '''possible combinations of statements
-            (1)    IF
-                        item
-                ----------------------------------------------------
-            (2)    for
-            (2.1)          item (with init OWSLib object)
-                       "or"
-            (2.2)          item (without init)
-                           item with ZIP
-            '''
-            cTmp = self.c
-            tag = str(mdDes[cTmp].tag).split()
-
-            tag1 = 'self.' + str(tag[-1])
-            tag = 'self.' + str(tag[-1]) + '.append(self.val)\n'
-
-            self.plusC()
-            # statements of current item
-            stat = mdDes[self.c].statements
-            str1 = ''
-            leng = len(mdDes[self.c].mdItem)
-
-            # (2.1) IF NECESSARY TO INITIALIZE OWSLIB OBJECT
-            if mdDes[cTmp].object and 'if' not in mdDes[cTmp].tag.split():
-                objStr = 'self.val=' + mdDes[cTmp].object + '\n'
-
-                for n in range(leng):
-                    numOfItems = 0
-                    str1 += objStr
-                    while mdDes[self.c].statements == stat and self.stop is False:
-                        metadata = re.split(r'[.]', mdDes[self.c].tag)
-                        metadata[0] = 'self.val.'
-                        str1 += ''.join(metadata) + "='"\
-                            + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
-                        self.plusC()
-                        numOfItems += 1
-
-                    str1 += tag
-                    self.executeStr1(str1, False)
-                    str1 = ''
-                    self.minusC(numOfItems)
-
-                self.plusC(numOfItems)
-            # (2.2) no init and py ZIP'
-            elif 'for' in mdDes[cTmp].tag.split() and mdDes[cTmp].object is None and ' zip(' in mdDes[cTmp].tag:
-                leng = len(mdDes[self.c].mdItem)
-                tag1 = mdutil.findBetween(mdDes[cTmp].tag, 'zip(', ')').split(',')
-
-                for n in range(leng):
-                    numOfItems = 0
-                    while mdDes[self.c].statements == stat and self.stop is False:
-                        str1 += 'self.' + tag1[numOfItems] + ".append('" + mdDes[self.c].mdItem[n].getValue() + "')\n"
-                        self.plusC()
-                        numOfItems += 1
-
-                    self.executeStr1(str1, False)
-                    str1 = ''
-                    self.minusC(numOfItems)
-
-                self.plusC(numOfItems)
-            # 'no init FOR'
-            elif 'for' in mdDes[cTmp].tag.split() and mdDes[cTmp].object is None:
-                leng = len(mdDes[self.c].mdItem)
-                numOfItems = 0
-                for n in range(leng):
-                    numOfItems = 0
-                    while mdDes[self.c].statements == stat and self.stop is False:
-                        str1 += tag1 + ".append('" + mdDes[self.c].mdItem[n].getValue() + "')\n"
-                        self.plusC()
-                        numOfItems += 1
-
-                    self.executeStr1(str1, False)
-                    str1 = ''
-                    self.minusC(numOfItems)
-
-                self.plusC(numOfItems)
-            # (1) 'no init IF'
-            elif 'if' in mdDes[cTmp].tag.split():
-
-                objStr = mdDes[cTmp].tag.replace(' md.', ' self.md.') + ':\n'
-
-                for n in range(leng):
-                    numOfItems = 0
-                    while mdDes[self.c].statements == stat and self.stop is False:
-                        metadata = 'self.' + mdDes[self.c].tag
-                        str1 += ''.join(metadata) + "='"\
-                            + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
-                        self.plusC()
-                        numOfItems += 1
-
-                    self.minusC(numOfItems)
-                    self.executeStr1(str1, False)
-                    str1 = ''
-                self.plusC(numOfItems)
-
-        def in2Statements():
-            '''possible combinations of statements
-            (1)    IF:
-                       FOR:
-            (1.1)           item (with init OWSLib object)
-                            "or"
-            (1.2)           item (without init)
-                ----------------------------------------------------
-            (2)     FOR:
-                        FOR:(implemented fixedly just for MD-keywords)
-            (2.1)            item (with init OWSLib object)
-                             "or"
-            (2.2)            item (without init)
-            '''
-            prepareStatements()
-            cTmp = self.c
-            cTmp1 = self.c + 1
-            tag = str(mdDes[cTmp].tag).split()
-            tag1 = str(mdDes[cTmp1].tag).split()
-            stat = mdDes[self.c + 2].statements
-
-            append = 'self.' + str(tag1[-1]) + '.append(self.val)\n'
-            appendNoInit = 'self.' + str(tag1[-1])
-            # (1)
-            # if statements-if in jinja template=skip and do single loop
-            if 'if' in tag and 'for' in tag1:
-                leng = len(mdDes[self.c + 2].mdItem)
-                # (1.1)
-                if mdDes[cTmp1].object:
-                    condition = mdDes[cTmp].tag.replace(' md.', ' self.md.') + ':\n'
-                    objectOWSLib = '\t' + 'self.val=' + mdDes[cTmp1].object + '\n'
-                    condition2 = '\t' + mdDes[cTmp1].tag.replace(' md.', ' self.md.') + ':\n'
-                    self.plusC()
-                    self.plusC()
-
-                    for n in range(leng):
-                        numOfItems = 0
-                        str1 = condition + '\n'
-                        str1 += condition2 + '\n'
-                        str1 += '\t' + objectOWSLib + '\n'
-
-                        while mdDes[self.c].statements == stat and self.stop is False:
-                            metadata = re.split(r'[.]', mdDes[self.c].tag)
-                            metadata[0] = '\t\tself.val'
-                            str1 += ''.join(metadata) + "='" + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
-                            self.plusC()
-                            numOfItems += 1
-
-                        str1 += '\t\t' + append
-                        self.executeStr1(str1, False)
-                        str1 = ''
-                        self.minusC(numOfItems)
-                    self.plusC(numOfItems)
-                # (1.2)"if and for "
-                else:
-                    self.plusC()
-                    self.plusC()
-                    numOfItems = 0
-                    size = len(mdDes[self.c].mdItem)
-                    for n in range(size):
-                        numOfItems = 0
-                        str1 = ''
-
-                        while mdDes[self.c].statements == stat and self.stop is False:
-                            str1 += appendNoInit + '.append("' + mdDes[self.c].mdItem[n].getValue() + '")\n'
-                            self.plusC()
-                            numOfItems += 1
-
-                        self.executeStr1(str1, False)
-                        self.minusC(numOfItems)
-                    self.plusC(numOfItems)
-            # (2) only keywords  (dict)
-            elif 'for' in tag and 'for' in tag1:  #
-                self.plusC()  # skip statementes 2x
-                self.plusC()
-                numOfkwGroup = len(mdDes[self.c + 1].mdItem)
-                for n in range(numOfkwGroup):
-                    kw = {}
-                    kw['keywords'] = []
-                    try:
-                        keyWordLen = len(mdDes[self.c].mdItem[n])
-                        for k in range(keyWordLen):
-                            kw['keywords'].append(mdDes[self.c].mdItem[n][k].getValue())
-                    except:
-                        kw['keywords'].append(mdDes[self.c].mdItem[n].getValue())
-
-                    kw['type'] = None
-                    kw['thesaurus'] = {}
-                    kw['thesaurus']['title'] = mdDes[self.c + 1].mdItem[n].getValue()
-                    kw['thesaurus']['date'] = mdDes[self.c + 2].mdItem[n].getValue()
-                    kw['thesaurus']['datetype'] = mdDes[self.c + 3].mdItem[n].getValue()
-                    self.md.identification.keywords.append(kw)
-
-                self.plusC()
-                self.plusC()
-                self.plusC()
-                self.plusC()
-#------------------------------------------------------------------------------ next function
-        self.mdo = MdFileWork()
-        self.md = self.mdo.initMD()
-        # most of objects from OWSLib is initialized in configure file
-        dirpath = os.path.dirname(os.path.realpath(__file__))
-        path = os.path.join(os.path.join(sys.path[0],'..'), 'config', 'init_md')
-
-        mdInitData = open(path, 'r')
-        mdExec = mdInitData.read()
-        self.executeStr1(mdExec, None)
-
-        self.c = 0
-        self.stop = False
-        self.max = len(self.mdDescription)
-        mdDes = self.mdDescription
-
-        while self.stop is False:
-            # if no statements
-            if mdDes[self.c].statements is None\
-                    and 'if' not in mdDes[self.c].tag.split()\
-                    and 'for' not in mdDes[self.c].tag.split():
-                noneStatements()
-
-            # if 2x statements
-            elif chckIf2xStatements():
-                in2Statements()
-
-            # if 1x statements
-            elif chckIf1Statements:
-                inStatements()
-
-        self.md = self.getKeywordsFromRepositoryWidget(self.md)
-        return self.md
-#------------------------------------ END- FILL OWSLib BY EDITED METADATA IN GUI
-
-    def exportToXml(self, jinjaPath, outPath, xmlOutName, msg):
-        self.saveMDfromGUI()
-        self.mdo.saveToXML(self.md, None, jinjaPath, outPath, xmlOutName, msg)
-
-    def exportTemplate(self, jinjaPath, outPath, xmlOutName):
-        self.profilePath = jinjaPath
-        owsTagList = self.defineTemplate()
-        self.saveMDfromGUI()
-        self.mdo.saveToXML(self.md, owsTagList,
-                           self.profilePath,
-                           outPath,
-                           xmlOutName,
-                           msg=True,
-                           rmTeplate=True)
-#------------------------------------------------------------------------ LAYOUT
-
-    def _layout(self):
-        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
-        self.SetSizer(self.mainSizer)
-        noteSizer = wx.BoxSizer(wx.VERTICAL)
-        self.notebook.SetSizer(noteSizer)
-        self.mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND)
-        self.Show()
-#----------------------------------------------------------------------
-if __name__ == "__main__":
-    app = wx.App(False)
-    frame = MdMainEditor()
-    app.MainLoop()
\ No newline at end of file

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswlib.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswlib.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswlib.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,1216 @@
+#!/usr/bin/env python
+
+import sys,os
+import grass.script as grass
+from modules.import_export import GdalImportDialog, GdalOutputDialog, ImportDialog
+
+from owslib.csw import CatalogueServiceWeb
+import webbrowser
+from cswutil import *
+import wx
+from wx import SplitterWindow
+import wx.html as html
+import webbrowser
+from threading import Thread
+import xml.etree.ElementTree as ET
+
+from wx.lib.buttons import ThemedGenBitmapTextButton as BitmapBtnTxt
+from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
+# import wx.html2 not supported in 2.8.12.1 (need for CSS support)
+from owslib.csw import CatalogueServiceWeb
+from owslib.fes import BBox, PropertyIsLike
+from owslib.ows import ExceptionReport
+import json
+import ipdb
+from core.utils import GetFormats
+from gui_core.forms import GUI
+from core.gcmd import RunCommand, GError, GMessage, GWarning
+from wx.html import HTML_URL_IMAGE, HTML_OPEN, EVT_HTML_LINK_CLICKED, HW_DEFAULT_STYLE, HW_SCROLLBAR_NEVER, \
+    HW_SCROLLBAR_AUTO
+import tempfile
+
+from subprocess import PIPE
+from grass.pygrass.modules import Module
+from grass.script import parse_key_val
+from cswutil import *
+#sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'config'))
+
+class ConstraintsBulder(wx.Panel):
+    def __init__(self, parent, settings=''):
+        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+        self.label = wx.StaticText(self, -1, label="Manual for creating constraints:\n\
+*Constraints must be in brackets([]) \n\
+*Constraints must be in quotation marks(') \n\
+Examples\n\
+      OR expression\n\
+      a || b || c\n\
+      ['a','b','c']\n\
+      \n\
+      AND expression \n\
+       a && b && c\n\
+      [['a','b','c']]\n\
+      \n\
+      More expressions \n\
+      (a && b) || c || d || e\n\
+      [['a','b'],['c'],['d'],['e']] or [['a','b'],'c','d','e']")
+
+        self.constrCtrl = wx.TextCtrl(self, -1)
+        self.applyBtt = wx.Button(self, -1, label='Apply')
+        self.cancelBtt = wx.Button(self, -1, label='Cancel')
+
+        self.constrCtrl.SetValue(settings)
+        self._layout()
+
+    def _layout(self):
+        panelSizer = wx.BoxSizer(wx.VERTICAL)
+        panelSizer.Add(self.label)
+        panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        panelSizer.Add(self.constrCtrl, 1, wx.EXPAND)
+
+        horSizer = wx.BoxSizer(wx.HORIZONTAL)
+        horSizer.Add(self.applyBtt)
+        horSizer.Add(self.cancelBtt)
+        panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        panelSizer.Add(horSizer)
+        self.SetSizerAndFit(panelSizer)
+
+
+class CSWBrowserPanel(wx.Panel):
+    def __init__(self, parent, main):
+        self.context = StaticContext()
+        self.config = wx.Config('g.gui.cswbrowser')
+        wx.Panel.__init__(self, parent)
+        self.parent = main
+        self.constraintsWidgets = []
+        self.constraintsWidgets1 = []
+        self.constraintsAdvanced = False
+        self.idResults = []
+        self.constString = ''
+        sizeConst = 55
+        self.splitterBrowser = SplitterWindow(self, style=wx.SP_3D | wx.SP_LIVE_UPDATE | wx.SP_BORDER)
+       # self.connectionFilePath = os.path.join('config', 'connections_resources.xml')
+        self.context=StaticContext()
+        self.connectionFilePath = os.path.join(self.context.addonsPath, 'connections_resources.xml')
+
+        self.pnlLeft = wx.Panel(self.splitterBrowser, id=wx.ID_ANY)
+        self.pnlRight = wx.Panel(self.splitterBrowser, -1)
+
+        self.keywordLbl = wx.StaticText(self.pnlLeft, -1, 'Keywords')
+        self.numResultsLbl = wx.StaticText(self.pnlLeft, -1, 'Max')
+        self.catalogLbl = wx.StaticText(self.pnlLeft, -1, 'Catalog')
+        self.findResNumLbl = wx.StaticText(self.pnlLeft, -1, '')
+        # self.advancedFilter = wx.Button(self.pnlLeft,-1,'Advanced')
+
+        self.advanceChck = wx.CheckBox(self.pnlLeft, label='Advanced')
+        self.advanceChck.Bind(wx.EVT_CHECKBOX, self.OnKeywordDialog)
+        self.stbFind = wx.StaticBox(self.pnlLeft, -1, 'Filter')
+        self.stbSearch = wx.StaticBox(self.pnlLeft, -1, 'Search settings')
+
+        # self.abstractCtrl = wx.TextCtrl(self.pnlRight, style=wx.TE_MULTILINE | wx.HSCROLL)
+
+        self.catalogCmb = wx.ComboBox(self.pnlLeft, id=-1, pos=wx.DefaultPosition)
+        self.catalogCmb.Bind(wx.EVT_COMBOBOX, self.OnSetCatalog)
+        w, self.h = self.catalogCmb.GetSize()
+        self.numResultsSpin = wx.SpinCtrl(self.pnlLeft, min=1, max=100, initial=20, size=(sizeConst, self.h),
+                                          style=wx.ALIGN_RIGHT | wx.SP_ARROW_KEYS)
+
+        self.keywordCtr = wx.TextCtrl(self.pnlLeft)
+        self.addKeywordCtr = wx.Button(self.pnlLeft, -1, '+', size=(self.h, self.h))
+        self.addKeywordCtr.Bind(wx.EVT_BUTTON, self.addKeyWidget)
+        self.findBtt = wx.Button(self.pnlLeft, size=(sizeConst, self.h), label='Find')
+        self.findBtt.SetBackgroundColour((255, 127, 80))
+        self.qtypeRb = wx.RadioButton(self.pnlLeft, label='All', style=wx.RB_GROUP)
+        self.qtypeRb1 = wx.RadioButton(self.pnlLeft, label='Dataset')
+        self.qtypeRb2 = wx.RadioButton(self.pnlLeft, label='Service')
+        self.qtypeRb.SetValue(True)
+
+        # -----Results---
+        self.resultList = AutoWidthListCtrl(self.pnlLeft)
+        self.resultList.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.setTooltip)
+        self.resultList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnRecord)
+        self.bttNextItem1 = wx.Button(self.pnlLeft, label=">")
+        self.bttNextItem2 = wx.Button(self.pnlLeft, label=">>")
+        self.bttBackItem1 = wx.Button(self.pnlLeft, label="<")
+        self.bttBackItem2 = wx.Button(self.pnlLeft, label="<<")
+
+        self.bttNextItem1.Bind(wx.EVT_BUTTON, self.OnNavigate, self.bttNextItem1)
+        self.bttNextItem2.Bind(wx.EVT_BUTTON, self.OnNavigate, self.bttNextItem2)
+        self.bttBackItem1.Bind(wx.EVT_BUTTON, self.OnNavigate, self.bttBackItem1)
+        self.bttBackItem2.Bind(wx.EVT_BUTTON, self.OnNavigate, self.bttBackItem2)
+        self.findBtt.Bind(wx.EVT_BUTTON, self.OnSearch)
+        self.refreshResultList()
+
+        # -----BB---------
+        self.stbBB = wx.StaticBox(self.pnlLeft, -1, 'Extent')
+        self.bbWestLb = wx.StaticText(self.pnlLeft, -1, 'Xmin')
+        self.bbSouthLb = wx.StaticText(self.pnlLeft, -1, 'Ymin')
+        self.bbEastLb = wx.StaticText(self.pnlLeft, -1, 'Xmax')
+        self.bbNorthLb = wx.StaticText(self.pnlLeft, -1, 'Ymax')
+
+        self.bbWest = wx.TextCtrl(self.pnlLeft)
+        self.bbSouth = wx.TextCtrl(self.pnlLeft)
+        self.bbEast = wx.TextCtrl(self.pnlLeft)
+        self.bbNorth = wx.TextCtrl(self.pnlLeft)
+        '''
+        self.bbWest.Bind(wx.EVT_TEXT_ENTER, self.OnTypeBB)
+        self.bbSouth.Bind(wx.EVT_TEXT_ENTER, self.OnTypeBB)
+        self.bbEast.Bind(wx.EVT_TEXT_ENTER, self.OnTypeBB)
+        self.bbNorth.Bind(wx.EVT_TEXT_ENTER, self.OnTypeBB)
+        '''
+        self.bbSetGlobalBtt1 = wx.Button(self.pnlLeft, label="Global")
+        self.bbSetMapExtendBtt1 = wx.Button(self.pnlLeft, label="Map extent")
+        self.bbSetGlobalBtt1.Bind(wx.EVT_BUTTON, self.setBBoxGlobal)
+        self.bbSetMapExtendBtt1.Bind(wx.EVT_BUTTON, self.setBBoxGRASS)
+        self.setBBoxGlobal()
+        # -----right panel
+
+        self.bttAddWms = wx.Button(self.pnlRight, label="Add WMS")
+        self.bttAddWfs = wx.Button(self.pnlRight, label="Add WFS")
+        self.bttAddWcs = wx.Button(self.pnlRight, label="Add WCS")
+        self.bttAddWms.Bind(wx.EVT_BUTTON, self.OnService, self.bttAddWms)
+        self.bttAddWfs.Bind(wx.EVT_BUTTON, self.OnService, self.bttAddWfs)
+        self.bttAddWcs.Bind(wx.EVT_BUTTON, self.OnService, self.bttAddWcs)
+
+        self.bttViewRequestXml = wx.Button(self.pnlRight, label="Request XML")
+        self.bttViewResponseXml = wx.Button(self.pnlRight, label="Response XML")
+
+        self.bttViewRequestXml.Bind(wx.EVT_BUTTON, self.OnShowReguest)
+        self.bttViewResponseXml.Bind(wx.EVT_BUTTON, self.OnShowResponse)
+
+        self.htmlView = html.HtmlWindow(self.pnlRight,
+                                        id=-1,
+                                        pos=wx.DefaultPosition,
+                                        size=wx.DefaultSize,
+                                        style=HW_DEFAULT_STYLE | HW_SCROLLBAR_AUTO,
+                                        name="metadata")
+        self.htmlView.Bind(EVT_HTML_LINK_CLICKED, self.onHtmlLinkClicked)
+        #self.htmlView=wx.html2.WebView.New(self.pnlRight, not supported in 2.8.12.1
+        self.refreshNavigationButt()
+        self._layout()
+
+    '''
+    def OnTypeBB(self,evt):
+        raw_value = evt.GetValue().strip()
+        # numeric check
+        print raw_value
+        if all(x in '0123456789.+-' for x in raw_value):
+            evt.ChangeValue(raw_value)
+    '''
+
+    def OnKeywordDialog(self, evt):
+        if self.advanceChck.GetValue():
+            self.geDialog = wx.Dialog(self, id=wx.ID_ANY,
+                                      title='constraints builder',
+                                      style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
+                                      size=wx.DefaultSize,
+                                      pos=wx.DefaultPosition)
+
+            self.geDialog.SetSize((500, 500))
+            self.constrPnl = ConstraintsBulder(self.geDialog, self.constString)
+            self.constrPnl.applyBtt.Bind(wx.EVT_BUTTON, self.OnSetAdvancedConstraints)
+            self.constrPnl.cancelBtt.Bind(wx.EVT_BUTTON, self._destroyDialog)
+            dbSizer = wx.BoxSizer(wx.VERTICAL)
+            dbSizer.Add(self.constrPnl, flag=wx.EXPAND)
+            self.geDialog.SetSizer(dbSizer)
+            self.geDialog.SetBestFittingSize()
+            self.geDialog.ShowModal()
+
+    def _destroyDialog(self, evt):
+        self.advanceChck.SetValue(False)
+        self.geDialog.Destroy()
+
+    def OnSetAdvancedConstraints(self, evt):
+        self.constString = self.constrPnl.constrCtrl.GetValue()
+        if self.constString == '':
+            return
+        # print self.constString
+        constString = 'self.constraints=' + self.constString
+        # print(constString)
+        try:
+            exec (constString)
+        except:
+            GMessage('Constraints syntax error')
+            return
+        self.constraintsAdvanced = True
+        self.geDialog.Destroy()
+
+    def addKeyWidget(self, evt):
+        name = evt.GetEventObject().GetLabel()
+        if name == '+':
+            kw = wx.TextCtrl(self.pnlLeft)
+            addKeywordCtr = wx.Button(self.pnlLeft, -1, '-', size=(self.h, self.h))
+            addKeywordCtr.Bind(wx.EVT_BUTTON, self.addKeyWidget)
+
+            self.constraintsWidgets.append(kw)
+            self.constraintsWidgets1.append(addKeywordCtr)
+
+            self.leftSearchSizer.Add(kw, 0, wx.EXPAND)
+            self.rightSearchSizer.Add(addKeywordCtr, 0)
+        else:
+            sizeLeft = len(self.leftSearchSizer.GetChildren())
+            sizeRight = len(self.rightSearchSizer.GetChildren())
+
+            self.constraintsWidgets.pop().Destroy()
+            self.constraintsWidgets1.pop().Destroy()
+
+            self.leftSearchSizer.Remove(sizeLeft)
+            self.rightSearchSizer.Remove(sizeRight)
+        self.Fit()
+
+    def OnShowReguest(self, evt):
+        # if self.webBrowser.GetValue:
+        request_html = encodeString(highlight_xml(self.context, self.catalog.request))
+        path = 'htmlRequest.html'
+
+        f = open(path, 'w')
+        f.write(request_html)
+        f.close()
+        if YesNo(self, 'Do you want to open <request> in default browser', 'Open file'):
+            open_url(path)
+        self.htmlView.SetPage((renderXML(self.context, self.catalog.request)))
+
+    def OnShowResponse(self, evt):
+        # if self.webBrowser.GetValue:
+        # print self.catalog.response
+        response_html = encodeString(highlight_xml(self.context, self.catalog.response))
+        path ='htmlResponse.html'
+        f = open(path, 'w')
+        f.write(response_html)
+        f.close()
+        if YesNo(self, 'Do you want to open <response> in default browser', 'Open file'):
+            open_url(path)
+        self.htmlView.SetPage((renderXML(self.context, self.catalog.response)))
+
+    def OnRecord(self, evt):
+        """show record metadata"""
+        self.refreshServiceButt()
+        curr = 0
+        idx = self.resultList.GetNextItem(curr, wx.LIST_NEXT_ALL,
+                                          wx.LIST_STATE_SELECTED)
+        if not idx:
+            return
+
+        identifier = self.get_item_data(idx, 'identifier')
+        try:
+            cat = CatalogueServiceWeb(self.catalog_url, timeout=self.timeout)
+            cat.getrecordbyid(
+                [self.catalog.records[identifier].identifier])
+        except ExceptionReport, err:
+            GWarning('Error getting response: %s' % err)
+            return
+        except KeyError, err:
+            GWarning('Record parsing error, unable to locate record identifier')
+            return
+
+        record = cat.records[identifier]
+        record.xml_url = cat.request
+
+        if self.catalog:
+            path='record_metadata_dc.html'
+            metadata = render_template('en', self.context,
+                                       record,
+                                       path)
+
+        try:
+            record = self.catalog.records[identifier]
+        except KeyError, err:
+            GWarning('@!Record parsing error, unable to locate record identifier')
+            return
+
+        self.htmlView.SetPage(metadata)
+        self.findServices(record, idx)
+
+    def findServices(self, record, item):
+        """scan record for WMS/WMTS|WFS|WCS endpoints"""
+        links = record.uris + record.references
+        WMSWMST_LINK_TYPES = [
+            'OGC:WMS',
+            'OGC:WMTS',
+            'OGC:WMS-1.1.1-http-get-map',
+            'OGC:WMS-1.1.1-http-get-capabilities',
+            'OGC:WMS-1.3.0-http-get-map',
+            'OGC:WMS-1.3.0-http-get-capabilities',
+            'urn:x-esri:specification:ServiceType:wms:url',
+            'urn:x-esri:specification:ServiceType:Gmd:URL.wms'
+        ]
+
+        WFS_LINK_TYPES = [
+            'OGC:WFS',
+            'OGC:WFS-1.0.0-http-get-capabilities',
+            'OGC:WFS-1.1.0-http-get-capabilities',
+            'urn:x-esri:specification:ServiceType:wfs:url',
+            'urn:x-esri:specification:ServiceType:Gmd:URL.wfs'
+        ]
+
+        WCS_LINK_TYPES = [
+            'OGC:WCS',
+            'OGC:WCS-1.1.0-http-get-capabilities',
+            'urn:x-esri:specification:ServiceType:wcs:url',
+            'urn:x-esri:specification:ServiceType:Gmd:URL.wcs'
+        ]
+        services = {}
+        for link in links:
+
+            if 'scheme' in link:
+                link_type = link['scheme']
+            elif 'protocol' in link:
+                link_type = link['protocol']
+            else:
+                link_type = None
+
+            if link_type is not None:
+                link_type = link_type.upper()
+
+            wmswmst_link_types = map(str.upper, WMSWMST_LINK_TYPES)
+            wfs_link_types = map(str.upper, WFS_LINK_TYPES)
+            wcs_link_types = map(str.upper, WCS_LINK_TYPES)
+
+            # if the link type exists, and it is one of the acceptable
+            # interactive link types, then set
+            if all([link_type is not None,
+                    link_type in wmswmst_link_types + wfs_link_types +
+                            wcs_link_types]):
+                if link_type in wmswmst_link_types:
+                    services['wms'] = link['url']
+                    self.bttAddWms.Enable()
+                if link_type in wfs_link_types:
+                    services['wfs'] = link['url']
+                    self.bttAddWfs.Enable()
+                if link_type in wcs_link_types:
+                    services['wcs'] = link['url']
+                    self.bttAddWcs.Enable()
+
+            self.set_item_data(item, 'link', json.dumps(services))
+
+    def refreshNavigationButt(self, stat=False):
+        if stat:
+            self.bttNextItem1.Enable()
+            self.bttNextItem2.Enable()
+            self.bttBackItem1.Enable()
+            self.bttBackItem2.Enable()
+            self.bttViewRequestXml.Enable()
+            self.bttViewResponseXml.Enable()
+        else:
+            self.bttNextItem1.Disable()
+            self.bttNextItem2.Disable()
+            self.bttBackItem1.Disable()
+            self.bttBackItem2.Disable()
+            self.bttAddWms.Disable()
+            self.bttAddWfs.Disable()
+            self.bttAddWcs.Disable()
+            self.bttViewRequestXml.Disable()
+            self.bttViewResponseXml.Disable()
+
+    def refreshServiceButt(self, stat=False):
+        if not stat:
+            self.bttAddWms.Disable()
+            self.bttAddWfs.Disable()
+            self.bttAddWcs.Disable()
+        else:
+            self.bttAddWms.Enable()
+            self.bttAddWfs.Enable()
+            self.bttAddWcs.Enable()
+
+    def OnNavigate(self, evt):
+        name = evt.GetEventObject().GetLabel()
+        if name == '<<':
+            self.startfrom = 0
+        elif name == '>>':
+            self.startfrom = self.catalog.results['matches'] - self.maxrecords
+        elif name == '>':
+            self.startfrom += self.maxrecords
+            if self.startfrom >= self.catalog.results["matches"]:
+                msg = 'End of results. Go to start?'
+                if YesNo(self, msg, 'End of results'):
+                    self.startfrom = 0
+                else:
+                    return
+        elif name == '<':
+            self.startfrom -= self.maxrecords
+            if self.startfrom < 0:
+                msg = 'Start of results. Go to end?'
+                if YesNo(self, msg, 'Navigation'):
+                    self.startfrom = (self.catalog.results['matches'] - self.maxrecords)
+                else:
+                    return
+
+        self.loadConstraints()
+        try:
+            self.catalog.getrecords2(constraints=self.constraints,
+                                     maxrecords=self.maxrecords,
+                                     startposition=self.startfrom, esn='full')
+        except ExceptionReport, err:
+            GWarning('Search error: %s' % err)
+            return
+        except Exception, err:
+            GWarning('Connection error: %s' % err)
+            return
+
+        self.displyResults()
+
+    def OnSetCatalog(self, evt):
+        val = evt.GetSelection()
+        self.config.WriteInt('/guiSearch/catalog', val)
+
+    def loadSettings(self):
+        n = self.config.ReadInt('/guiSearch/catalog', 0)
+        self.catalogCmb.SetSelection(n)
+
+
+    def setTooltip(self, evt):
+        index = evt.GetIndex()
+        text = self.resultList.GetItem(index, 1)
+        text = text.GetText()
+
+        self.resultList.SetToolTip(wx.ToolTip(text))
+
+    def setBBoxGRASS(self, evt=None):
+        vdb = Module('g.region', flags='bg', stdout_=PIPE)
+        vdb = parse_key_val(vdb.outputs.stdout)
+        self.bbNorth.SetValue(vdb['ll_n'])
+        self.bbSouth.SetValue(vdb['ll_s'])
+        self.bbWest.SetValue(vdb['ll_w'])
+        self.bbEast.SetValue(vdb['ll_e'])
+
+    def setBBoxGlobal(self, evt=None):
+        self.bbNorth.SetValue('90')
+        self.bbSouth.SetValue('-90')
+        self.bbWest.SetValue('-180')
+        self.bbEast.SetValue('180')
+
+    def _get_csw(self):
+        """function to init owslib.csw.CatalogueServiceWeb"""
+        # connect to the server
+        try:
+            # QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
+            self.catalog = CatalogueServiceWeb(self.catalog_url,
+                                               timeout=self.timeout)
+            return True
+        except ExceptionReport, err:
+            msg = 'Error connecting to service: %s' % err
+        except ValueError, err:
+            msg = 'Value Error: %s' % err
+        except Exception, err:
+            msg = 'Unknown Error: %s' % err
+            GMessage('CSW Connection error: %s' % msg)
+        return False
+
+    def refreshResultList(self):
+        self.resultList.ClearAll()
+        self.resultList.InsertColumn(0, 'Type', width=wx.LIST_AUTOSIZE)
+        self.resultList.InsertColumn(1, 'Service', width=300)
+
+    def loadConstraints(self):
+        if not self.advanceChck.GetValue():
+            self.constraints = []
+            kw = self.keywordCtr.GetValue()
+            if kw:
+                self.constraints.append(PropertyIsLike('csw:AnyText', kw))
+            for constraint in self.constraintsWidgets:
+                kw = constraint.GetValue()
+                if kw != '':
+                    self.constraints.append(PropertyIsLike('csw:AnyText', kw))
+            if len(self.constraints) > 1:  # exclusive search (a && b)
+                self.constraints = [self.constraints]
+        else:
+            # convert constreints to owslib object fes
+            tmpConstraints = self.constraints
+            for x, constraint in enumerate(tmpConstraints):
+                if type(constraint) is list:
+                    for y, const in enumerate(constraint):
+                        self.constraints[x][y] = PropertyIsLike('csw:AnyText', const)
+                    continue
+                self.constraints[x] = PropertyIsLike('csw:AnyText', constraint)
+
+    def gdalImport(self, ogr, url, type, evt):
+        serviceDialog = GdalImportDialog(self, None, ogr=ogr, link=True)
+        dns = serviceDialog.dsnInput
+        dns.source.SetSelection(3)
+
+        dns.SetSourceType('pro')
+        if type == 'wms':
+            dns.protocolWidgets['format'].SetSelection(2)
+        if type == 'wcs':
+            dns.protocolWidgets['format'].SetSelection(1)
+        if type == 'wfs':
+            dns.protocolWidgets['format'].SetSelection(2)
+        dns.SetExtension(dns.protocolWidgets['format'].GetStringSelection())
+        dns.protocolWidgets['text'].SetValue(url)
+        dns.OnUpdate(evt)
+        serviceDialog.Show()
+
+    def OnService(self, evt):
+        name = evt.GetEventObject().GetLabel()
+        idx = self.resultList.GetNextItem(0, wx.LIST_NEXT_ALL,
+                                          wx.LIST_STATE_SELECTED)
+        if not idx:
+            return
+        cmd = []
+        item_data = "item_data=" + self.get_item_data(idx, 'link')
+        exec (item_data)
+        if name == "Add WMS":
+            data_url = item_data['wms']
+            service = ['r.in.gdal', 'r.in.wms']
+            dlg = wx.SingleChoiceDialog(
+                self, 'Choice module of WMS service ', 'Service module',
+                service,
+                wx.CHOICEDLG_STYLE
+            )
+
+            if dlg.ShowModal() == wx.ID_OK:
+                if dlg.GetStringSelection() == service[0]:
+                    self.gdalImport(False, data_url, type='wms', evt=evt)
+                else:
+                    cmd.append('r.in.wms')
+                    cmd.append('url=%s' % data_url)
+                    GUI(parent=self, show=True, modal=True).ParseCommand(cmd=cmd)
+            dlg.Destroy()
+
+        elif name == "Add WFS":
+            data_url = item_data['wfs']
+            service = ['v.in.ogr', 'v.in.wfs']
+            dlg = wx.SingleChoiceDialog(
+                self, 'Choice module of WFS service ', 'Service module',
+                service,
+                wx.CHOICEDLG_STYLE
+            )
+
+            if dlg.ShowModal() == wx.ID_OK:
+                if dlg.GetStringSelection() == service[0]:
+                    self.gdalImport(True, data_url, type='wfs', evt=evt)
+                else:
+                    cmd.append('v.in.wfs')
+                    cmd.append('url=%s' % data_url)
+                    GUI(parent=self, show=True, modal=True).ParseCommand(cmd=cmd)
+            dlg.Destroy()
+
+        elif name == "Add WCS":
+
+            data_url = item_data['wcs']
+            self.gdalImport(False, data_url, type='wcs', evt=evt)
+
+            ipdb.set_trace()
+
+
+    def GetQtype(self):  # TODO need to implement
+        if self.qtypeRb.GetValue():
+            return None
+        elif self.qtypeRb1.GetValue():
+            return 'dataset'
+        else:
+            return 'service'
+
+    def OnSearch(self, evt):
+        """execute search"""
+        self.refreshResultList()
+        self.catalog = None
+        self.loadConstraints()
+        self.catalog_url = None
+        # clear all fields and disable buttons
+        self.findResNumLbl.SetLabel("")
+
+        current_text = self.catalogCmb.GetValue()
+        if current_text == '':
+            GMessage('Please set catalog')
+            return
+        key = '/connections/%s' % current_text
+        self.catalog_url = self.config.Read('%s/url' % key)
+
+        # start position and number of records to return
+        self.startfrom = 0
+        self.maxrecords = self.numResultsSpin.GetValue()
+
+        # set timeout
+        self.timeout = self.parent.CSWConnectionPanel.timeout
+
+        # bbox
+        minx = self.bbWest.GetValue()  # TODO add grass number validator
+        miny = self.bbSouth.GetValue()
+        maxx = self.bbEast.GetValue()
+        maxy = self.bbNorth.GetValue()
+        bbox = [minx, miny, maxx, maxy]
+
+        if bbox != ['-180', '-90', '180', '90']:
+            self.constraints.append(BBox(bbox))
+
+        # (a && b)
+        # build request
+        if not self._get_csw():
+            return
+
+        # TODO: allow users to select resources types
+        # to find ('service', 'dataset', etc.)
+        # print self.constraints
+        try:
+            self.catalog.getrecords2(constraints=self.constraints,
+                                     maxrecords=self.maxrecords, esn='full')
+        except ExceptionReport, err:
+            GError('Search error: %s' % err)
+            return
+        except Exception, err:
+            GError('Connection error: %s'% err)
+            return
+
+        if self.catalog.results['matches'] == 0:
+            self.findResNumLbl.SetLabel('0 results')
+            return
+
+        self.refreshNavigationButt(True)
+        self.displyResults()
+
+    def get_item_data(self, index, field):
+        if field == 'identifier':
+            return self.idResults[index]['identifier']
+        else:
+            return self.idResults[index]['link']
+
+    def set_item_data(self, index, field, value):
+        """set identifier for a QTreeWidgetItem"""
+        # self.resultList.SetStringItem(, self._get_field_value(field), value)
+
+        try:
+            self.idResults[index]
+            idx = True
+        except IndexError:
+            idx = False
+
+        if idx:
+            if field == "identifier":
+                self.idResults[index]['identifier'] = value
+            if field == "link":
+                # print value
+                self.idResults[index]['link'] = value
+        else:
+            d = {}
+            if field == "identifier":
+                d['identifier'] = value
+            if field == "link":
+                d[index]['link'] = value
+            self.idResults.insert(index, d)
+
+
+    def displyResults(self):
+        """display search results"""
+
+        self.refreshResultList()
+        # print "display"
+        # self.resultList.SetItem(index,0,'ahoj')
+        position = self.catalog.results['returned'] + self.startfrom
+
+        msg = 'Showing %s - %s of %s result(s)' % ( self.startfrom + 1,
+                                                    position,
+                                                    self.catalog.results['matches'],
+
+        )
+        # % (self.startfrom + 1,position)
+
+        self.findResNumLbl.SetLabel(msg)
+        index = 0
+        for rec in self.catalog.records:
+            # tem = QTreeWidgetItem(self.treeRecords)
+            if self.catalog.records[rec].type:
+                item = wx.ListItem()
+                self.resultList.InsertStringItem(index, normalize_text(self.catalog.records[rec].type))
+            else:
+                self.resultList.SetStringItem(index, 0, 'unknown')
+            if self.catalog.records[rec].title:
+                self.resultList.SetStringItem(index, 1, normalize_text(self.catalog.records[rec].title))
+
+            if self.catalog.records[rec].identifier:
+                # self.resultList.SetStringItem(index,1,normalize_text(self.catalog.records[rec].identifier))
+                self.set_item_data(index, 'identifier',
+                                   self.catalog.records[rec].identifier)
+                # print index
+
+            if index % 2:
+                self.resultList.SetItemBackgroundColour(index, "LIGHT GREY")
+            index += 1
+
+        self.Fit()
+
+    def onHtmlLinkClicked(self, event):
+        Thread(
+            target=webbrowser.open,
+            args=(event.GetLinkInfo().GetHref(), 0)
+        ).start()
+
+    def updateCatalogBox(self, evt=None):
+        # print('update')
+
+        if self.catalogCmb.GetCount() == 0:
+            msg = 'No services/connections defined.'
+            self.htmlView.SetPage('<p><h3>%s</h3></p>' % msg)
+
+    def _layout(self):
+        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
+        rightPanelSizer = wx.BoxSizer(wx.VERTICAL)
+        leftPanelSizer = wx.BoxSizer(wx.VERTICAL)
+
+        # search static box sizers---start
+        mainSearchSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.rightSearchSizer = wx.BoxSizer(wx.VERTICAL)
+        self.leftSearchSizer = wx.BoxSizer(wx.VERTICAL)
+        upSearchSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        upSearchSizer.Add(self.qtypeRb, 0)
+        upSearchSizer.Add(self.qtypeRb1, 0)
+        upSearchSizer.Add(self.qtypeRb2, 0)
+
+        self.leftSearchSizer.Add(upSearchSizer, 1, )
+        self.rightSearchSizer.Add(wx.StaticText(self), 0)
+        mainSearchSizer.Add(self.leftSearchSizer, wx.EXPAND)
+        mainSearchSizer.Add(self.rightSearchSizer)
+
+        self.leftSearchSizer.Add(self.keywordLbl, 0)
+
+        self.leftSearchSizer.AddSpacer(7, 0, 1, wx.EXPAND)
+        # self.rightSearchSizer.Add(self.advancedFilter, 0)
+        self.rightSearchSizer.Add(self.advanceChck, 0)
+
+        self.leftSearchSizer.Add(self.keywordCtr, 0, wx.EXPAND)
+        self.rightSearchSizer.Add(self.addKeywordCtr, 0)
+
+        stbBox0Sizer = wx.StaticBoxSizer(self.stbSearch, wx.VERTICAL)
+
+        self.stBox1Sizer = wx.StaticBoxSizer(self.stbFind, wx.VERTICAL)
+        self.stBox1Sizer.Add(mainSearchSizer, 0, wx.EXPAND)
+
+        # bounding box sizer---------------
+        bb1sizer = wx.BoxSizer(wx.HORIZONTAL)
+        bb2sizer = wx.BoxSizer(wx.HORIZONTAL)
+        bb3sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.stBox2Sizer = wx.StaticBoxSizer(self.stbBB, wx.VERTICAL)
+        bb1sizer.Add(self.bbWestLb)
+        bb1sizer.AddSpacer(14, 10, 1, wx.EXPAND)
+        bb1sizer.Add(self.bbWest, 1, wx.EXPAND)
+        bb1sizer.AddSpacer(20, 10, 1, wx.EXPAND)
+        bb1sizer.Add(self.bbSouthLb)
+        bb1sizer.AddSpacer(14, 10, 1, wx.EXPAND)
+        bb1sizer.Add(self.bbSouth, 1, wx.EXPAND)
+        bb2sizer.Add(self.bbEastLb)
+        bb2sizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        bb2sizer.Add(self.bbEast, 1, wx.EXPAND)
+        bb2sizer.AddSpacer(20, 10, 1, wx.EXPAND)
+        bb2sizer.Add(self.bbNorthLb)
+        bb2sizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        bb2sizer.Add(self.bbNorth, 1, wx.EXPAND)
+        bb3sizer.Add(self.bbSetGlobalBtt1, wx.EXPAND)
+        bb3sizer.Add(self.bbSetMapExtendBtt1, wx.EXPAND)
+        self.stBox2Sizer.Add(bb2sizer, 1, wx.EXPAND)
+        self.stBox2Sizer.Add(bb1sizer, 1, wx.EXPAND)
+        self.stBox2Sizer.Add(bb3sizer, 1, wx.EXPAND)
+        # bounding box sizer---------------end
+        stbBox0Sizer.Add(self.catalogLbl, 0)
+        stbBox0Sizer.Add(self.catalogCmb, 1, wx.EXPAND)
+        stbBox0Sizer.AddSpacer(10, 10, 1, wx.EXPAND)
+
+        stbBox0Sizer.Add(self.stBox1Sizer, 0, wx.EXPAND)
+        stbBox0Sizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        stbBox0Sizer.Add(self.stBox2Sizer, 0, wx.EXPAND)
+        leftPanelSizer.Add(stbBox0Sizer, 0, wx.EXPAND)
+        leftPanelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+
+        findPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        findPanelSizer.Add(self.numResultsLbl, 0)
+        findPanelSizer.Add(self.numResultsSpin, 0)
+
+        findPanelSizer.Add(self.findBtt, 1, wx.EXPAND)
+        leftPanelSizer.Add(findPanelSizer, 0, wx.EXPAND)
+        leftPanelSizer.Add(self.findResNumLbl, 0)
+        leftPanelSizer.Add(self.resultList, 1, wx.EXPAND)
+        leftPanelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+
+        listerSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        listerSizer.Add(self.bttBackItem2, 1)
+        listerSizer.Add(self.bttBackItem1, 1)
+        listerSizer.Add(self.bttNextItem1, 1)
+        listerSizer.Add(self.bttNextItem2, 1)
+        leftPanelSizer.Add(listerSizer, 0, wx.EXPAND)
+
+        rightTOPsizer = wx.BoxSizer(wx.HORIZONTAL)
+        rightTOPsizer.Add(self.bttViewRequestXml)
+        rightTOPsizer.Add(self.bttViewResponseXml)
+        rightTOPsizer.Add(self.bttAddWms)
+        rightTOPsizer.Add(self.bttAddWfs)
+        rightTOPsizer.Add(self.bttAddWcs)
+
+        rightPanelSizer.Add(rightTOPsizer)
+        rightPanelSizer.Add(self.htmlView, 1, wx.EXPAND)
+        self.pnlLeft.SetSizer(leftPanelSizer)
+        self.pnlRight.SetSizer(rightPanelSizer)
+
+        self.splitterBrowser.SplitVertically(self.pnlLeft, self.pnlRight)
+
+        self.splitterBrowser.SetSashGravity(0.35)
+        self.splitterBrowser.SetSashPosition(300)
+        self.splitterBrowser.SetMinimumPaneSize(200)
+        self.mainsizer.Add(self.splitterBrowser, 1, wx.EXPAND)
+        self.SetSizerAndFit(self.mainsizer)
+
+class CSWConnectionPanel(wx.Panel):
+    def __init__(self, parent, main,cswBrowser=True):
+        wx.Panel.__init__(self, parent)
+        self.parent = main
+        self.config = wx.Config('g.gui.cswbrowser')
+        self.cswBrowser=cswBrowser
+        self.splitterConn = SplitterWindow(self, style=wx.SP_3D |
+                                                       wx.SP_LIVE_UPDATE | wx.SP_BORDER)
+        self.panelLeft = wx.Panel(self.splitterConn, id=wx.ID_ANY)
+        self.stBoxConnections = wx.StaticBox(self.panelLeft, -1, 'Connections list')
+        self.stBoxConnections1 = wx.StaticBox(self.panelLeft, -1, 'Connection manager')
+        self.panelRight = wx.Panel(self.splitterConn, -1)
+        self.connectionLBox = wx.ListBox(self.panelLeft, id=-1, pos=wx.DefaultPosition)
+        self.timeoutSpin = wx.SpinCtrl(self.panelLeft, min=1, max=100, initial=10 , style=wx.ALIGN_RIGHT | wx.SP_ARROW_KEYS)
+        self.context = StaticContext()
+        self.connectionFilePath = os.path.join(self.context.addonsPath, 'connections_resources.xml')
+        self.servicePath = 'service_metadata.html'
+        self.serviceInfoBtt = wx.Button(self.panelLeft, -1, label='Service info')
+        self.newBtt = wx.Button(self.panelLeft, label='New')
+        self.removeBtt = wx.Button(self.panelLeft, label='Remove')
+        self.setDefaultFile = wx.Button(self.panelLeft, label='Load catalog list')
+        self.setDefaultFile.Bind(wx.EVT_BUTTON, self.onOpenConnFile)
+        self.textMetadata = html.HtmlWindow(self.panelRight,
+                                            id=-1,
+                                            pos=wx.DefaultPosition,
+                                            size=wx.DefaultSize,
+                                            style=HW_DEFAULT_STYLE | HW_SCROLLBAR_AUTO,
+                                            name="metadata")
+
+        # self.connectionLBox.Bind(wx.EVT_LISTBOX, self.addDefaultConnections())
+        self.addDefaultConnections()
+        self.connectionLBox.Bind(wx.EVT_LISTBOX_DCLICK, self.onServiceInfo)
+        # self.connectionLBox.Bind(wx.EVT_LISTBOX, self.OnSetCatalog)
+        self.newBtt.Bind(wx.EVT_BUTTON, self.onNewconnection)
+        self.removeBtt.Bind(wx.EVT_BUTTON, self.onRemoveConnection)
+        self.serviceInfoBtt.Bind(wx.EVT_BUTTON, self.onServiceInfo)
+
+        self.textMetadata.Bind(EVT_HTML_LINK_CLICKED, self.onHtmlLinkClicked)
+        # self.loadSettings()
+        # self.connectionLabel=wx.StaticText(self.panelLeft,label='Catalog service:')
+        self._layout()
+
+    def GetUrl(self):
+        return self.catalog_url
+
+    def onNewconnection(self, evt=None, cancel=False):
+        if self.newBtt.GetLabel() == "New":
+            self.newBtt.SetLabel('Save')
+            self.newBtt.Disable()
+
+            self.connNameNew = wx.TextCtrl(self.panelLeft)
+            self.connNameNewLabel = wx.StaticText(self.panelLeft, label='Name')
+            self.connNameNew.Bind(wx.EVT_TEXT, self.validateNewConn)
+
+            self.connUrlNew = wx.TextCtrl(self.panelLeft)
+            self.connUrlNewLabel = wx.StaticText(self.panelLeft, label='Url')
+            self.connUrlNew.Bind(wx.EVT_TEXT, self.validateNewConn)
+
+            self.cancelBtt = wx.Button(self.panelLeft, label="Cancel")
+            self.cancelBtt.Bind(wx.EVT_BUTTON, self.cancelAddingNewURL)
+            self.stBoxConnections1Sizer.Hide(1)
+            self.stBoxConnections1Sizer.Add(self.cancelBtt, 1, wx.EXPAND)
+            self.stBoxConnections1Sizer.Add(self.connNameNewLabel, 1, wx.EXPAND)
+            self.stBoxConnections1Sizer.Add(self.connNameNew, 1, wx.EXPAND)
+            self.stBoxConnections1Sizer.Add(self.connUrlNewLabel, 1, wx.EXPAND)
+            self.stBoxConnections1Sizer.Add(self.connUrlNew, 1, wx.EXPAND)
+
+
+        else:
+            # test validity of connection
+            url = self.connUrlNew.GetValue()
+            if cancel:
+                self.newBtt.SetLabel('New')
+                self.newBtt.Enable()
+                self.stBoxConnections1Sizer.Remove(self.connNameNewLabel)
+                self.stBoxConnections1Sizer.Remove(self.connNameNew)
+                self.stBoxConnections1Sizer.Remove(self.connUrlNewLabel)
+                self.stBoxConnections1Sizer.Remove(self.connUrlNew)
+                self.connNameNew.Destroy()
+                self.connNameNewLabel.Destroy()
+                self.connUrlNewLabel.Destroy()
+                self.connUrlNew.Destroy()
+                self.stBoxConnections1Sizer.Show(1)
+                self.stBoxConnections1Sizer.Remove(self.cancelBtt)
+                self.cancelBtt.Destroy()
+                self.Fit()
+                return
+            if self.checkURLCSWvalidity(url):
+                name = self.connNameNew.GetValue()
+                if not self.addConection(name, url):
+                    return
+                self.newBtt.SetLabel('New')
+                self.newBtt.Enable()
+                self.stBoxConnections1Sizer.Remove(self.connNameNewLabel)
+                self.stBoxConnections1Sizer.Remove(self.connNameNew)
+                self.stBoxConnections1Sizer.Remove(self.connUrlNewLabel)
+                self.stBoxConnections1Sizer.Remove(self.connUrlNew)
+                self.connNameNew.Destroy()
+                self.connNameNewLabel.Destroy()
+                self.connUrlNewLabel.Destroy()
+                self.connUrlNew.Destroy()
+                self.stBoxConnections1Sizer.Show(1)
+                self.stBoxConnections1Sizer.Remove(self.cancelBtt)
+                self.cancelBtt.Destroy()
+            else:
+                GMessage('Url is not valid')
+
+        self.Fit()
+
+    def cancelAddingNewURL(self, evt):
+        self.onNewconnection(cancel=True)
+
+    def validateNewConn(self, evt):
+        if self.connNameNew.GetValue() != '' and self.connUrlNew.GetValue() != '':
+            self.newBtt.Enable()
+        else:
+            self.newBtt.Disable()
+
+    def onRemoveConnection(self, evt):
+        if self.connectionLBox.GetSelection() == wx.NOT_FOUND:
+            GMessage('Please select catalog')
+            return
+        name = self.connectionLBox.GetString(self.connectionLBox.GetSelection())
+        if YesNo(self, "Do you want to remove < %s > from list " % name, "Remove connection"):
+            key = '/connections/%s' % name
+            self.config.DeleteGroup(key)
+        if YesNo(self, "Do you want to remove < %s > from default connection file " % name, "Remove connection"):
+            tree = ET.parse(self.connectionFilePath)
+            root = tree.getroot()
+            for bad in root.findall('csw'):
+                if bad.attrib['name'] == name:
+                    root.remove(bad)
+
+            tree.write(self.connectionFilePath)
+            # n=self.connectionLBox.GetSelection()
+            # self.connectionLBox.Remove(n)
+            self.updateConnectionList()
+
+    def publishCSW(self,path):
+        """show connection info"""
+        if self.connectionLBox.GetSelection() == wx.NOT_FOUND:
+            GMessage('Please select catalog')
+            return
+        current_text = self.connectionLBox.GetString(self.connectionLBox.GetSelection())
+        key = '/connections/%s' % current_text
+
+        self.catalog_url = self.config.Read('%s/url' % key)
+
+        if not self._get_csw():
+            return
+
+        if self.catalog:  # display service metadata
+            metadata = render_template('en', self.context,
+                                       self.catalog,
+                                       self.servicePath)
+
+        try:
+            self.catalog.transaction(ttype='insert', typename='gmd:MD_Metadata', record=open(path).read())
+        except Exception, e:
+            GWarning('Transaction error: <%s>'%e)
+
+    def onHtmlLinkClicked(self, event):
+        Thread(
+            target=webbrowser.open,
+            args=(event.GetLinkInfo().GetHref(), 0)
+        ).start()
+
+    def checkURLCSWvalidity(self, url):
+        self.catalog_url = url
+        if not self._get_csw():
+            return False
+        if self.catalog:
+            metadata = render_template('en', self.context,
+                                       self.catalog,
+                                       self.servicePath)
+            if self.textMetadata.SetPage(metadata):
+                return True
+        return False
+
+    def onServiceInfo(self, evt=None):
+        """show connection info"""
+        if self.connectionLBox.GetSelection() == wx.NOT_FOUND:
+            GMessage('Please select catalog')
+            return
+        current_text = self.connectionLBox.GetString(self.connectionLBox.GetSelection())
+        key = '/connections/%s' % current_text
+
+        self.catalog_url = self.config.Read('%s/url' % key)
+
+        if not self._get_csw():
+            return
+
+        if self.catalog:  # display service metadata
+            metadata = render_template('en', self.context,
+                                       self.catalog,
+                                       self.servicePath)
+
+            self.textMetadata.SetPage(metadata)
+
+
+    def _get_csw(self):
+        """function to init owslib.csw.CatalogueServiceWeb"""
+        # connect to the server
+        try:
+            self.catalog = CatalogueServiceWeb(self.catalog_url,
+                                               timeout=self.timeoutSpin.GetValue())
+            return True
+        except ExceptionReport, err:
+            msg = 'Error connecting to service: %s' % err
+        except ValueError, err:
+            msg = 'Value Error: %s' % err
+        except Exception, err:
+            msg = 'Unknown Error: %s' % err
+
+            GMessage('CSW Connection error: %s' % msg)
+        return False
+
+    def addDefaultConnections(self, path=None):
+        """add default connections from file"""
+        # print path
+        if path is not None:
+            self.connectionFilePath = path
+            if YesNo(self, "Do you want to remove temporary connections?", "Remove tmp connections"):
+                self.config.DeleteGroup('/connections')
+
+        noerr, doc =get_connections_from_file( self.connectionFilePath)
+        if not noerr:
+            GError(doc)
+
+        if doc is None:
+            return
+        self.config.SetPath('/connections')
+
+        for server in doc.findall('csw'):
+            name = server.attrib.get('name')
+            url = server.attrib.get('url')
+            key = '/connections/%s' % name
+            self.config.Write('%s/url' % key, url)
+        self.updateConnectionList()
+
+    def addConection(self, name, url):
+        conns = [self.connectionLBox.GetString(i) for i in range(self.connectionLBox.GetCount())]
+
+        if name in conns:
+            GMessage("Name of catalog is exists, new catalog is not saved")
+            n = self.connectionLBox.FindString(name)
+            self.connectionLBox.SetSelection(n)
+            return False
+        self.config.SetPath('/connections')
+        key = '/connections/%s' % name
+        self.config.Write('%s/url' % key, url)
+        self.updateConnectionList()
+        if YesNo(self, "Do you want to add connection to default configuration file", "Default connection"):
+            tree = ET.parse(self.connectionFilePath)
+            root = tree.getroot()
+
+            st = ET.Element("csw", name=name, url=url)
+            root.append(st)
+            tree.write(self.connectionFilePath)
+        return True
+
+    def updateConnectionList(self):
+
+            """populate select box with connections"""
+            self.connectionLBox.Clear()
+
+            more, value, index = self.config.GetFirstGroup()
+            first = value
+            if self.cswBrowser:# ONLY FOR g.gui.cswbrowser
+                self.parent.BrowserPanel.catalogCmb.Clear()
+
+            while more:
+                if self.cswBrowser:
+                    self.parent.BrowserPanel.catalogCmb.Append(value)
+                self.connectionLBox.Append(value)
+                more, value, index = self.config.GetNextGroup(index)
+                # print value
+            n = self.connectionLBox.GetCount()
+            self.connectionLBox.SetString(n + 1, first)
+            if self.connectionLBox.GetCount() == 0:
+                msg = 'No services/connections defined.'
+                self.textMetadata.SetPage('<p><h3>%s</h3></p>' % msg)
+            if self.cswBrowser:
+                self.parent.BrowserPanel.loadSettings()
+
+
+
+    '''
+    def OnSetCatalog(self, evt):
+        val = evt.GetSelection()
+        print val
+        print self.config.WriteInt('/guiConn1/catalog', val)
+
+    def loadSettings(self):
+        n = self.config.ReadInt('/guiConn1/catalog',0)
+        print type(n)
+        print n
+        self.connectionLBox.SetSelection(n)
+    '''
+
+    def onOpenConnFile(self, event):
+
+        openFileDialog = wx.FileDialog(self, "Open catalog file", "", "",
+                                       "XML files (*.xml)|*.xml", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
+
+        if openFileDialog.ShowModal() == wx.ID_CANCEL:
+            return
+
+        input_stream = openFileDialog.GetPath()
+        self.addDefaultConnections(input_stream)
+
+
+    def _layout(self):
+        self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        rightPanelSizer = wx.BoxSizer(wx.VERTICAL)
+        self.configureSizer = wx.BoxSizer(wx.VERTICAL)
+        self.stBoxConnectionsSizer = wx.StaticBoxSizer(self.stBoxConnections, wx.VERTICAL)
+        self.stBoxConnectionsSizer.Add(self.connectionLBox, 1, wx.EXPAND)
+        self.stBoxConnectionsSizer.AddSpacer(20, 10, 1, wx.EXPAND)
+        self.stBoxConnectionsSizer.Add(wx.StaticText(self.panelLeft,label='Timeout'),0)
+        self.stBoxConnectionsSizer.Add(self.timeoutSpin, 0)
+
+        self.stBoxConnectionsSizer.Add(self.serviceInfoBtt, 0, wx.EXPAND)
+        self.configureSizer.Add(self.stBoxConnectionsSizer, 1, wx.EXPAND)
+
+        self.configureSizer.AddSpacer(20, 10, 1, wx.EXPAND)
+        self.stBoxConnections1Sizer = wx.StaticBoxSizer(self.stBoxConnections1, wx.VERTICAL)
+        self.stBoxConnections1Sizer.Add(self.newBtt, 0, wx.EXPAND)
+        self.stBoxConnections1Sizer.Add(self.removeBtt, 0, wx.EXPAND)
+
+        self.configureSizer.Add(self.stBoxConnections1Sizer, 0, wx.EXPAND)
+        self.configureSizer.Add(self.setDefaultFile, 0, wx.EXPAND)
+        rightPanelSizer.Add(self.textMetadata, 1, wx.EXPAND)
+
+        self.panelRight.SetSizer(rightPanelSizer)
+        self.panelLeft.SetSizer(self.configureSizer)
+
+        self.splitterConn.SplitVertically(self.panelLeft, self.panelRight, sashPosition=0.8)
+        self.splitterConn.SetSashGravity(0.2)
+        self.splitterConn.SetMinimumPaneSize(200)
+        self.mainsizer.Add(self.splitterConn, 1, wx.EXPAND)
+        self.SetInitialSize()
+        self.SetSizer(self.mainsizer)
+
+class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
+    def __init__(self, parent):
+        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.BORDER_SUNKEN)
+        ListCtrlAutoWidthMixin.__init__(self)
+
+
+
+
+
+def YesNo(parent, question, caption='Yes or no?'):
+    dlg = wx.MessageDialog(parent, question, caption, wx.YES_NO | wx.ICON_QUESTION)
+    result = dlg.ShowModal() == wx.ID_YES
+    dlg.Destroy()
+    return result
+
+
+
+class CswPublisher():
+    def __init__(self):
+        CSWConnectionPanel(self)


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswlib.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswutil.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswutil.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswutil.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+from gettext import gettext, ngettext
+import os
+import webbrowser
+from xml.dom.minidom import parseString
+import xml.etree.ElementTree as etree
+
+from jinja2 import Environment, FileSystemLoader
+from pygments import highlight
+from pygments.lexers import XmlLexer
+from pygments.formatters import HtmlFormatter
+
+
+class StaticContext(object):
+    def __init__(self):
+        self.ppath = os.path.dirname(os.path.abspath(__file__))
+        self.addonsPath=os.path.join(os.getenv('GRASS_ADDON_BASE') ,'etc','config')
+
+
+def get_connections_from_file( filename):
+    """load connections from connection file"""
+
+    error = 0
+    try:
+        doc = etree.parse(filename).getroot()
+        if doc.tag != 'qgsCSWConnections':
+            error = 1
+            msg = 'Invalid CSW connections XML.'
+    except etree.ParseError, err:
+        error = 1
+        msg = ('Cannot parse XML file: %s' % err)
+    except IOError, err:
+        error = 1
+        msg = ('Cannot open file: %s' % err)
+
+    if error == 1:
+        return False,msg
+    return True,doc
+
+
+def render_template(language, context, data, template):
+    """Renders HTML display of metadata XML"""
+
+    env = Environment(extensions=['jinja2.ext.i18n'],
+                      loader=FileSystemLoader(context.addonsPath))
+    env.install_gettext_callables(gettext, ngettext, newstyle=True)
+
+    template_file = template
+    template = env.get_template(template_file)
+    return template.render(language=language, obj=data)
+
+
+def prettify_xml(xml):
+    """convenience function to prettify XML"""
+    if xml.count('\n') > 5:  # likely already pretty printed
+        return xml
+    else:
+        # check if it's a GET request
+        if xml.startswith('http'):
+            return xml
+        else:
+            return parseString(xml).toprettyxml()
+
+
+def encodeString(str):
+    return str.encode('ascii', 'ignore')
+
+
+def highlight_xml(context, xml):
+    """render XML as highlighted HTML"""
+
+    hformat = HtmlFormatter()
+    css = hformat.get_style_defs('.highlight')
+    body = highlight(prettify_xml(xml), XmlLexer(), hformat)
+
+    env = Environment(loader=FileSystemLoader(context.addonsPath))
+
+    template_file = 'xml_highlight.html'
+    template = env.get_template(template_file)
+    return template.render(css=css, body=body)
+
+
+def renderXML(context, xml):
+    hformat = HtmlFormatter()
+    body = highlight(prettify_xml(xml), XmlLexer(), hformat)
+    env = Environment(loader=FileSystemLoader(context.addonsPath))
+
+    template_file = 'xml_render.html'
+    template = env.get_template(template_file)
+    return template.render(body=body)
+
+
+def open_url(url):
+    """open URL in web browser"""
+
+    webbrowser.open(url)
+
+
+def normalize_text(text):
+    """tidy up string"""
+    return text.replace('\n', '')
+
+
+def serialize_string(input_string):
+    """apply a serial counter to a string"""
+
+    s = input_string.strip().split()
+
+    last_token = s[-1]
+    all_other_tokens_as_string = input_string.replace(last_token, '')
+
+    if last_token.isdigit():
+        value = '%s%s' % (all_other_tokens_as_string, int(last_token) + 1)
+    else:
+        value = '%s 1' % input_string
+
+    return value
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/cswutil.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Deleted: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/jinjainfo.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/jinjainfo.py	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/jinjainfo.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -1,193 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8
-"""
- at package jinjainfo
- at module g.gui.metadata
- at brief  Library for parsing information from jinja template
-
-Classes:
- - jinjainfo::MdDescription
- - jinjainfo::JinjaTemplateParser
-
-(C) 2014 by the GRASS Development Team
-This program is free software under the GNU General Public License
-(>=v2). Read the file COPYING that comes with GRASS for details.
-
- at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
-"""
-from core.gcmd import GError
-from mdutil import findBetween
-
-
-class MdDescription():
-
-    '''Object which is initialzed by jinja template in '{# #}'
-    '''
-
-    def __init__(self, tag=None, object=None, name='', desc=None,
-                 example=None, type=None, multi=0, inboxmulti=None,
-                 group=None, inbox=None, multiline=None, validator=None,
-                 num=None, ref=None, selfInfoString=None,database=None):
-        '''
-        @param tag: OWSLib object which will be replaced by value of object after jinja template system renders new file
-        @param object: some objects in OWSLib need to be initialized temporally in gui generator. Others are initialized by configure file
-        @param name:  label and tooltip name
-        @param desc: description/definition of metadata item
-        @param example: example of md item (tooltip)
-        @param type: data type, necessary to validate widgets
-        @param multi: 0=only one instance of editor::MdItem widget can be, 1= multiple instances of widgets can be
-        @param inboxmulti: 0=static box of items has not button for duplicating self 1=has button
-        @param group: this param initializes page in notebook in mani editor
-        @param inbox: Every item in block of code in jinja template must have same value of inbox.
-               The value of inbox representing label of static box in gui.
-        @param multiline: If true- textCtrl widget will be initalized with multiline control
-        @param validator: Currently not used
-        @param ref: additional information about reference of metadata item (ISO reference)
-        @param selfInfoString: string value representing all these information (parsed from jinja template)
-        @var mdItem: very important parameter which holds instances of widgets(editor::MdItem)
-             on every index of list is one instance of widget. In case, if is in static box MdItem with duplicating button:
-            index of list is represented by list of these items
-        @var statements: hold information about first statement in block
-        @var statements1: hold info about second statement in block of var: statement
-        '''
-        self.tag = tag
-        self.object = object
-        self.name = name
-        self.desc = desc
-        self.example = example
-        self.type = type
-        self.multiplicity = multi  # multiplicity of MD item
-        self.group = group
-        self.inbox = inbox
-        self.ref = ref
-        self.databaseAttr=database
-        self.selfInfoString = selfInfoString
-
-        self.inboxmulti = inboxmulti
-        self.multiline = multiline  # type of ctrl text
-        self.validator = validator
-        # --info from jinja -end
-
-        self.statements = None
-        self.statements1 = None
-        self.mdItem = list()
-
-    def addMdItem(self, newMdItem, oldMdItem=None):
-        '''care about integrity of var: self.mdItem
-        '''
-        # if new mditem is from box- need to hold information
-        # about it (list on the same index in self.mdItem)
-        if oldMdItem is not None:
-            for n, item in enumerate(self.mdItem):
-                for i in item:
-                    if i == oldMdItem:
-                        self.mdItem[n].append(newMdItem)
-        else:
-            self.mdItem.append(newMdItem)
-
-    def removeMdItem(self, item):
-        '''care about integrity of var: self.mdItem
-        '''
-        try:
-            for k, oldListItem in enumerate(self.mdItem):
-                for i in oldListItem:
-                    if i == item:
-                        self.mdItem[k].remove(item)
-        except:
-            self.mdItem.remove(item)
-
-    def addStatements(self, stat):
-        if self.statements is None:
-            self.statements = stat
-
-    def addStatements1(self, stat):
-        if self.statements1 is None:
-            self.statements1 = stat
-
-
-class JinjaTemplateParser():
-
-    '''Parser of OWSLib tag and init. values of jinjainfo::MdDescription from jinja template.
-    '''
-
-    def __init__(self, template):
-        '''
-        @var mdDescription: list of jinjainfo::mdDescription
-        @var mdOWSTag: list of tags in jinja templates
-        @var mdOWSTagStr: string representing OWSLib tags from template (per line)
-        @var mdOWSTagStrList: on each index of list is one line with parsed OWSLib tag
-        '''
-        self.mdDescription = []
-        self.mdOWSTag = []
-        self.template = template
-
-        self.mdOWSTagStr = ''
-        self.mdOWSTagStrList = []
-
-        self._readJinjaInfo()
-        self._readJinjaTags()
-        self._formatMdOWSTagStrToPythonBlocks()
-
-    def _readJinjaTags(self):
-        '''Parser of OWSLib tag from jinja template to list
-        '''
-        try:
-            with open(self.template, "r") as f:
-                for line in f:
-
-                    # if found start of comments
-                    if str(line).find("{{") != -1:
-                        obj = findBetween(line, "{{", "}}")
-                        self.mdOWSTag.append(obj)
-
-                    if str(line).find("{%") != -1:
-                        obj = findBetween(line, "{%", "-%}")
-                        self.mdOWSTag.append(obj)
-
-        except:
-            GError('Cannot open jinja template')
-            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
-
-    def _readJinjaInfo(self):
-        '''Parser  of 'comments'({# #}) in jinja template which are represented by jinjainfo::MdDescription
-        parsed values initializing list of jinjainfo::MdDesctiption obect
-        '''
-        try:
-            with open(self.template, "r") as f:
-                for line in f:
-                    # if found start of comments
-                    if str(line).find("{#") != -1:
-                        values = findBetween(line, "{#", "#}")
-                        values1 = findBetween(line, "{%", "#}")
-                        values2 = findBetween(line, "{{", "#}")
-                        if values1 != '':
-                            values += ",selfInfoString='''{%" + values1 + "#}'''"
-                        else:
-                            values += ",selfInfoString='''{{" + values2 + "#}'''"
-
-                        exe_str = "self.mdDescription.append(MdDescription(%s))" % values
-                        exe_str = exe_str.decode("utf-8", 'ignore')
-                        eval(exe_str)
-        except:
-            GError('Cannot open jinja template')
-            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
-
-    def _formatMdOWSTagStrToPythonBlocks(self):
-        '''Formatting of parsed tags to pythonic blocks
-        '''
-        self.mdOWSTagStr = ""
-        tab = 0
-        for item in self.mdOWSTag:
-            if str(item).find(" endfor ") != -1 or \
-                    str(item).find(" endif ") != -1:
-                tab -= 1
-                continue
-
-            tabstr = '\t' * tab
-            str1 = tabstr + item[1:] + '\n'
-            self.mdOWSTagStr += str1
-            self.mdOWSTagStrList.append(tabstr + item[1:])
-
-            if str(item).find(" for ") != -1  \
-                    or str(item).find(" if ") != -1:
-                tab += 1

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdeditorfactory.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdeditorfactory.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdeditorfactory.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,1631 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+ at package editor
+ at module g.gui.metadata
+ at brief base editor, read/write ISO metadata, generator of widgets in editor
+
+Classes:
+ - editor::MdFileWork
+ - editor::MdBox
+ - editor::MdWxDuplicator
+ - editor::MdItem
+ - editor::MdNotebookPage
+ - editor::MdMainEditor
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
+"""
+import re
+import os
+import sys
+import tempfile
+import contextlib
+from lxml import etree
+
+import wx
+from wx import ID_ANY
+from wx import EVT_BUTTON
+import wx.lib.scrolledpanel as scrolled
+
+from owslib.iso import *
+from mdjinjaparser import JinjaTemplateParser
+from jinja2 import Environment, FileSystemLoader
+
+from core.gcmd import RunCommand, GError, GMessage
+from gui_core.widgets import IntegerValidator, NTCValidator, SimpleValidator,\
+    TimeISOValidator, EmailValidator  # ,EmptyValidator
+
+import mdutil
+from core.gcmd import RunCommand
+from subprocess import PIPE
+from grass.pygrass.modules import Module
+#=========================================================================
+# MD filework
+#=========================================================================
+
+
+class MdFileWork():
+
+    ''' initializer of metadata in OWSLib and export OWSLib object to xml by jinja template system
+    '''
+
+    def __init__(self, pathToXml=None):
+        self.path = pathToXml
+        self.owslibInfo = None
+
+    def initMD(self, path=None):
+        '''
+        @brief initialize metadata
+        @param path: path to xml
+        @return: initialized md object by input xml
+        '''
+        if path is None:
+            self.md = mdutil.MD_MetadataMOD(md=None)
+            return self.md
+        else:
+            io = open(path, 'r')
+            str1 = ''
+            for line in io.readlines():
+                str1 += mdutil.removeNonAscii(line)
+            io.close()
+            io1 = open(path, 'w')
+            io1.write(str1)
+            io1.close()
+
+            try:
+                tree = etree.parse(path)
+                root = tree.getroot()
+                self.md = mdutil.MD_MetadataMOD(root)
+
+                return self.md
+
+            except Exception, e:
+                GError('Error loading xml:\n' + str(e))
+
+    def saveToXML(self, md, owsTagList, jinjaPath, outPath=None, xmlOutName=None, msg=True, rmTeplate=False):
+        '''
+        @note creator of xml with using OWSLib md object and jinja template
+        @param md: owslib.iso.MD_Metadata
+        @param owsTagList: in case if user is defining template
+        @param jinjaPath: path to jinja template
+        @param outPath: path of exported xml
+        @param xmlOutName: name of exported xml
+        @param msg: gmesage info after export
+        @param rmTeplate: remove template after use
+        @return: initialized md object by input xml
+        '''
+    # if  output file name is None, use map name and add postfix
+        self.dirpath = os.path.dirname(os.path.realpath(__file__))
+        self.md = md
+        self.owsTagList = owsTagList
+
+        if xmlOutName is None:
+            xmlOutName = 'RANDExportMD'  # TODO change to name of map
+        if not xmlOutName.lower().endswith('.xml'):
+            xmlOutName += '.xml'
+        # if path is None, use lunch. dir
+        # TODO change default folder to mapset location
+        if not outPath:
+            outPath = os.path.join(self.dirpath, xmlOutName)
+        else:
+            outPath = os.path.join(outPath, xmlOutName)
+        xml = open(jinjaPath, 'r')
+
+        str1 = ''
+        for line in xml.readlines():
+            line = mdutil.removeNonAscii(line)
+            str1 += line
+        xml.close
+        io = open(jinjaPath, 'w')
+        io.write(str1)
+        io.close()
+
+        # generating xml using jinja templates
+        head, tail = os.path.split(jinjaPath)
+        env = Environment(loader=FileSystemLoader(head))
+        env.globals.update(zip=zip)
+        template = env.get_template(tail)
+        if self.owsTagList is None:
+            iso_xml = template.render(md=self.md)
+        else:
+            iso_xml = template.render(md=self.md, owsTagList=self.owsTagList)
+        xml_file = xmlOutName
+
+        try:
+            xml_file = open(outPath, "w")
+            xml_file.write(iso_xml)
+            xml_file.close()
+
+            if msg:
+                GMessage('File is exported to: %s' % outPath)
+
+            if rmTeplate:
+                os.remove(jinjaPath)
+
+            return outPath
+
+        except Exception, e:
+            GError('Error writing xml:\n' + str(e))
+
+#=========================================================================
+# CREATE BOX (staticbox+button(optional)
+#=========================================================================
+
+    
+
+class MdBox(wx.Panel):
+
+    '''widget(static box) which include metadata items (MdItem)
+    '''
+
+    def __init__(self, parent, label='label'):
+        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+        self.label = label
+        self.mdItems = list()
+        self.stbox = wx.StaticBox(self, label=label, id=ID_ANY, style=wx.RAISED_BORDER)
+        self.stbox.SetForegroundColour((0, 0, 0))
+        self.stbox.SetBackgroundColour((200, 200, 200))
+        self.stbox.SetFont(wx.Font(12, wx.NORMAL, wx.NORMAL, wx.NORMAL))
+
+    def addItems(self, items, multi=True, rmMulti=False, isFirstNum=-1):
+        '''
+        @param items: editor::MdItems
+        @param multi: true in case when box has button for duplicating box and included items
+        @param rmMulti: true in case when box has button for removing box and included items
+        @param isFirstNum: handling with 'add' and 'remove' button of box.
+                            this param is necessary for generating editor in editor::MdEditor.generateGUI.inBlock()
+                            note: just first generated box has 'add' button (because being mandatory) and next others has
+                            'remove' button
+        '''
+        if isFirstNum != 1:
+            multi = False
+            rmMulti = True
+
+        # if not initialize in jinja template (default is true)
+        if multi is None:
+            multi = True
+
+        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.panelSizer)
+
+        self.boxButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        self.panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        self.panelSizer.Add(self.boxButtonSizer, flag=wx.EXPAND, proportion=1)
+
+        self.stBoxSizer = wx.StaticBoxSizer(self.stbox, orient=wx.VERTICAL)
+        self.boxButtonSizer.Add(self.stBoxSizer, flag=wx.EXPAND, proportion=1)
+
+        for item in items:
+            self.mdItems.append(item)
+            self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
+            self.stBoxSizer.AddSpacer(5, 5, 1, wx.EXPAND)
+
+        if multi:
+            self.addBoxButt = wx.Button(self, id=ID_ANY, size=(30, 30), label='+')
+            self.boxButtonSizer.Add(self.addBoxButt, 0)
+            self.addBoxButt.Bind(EVT_BUTTON, self.duplicateBox)
+
+        if rmMulti:
+            self.rmBoxButt = wx.Button(self, id=ID_ANY, size=(30, 30), label='-')
+            self.boxButtonSizer.Add(self.rmBoxButt, 0)
+            self.rmBoxButt.Bind(EVT_BUTTON, self.removeBox)
+
+
+        
+    def addDuplicatedItem(self, item):
+        self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
+        self.stBoxSizer.AddSpacer(5, 5, 1, wx.EXPAND)
+        self.GetParent().Layout()
+
+    def getCtrlID(self):
+        return self.GetId()
+
+    def removeBox(self, evt):
+        for item in self.mdItems:
+            item.mdDescription.removeMdItem(item)
+        self.GetParent().removeBox(self)
+
+    def removeMdItem(self, mdItem, items):
+        '''
+        @param mdItem: object editor::MdItem
+        @param items: widgets to destroy
+        '''
+        mdItem.mdDescription.removeMdItem(mdItem)
+        for item in items:
+            try:
+                item.Destroy()
+            except:
+                pass
+        self.stBoxSizer.RemovePos(-1)  # remove wxSpacer
+        self.stBoxSizer.Remove(mdItem)
+        self.GetParent().Layout()
+
+    def duplicateBox(self, evt):
+        duplicator = MdWxDuplicator(self.mdItems, self.GetParent(), self.label)
+        clonedBox = duplicator.mdBox
+        self.GetParent().addDuplicatedItem(clonedBox, self.GetId())
+
+
+#===============================================================================
+# Handling keywords from database
+#===============================================================================
+class MdBoxKeywords(MdBox):
+    def __init__(self,parent,parent2,label):
+        super(MdBoxKeywords, self).__init__(parent,label)
+        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.panelSizer)
+        self.boxButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.parent2=parent2
+
+        self.panelSizer.AddSpacer(10, 10, 1, wx.EXPAND)
+        self.panelSizer.Add(self.boxButtonSizer, flag=wx.EXPAND, proportion=1)
+        self.parent=parent
+        self.stBoxSizer = wx.StaticBoxSizer(self.stbox, orient=wx.VERTICAL)
+        self.boxButtonSizer.Add(self.stBoxSizer, flag=wx.EXPAND, proportion=1)
+        self.itemHolder=[]
+        self.textTMP=None
+
+    def addKeywordItem(self,item):
+        self.stBoxSizer.Add(item, flag=wx.EXPAND, proportion=1)
+
+    def removeKeywordItem(self,item):
+        self.parent2.removeKeyfromBox(item,self.textTMP)
+        self.stBoxSizer.Remove(item)
+        self.parent.Fit()
+
+
+#===============================================================================
+# DUPLICATOR OF WIDGETS-mditem
+#===============================================================================
+
+class MdWxDuplicator():
+
+    '''duplicator of MdBox and MdItem object
+    '''
+
+    def __init__(self, mdItems, parent, boxlabel=None, mdItemOld=None, template=None):
+        '''
+        @param mdItems:  list of editor::MdItem
+        @param parent: parent of new duplicated box
+        @param boxlabel: label of static box
+        @param mdItemOld: object which will be duplicated
+        @param template: in case if 'template mode' is on in editor
+        '''
+        # duplicate box of items
+        if boxlabel:
+            itemList = list()
+            self.mdBox = MdBox(parent, boxlabel)
+            for i in mdItems:
+                try:  # check if item has multiple button
+                    i.addItemButt.GetLabel()
+                    multi = True
+                except:
+                    multi = False
+                try:  # check if chckBoxEdit exists
+                    i.chckBoxEdit.GetValue()
+                    template = True
+                except:
+                    template = False
+
+                i = i.mdDescription  # var mdDescription is  jinjainfo::MdDescription
+                mdItem1 = MdItem(parent=self.mdBox,
+                                 item=i,
+                                 multiplicity=multi,
+                                 isFirstNum=1,
+                                 chckBox=template)
+
+                itemList.append(mdItem1)
+
+                i.addMdItem(mdItem1)  # add item with using jinjainfo::MDescription
+            self.mdBox.addItems(itemList, False, True)  # fill box
+
+        else:  # duplicate only MdItem
+            self.mdItem = MdItem(parent=parent,
+                                 item=mdItems,
+                                 multiplicity=False,
+                                 rmMulti=True,
+                                 isFirstNum=-1,
+                                 chckBox=template)
+
+            try:
+                if mdItems.inbox is not None:
+                    mdItems.addMdItem(self.mdItem, mdItemOld)
+                else:
+                    mdItems.addMdItem(self.mdItem)
+            except:
+                mdItems.addMdItem(self.mdItem)
+
+#=========================================================================
+# METADATA ITEM (label+ctrlText+button(optional)+chckbox(template)
+#=========================================================================
+class MdItem(wx.BoxSizer):
+
+    '''main building blocks of generated GUI of editor
+    '''
+
+    def __init__(self, parent, item, multiplicity=None, rmMulti=False, isFirstNum=-1, chckBox=False):
+        '''
+        @param item: jinjainfo::MdDescription(initialized by parsing information from jinja template)
+        @param multiplicity: if true- widget has button for duplicate self
+        @param rmMulti: if true- widget has button for remove self
+        @param isFirstNum: handling with 'add' and 'remove' button of box.
+                            this param is necessary for generating editor in editor::MdEditor.generateGUI.inBlock()
+                            note: just first generated box has 'add' button (because being mandatory) and next others has
+                            'remove' button
+        @param chckBox: in case-True  'template editor' is on and widget has checkbox
+        '''
+        wx.BoxSizer.__init__(self, wx.VERTICAL)
+        self.isValid = False
+        self.isChecked = False
+        self.mdDescription = item
+        self.chckBox = chckBox
+        self.multiple = multiplicity
+        self.parent=parent
+        added=False
+        if multiplicity is None:
+            self.multiple = item.multiplicity
+
+        if isFirstNum != 1:
+            self.multiple = False
+
+        if isFirstNum != 1 and item.multiplicity:
+            rmMulti = True
+        self.tagText = wx.StaticText(parent=parent, id=ID_ANY, label=item.name)
+        if self.mdDescription.databaseAttr =='language':
+            self.fillComboDB('language')
+            added=True
+        elif self.mdDescription.databaseAttr =='topicCategory':
+            self.fillComboDB('topicCategory')
+            added=True
+        elif self.mdDescription.databaseAttr =='degree':
+            self.fillComboDB('degree')
+            added=True
+        elif self.mdDescription.databaseAttr =='dateType':
+            self.fillComboDB('dateType')
+            added=True
+        elif self.mdDescription.databaseAttr =='role':
+            self.fillComboDB('role')
+            added=True
+
+        if self.chckBox is False and not added:
+            if item.multiline is True:
+                self.valueCtrl = wx.TextCtrl(parent, id=ID_ANY, size=(0, 70),
+                                             validator=self.validators(item.type),
+                                             style=wx.VSCROLL |
+                                             wx.TE_MULTILINE | wx.TE_WORDWRAP |
+                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER)
+            else:
+                self.valueCtrl = wx.TextCtrl(parent, id=wx.ID_ANY,
+                                             validator=self.validators(item.type),
+                                             style=wx.VSCROLL | wx.TE_DONTWRAP |
+                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER | wx.HSCROLL)
+        elif self.chckBox is True and not added:
+            if item.multiline is True:
+                self.valueCtrl = wx.TextCtrl(parent, id=ID_ANY, size=(0, 70),
+                                             style=wx.VSCROLL |
+                                             wx.TE_MULTILINE | wx.TE_WORDWRAP |
+                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER)
+            else:
+                self.valueCtrl = wx.TextCtrl(parent, id=wx.ID_ANY,
+                                             style=wx.VSCROLL | wx.TE_DONTWRAP |
+                                             wx.TAB_TRAVERSAL | wx.RAISED_BORDER | wx.HSCROLL)
+
+
+        self.valueCtrl.Bind(wx.EVT_MOTION, self.onMove)
+        self.valueCtrl.SetExtraStyle(wx.WS_EX_VALIDATE_RECURSIVELY)
+
+        if self.multiple:
+            self.addItemButt = wx.Button(parent, -1, size=(30, 30), label='+')
+            self.addItemButt.Bind(EVT_BUTTON, self.duplicateItem)
+
+        if rmMulti:
+            self.rmItemButt = wx.Button(parent, -1, size=(30, 30), label='-')
+            self.rmItemButt.Bind(EVT_BUTTON, self.removeItem)
+
+        if self.chckBox:
+            self.chckBoxEdit = wx.CheckBox(parent, -1, size=(30, 30))
+            self.chckBoxEdit.Bind(wx.EVT_CHECKBOX, self.onChangeChckBox)
+            self.chckBoxEdit.SetValue(False)
+            self.isChecked = False
+            self.valueCtrl.Disable()
+
+        self.createInfo()
+        self.tip = wx.ToolTip(self.infoTip)
+
+        self._addItemLay(item.multiline, rmMulti)
+
+    def fillComboDB(self,label):
+        if label == 'language':
+            lang=["Afrikaans","Albanian","Arabic","Armenian","Basque","Bengali",
+                  "Bulgarian","Catalan","Cambodian","Chinese","Croatian","Czech",
+                  "Danish","Dutch","English","Estonian","Fiji","Finnish","French",
+                  "Georgian","German","Greek","Gujarati","Hebrew","Hindi","Hungarian",
+                  "Icelandic","Indonesian","Irish","Italian","Japanese","Javanese","Korean",
+                  "Latin","Latvian","Lithuanian","Macedonian","Malay","Malayalam","Maltese",
+                  "Maori","Marathi","Mongolian","Nepali","Norwegian","Persian","Polish","Portuguese",
+                  "Punjabi","Quechua","Romanian","Russian","Samoan","Serbian","Slovak","Slovenian",
+                  "Spanish","Swahili","Swedish","Tamil","Tatar","Telugu","Thai","Tibetan","Tonga",
+                  "Turkish","Ukrainian","Urdu","Uzbek","Vietnamese","Welsh","Xhosa"]
+            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
+            for lng in lang:
+                self.valueCtrl.Append(lng)
+        if label == 'topicCategory':
+            lang= ['farming','biota','boundaries','climatologyMeteorologyAtmosphere','economy',
+                   'elevation','enviroment','geoscientificInformation','health','imageryBaseMapsEarthCover',
+                   'intelligenceMilitary','inlandWaters','location','planningCadastre','society','structure',
+                   'transportation','utilitiesCommunication']
+            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
+            for lng in lang:
+                self.valueCtrl.Append(lng)
+        if label == 'degree':
+            lang=['Not evaluated','Not conformant','Conformant']
+            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
+            for lng in lang:
+                self.valueCtrl.Append(lng)
+        if label == 'dateType':
+            lang=['Date of creation','Date of last revision', 'Date of publication']
+            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
+            for lng in lang:
+                self.valueCtrl.Append(lng)
+        if label == 'role':
+            lang=['Author','Custodian','Distributor','Originator','Owner','Point of contact','Principal Investigation',
+                  'Processor','Publisher','Resource provider','User']
+            self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
+            for lng in lang:
+                self.valueCtrl.Append(lng)
+    def validators(self, validationStyle):
+
+        if validationStyle == 'email':
+            return EmailValidator()
+
+        if validationStyle == 'integer':
+            return NTCValidator('DIGIT_ONLY')
+
+        if validationStyle == 'decimal':
+            return NTCValidator('DIGIT_ONLY')
+
+        if validationStyle == 'date':
+            return TimeISOValidator()
+
+        # return EmptyValidator()
+        return SimpleValidator('')
+
+    def onChangeChckBox(self, evt):
+        '''current implementation of editor mode for defining templates not allowed to check
+        only single items in static box. There are two cases:  all items in box are checked or not.
+        '''
+        if self.mdDescription.inbox:  # MdItems are in box
+            try:
+                items = self.valueCtrl.GetParent().mdItems
+                if self.isChecked:
+                    self.valueCtrl.Disable()
+                    self.isChecked = False
+                else:
+                    self.valueCtrl.Enable()
+                    self.isChecked = True
+
+                for item in items:
+                    if self.isChecked:
+                        item.valueCtrl.Enable()
+                        item.chckBoxEdit.SetValue(True)
+                        item.isChecked = True
+                    else:
+                        item.valueCtrl.Disable()
+                        item.chckBoxEdit.SetValue(False)
+                        item.isChecked = False
+            except:
+                pass
+        else:
+            if self.isChecked:
+                self.valueCtrl.Disable()
+                self.isChecked = False
+            else:
+                self.valueCtrl.Enable()
+                self.isChecked = True
+
+    def onMove(self, evt=None):
+        self.valueCtrl.SetToolTip(self.tip)
+
+    def createInfo(self):
+        """Feed for tooltip
+        """
+        string = ''
+        if self.mdDescription.ref is not None:
+            string += self.mdDescription.ref + '\n\n'
+        if self.mdDescription.name is not None:
+            string += 'NAME: \n' + self.mdDescription.name + '\n\n'
+        if self.mdDescription.desc is not None:
+            string += 'DESCRIPTION: \n' + self.mdDescription.desc + '\n\n'
+        if self.mdDescription.example is not None:
+            string += 'EXAMPLE: \n' + self.mdDescription.example + '\n\n'
+        if self.mdDescription.type is not None:
+            string += 'DATA TYPE: \n' + self.mdDescription.type + '\n\n'
+        string += '*' + '\n'
+        if self.mdDescription.statements is not None:
+            string += 'Jinja template info: \n' + self.mdDescription.statements + '\n'
+
+        if self.mdDescription.statements1 is not None:
+            string += self.mdDescription.statements1 + '\n'
+        string += 'OWSLib info:\n' + self.mdDescription.tag
+        self.infoTip = string
+
+    def removeItem(self, evt):
+        """adding all items in self(mdItem) to list and call parent remover
+        """
+        ilist = [self.valueCtrl, self.tagText]
+        try:
+            ilist.append(self.rmItemButt)
+        except:
+            pass
+        try:
+            ilist.append(self.chckBoxEdit)
+        except:
+            pass
+        self.valueCtrl.GetParent().removeMdItem(self, ilist)
+
+    def duplicateItem(self, evt):
+        '''add Md item to parent(box or notebook page)
+        '''
+        parent = self.valueCtrl.GetParent()
+        # if parent is box
+        if self.mdDescription.inbox:
+            duplicator = MdWxDuplicator(mdItems=self.mdDescription,
+                                        parent=parent,
+                                        mdItemOld=self,
+                                        template=self.chckBox)
+        else:
+            duplicator = MdWxDuplicator(mdItems=self.mdDescription,
+                                        parent=parent,
+                                        template=self.chckBox)
+
+        clonedMdItem = duplicator.mdItem
+        # call parent "add" function
+        self.valueCtrl.GetParent().addDuplicatedItem(clonedMdItem, self.valueCtrl.GetId())
+
+    def setValue(self, value):
+        '''Set value & color of widgets
+        in case if is template creator 'on':
+            yellow: in case if value is marked by $NULL(by mdgrass::GrassMD)
+            red:    if value is '' or object is not initialized. e.g. if user
+                    read non fully valid INSPIRE xml with INSPIRE jinja template,
+                    the GUI generating mechanism will create GUI according to template
+                    and all missing tags(xml)-gui(TextCtrls) will be marked by red
+        '''
+        if value is None or value is '':
+            if self.chckBox:
+                self.chckBoxEdit.SetValue(True)
+                self.isChecked = True
+                try:
+                    self.onChangeChckBox(None)
+                    self.onChangeChckBox(None)
+                except:
+                    pass
+                self.valueCtrl.SetBackgroundColour((245, 204, 230))  # red
+
+            self.valueCtrl.SetValue('')
+            self.valueCtrl.Enable()
+
+        elif self.chckBox and value == '$NULL':
+            self.valueCtrl.SetBackgroundColour((255, 255, 82))  # yellow
+            self.valueCtrl.SetValue('')
+
+            if self.chckBox:
+                self.chckBoxEdit.SetValue(True)
+                self.isChecked = True
+                self.valueCtrl.Enable()
+                try:
+                    self.onChangeChckBox(None)
+                    self.onChangeChckBox(None)
+                except:
+                    pass
+
+        elif value == '$NULL':
+            self.valueCtrl.SetValue('')
+
+        else:
+            self.isValid = True
+            self.valueCtrl.SetValue(value)
+
+    def getValue(self):
+
+        value = mdutil.replaceXMLReservedChar(self.valueCtrl.GetValue())
+        value = value.replace('\n', '')
+        value = value.replace('"', '')
+        value = value.replace("'", '')
+        return value
+
+    def getCtrlID(self):
+        return self.valueCtrl.GetId()
+
+    def _addItemLay(self, multiline, rmMulti):
+        self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)
+        if multiline is True:
+            self.textFieldSizer.Add(self.valueCtrl, proportion=1, flag=wx.EXPAND)
+        else:
+            self.textFieldSizer.Add(self.valueCtrl, proportion=1)
+
+        if self.multiple:
+            self.textFieldSizer.Add(self.addItemButt, 0)
+
+        if rmMulti:
+            self.textFieldSizer.Add(self.rmItemButt, 0)
+
+        if self.chckBox:
+            self.textFieldSizer.Add(self.chckBoxEdit, 0)
+
+        self.Add(item=self.tagText, proportion=0)
+        self.Add(item=self.textFieldSizer, proportion=0, flag=wx.EXPAND)
+
+
+class MdItemKeyword(wx.BoxSizer):
+    def __init__(self, parent, text,keyword,title, keywordObj):
+        wx.BoxSizer.__init__(self, wx.VERTICAL)
+        self.isValid = False
+        self.isChecked = False
+        self.keywordObj=keywordObj
+        self.text = wx.StaticText(parent=parent, id=ID_ANY, label=text)
+        self.parent=parent
+        self.rmItemButt = wx.Button(parent, -1, size=(30, 30), label='-')
+        self.rmItemButt.Bind(EVT_BUTTON, self.removeItem)
+        self.keyword=keyword
+        self.title=title
+        #self.createInfo()
+        #self.tip = wx.ToolTip(self.infoTip)
+        self.layout()
+
+    def getVal(self):
+        return  self.text.GetLabel()
+
+    def getKyewordObj(self):
+        self.keywordObj['keywords']=self.keyword
+        self.keywordObj['title']=self.title
+        return self.keywordObj
+
+    def removeItem(self,evt):
+        self.parent.textTMP=self.text.GetLabel()
+        self.textFieldSizer.Clear()
+        #self.textFieldSizer.Destroy()
+
+        self.rmItemButt.Destroy()
+        self.text.Destroy()
+        self.parent.removeKeywordItem(self)
+
+    def layout(self):
+        self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        self.textFieldSizer.Add(self.rmItemButt, 0,flag=wx.LEFT)
+        self.textFieldSizer.Add(self.text, 0,flag=wx.RIGHT)
+        self.Add(item=self.textFieldSizer, proportion=0, flag=wx.EXPAND)
+#=========================================================================
+#=========================================================================
+# ADD NOTEBOOK PAGE
+#=========================================================================
+
+class MdNotebookPage(scrolled.ScrolledPanel):
+
+    """
+    every notebook page is initialized by jinjainfo::MdDescription.group (label)
+    """
+
+    def __init__(self, parent):
+        scrolled.ScrolledPanel.__init__(self, parent=parent, id=wx.ID_ANY)
+        self.items = []
+        self.SetupScrolling()
+        self._addNotebookPageLay()
+        self.sizerIndexDict = {}
+        self.sizerIndex = 0
+
+    def _addNotebookPageLay(self):
+        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.mainSizer)
+
+    def _getIndex(self):
+        '''
+        index for handling position of editor::MdBox,MdItem in editor::MdNotebookPage(self).
+        Primary for correct duplicating Boxes or items on notebook page
+        '''
+        self.sizerIndex += 1
+        return self.sizerIndex
+
+    def addKeywordObj(self,item):
+        self.mainSizer.Add(item, proportion=0, flag=wx.EXPAND)
+
+    def addItem(self, item):
+        '''
+        @param item: can be editor::MdBox or editor::MDItem
+        '''
+        if isinstance(item, list):
+            for i in item:
+                if isinstance(i, list):
+                    for ii in i:
+                        self.sizerIndexDict[ii.getCtrlID()] = self._getIndex()
+                        self.mainSizer.Add(ii, proportion=0, flag=wx.EXPAND)
+                else:
+                    self.sizerIndexDict[i.getCtrlID()] = self._getIndex()
+                    self.mainSizer.Add(i, proportion=0, flag=wx.EXPAND)
+        else:
+            self.sizerIndexDict[item.getCtrlID()] = self._getIndex()
+            self.mainSizer.Add(item, proportion=0, flag=wx.EXPAND)
+
+    def addDuplicatedItem(self, item, mId):
+        '''adding duplicated object to sizer to position after parent
+        '''
+        self.items.append(item)
+        posIndex = self.sizerIndexDict[mId]
+        self.mainSizer.Insert(posIndex, item, proportion=0, flag=wx.EXPAND)
+        self.SetSizerAndFit(self.mainSizer)
+        self.GetParent().Refresh()
+
+    def removeBox(self, box):
+        box.Destroy()
+        self.SetSizerAndFit(self.mainSizer)
+
+    def removeMdItem(self, mdDes, items):
+        '''Remove children
+        @param mdDes: editor::MdItem.mdDescription
+        @param items: all widgets to remove of MdItem
+        '''
+        mdDes.mdDescription.removeMdItem(mdDes)  # remove from jinjainfi:MdDEscription object
+        for item in items:
+            item.Destroy()
+        self.SetSizerAndFit(self.mainSizer)
+
+#class MdItemKyewords
+class MdKeywords(wx.BoxSizer):
+    def __init__(self,parent,mdObject,mdOWS):
+        wx.BoxSizer.__init__(self, wx.VERTICAL)
+        self.itemHolder=set()
+        self.parent=parent
+        self.keywordsOWSObject=mdOWS
+
+        self.comboKeysLabel=wx.StaticText(parent=self.parent,id=ID_ANY,label='Keywords from repositories')
+        self.comboKeys=wx.ComboBox(parent=self.parent, id=ID_ANY)
+
+        self.keysList=wx.TreeCtrl(parent=self.parent, id=ID_ANY,size=(0, 120),style=wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_DEFAULT_STYLE)
+        self.box=MdBoxKeywords(parent=parent,parent2=self,label='Keywords')
+        self.memKeys=set()
+        self.comboKeys.Bind(wx.EVT_COMBOBOX,self.onSetVocabulary)
+        self.keysList.Bind(wx.EVT_TREE_ITEM_ACTIVATED,self.addItemsToBox)
+        self.layout()
+        Module('db.connect',flags='d')
+        self.fillDb()
+        self.fillKeywordsList()
+
+    def removeKeyfromBox(self,item,text):
+        self.memKeys.remove(text)
+        self.itemHolder.remove(item)
+
+    def addItemsToBox(self,evt):
+        item = evt.GetItem()
+        if item == self.keysList.GetRootItem():
+            return
+
+        keyword=self.keysList.GetItemText(item)
+        currKeyword=self.titles[self.comboKeys.GetValue()]
+        out=self.comboKeys.GetValue()+', '+ keyword+', '+ currKeyword['type']+', '+ currKeyword['date']
+        if keyword in self.memKeys:
+            return
+        self.memKeys.add(out)
+
+        kItem=MdItemKeyword(self.box,out,keyword,self.comboKeys.GetValue(),currKeyword)
+        self.itemHolder.add(kItem)
+        self.box.addKeywordItem(kItem)
+        self.box.Fit()
+        self.parent.Fit()
+
+    def dbSelect(self,sql):
+        res = Module('db.select',
+                sql=sql,
+                flags='c',
+                stdout_=PIPE)
+        return res.outputs.stdout
+
+    def dbExecute(self,sql):
+        Module('db.execute',
+                sql=sql)
+
+    def GetKws(self):
+        return self.itemHolder# dict is in var keywordObj
+
+    def fillDb(self):
+
+
+
+        if not mdutil.isTableExists('metadata_themes'):
+            sql='create table if not exists metadata_themes (title TEXT, keyword TEXT, date_iso TEXT ,date_type TEXT)'
+            self.dbExecute(sql)
+            p1=os.path.join(sys.path[0],'..')
+
+            titles = [['keywordConcepts.txt','GEMET - Concepts, version 2.4'],
+                     ['keywordThemes.txt','GEMET - Themes, version 2.4'],
+                     ['keywordGroups.txt','GEMET - Groups, version 2.4']]
+            for title in titles:
+                path = os.path.join(p1, 'config', title[0])
+                str=''
+                with open(path, "r") as inp :
+                    exec(inp.read())
+
+                    for item in keywords:
+                            str+="('%s','%s','%s','%s'),"%(title[1],item['preferredLabel']['string'],'2010-01-13','publication')
+                    str=str[:-1]
+                    sql="INSERT INTO 'metadata_themes' ('title', 'keyword', 'date_iso' ,'date_type' ) VALUES"+str
+                inp.close()
+                self.dbExecute(sql)
+
+    def fillKeywordsList(self):
+        sql='SELECT title,keyword,date_iso,date_type FROM metadata_themes'
+
+        #TODO check if database exist
+        self.keysDict=None
+        metaRepository=self.dbSelect(sql)
+        self.titles={}
+        theme=''
+        titleTmp=None
+        lines=metaRepository.splitlines()
+        #lines.pop()
+        for line in lines:
+            line=line.split('|')
+            if theme != line[0]: #if new theme found
+                if titleTmp is not None:#first loop
+                    self.titles[titleTmp]=self.keysDict
+                theme=line[0]
+                self.keysDict={}
+                self.keysDict['date']=line[2]
+                self.keysDict['type']=line[3]
+                self.keysDict['keywords']=[1]
+            self.keysDict['keywords'].append(str(line[1]))
+            titleTmp=line[0]
+
+        if self.keysDict is None:
+            GMessage('Predefined values of metadata are missing in database')
+            return
+        self.titles[titleTmp]=self.keysDict
+
+        for key in self.titles.keys():
+            self.comboKeys.Append(key)
+
+    def onSetVocabulary(self,evt):
+        self.keysList.DeleteAllItems()
+        self.root=self.keysList.AddRoot('Keywords')
+        title=self.comboKeys.GetValue()
+
+        keywords=self.titles[title]['keywords']
+        keywords.pop(0)
+        for keyword in keywords:
+            self.keysList.AppendItem(parent=self.root,text=str(keyword))
+        self.keysList.ExpandAll()
+
+    def layout(self):
+        self.Add(self.box,flag=wx.EXPAND)
+        self.Add(self.comboKeysLabel,flag=wx.EXPAND)
+        self.Add(self.comboKeys,flag=wx.EXPAND)
+        self.AddSpacer(10, 10, 1, wx.EXPAND)
+
+        self.Add(self.keysList,proportion=1,flag=wx.EXPAND)
+
+
+#=========================================================================
+# MAIN FRAME
+#=========================================================================
+class MdMainEditor(wx.Panel):
+
+    '''
+    main functions : self.generateGUI(): generating GUI from: editor:MdItem,MdBox,MdNotebookPage
+                     self.createNewMD(): filling OWSLib.iso.MD_Metadata by values from generated GUI
+                     self.defineTemplate(): creator of predefined templates in template editor mode
+    '''
+
+    def __init__(self, parent, profilePath, xmlMdPath, templateEditor=False):
+        '''
+        @param profilePath: path to jinja template for generating GUI of editor
+        @param xmlMdPath: path of xml for init Editor
+        @param templateEditor: mode-creator of template
+        '''
+        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
+        self.mdo = MdFileWork()
+        self.md = self.mdo.initMD(xmlMdPath)
+        self.templateEditor = templateEditor
+        self.profilePath = profilePath
+
+        self.jinj = JinjaTemplateParser(self.profilePath)
+        # list of object MdDescription
+        self.mdDescription = self.jinj.mdDescription
+        # string of tags from jinja template (loops and OWSLib objects)
+        self.mdOWSTagStr = self.jinj.mdOWSTagStr
+        self.mdOWSTagStrList = self.jinj.mdOWSTagStrList  #
+        self.keywords=None
+        self.nbPage=None
+        self.generateGUI()
+        self._layout()
+
+ #----------------------------------------------------------- GUI GENERATOR START
+    def executeStr(self, stri, mdDescrObj):
+        '''note- exec cannot be in sub function
+        for easy understanding to product of self.generateGUI()- print stri
+        '''
+        print stri
+        exec stri
+
+    def plusC(self, num=None):
+        '''iterator for handling jinja teplate items in self.generateGUI and self.createNewMD
+
+        '''
+        if num is None:
+            num = 1
+        self.c += num
+        if self.c >= self.max:
+            self.c -= 1  # ensure to 'list out of bounds'
+            self.stop = True
+
+    def minusC(self, num=None):
+        '''iterator for handling jinja template items in self.generateGUI and self.createNewMD
+        '''
+        if num is None:
+            num = 1
+        self.c -= num
+        if self.c <= self.max:
+            self.stop = False
+
+    def generateGUI(self):
+        '''
+        @var tagStringLst:  tagStringLst is self.mdOWSTagStr in list.
+                            Item=line from jinja template(only lines with owslib objects and loops)
+        @var mdDescrObj:    list of MdDescription() objects initialized\
+                            by information from jinja t.
+        @var self.c:        index of var: tagStringLst and var: self.mdDescription
+        @var markgroup:     markers of created list in GUI notebook
+        @var self.max:      length of tagStringLst and mdDescrObj
+        @var self.stop:     index self.c is increasing  by function plusC(),\
+                            that care about not exceeding the index
+        HINT: print param stri in self.executeStr()
+        '''
+        def prepareStatements():
+            '''in jinja template are defining some py-function specifically:
+            e.g. |length=len
+            also statements with pythonic 'zip' must be prepare specifically for generator of GUI
+            '''
+            for c in range(self.max):
+                if '|length' in str(tagStringLst[c]):
+                    a = tagStringLst[c]
+                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
+                    tagStringLst[c] = a
+                if 'zip(' in tagStringLst[c]:
+                    sta = tagStringLst[c]
+                    tagStringLst[c] = sta.replace('md.', 'self.md.')
+
+        def chckIfJumpToLoop(sta):
+            '''if loaded xml not include tags(OWSLib object) from jinja template, this function will
+                    generate sample of item(marked by red in GUI-template mode).
+            @note: in case of sub statements e.g. metadata-keywords is need to check booth statements
+            @param sta: statements of the loop
+            for understanding print param for self.executeStr()
+            '''
+            self.isValidS = False
+            staTMP = sta
+            if not '\t'in staTMP:
+                tab = '\t'
+                tab1 = ''
+                staTMP = staTMP + ":\n" + tab + 'self.isValidS=True'
+            else:
+                tab = '\t'
+                tab1 = '\t'
+                staTMP = staTMP.replace('\t', '') + ":\n" + tab + 'self.isValidS=True'
+
+            try:  # if loop for in for
+                self.executeStr(staTMP, False)
+            except:
+                staTMP = self.staTMP.replace('self.isValidS=True', '') + '\n\t' + staTMP.replace('\t', '\t\t')
+                self.executeStr(staTMP, False)
+
+            self.staTMP = staTMP
+            if self.isValidS:
+                return sta
+            else:
+                return tab1 + 'for n in range(1)'
+
+        def inBlock():
+            '''This part of code build string-code for executing. This can happend if is necassary to use statements
+                to generate gui(OWSLib objects in list). The block of code is building from "statement" which is represended by OWSLib object.
+                In case if OWSLib object is non initialized(metadata missing), function chckIfJumpToLoop() replace statements by "for n in range(1)".
+            @var IFStatements: True= string is IF statements
+            @var loop: current statements, mostly loop FOR
+            @var str1: final string for execute
+            @var box:  True if editor::MdItems is in editor::MdBox
+            @var isValid: True in case if OWSLib object in statement is initialized. False= statements is 'for n in range(1)'
+            '''
+            IFStatements = False
+            statements = tagStringLst[self.c - 1]
+            if 'if' in statements.split():
+                IFStatements = True
+            loop = statements.replace(' md.', ' self.md.')
+            looptmp = chckIfJumpToLoop(loop)
+            str2 = 'numOfSameBox=0\n'
+            str2 += looptmp
+
+            str2 += ':\n'
+            str2 += '\t' + 'self.ItemList=list()\n'  # initialize list
+            str2 += '\t' + 'numOfSameBox+=1\n'
+
+            box = False
+            if self.mdDescription[self.c].inbox:
+                box = True
+                str2 += '\t' + 'box=MdBox(self.nbPage,mdDescrObj[' + str(self.c) + '].inbox)\n'  # add box
+
+            str1 = str2
+            while '\t' in tagStringLst[self.c] and self.stop is False:
+                if  'for' not in str(tagStringLst[self.c]).split()\
+                        and 'if' not in str(tagStringLst[self.c]).split():
+
+                    value = str(self.mdOWSTagStrList[self.c])
+                    str1 += '\t' + 'self.mdDescription[' + str(self.c) + "].addStatements('" + loop + "')\n"
+
+                    if box:
+                        str1 +=     '\t' + \
+                            'it=MdItem(parent=box,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameBox,chckBox=self.templateEditor)\n'
+                    else:
+                        str1 +=     '\t' + \
+                            'it=MdItem(parent=self.nbPage,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameBox,chckBox=self.templateEditor)\n'
+
+                    if self.isValidS:  # if metadata are loaded to owslib
+                        if IFStatements:
+                            str1 += '\t' + 'it.setValue(self.' + str(value) + ')\n'
+                        else:
+                            str1 += '\t' + 'it.setValue(' + str(value) + ')\n'
+                    else:
+                        if IFStatements:
+                            str1 += '\t' + 'it.setValue("")\n'
+                        else:
+                            str1 += '\t' + 'it.setValue("")\n'
+
+                    str1 += '\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(it)\n'
+                    str1 += '\t' + 'self.ItemList.append(it)\n'
+                    tab = '\t'
+                    self.plusC()
+
+                else:  # if statements in statements
+                    statements = tagStringLst[self.c]
+                    str2 = ''
+                    keyword = False
+
+                    if '["keywords"]' in statements:
+                        keyword = True
+                        str2 += '\t' + 'self.keywordsList=[]\n'
+
+                    str2 += '\t' + 'numOfSameItem=0\n'
+                    loop2 = statements.replace(' md.', ' self.md.')
+                    looptmp1 = chckIfJumpToLoop(loop2)
+                    str2 += looptmp1 + ':\n'
+                    self.plusC()
+                    str1 += str2
+                    while '\t\t' in tagStringLst[self.c] and self.stop is False:
+                        value = str(self.mdOWSTagStrList[self.c])
+                        # save information about loops
+                        str1 += '\t\t' + 'numOfSameItem+=1\n'
+                        str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + "].addStatements('" + loop + "')\n"
+                        str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + "].addStatements1('" + loop2 + "')\n"
+
+                        if box:
+                            str1 += '\t\t' + \
+                                'it=MdItem(parent=box,item=mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameItem,chckBox=self.templateEditor)\n'
+                        else:
+                            str1 += '\t\t' + \
+                                'it=MdItem(self.nbPage,mdDescrObj[' + str(self.c) + '],isFirstNum=numOfSameItem,chckBox=self.templateEditor)\n'
+
+                        if self.isValidS:
+                            str1 += '\t\t' + 'it.setValue(' + str(value) + ')\n'
+                        else:
+                            str1 += '\t\t' + 'it.setValue("")\n'
+
+                        str1 += '\t\t' + 'self.ItemList.append(it)\n'
+                        if keyword:
+                            str1 += '\t\t' + 'self.keywordsList.append(it)\n'
+                            str1 += '\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(self.keywordsList)\n'
+                        else:
+                            str1 += '\t\t' + 'self.mdDescription[' + str(self.c) + '].addMdItem(it)\n'
+
+                        tab = '\t\t'
+                        self.plusC()
+            if box:
+                str1 += tab +\
+                    'box.addItems(items=self.ItemList,multi=mdDescrObj[self.c].inboxmulti,isFirstNum=numOfSameBox)\n'
+                str1 += tab + 'self.nbPage.addItem(box)\n'
+            else:
+                str1 += tab + 'self.nbPage.addItem(self.ItemList)\n'
+
+            self.executeStr(str1, mdDescrObj)
+
+    #--------------------------------------------------------------------- INIT VARS
+        self.notebook = wx.Notebook(self)
+        markedgroup = []  # notebook panel marker
+        tagStringLst = self.mdOWSTagStrList
+        mdDescrObj = self.mdDescription  # from jinja
+        self.c = 0
+        self.stop = False
+        self.max = len(mdDescrObj)
+        prepareStatements()
+        self.notebokDict = {}
+    # --------------------------------------------- #START of the loop of generator
+        while self.stop is False:  # self.stop is managed by def plusC(self):
+            group = mdDescrObj[self.c].group
+
+            if group not in markedgroup:  # if group is not created
+                markedgroup.append(group)  # mark group
+                self.nbPage = MdNotebookPage(self.notebook)
+                self.notebook.AddPage(self.nbPage, mdDescrObj[self.c].group)
+                if mdDescrObj[self.c].group=='Keywords':
+                    self.keywords=MdKeywords(parent=self.nbPage,mdObject=mdDescrObj[self.c],mdOWS=self.md.identification.keywords)
+                    self.nbPage.addKeywordObj(self.keywords)
+                self.notebokDict[mdDescrObj[self.c].group] = self.nbPage
+            else:
+                self.nbPage = self.notebokDict[mdDescrObj[self.c].group]
+
+            # if  statements started
+            if '\t' in tagStringLst[self.c] and self.stop is False:
+                inBlock()
+            # if is just single item without statements
+            elif 'for' not in str(tagStringLst[self.c]).split() and 'if' not in str(tagStringLst[self.c]).split():
+                it = MdItem(parent=self.nbPage, item=mdDescrObj[self.c], chckBox=self.templateEditor)
+                value = 'self.' + str(self.mdOWSTagStrList[self.c]).replace('\n', '')
+                value = eval(value)
+                if value is None:
+                    value = ''
+
+                it.setValue(value)
+                self.mdDescription[self.c].addMdItem(it)
+                self.nbPage.addItem(it)
+                self.plusC()
+            else:
+                self.plusC()
+        if self.templateEditor:
+            self.refreshChkboxes()
+
+    def refreshChkboxes(self):
+        '''In case if template editor is on, after generating GUI it is
+         obligatory to refresh checkboxes
+        '''
+        for item in self.mdDescription:
+            for i in item.mdItem:
+                try:
+                    i.onChangeChckBox(None)
+                    i.onChangeChckBox(None)
+                except:
+                    pass
+    #----------------------------------------------------------- GUI GENERATOR END
+
+    def defineTemplate(self):
+        '''Main function for generating jinja template in mode "template editor"
+        Every widget MdItem is represented by 'jinja tag'. Not checked widget= tag in jinja template will be replaced by
+        list of string with string of replaced tag. In rendering template this produces holding(non removing) jinja-tag from template.
+        In case if widget is checked= rendering will replace OWSLib object by filled values( like in normal editing mode)
+        @var finalTemplate:    string included final jinja template
+        '''
+        try:
+            template = open(self.profilePath, 'r')
+        except Exception, e:
+            GError('Error loading template:\n' + str(e))
+
+        owsTagList = list()
+        indexowsTagList = 0
+        finalTemplate = ''
+        chcked = False
+        forSTS = False
+        ifSTS = False
+
+        for line in template.readlines():
+            if '{% for' in line:
+                forSTS = True
+
+            if '{% if' in line:
+                ifSTS = True
+
+            for r, item in enumerate(self.mdDescription):
+                str1 = item.selfInfoString
+                if str1 in line:  # owslib definition in line
+                    try:
+                        if item.mdItem[0].isChecked == False:
+                            chcked = False
+                    except:
+                        try:
+                            if self.mdDescription[r + 1].mdItem[0].isChecked == False:
+                                chcked = False
+                        except:
+                            try:
+                                if self.mdDescription[r + 2].mdItem[0].isChecked == False:
+                                    chcked = False
+                            except:
+                                try:
+                                    if self.mdDescription[r + 3].mdItem[0].isChecked == False:
+                                        chcked = False
+                                except:
+                                    pass
+                    if not chcked:  # chckbox in gui
+
+                        if forSTS:
+                            forSTS = False
+
+                        if ifSTS:
+                            ifSTS = False
+
+                        owsTagList.append(str1)
+                        templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
+                        indexowsTagList += 1
+
+                        line = line.replace(str1, templateStr)
+                        tag = '{{ ' + item.tag + ' }}'
+                        line = line.replace(tag, templateStr)
+
+                        finalTemplate += line
+                        continue
+
+            if chcked:
+                if '{% endfor -%}' in line and forSTS == 0:
+                    str1 = '{% endfor -%}'
+                    owsTagList.append(str1)
+                    templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
+                    indexowsTagList += 1
+
+                    line = line.replace(str1, templateStr)
+                    tag = '{{' + item.tag + '}}'
+                    line = line.replace(tag, templateStr)
+                    finalTemplate += line
+
+                elif '{% endif -%}' in line and ifSTS == 0:
+                    str1 = '{% endif -%}'
+                    owsTagList.append(str1)
+                    templateStr = '{{ owsTagList[' + str(indexowsTagList) + '] }}'
+                    indexowsTagList += 1
+
+                    line = line.replace(str1, templateStr)
+                    tag = '{{' + item.tag + '}}'
+                    line = line.replace(tag, templateStr)
+                    finalTemplate += line
+
+                else:
+                    finalTemplate += line
+            chcked = True
+
+        head, tail = os.path.split(self.profilePath)
+        tail = 'EXPT' + tail
+        self.profilePath = os.path.join(head, tail)
+        templateOut = open(self.profilePath, 'w')
+        templateOut.write(finalTemplate)
+        templateOut.close()
+
+
+        return owsTagList
+    #----------------------------------------- FILL OWSLib BY EDITED METADATA IN GUI
+
+    def executeStr1(self, stri, item):
+        '''note- exec cannot be in sub function
+        for easier understanding to product of self.createNewMD()- print stri
+        '''
+        #print stri
+        exec stri
+
+    def getKeywordsFromRepositoryWidget(self,md):
+        if  self.keywords is not None:
+            for item in self.keywords.GetKws():
+                titles=item.getKyewordObj()
+
+                kw = {}
+                kw['keywords'] = []
+                kw['keywords'].append(titles['keywords'])
+                kw['type'] = None
+                kw['thesaurus'] = {}
+                kw['thesaurus']['title']=titles['title']
+                kw['thesaurus']['date']=titles['date']
+                kw['thesaurus']['datetype']=titles['type']
+                md.identification.keywords.append(kw)
+        return md
+
+    def saveMDfromGUI(self, evt=None):
+        '''Main function for exporting metadata from filled widgets.
+           Initializing owslib object by metadata from gui(export of metadata)
+        '''
+        def prepareStatements():
+            '''replacing some specific declaration of python function in jinja template
+            '''
+            for c in range(self.max):
+                if '|length' in str(mdDes[c].tag):
+                    a = mdDes[c].tag
+                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
+                    mdDes[c].tag = a
+                if '|length' in str(mdDes[c].statements):
+                    a = mdDes[c].statements
+                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
+                    mdDes[c].statements = a
+                if '|length' in str(mdDes[c].statements1):
+                    a = mdDes[c].statements1
+                    a = a.replace('|length', ')').replace('if ', 'if len(self.')
+                    mdDes[c].statements1 = a
+
+        def chckIf1Statements():
+            '''Return true if next item in jinjainfo::MdDescription is statement
+            '''
+            try:
+                if mdDes[self.c + 1].statement:
+                    return True
+                else:
+                    return False
+            except:
+                return False
+
+        def chckIf2xStatements():
+            '''Return true if next two items in jinjainfo::MdDescription are representing statements
+            '''
+            if 'if'in mdDes[self.c].tag.split() or 'for' in mdDes[self.c].tag.split():
+                try:
+                    if 'if'in mdDes[self.c + 1].tag.split() or 'for'in mdDes[self.c + 1].tag.split():
+                        return True
+                    else:
+                        return False
+                except:
+                    return False
+
+        def noneStatements():
+            '''Without condition or loop
+            '''
+            str1 = ''
+            for wxCtrl in mdDes[self.c].mdItem:
+                if wxCtrl.getValue() is not None:
+                    str1 += 'self.' + mdDes[self.c].tag + '="' + str(wxCtrl.getValue()) + '"\n'
+                    self.executeStr1(str1, mdDes[self.c])
+                    str1 = ''
+            self.plusC()
+
+        def inStatements():
+            '''possible combinations of statements
+            (1)    IF
+                        item
+                ----------------------------------------------------
+            (2)    for
+            (2.1)          item (with init OWSLib object)
+                       "or"
+            (2.2)          item (without init)
+                           item with ZIP
+            '''
+            cTmp = self.c
+            tag = str(mdDes[cTmp].tag).split()
+
+            tag1 = 'self.' + str(tag[-1])
+            tag = 'self.' + str(tag[-1]) + '.append(self.val)\n'
+
+            self.plusC()
+            # statements of current item
+            stat = mdDes[self.c].statements
+            str1 = ''
+            leng = len(mdDes[self.c].mdItem)
+
+            # (2.1) IF NECESSARY TO INITIALIZE OWSLIB OBJECT
+            if mdDes[cTmp].object and 'if' not in mdDes[cTmp].tag.split():
+                objStr = 'self.val=' + mdDes[cTmp].object + '\n'
+
+                for n in range(leng):
+                    numOfItems = 0
+                    str1 += objStr
+                    while mdDes[self.c].statements == stat and self.stop is False:
+                        metadata = re.split(r'[.]', mdDes[self.c].tag)
+                        metadata[0] = 'self.val.'
+                        str1 += ''.join(metadata) + "='"\
+                            + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
+                        self.plusC()
+                        numOfItems += 1
+
+                    str1 += tag
+                    self.executeStr1(str1, False)
+                    str1 = ''
+                    self.minusC(numOfItems)
+
+                self.plusC(numOfItems)
+            # (2.2) no init and py ZIP'
+            elif 'for' in mdDes[cTmp].tag.split() and mdDes[cTmp].object is None and ' zip(' in mdDes[cTmp].tag:
+                leng = len(mdDes[self.c].mdItem)
+                tag1 = mdutil.findBetween(mdDes[cTmp].tag, 'zip(', ')').split(',')
+
+                for n in range(leng):
+                    numOfItems = 0
+                    while mdDes[self.c].statements == stat and self.stop is False:
+                        str1 += 'self.' + tag1[numOfItems] + ".append('" + mdDes[self.c].mdItem[n].getValue() + "')\n"
+                        self.plusC()
+                        numOfItems += 1
+
+                    self.executeStr1(str1, False)
+                    str1 = ''
+                    self.minusC(numOfItems)
+
+                self.plusC(numOfItems)
+            # 'no init FOR'
+            elif 'for' in mdDes[cTmp].tag.split() and mdDes[cTmp].object is None:
+                leng = len(mdDes[self.c].mdItem)
+                numOfItems = 0
+                for n in range(leng):
+                    numOfItems = 0
+                    while mdDes[self.c].statements == stat and self.stop is False:
+                        str1 += tag1 + ".append('" + mdDes[self.c].mdItem[n].getValue() + "')\n"
+                        self.plusC()
+                        numOfItems += 1
+
+                    self.executeStr1(str1, False)
+                    str1 = ''
+                    self.minusC(numOfItems)
+
+                self.plusC(numOfItems)
+            # (1) 'no init IF'
+            elif 'if' in mdDes[cTmp].tag.split():
+
+                objStr = mdDes[cTmp].tag.replace(' md.', ' self.md.') + ':\n'
+
+                for n in range(leng):
+                    numOfItems = 0
+                    while mdDes[self.c].statements == stat and self.stop is False:
+                        metadata = 'self.' + mdDes[self.c].tag
+                        str1 += ''.join(metadata) + "='"\
+                            + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
+                        self.plusC()
+                        numOfItems += 1
+
+                    self.minusC(numOfItems)
+                    self.executeStr1(str1, False)
+                    str1 = ''
+                self.plusC(numOfItems)
+
+        def in2Statements():
+            '''possible combinations of statements
+            (1)    IF:
+                       FOR:
+            (1.1)           item (with init OWSLib object)
+                            "or"
+            (1.2)           item (without init)
+                ----------------------------------------------------
+            (2)     FOR:
+                        FOR:(implemented fixedly just for MD-keywords)
+            (2.1)            item (with init OWSLib object)
+                             "or"
+            (2.2)            item (without init)
+            '''
+            prepareStatements()
+            cTmp = self.c
+            cTmp1 = self.c + 1
+            tag = str(mdDes[cTmp].tag).split()
+            tag1 = str(mdDes[cTmp1].tag).split()
+            stat = mdDes[self.c + 2].statements
+
+            append = 'self.' + str(tag1[-1]) + '.append(self.val)\n'
+            appendNoInit = 'self.' + str(tag1[-1])
+            # (1)
+            # if statements-if in jinja template=skip and do single loop
+            if 'if' in tag and 'for' in tag1:
+                leng = len(mdDes[self.c + 2].mdItem)
+                # (1.1)
+                if mdDes[cTmp1].object:
+                    condition = mdDes[cTmp].tag.replace(' md.', ' self.md.') + ':\n'
+                    objectOWSLib = '\t' + 'self.val=' + mdDes[cTmp1].object + '\n'
+                    condition2 = '\t' + mdDes[cTmp1].tag.replace(' md.', ' self.md.') + ':\n'
+                    self.plusC()
+                    self.plusC()
+
+                    for n in range(leng):
+                        numOfItems = 0
+                        str1 = condition + '\n'
+                        str1 += condition2 + '\n'
+                        str1 += '\t' + objectOWSLib + '\n'
+
+                        while mdDes[self.c].statements == stat and self.stop is False:
+                            metadata = re.split(r'[.]', mdDes[self.c].tag)
+                            metadata[0] = '\t\tself.val'
+                            str1 += ''.join(metadata) + "='" + str(mdDes[self.c].mdItem[n].getValue()) + "'\n"
+                            self.plusC()
+                            numOfItems += 1
+
+                        str1 += '\t\t' + append
+                        self.executeStr1(str1, False)
+                        str1 = ''
+                        self.minusC(numOfItems)
+                    self.plusC(numOfItems)
+                # (1.2)"if and for "
+                else:
+                    self.plusC()
+                    self.plusC()
+                    numOfItems = 0
+                    size = len(mdDes[self.c].mdItem)
+                    for n in range(size):
+                        numOfItems = 0
+                        str1 = ''
+
+                        while mdDes[self.c].statements == stat and self.stop is False:
+                            str1 += appendNoInit + '.append("' + mdDes[self.c].mdItem[n].getValue() + '")\n'
+                            self.plusC()
+                            numOfItems += 1
+
+                        self.executeStr1(str1, False)
+                        self.minusC(numOfItems)
+                    self.plusC(numOfItems)
+            # (2) only keywords  (dict)
+            elif 'for' in tag and 'for' in tag1:  #
+                self.plusC()  # skip statementes 2x
+                self.plusC()
+                numOfkwGroup = len(mdDes[self.c + 1].mdItem)
+                for n in range(numOfkwGroup):
+                    kw = {}
+                    kw['keywords'] = []
+                    try:
+                        keyWordLen = len(mdDes[self.c].mdItem[n])
+                        for k in range(keyWordLen):
+                            kw['keywords'].append(mdDes[self.c].mdItem[n][k].getValue())
+                    except:
+                        kw['keywords'].append(mdDes[self.c].mdItem[n].getValue())
+
+                    kw['type'] = None
+                    kw['thesaurus'] = {}
+                    kw['thesaurus']['title'] = mdDes[self.c + 1].mdItem[n].getValue()
+                    kw['thesaurus']['date'] = mdDes[self.c + 2].mdItem[n].getValue()
+                    kw['thesaurus']['datetype'] = mdDes[self.c + 3].mdItem[n].getValue()
+                    self.md.identification.keywords.append(kw)
+
+                self.plusC()
+                self.plusC()
+                self.plusC()
+                self.plusC()
+#------------------------------------------------------------------------------ next function
+        self.mdo = MdFileWork()
+        self.md = self.mdo.initMD()
+        # most of objects from OWSLib is initialized in configure file
+        #dirpath = os.path.dirname(os.path.realpath(__file__))
+        path = os.path.join(os.path.join(sys.path[0],'..'), 'config', 'init_md.txt')
+
+        mdInitData = open(path, 'r')
+        mdExec = mdInitData.read()
+        self.executeStr1(mdExec, None)
+
+        self.c = 0
+        self.stop = False
+        self.max = len(self.mdDescription)
+        mdDes = self.mdDescription
+
+        while self.stop is False:
+            # if no statements
+            if mdDes[self.c].statements is None\
+                    and 'if' not in mdDes[self.c].tag.split()\
+                    and 'for' not in mdDes[self.c].tag.split():
+                noneStatements()
+
+            # if 2x statements
+            elif chckIf2xStatements():
+                in2Statements()
+
+            # if 1x statements
+            elif chckIf1Statements:
+                inStatements()
+
+        self.md = self.getKeywordsFromRepositoryWidget(self.md)
+        return self.md
+#------------------------------------ END- FILL OWSLib BY EDITED METADATA IN GUI
+
+    def exportToXml(self, jinjaPath, outPath, xmlOutName, msg):
+        self.saveMDfromGUI()
+        self.mdo.saveToXML(self.md, None, jinjaPath, outPath, xmlOutName, msg)
+
+    def exportTemplate(self, jinjaPath, outPath, xmlOutName):
+        self.profilePath = jinjaPath
+        owsTagList = self.defineTemplate()
+        self.saveMDfromGUI()
+        self.mdo.saveToXML(self.md, owsTagList,
+                           self.profilePath,
+                           outPath,
+                           xmlOutName,
+                           msg=True,
+                           rmTeplate=True)
+#------------------------------------------------------------------------ LAYOUT
+
+    def _layout(self):
+        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.mainSizer)
+        noteSizer = wx.BoxSizer(wx.VERTICAL)
+        self.notebook.SetSizer(noteSizer)
+        self.mainSizer.Add(self.notebook, proportion=1, flag=wx.EXPAND)
+        self.Show()


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdeditorfactory.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -30,8 +30,8 @@
 from subprocess import PIPE
 from datetime import date, datetime
 from grass.script import core as grass
+from osgeo import osr
 
-
 class GrassMD():
 
     '''
@@ -52,7 +52,7 @@
         # suffix of output xml file (variables)
         self.schema_type = '_basic.xml'
         self.profileName='GRASS BASIC'
-        self.dirpath = os.path.join(os.getenv('GRASS_ADDON_BASE'), 'etc')
+        self.dirpath = os.getenv('GRASS_ADDON_BASE')
         # metadata object from OWSLIB ( for define md values)
         self.md = mdutil.MD_MetadataMOD(md=None)
         self.profilePath = None  # path to file with xml templates
@@ -152,7 +152,6 @@
         #self.md_abstract    string created by merge information from 'description' and 'source'
         '''
         map=str(self.map).partition('@')[0]
-        print map
         rinfo = Module('r.info',
                        map,
                        flags='gre',
@@ -174,13 +173,45 @@
         self.md_abstract += 'Total cells: ' + self.md_grass['cells'] + '; '
         self.md_abstract += 'A range of values: min: ' + \
             self.md_grass['min'] + '  max: ' + self.md_grass['max']
-        self.md_abstract.translate(None, """&<>"'""")
+        self.md_abstract.translate("""&<>"'""")
 
+    def getEPSG(self):
+        print 'epsg process'
+        proj=Module('g.proj',
+                   flags='p',
+                   quiet=True,
+                   stdout_=PIPE)
+        proj=proj.outputs.stdout
+        epsg=None
+        for line in proj.splitlines():
+            if 'EPSG' in line:
+                epsg=line.split(':')[1].replace(' ','')
+                return epsg
+        try:
+            proj=Module('g.proj',
+                   flags='wf',
+                   quiet=True,
+                   stdout_=PIPE)
+            proj=proj.outputs.stdout
+            epsg=self.esriprj2standards(proj)
+            print epsg
+            return epsg
+        except:
+            return None
+
+    def esriprj2standards(self,prj_txt):
+       srs = osr.SpatialReference()
+       srs.ImportFromESRI([prj_txt])
+       #print 'Shape prj is: %s' % prj_txt
+       #print 'WKT is: %s' % srs.ExportToWkt()
+       #print 'Proj4 is: %s' % srs.ExportToProj4()
+       srs.AutoIdentifyEPSG()
+       return srs.GetAuthorityCode(None)
+
     def createTemporalISO(self, profile=None):
         '''Create GRASS Temporal profile based on ISO
         - unknown values are filling by n = '$NULL'
         '''
-
         n = '$NULL'
         # jinja templates
         if profile is None:
@@ -188,7 +219,7 @@
         else:
             self.profilePath = profile
         self.schema_type = '_temporal.xml'
-        self.profileName='TEMPORAL'
+        self.profileName = 'TEMPORAL'
 
         # OWSLib md object
         self.md.identification = mdutil.MD_DataIdentification_MOD()
@@ -248,8 +279,6 @@
             self.md.identification.radixT = mdutil.replaceXMLReservedChar(None)
             self.md.identification.factor = mdutil.replaceXMLReservedChar(None)
 
-
-
         self.md.dataquality.lineage= "TODO"
         self.profilePathAbs = os.path.join(self.dirpath, self.profilePath)
 
@@ -305,6 +334,12 @@
         self.md.dataquality.conformancetitle.append(
             'GRASS GIS basic metadata profile based on ISO 19115, 19139')
 
+        epsg=self.getEPSG()
+        if epsg is not None:
+            self.md.referencesystem=MD_ReferenceSystem(None)
+            self.md.referencesystem.code='http://www.opengis.net/def/crs/EPSG/0/%s'%epsg
+
+        print self.md.referencesystem.code
         # Conformity/Date:
         self.md.dataquality.conformancedate.append(mdutil.replaceXMLReservedChar(date.today().isoformat()))
         self.md.dataquality.conformancedatetype.append('publication')

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdjinjaparser.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdjinjaparser.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdjinjaparser.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+ at package jinjainfo
+ at module g.gui.metadata
+ at brief  Library for parsing information from jinja template
+
+Classes:
+ - jinjainfo::MdDescription
+ - jinjainfo::JinjaTemplateParser
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
+"""
+from core.gcmd import GError
+from mdutil import findBetween
+
+
+class MdDescription():
+
+    '''Object which is initialzed by jinja template in '{# #}'
+    '''
+
+    def __init__(self, tag=None, object=None, name='', desc=None,
+                 example=None, type=None, multi=0, inboxmulti=None,
+                 group=None, inbox=None, multiline=None, validator=None,
+                 num=None, ref=None, selfInfoString=None,database=None):
+        '''
+        @param tag: OWSLib object which will be replaced by value of object after jinja template system renders new file
+        @param object: some objects in OWSLib need to be initialized temporally in gui generator. Others are initialized by configure file
+        @param name:  label and tooltip name
+        @param desc: description/definition of metadata item
+        @param example: example of md item (tooltip)
+        @param type: data type, necessary to validate widgets
+        @param multi: 0=only one instance of editor::MdItem widget can be, 1= multiple instances of widgets can be
+        @param inboxmulti: 0=static box of items has not button for duplicating self 1=has button
+        @param group: this param initializes page in notebook in mani editor
+        @param inbox: Every item in block of code in jinja template must have same value of inbox.
+               The value of inbox representing label of static box in gui.
+        @param multiline: If true- textCtrl widget will be initalized with multiline control
+        @param validator: Currently not used
+        @param ref: additional information about reference of metadata item (ISO reference)
+        @param selfInfoString: string value representing all these information (parsed from jinja template)
+        @var mdItem: very important parameter which holds instances of widgets(editor::MdItem)
+             on every index of list is one instance of widget. In case, if is in static box MdItem with duplicating button:
+            index of list is represented by list of these items
+        @var statements: hold information about first statement in block
+        @var statements1: hold info about second statement in block of var: statement
+        '''
+        self.tag = tag
+        self.object = object
+        self.name = name
+        self.desc = desc
+        self.example = example
+        self.type = type
+        self.multiplicity = multi  # multiplicity of MD item
+        self.group = group
+        self.inbox = inbox
+        self.ref = ref
+        self.databaseAttr=database
+        self.selfInfoString = selfInfoString
+
+        self.inboxmulti = inboxmulti
+        self.multiline = multiline  # type of ctrl text
+        self.validator = validator
+        # --info from jinja -end
+
+        self.statements = None
+        self.statements1 = None
+        self.mdItem = list()
+
+    def addMdItem(self, newMdItem, oldMdItem=None):
+        '''care about integrity of var: self.mdItem
+        '''
+        # if new mditem is from box- need to hold information
+        # about it (list on the same index in self.mdItem)
+        if oldMdItem is not None:
+            for n, item in enumerate(self.mdItem):
+                for i in item:
+                    if i == oldMdItem:
+                        self.mdItem[n].append(newMdItem)
+        else:
+            self.mdItem.append(newMdItem)
+
+    def removeMdItem(self, item):
+        '''care about integrity of var: self.mdItem
+        '''
+        try:
+            for k, oldListItem in enumerate(self.mdItem):
+                for i in oldListItem:
+                    if i == item:
+                        self.mdItem[k].remove(item)
+        except:
+            self.mdItem.remove(item)
+
+    def addStatements(self, stat):
+        if self.statements is None:
+            self.statements = stat
+
+    def addStatements1(self, stat):
+        if self.statements1 is None:
+            self.statements1 = stat
+
+
+class JinjaTemplateParser():
+
+    '''Parser of OWSLib tag and init. values of jinjainfo::MdDescription from jinja template.
+    '''
+    def __init__(self, template):
+        '''
+        @var mdDescription: list of jinjainfo::mdDescription
+        @var mdOWSTag: list of tags in jinja templates
+        @var mdOWSTagStr: string representing OWSLib tags from template (per line)
+        @var mdOWSTagStrList: on each index of list is one line with parsed OWSLib tag
+        '''
+        self.mdDescription = []
+        self.mdOWSTag = []
+        self.template = template
+
+        self.mdOWSTagStr = ''
+        self.mdOWSTagStrList = []
+
+        self._readJinjaInfo()
+        self._readJinjaTags()
+        self._formatMdOWSTagStrToPythonBlocks()
+
+    def _readJinjaTags(self):
+        '''Parser of OWSLib tag from jinja template to list
+        '''
+        try:
+            with open(self.template, "r") as f:
+                for line in f:
+
+                    # if found start of comments
+                    if str(line).find("{{") != -1:
+                        obj = findBetween(line, "{{", "}}")
+                        self.mdOWSTag.append(obj)
+
+                    if str(line).find("{%") != -1:
+                        obj = findBetween(line, "{%", "-%}")
+                        self.mdOWSTag.append(obj)
+
+        except:
+            GError('Cannot open jinja template')
+            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
+
+    def _readJinjaInfo(self):
+        '''Parser  of 'comments'({# #}) in jinja template which are represented by jinjainfo::MdDescription
+        parsed values initializing list of jinjainfo::MdDesctiption obect
+        '''
+        try:
+            with open(self.template, "r") as f:
+                for line in f:
+                    # if found start of comments
+                    if str(line).find("{#") != -1:
+                        values = findBetween(line, "{#", "#}")
+                        values1 = findBetween(line, "{%", "#}")
+                        values2 = findBetween(line, "{{", "#}")
+                        if values1 != '':
+                            values += ",selfInfoString='''{%" + values1 + "#}'''"
+                        else:
+                            values += ",selfInfoString='''{{" + values2 + "#}'''"
+
+                        exe_str = "self.mdDescription.append(MdDescription(%s))" % values
+                        exe_str = exe_str.decode("utf-8", 'ignore')
+                        eval(exe_str)
+        except:
+            GError('Cannot open jinja template')
+            # print "I/O error({0}): {1}".format(e.errno, e.strerror)
+
+    def _formatMdOWSTagStrToPythonBlocks(self):
+        '''Formatting of parsed tags to pythonic blocks
+        '''
+        self.mdOWSTagStr = ""
+        tab = 0
+        for item in self.mdOWSTag:
+            if str(item).find(" endfor ") != -1 or \
+                    str(item).find(" endif ") != -1:
+                tab -= 1
+                continue
+
+            tabstr = '\t' * tab
+            str1 = tabstr + item[1:] + '\n'
+            self.mdOWSTagStr += str1
+            self.mdOWSTagStrList.append(tabstr + item[1:])
+
+            if str(item).find(" for ") != -1  \
+                    or str(item).find(" if ") != -1:
+                tab += 1


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdjinjaparser.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdffactory.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdffactory.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdffactory.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,635 @@
+from owslib.iso import *
+from reportlab.platypus import PageBreak
+import tempfile, sys, os
+import math
+from reportlab.platypus import Paragraph, Image, Table
+from mdpdftheme import *
+
+from grass.script import core as grass
+
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'pdf'))
+
+
+class MyTheme(DefaultTheme):
+    doc = {
+        'leftMargin': 25,
+        'rightMargin': 25,
+        'bottomMargin': 25,
+        'allowSplitting': False
+    }
+
+
+class PdfCreator(object):
+    def __init__(self, MD_metadata, pdf_file, map, type, filename, profile):
+
+        '''@:param MD_metadata- instance of metadata(owslib)
+           @:param pdf_file- path and name of generated report
+        '''
+
+        self.md = MD_metadata
+        self.pdf_file = pdf_file
+        self.TABLE_WIDTH = 540
+        self.map = map
+        self.type = type
+        self.profile = profile
+        if self.profile is None:
+            self.profile = 'custom iso profile'
+        self.filename = filename
+
+    def getMapPic(self):
+        f = os.path.join(tempfile.gettempdir(), 'tmpPic.png')
+
+        grass.run_command('g.region', save='tmpPdf', overwrite=True)
+        grass.run_command('g.region', flags='d')
+
+        grass.run_command('d.mon', start='cairo', output=f, width=200, height=200, overwrite=True)
+        grass.run_command('d.erase')
+        if self.type == 'raster':
+            grass.run_command('d.rast', map=self.map)
+        if self.type == 'vector':
+            grass.run_command('d.vect', map=self.map)
+        grass.run_command('d.mon', stop='cairo')
+        grass.run_command('g.region', region='tmpPdf')
+        return f
+
+
+    def findItem(self, items, name2, idx=-1):
+        values = []
+        for i in items:
+            if i.name2 == name2:
+                values.append(i.value[0])
+
+        if idx == -1:
+            if len(values) == 0:
+                values.append('unknown')
+            return values
+
+        if len(values) <= idx:
+            return 'unknown'
+
+        if values[idx] is not None:
+            return values[idx]
+
+        return 'unknown'
+
+    # def chckTextValidity(self):
+    def tableFactory(self, title, headers, key):
+        '''
+        @:param headers - list of header
+        '''
+        self.doc.add_header(title, H4)
+        head = []
+        head.append(headers)
+        tmp = []
+        for i in range(len(self.findItem(self.story[key], headers[0]))):
+            for header in headers:
+                value = self.findItem(self.story[key], header, i)
+                #value=self.chckTextValidity(value)
+                text = Paragraph("""
+                %s<br/>
+                """ % value, MyTheme.paragraph)
+                tmp.append(text)
+            head.append(tmp)
+            tmp = []
+
+        self.doc.add_table(head, self.TABLE_WIDTH)
+
+    def textFactory(self, title, tag, name, multiple=0):
+        self.doc.add_header(title, H4)
+        val = self.findItem(self.story[tag], name, multiple)
+        lines = ''
+        if len(val) > 1 and multiple == -1:
+            tmp = []
+            for v in val:
+                tmp.append(v)
+            lines = ', '.join(tmp)
+            text = Paragraph("""
+            %s<br/>
+            """ % lines, MyTheme.paragraph)
+            self.doc.add_fparagraph(text)
+            return
+
+        if len(val) > 400:
+            for line in val.splitlines():
+                lines += line + '\n'
+                if len(lines) > 400:
+                    text = Paragraph("""
+                                    %s<br/>
+                                    """ % lines, MyTheme.paragraph)
+                    self.doc.add_fparagraph(text)
+                    lines = ''
+        else:
+            text = Paragraph("""
+                            %s<br/>
+                            """ % val, MyTheme.paragraph)
+            self.doc.add_fparagraph(text)
+
+    def createPDF(self, save=True):
+        self.story = self._parseMDOWS()
+        self.doc = Pdf('Metadata file', 'GRASS GIS')
+
+        self.doc.set_theme(MyTheme)
+
+        logo_path = '/home/matt/Dropbox/GSOC2015/pdfExp/logo.png'
+        self.doc.add_image(logo_path, 50, 50, LEFT)
+
+        if self.map is None:
+            self.doc.add_header(self.filename, T1)
+        else:
+            self.doc.add_header(self.map, T1)
+            self.doc.add_header(self.filename, T2)
+
+        if self.type == 'vector':
+            name = 'vector map'
+            self.doc.add_header(name, T2)
+        else:
+            name = 'raster map'
+            self.doc.add_header(name, T2)
+
+        self.doc.add_header("%s metadata profile" % self.profile, T3)
+
+        self.doc.add_spacer(2)
+
+        if map is not None:
+            mapPic = self.getMapPic()
+            self.doc.add_image(mapPic, 200, 200, CENTER)
+
+        self.textFactory(title="Keywords", name='Keywords', tag='identification', multiple=-1)
+        self.textFactory(title="Abstract", name='Abstract', tag='identification')
+        # #################### metadata #################################
+        self.doc.add_spacer(25)
+        self.doc.add_header("Metadata on metadata", H1)
+        head = ['Organization name', 'E-mail', 'Role']  # this is the header row
+        self.tableFactory("Metadata point of contact", head, 'contact')
+        self.textFactory(title="Metadata date", name='Datestamp', tag='datestamp')
+        self.textFactory(title="Metadata language", name='Language', tag='languagecode')
+        # #################### identification #################################
+        self.doc.add(PageBreak())
+        self.doc.add_header("Identification", H1)
+        self.textFactory(title="Restource title", name='Title', tag='identification')
+        self.textFactory(title="Identifier", name='Identifier', tag='identifier')
+        # self.textFactory(title="Resource locator", name='Identifier',tag='identifier')#TODO linkage is missing
+
+        self.tableFactory("Resource language", ['Language'], 'identification')
+        # head = ['Organization name', 'E-mail','Role']
+        #.tableFactory("identifier",head,'contact')
+
+        ##################### Keywords ################################## TODO
+
+
+
+
+        ##################### Geographic ##################################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Geographic Location', H1)
+
+        maxy = float(self.findItem(self.story['identification'], 'maxy', 0))
+        maxx = float(self.findItem(self.story['identification'], 'maxx', 0))
+        miny = float(self.findItem(self.story['identification'], 'miny', 0))
+        minx = float(self.findItem(self.story['identification'], 'minx', 0))
+
+        head = [['North Bound Latitude', 'East Bound Longitude', 'South Bound Latitude', 'West Bound Longitude']]
+        head.append([maxx, maxy, minx, miny])
+        self.doc.add_table(head, self.TABLE_WIDTH)
+        self.doc.add_spacer(25)
+        mapPath = MapBBFactory([[maxx, minx], [maxy, miny]], )
+
+        gmap = Image(mapPath.link1, 200, 200)
+        gmap1 = Image(mapPath.link2, 200, 200)
+        self.doc.add(Table([[gmap1, gmap]]))
+        self.doc.add(PageBreak())
+        ##################### Temporal ##################################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Temporal reference', H1)
+        self.textFactory(title="Temporal extend start", name='Temporal extend start', tag='identification')
+        self.textFactory(title="Temporal extend end", name='Temporal extend end', tag='identification')
+
+        ##################### Quality ##################################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Quality a validity', H1)
+        self.textFactory(title="Lineage", name='Lineage', tag='dataquality')
+
+        #self.textFactory(title="Temporal extend start", name='Temporal extend start',tag='identification')
+        # TODO md.identification.denominators
+
+        ######################Conformity ########################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Conformity', H1)
+        head = ['Conformance date', "Conformance date type", 'Specification']
+        self.tableFactory("Conformity", head, 'dataquality')
+        ###################### Constraints ########################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Constraints', H1)
+        self.tableFactory("Condition applying to use", ["Use constraints"], 'identification')
+        self.tableFactory("Condition applying to access", ["Access constraints"], 'identification')
+        self.tableFactory("Limitation on public access", ["Other constraintrs"], 'identification')
+        ###################### Responsible party ########################
+        self.doc.add_spacer(25)
+        self.doc.add_header('Responsible party', H1)
+        header = ["Organization name", "E-mail", "Role"]
+        self.tableFactory(
+            "Organisations responsible for the establishment, management, maintenance and distribution of spatial data sets and services",
+            header, 'identification')
+
+        text = self.doc.render()
+        # http://www.reportlab.com/docs/reportlab-userguide.pdf
+        if save and self.pdf_file is not None:
+            path = self.savePDF(text)
+            return path
+
+        return text
+
+    def _parseMDOWS(self, md=None):
+
+        if md is None:
+            md = self.md
+        metadata = {}
+        metadata["identification"] = []
+        metadata["languagecode"] = []
+        metadata["datestamp"] = []
+        metadata["identifier"] = []
+        metadata["dataquality"] = []
+        metadata["contact"] = []
+        metadata['distance'] = []
+        # #########################################################
+        # ##############  identification  #########################
+        if md.identification is not None:
+            if md.identification.contact is not None:
+                for contact in md.identification.contact:
+                    if contact.organization is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(contact.organization, "gmd:CI_ResponsibleParty", "Organization name"))
+                    if contact.email is not (None or ''):
+                        metadata["identification"].append(MD_ITEM(contact.email, "gmd:CI_ResponsibleParty", "E-mail"))
+                    if contact.role is not (None or ''):
+                        metadata["identification"].append(MD_ITEM(contact.role, "gmd:CI_ResponsibleParty", "Role"))
+
+            if md.identification.title is not (None or ''):
+                metadata["identification"].append(
+                    MD_ITEM(md.identification.title, "gmd:md_DataIdentification", "Title"))
+
+            if md.identification.abstract is not (None or ''):
+                metadata["identification"].append(
+                    MD_ITEM(md.identification.abstract, "gmd:md_DataIdentification", "Abstract"))
+
+            if md.identification.identtype is not (None or ''):
+                metadata["identification"].append(
+                    MD_ITEM(md.identification.identtype, "gmd:md_ScopeCode", "Resource type"))
+
+            if md.identification.resourcelanguage is not None:
+                for language in md.identification.resourcelanguage:
+                    if language != '':
+                        metadata["identification"].append(MD_ITEM(language, "gmd:language", "Language"))
+
+            if md.identification.uricode is not None:
+                for uri in md.identification.uricode:
+                    if uri != '':
+                        metadata["identification"].append(
+                            MD_ITEM(uri, "gmd:RS_Identifier", "Unique Resource Identifier"))
+
+            if md.identification.topiccategory is not None:
+                for topic in md.identification.topiccategory:
+                    if topic != '':
+                        metadata["identification"].append(MD_ITEM(topic, "gmd:topicCategory", "Topic Category"))
+
+            # #########################################################
+            # ########################  keywords  #########################
+            if md.identification.keywords is not None:
+                for key in md.identification.keywords:
+                    for k in key['keywords']:
+                        if k is not (None or ''):
+                            metadata["identification"].append(MD_ITEM(k, "gmd:MD_Keywords", "Keywords"))
+
+                    if key['thesaurus'] is not (None or ''):
+                        if key['thesaurus']['title'] is not (None or ''):
+                            metadata["identification"].append(
+                                MD_ITEM(key['thesaurus']['title'], "gmd:thesaurusName", "Thesaurus title"))
+                        if key['thesaurus']['date'] is not (None or ''):
+                            metadata["identification"].append(
+                                MD_ITEM(key['thesaurus']['date'], "gmd:thesaurusName", "Thesaurus date"))
+                        if key['thesaurus']['datetype'] is not (None or ''):
+                            metadata["identification"].append(
+                                MD_ITEM(key['thesaurus']['datetype'], "gmd:thesaurusName", "Thesaurus date type "))
+
+            if md.identification.extent is not None:
+                if md.identification.extent.boundingBox is not None:
+                    if md.identification.extent.boundingBox.minx is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(md.identification.extent.boundingBox.minx, "gmd:westBoundLongitude", "minx"))
+                    if md.identification.extent.boundingBox.maxx is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(md.identification.extent.boundingBox.maxx, "gmd:eastBoundLongitude", "maxx"))
+                    if md.identification.extent.boundingBox.miny is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(md.identification.extent.boundingBox.miny, "gmd:southBoundLatitude", "miny"))
+                    if md.identification.extent.boundingBox.maxy is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(md.identification.extent.boundingBox.maxy, "gmd:northBoundLatitude", "maxy"))
+
+            if md.identification.date is not None:
+                for date in md.identification.date:
+                    if date is not (None or ''):
+                        metadata["identification"].append(MD_ITEM(date, "gmd:CI_Date", "Date"))
+
+            if md.identification.temporalextent_start is not (None or ''):
+                metadata["identification"].append(
+                    MD_ITEM(md.identification.temporalextent_start, "gmd:EX_TemporalExtent", "Temporal extend start"))
+            if md.identification.temporalextent_end is not (None or ''):
+                metadata["identification"].append(
+                    MD_ITEM(md.identification.temporalextent_end, "gmd:EX_TemporalExtent", "Temporal extend end"))
+
+            if md.identification.uselimitation is not None:
+                for limitation in md.identification.uselimitation:
+                    if limitation is not (None or ''):
+                        metadata["identification"].append(MD_ITEM(limitation, "gmd:useLimitation", "Use limitation"))
+
+            if md.identification.accessconstraints is not None:
+                for accessconstraints in md.identification.accessconstraints:
+                    if accessconstraints is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(accessconstraints, "gmd:accessConstraints", "Access constraints"))
+
+            if md.identification.otherconstraints is not None:
+                for otherconstraints in md.identification.otherconstraints:
+                    if otherconstraints is not (None or ''):
+                        metadata["identification"].append(
+                            MD_ITEM(otherconstraints, "gmd:otherConstraints", "Other constraintrs"))
+
+
+        # #########################################################
+        # ########################  date  #########################
+        if md.languagecode is not (None or ''):
+            metadata["languagecode"].append(MD_ITEM(md.languagecode, "gmd:LanguageCode", "Language"))
+
+        if md.datestamp is not (None or ''):
+            metadata["datestamp"].append(MD_ITEM(md.datestamp, "gmd:dateStamp", "Datestamp"))
+
+        if md.identifier is not (None or ''):
+            metadata["identifier"].append(MD_ITEM(md.identifier, "gmd:identifier", "Identifier"))
+
+        if md.dataquality is not (None or ''):
+            if md.dataquality.lineage is not (None or ''):
+                metadata["dataquality"].append(MD_ITEM(md.dataquality.lineage, "gmd:LI_Lineage", "Lineage"))
+
+            if md.dataquality.conformancedate is not None:
+                for conformancedate in md.dataquality.conformancedate:
+                    if conformancedate is not (None or ''):
+                        metadata["dataquality"].append(
+                            MD_ITEM(conformancedate, "gmd:DQ_ConformanceResult", "Conformance date"))
+
+            if md.dataquality.conformancedatetype is not None:
+                for conformancedatetype in md.dataquality.conformancedatetype:
+                    if conformancedate is not (None or ''):
+                        metadata["dataquality"].append(
+                            MD_ITEM(conformancedatetype, "gmd:DQ_ConformanceResult", "Conformance date type"))
+
+            if md.dataquality.conformancetitle is not None:
+                for conformancetitle in md.dataquality.conformancetitle:
+                    if conformancedate is not (None or ''):
+                        metadata["dataquality"].append(
+                            MD_ITEM(conformancetitle, "gmd:DQ_ConformanceResult", "Specification"))
+
+        if md.contact is not None:
+            for contact in md.contact:
+                if contact.organization is not (None or ''):
+                    metadata["contact"].append(MD_ITEM(contact.organization, "gmd:contact", "Organization name"))
+
+                if contact.email is not (None or ''):
+                    metadata["contact"].append(
+                        MD_ITEM(contact.email, "gmd:contact", "E-mail"))  # TODO more email can be
+
+                if contact.role is not (None or ''):
+                    metadata["contact"].append(MD_ITEM(contact.role, "gmd:role", "Role"))
+
+        # #### quality validity
+        if self.md.identification.distance is not (None or ''):
+            metadata['distance'].append(MD_ITEM(self.md.identification.distance, 'gmd:distance', 'Distance'))
+        return metadata
+
+    def savePDF(self, doc, pathToPdf=None):
+        if pathToPdf is None:
+            pathToPdf = self.pdf_file
+        out = open(pathToPdf, 'w+')
+        out.writelines(doc)
+        out.close()
+        return pathToPdf
+
+
+class MD_ITEM():
+    def __init__(self, value, name1, name2=None):
+        self.value = []
+        self.name1 = name1
+        self.name2 = name2
+        self.addValue(value)
+
+    def addValue(self, value):
+        self.value.append(value)
+
+
+class Point():
+    """Stores a simple (x,y) point.  It is used for storing x/y pixels.
+
+    Attributes:
+      x: An int for a x value.
+      y: An int for a y value.
+    """
+
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+    def ToString(self):
+        return '(%s, %s)' % (self.x, self.y)
+
+    def Equals(self, other):
+        if other is None:
+            return False
+        else:
+            return (other.x == self.x and other.y == self.y)
+
+
+class MapBBFactory():
+    '''Class for compute bounding box for static map with using google maps API
+    '''
+
+    def __init__(self, coords, size=[200, 200]):
+        self.pixels_per_lon_degree = []
+        self.pixels_per_lon_radian = []
+        self.pixel_origo = []
+        self.pixel_range = []
+        self.pixels = 256
+        self.size = size
+        zoom_levels = range(0, 18)
+        for z in zoom_levels:
+            origin = self.pixels / 2
+            self.pixels_per_lon_degree.append(self.pixels / 360)
+            self.pixels_per_lon_radian.append(self.pixels / (2 * math.pi))
+            self.pixel_origo.append(Point(origin, origin))
+            self.pixel_range.append(self.pixels)
+            self.pixels = self.pixels * 2
+
+        bounds = self.CalcBoundsFromPoints(coords[0], coords[1])
+        corners = self.calcCornersFromBounds(bounds)
+        center = self.CalcCenterFromBounds(bounds)
+        zoom = self.CalculateBoundsZoomLevel(bounds, size)
+        self.link1, self.link2 = self.buildLink(center, zoom, corners)
+
+    def calcCornersFromBounds(self, bounds):
+        """
+        :param bounds: An int that is either the value passed in or the min or the max.
+        :return: polygon defined by 5 points represented by string (format for generating
+        """
+        YmaxXmin = str(bounds[0][0]) + ',' + str(bounds[0][1])
+        YminXmin = str(bounds[0][0]) + ',' + str(bounds[1][1])
+        YminXmax = str(bounds[1][0]) + ',' + str(bounds[1][1])
+        YmaxXmax = str(bounds[1][0]) + ',' + str(bounds[0][1])
+
+        corners = YmaxXmin + "|" + YminXmin + "|" + YminXmax + "|" + YmaxXmax + "|" + YmaxXmin
+        return corners
+
+    def buildLink(self, center, zoom, corners):
+        size = str(self.size[0]) + 'x' + str(self.size[1])
+
+        pic = ("http://maps.googleapis.com/maps/api/staticmap?center=" +
+               str(center['lat']) + ',' + str(center['lng']) + "&zoom=" + str(zoom) +
+               "&size=" + size + "&sensor=false&path=color:red|weight:3|" + corners)
+        pic1 = ("http://maps.googleapis.com/maps/api/staticmap?center=" +
+                str(center['lat']) + ',' + str(center['lng']) + "&zoom=" + str(zoom - 4) +
+                "&size=" + size + "&sensor=false&path=color:red|weight:3|" + corners)
+        return pic, pic1
+
+    def CalcCenterFromBounds(self, bounds):
+        """Calculates the center point given southwest/northeast lat/lng pairs.
+
+        Given southwest and northeast bounds, this method will return the center
+        point.  We use this method when we have done a search for points on the map,
+        and we get multiple results.  In the results we don't get anything to
+        calculate the center point of the map so this method calculates it for us.
+
+        Args:
+          bounds: A list of length 2, each holding a list of length 2. It holds
+            the southwest and northeast lat/lng bounds of a map.  It should look
+            like this: [[southwestLat, southwestLat], [northeastLat, northeastLng]]
+
+        Returns:
+          An dict containing keys lat and lng for the center point.
+        """
+        north = bounds[1][0]
+        south = bounds[0][0]
+        east = bounds[1][1]
+        west = bounds[0][1]
+        center = {}
+        center['lat'] = north - float((north - south) / 2)
+        center['lng'] = east - float((east - west) / 2)
+        return center
+
+    def Bound(self, value, opt_min, opt_max):
+        """Returns value if in min/max, otherwise returns the min/max.
+
+        Args:
+          value: The value in question.
+          opt_min: The minimum the value can be.
+          opt_max: The maximum the value can be.
+
+        Returns:
+          An int that is either the value passed in or the min or the max.
+        """
+        if opt_min is not None:
+            value = max(value, opt_min)
+        if opt_max is not None:
+            value = min(value, opt_max)
+        return value
+
+
+    def DegreesToRadians(self, deg):
+        return deg * (math.pi / 180)
+
+
+    def FromLatLngToPixel(self, lat_lng, zoom):
+        """Given lat/lng and a zoom level, returns a Point instance.
+
+        This method takes in a lat/lng and a _test_ zoom level and based on that it
+        calculates at what pixel this lat/lng would be on the map given the zoom
+        level.  This method is used by CalculateBoundsZoomLevel to see if this
+        _test_ zoom level will allow us to fit these bounds in our given map size.
+
+        Args:
+          lat_lng: A list of a lat/lng point [lat, lng]
+          zoom: A list containing the width/height in pixels of the map.
+
+        Returns:
+          A Point instance in pixels.
+        """
+        o = self.pixel_origo[zoom]
+        x = round(o.x + lat_lng[1] * self.pixels_per_lon_degree[zoom])
+        siny = self.Bound(math.sin(self.DegreesToRadians(lat_lng[0])),
+                          -0.9999, 0.9999)
+        y = round(o.y + 0.5 * math.log((1 + siny) /
+                                       (1 - siny)) * -self.pixels_per_lon_radian[zoom])
+        return Point(x, y)
+
+
+    def CalculateBoundsZoomLevel(self, bounds, view_size):
+        """Given lat/lng bounds, returns map zoom level.
+
+        This method is used to take in a bounding box (southwest and northeast
+        bounds of the map view we want) and a map size and it will return us a zoom
+        level for our map.  We use this because if we take the bottom left and
+        upper right on the map we want to show, and calculate what pixels they
+        would be on the map for a given zoom level, then we can see how many pixels
+        it will take to display the map at this zoom level.  If our map size is
+        within this many pixels, then we have the right zoom level.
+
+        Args:
+          bounds: A list of length 2, each holding a list of length 2. It holds
+            the southwest and northeast lat/lng bounds of a map.  It should look
+            like this: [[southwestLat, southwestLat], [northeastLat, northeastLng]]
+          view_size: A list containing the width/height in pixels of the map.
+
+        Returns:
+          An int zoom level.
+        """
+        zmax = 18
+        zmin = 0
+        bottom_left = bounds[0]
+        top_right = bounds[1]
+        backwards_range = range(zmin, zmax)
+        backwards_range.reverse()
+        for z in backwards_range:
+            bottom_left_pixel = self.FromLatLngToPixel(bottom_left, z)
+            top_right_pixel = self.FromLatLngToPixel(top_right, z)
+            if bottom_left_pixel.x > top_right_pixel.x:
+                bottom_left_pixel.x -= self.CalcWrapWidth(z)
+            if abs(top_right_pixel.x - bottom_left_pixel.x) <= view_size[0] \
+                    and abs(top_right_pixel.y - bottom_left_pixel.y) <= view_size[1]:
+                return z
+        return 0
+
+
+    def CalcBoundsFromPoints(self, lats, lngs):
+        """Calculates the max/min lat/lng in the lists.
+
+        This method takes in a list of lats and a list of lngs, and outputs the
+        southwest and northeast bounds for these points.  We use this method when we
+        have done a search for points on the map, and we get multiple results.  In
+        the results we don't get a bounding box so this method calculates it for us.
+
+        Args:
+          lats: List of latitudes
+          lngs: List of longitudes
+
+        Returns:
+          A list of length 2, each holding a list of length 2.  It holds
+          the southwest and northeast lat/lng bounds of a map.  It should look
+          like this: [[southwestLat, southwestLat], [northeastLat, northeastLng]]
+        """
+        lats = [float(x) for x in lats]
+        lngs = [float(x) for x in lngs]
+        flats = map(float, lats)
+        flngs = map(float, lngs)
+        west = min(flngs)
+        east = max(flngs)
+        north = max(flats)
+        south = min(flats)
+        return [[south, west], [north, east]]
+


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdffactory.py
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdftheme.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdftheme.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdftheme.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,336 @@
+from reportlab.lib.styles import ParagraphStyle, _baseFontNameB, _baseFontNameI, _baseFontNameBI
+from reportlab.lib.units import inch
+from reportlab.lib import colors
+from reportlab.rl_config import canvas_basefontname as _baseFontName
+from reportlab.lib.enums import TA_LEFT, TA_CENTER
+import cStringIO
+import urllib
+from reportlab.platypus.doctemplate import SimpleDocTemplate
+from reportlab.platypus.flowables import Image
+from reportlab.platypus import Paragraph, Spacer, KeepTogether
+from reportlab.platypus.tables import Table, TableStyle, LongTable
+
+
+# Header levels
+H1, H2, H3, H4, H5, H6, T1, T2, T3, T4 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+
+# List styles
+UL, OL = 0, 1
+
+# Titles
+
+# Alignment
+CENTER, LEFT, RIGHT = 'CENTER', 'LEFT', 'RIGHT'
+
+
+class MySheet:
+    _stylesheet1_undefined = object()
+
+    def __init__(self):
+        self.byName = {}
+        self.byAlias = {}
+
+    def __getitem__(self, key):
+        try:
+            return self.byAlias[key]
+        except KeyError:
+            try:
+                return self.byName[key]
+            except KeyError:
+                raise KeyError("Style '%s' not found in stylesheet" % key)
+
+    def get(self, key, default=_stylesheet1_undefined):
+        try:
+            return self[key]
+        except KeyError:
+            if default != _stylesheet1_undefined: return default
+            raise
+
+    def __contains__(self, key):
+        return key in self.byAlias or key in self.byName
+
+    def has_key(self, key):
+        return key in self
+
+    def add(self, style, alias=None):
+        key = style.name
+        if key in self.byName:
+            raise KeyError("Style '%s' already defined in stylesheet" % key)
+        if key in self.byAlias:
+            raise KeyError("Style name '%s' is already an alias in stylesheet" % key)
+
+        if alias:
+            if alias in self.byName:
+                raise KeyError("Style '%s' already defined in stylesheet" % alias)
+            if alias in self.byAlias:
+                raise KeyError("Alias name '%s' is already an alias in stylesheet" % alias)
+        #passed all tests?  OK, add it
+        self.byName[key] = style
+        if alias:
+            self.byAlias[alias] = style
+
+    def list(self):
+        styles = list(self.byName.items())
+        styles.sort()
+        alii = {}
+        for (alias, style) in list(self.byAlias.items()):
+            alii[style] = alias
+        for (name, style) in styles:
+            alias = alii.get(style, None)
+            style.listAttrs('    ')
+
+
+    def getSampleStyleSheet(self):
+        """Returns a stylesheet object"""
+        stylesheet = MySheet()
+
+        stylesheet.add(ParagraphStyle(name='Normal',
+                                      fontName=_baseFontName,
+                                      fontSize=10,
+                                      leading=12)
+        )
+        stylesheet.add(ParagraphStyle(name='Title',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameB,
+                                      fontSize=18,
+                                      leading=22,
+                                      alignment=TA_CENTER,
+                                      spaceAfter=6),
+                       alias='title')
+
+        stylesheet.add(ParagraphStyle(name='Title2',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontName,
+                                      fontSize=13,
+                                      leading=22,
+                                      alignment=TA_CENTER,
+                                      spaceAfter=0),
+                       alias='title2')
+
+        stylesheet.add(ParagraphStyle(name='Title3',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontName,
+                                      fontSize=10,
+                                      leading=5,
+                                      alignment=TA_CENTER,
+                                      spaceAfter=10),
+                       alias='title3')
+
+        stylesheet.add(ParagraphStyle(name='Title4',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontName,
+                                      fontSize=8,
+                                      leading=10,
+                                      alignment=TA_CENTER,
+                                      spaceAfter=5),
+                       alias='title4')
+
+        stylesheet.add(ParagraphStyle(name='BodyText',
+                                      parent=stylesheet['Normal'],
+                                      spaceBefore=6)
+        )
+        stylesheet.add(ParagraphStyle(name='Italic',
+                                      parent=stylesheet['BodyText'],
+                                      fontName=_baseFontNameI)
+        )
+
+        stylesheet.add(ParagraphStyle(name='Heading1',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameB,
+                                      fontSize=18,
+                                      leading=22,
+                                      spaceAfter=6),
+                       alias='h1')
+
+        stylesheet.add(ParagraphStyle(name='Heading2',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameB,
+                                      fontSize=14,
+                                      leading=18,
+                                      spaceBefore=12,
+                                      spaceAfter=6),
+                       alias='h2')
+
+        stylesheet.add(ParagraphStyle(name='Heading3',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameBI,
+                                      fontSize=12,
+                                      leading=14,
+                                      spaceBefore=12,
+                                      spaceAfter=6),
+                       alias='h3')
+
+        stylesheet.add(ParagraphStyle(name='Heading4',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameBI,
+                                      fontSize=10,
+                                      leading=12,
+                                      spaceBefore=10,
+                                      spaceAfter=4),
+                       alias='h4')
+
+        stylesheet.add(ParagraphStyle(name='Heading5',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameB,
+                                      fontSize=9,
+                                      leading=10.8,
+                                      spaceBefore=8,
+                                      spaceAfter=4),
+                       alias='h5')
+
+        stylesheet.add(ParagraphStyle(name='Heading6',
+                                      parent=stylesheet['Normal'],
+                                      fontName=_baseFontNameB,
+                                      fontSize=7,
+                                      leading=8.4,
+                                      spaceBefore=6,
+                                      spaceAfter=2),
+                       alias='h6')
+
+        stylesheet.add(ParagraphStyle(name='Bullet',
+                                      parent=stylesheet['Normal'],
+                                      firstLineIndent=0,
+                                      spaceBefore=3),
+                       alias='bu')
+
+        stylesheet.add(ParagraphStyle(name='Definition',
+                                      parent=stylesheet['Normal'],
+                                      firstLineIndent=0,
+                                      leftIndent=36,
+                                      bulletIndent=0,
+                                      spaceBefore=6,
+                                      bulletFontName=_baseFontNameBI),
+                       alias='df')
+
+        stylesheet.add(ParagraphStyle(name='Code',
+                                      parent=stylesheet['Normal'],
+                                      fontName='Courier',
+                                      fontSize=8,
+                                      leading=8.8,
+                                      firstLineIndent=0,
+                                      leftIndent=36))
+
+        return stylesheet
+
+
+class DefaultTheme(object):
+    s = MySheet()
+    _s = s.getSampleStyleSheet()
+
+    doc = {
+        'leftMargin': None,
+        'rightMargin': None,
+        'topMargin': None,
+        'bottomMargin': None
+    }
+    headers = {
+        H1: _s['Heading1'],
+        H2: _s['Heading2'],
+        H3: _s['Heading3'],
+        H4: _s['Heading4'],
+        H5: _s['Heading5'],
+        H6: _s['Heading6'],
+        T1: _s['Title'],
+        T2: _s['Title2'],
+        T3: _s['Title3'],
+        T4: _s['Title4']
+    }
+
+    paragraph = _s['Normal']
+
+    spacer_height = 0.25 * inch
+    table_style = [
+        ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
+        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
+        ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
+        ('LINEBELOW', (0, 0), (-1, 0), 1, colors.black),
+        ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#C0C0C0')),
+        ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#E0E0E0')])
+    ]
+
+    @classmethod
+    def doc_template_args(cls):
+        return dict([(k, v) for k, v in cls.doc.items() if v is not None])
+
+    @classmethod
+    def header_for_level(cls, level):
+        return cls.headers[level]
+
+    def __new__(cls, *args, **kwargs):
+        raise TypeError("Theme classes may not be instantiated.")
+
+
+def calc_table_col_widths(rows, table_width):
+    max_chars_per_col = [0] * len(rows[0])
+    for row in rows:
+        for idx, col in enumerate(row):
+            for line in str(col).split('\n'):
+                max_chars_per_col[idx] = max(len(line),
+                                             max_chars_per_col[idx])
+    sum_chars = sum(max_chars_per_col)
+    return [(x * table_width / sum_chars) for x in max_chars_per_col]
+
+
+_stylesheet1_undefined = object()
+
+
+class Pdf(object):
+    story = []
+    theme = DefaultTheme
+
+    def __init__(self, title, author):
+        self.title = title
+        self.author = author
+
+    def set_theme(self, theme):
+        self.theme = theme
+
+    def add(self, flowable):
+        self.story.append(flowable)
+
+    def add_header(self, text, level=H1):
+        p = Paragraph(text, self.theme.header_for_level(level))
+        self.add(p)
+
+    def add_fparagraph(self, text, style=None):
+        if style is not None:
+            self.add(Table([[text]], style=style))
+        else:
+            self.add(Table([[text]]))
+
+    def add_spacer(self, height_inch=None):
+        height_inch = height_inch or self.theme.spacer_height
+        self.add(Spacer(1, height_inch))  # magic 1? no, first param not yet implemented by rLab guys
+
+    def add_paragraph(self, text, style=None):
+        style = style or self.theme.paragraph
+        p = Paragraph(text, style)
+        self.add(p)
+
+    def add_list(self, items, list_style=UL):
+        raise NotImplementedError
+
+    def add_table(self, rows, width=None, col_widths=None, align=CENTER,
+                  extra_style=[]):
+        style = self.theme.table_style + extra_style
+        if width and col_widths is None:  # one cannot spec table width in rLab only col widths
+            col_widths = calc_table_col_widths(rows, width)  # this helper calcs it for us
+        table = LongTable(rows, col_widths, style=style, hAlign=align)
+        self.add(table)
+
+    def add_image(self, src, width, height, align=CENTER):
+        img = Image(src, width, height)
+        img.hAlign = align
+        self.add(img)
+
+    def render(self):
+        buffer = cStringIO.StringIO()
+        doc_template_args = self.theme.doc_template_args()
+        doc = SimpleDocTemplate(buffer, title=self.title, author=self.author,
+                                **doc_template_args)
+        doc.build(self.story)
+        pdf = buffer.getvalue()
+        buffer.close()
+        return pdf
+
+


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdpdftheme.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,6 @@
+MODULE_TOPDIR = ..
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default:
+	$(INSTALL_DATA) *.xml $(ETC)
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml	2015-08-10 13:13:38 UTC (rev 65871)
@@ -38,6 +38,22 @@
     <gmd:metadataStandardVersion>
         <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
     </gmd:metadataStandardVersion>
+{% if md.referencesystem != None -%}{# tag=" if md.referencesystem != None" ,multi= 0 , group= "Geographic" , multiline= False,inbox="EPSG url code",inboxmulti= 0 #}
+  <gmd:referenceSystemInfo>
+      <gmd:MD_ReferenceSystem>
+         <gmd:referenceSystemIdentifier>
+            <gmd:RS_Identifier>
+               <gmd:code>
+                  <gco:CharacterString>{{ md.referencesystem.code }}{# tag="md.referencesystem.code" , name="Reference system" , ref= "Part -" , desc= "Reference system EPSG url",type = "url" , example = "http://www.opengis.net/def/crs/EPSG/0/3035" , multi= 0 , group= "Geographic" , multiline= False #}</gco:CharacterString>
+               </gmd:code>
+               <gmd:codeSpace>
+                  <gco:CharacterString>INSPIRE RS registry</gco:CharacterString>
+               </gmd:codeSpace>
+            </gmd:RS_Identifier>
+         </gmd:referenceSystemIdentifier>
+      </gmd:MD_ReferenceSystem>
+  </gmd:referenceSystemInfo>
+  {% endif -%}
     <gmd:identificationInfo>
         <gmd:MD_DataIdentification>
             <gmd:citation>

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml	2015-08-09 19:59:21 UTC (rev 65870)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml	2015-08-10 13:13:38 UTC (rev 65871)
@@ -8,12 +8,12 @@
     <gmd:fileIdentifier>
         <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "string", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
     </gmd:fileIdentifier>
-     <gmd:hierarchyLevel>
-        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "MD_ScopeCode", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
-    </gmd:hierarchyLevel>
-        <gmd:language>
+    <gmd:language>
         <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ md.languagecode }}{# tag="md.languagecode", name ="Metadata language", desc ="Language(s) used within the datasets", example ="eng", type = "string", multi = 0, group = "Metadata",multiline=False #}">{{ md.languagecode }}</gmd:LanguageCode>
     </gmd:language>
+    <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
+    </gmd:hierarchyLevel>
   {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
     <gmd:contact>
         <gmd:CI_ResponsibleParty>
@@ -32,7 +32,7 @@
                 </gmd:CI_Contact>
             </gmd:contactInfo>
             <gmd:role>
-                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party",database="role" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
             </gmd:role>
         </gmd:CI_ResponsibleParty>
     </gmd:contact>
@@ -46,6 +46,22 @@
     <gmd:metadataStandardVersion>
         <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
     </gmd:metadataStandardVersion>
+{% if md.referencesystem != None -%}{# tag=" if md.referencesystem != None" ,multi= 0 , group= "Geographic" , multiline= False,inbox="EPSG url code",inboxmulti= 0 #}
+  <gmd:referenceSystemInfo>
+      <gmd:MD_ReferenceSystem>
+         <gmd:referenceSystemIdentifier>
+            <gmd:RS_Identifier>
+               <gmd:code>
+                  <gco:CharacterString>{{ md.referencesystem.code }}{# tag="md.referencesystem.code" , name="Reference system" , ref= "Part -" , desc= "Reference system EPSG url",type = "url" , example = "http://www.opengis.net/def/crs/EPSG/0/3035" , multi= 0 , group= "Geographic" , multiline= False #}</gco:CharacterString>
+               </gmd:code>
+               <gmd:codeSpace>
+                  <gco:CharacterString>INSPIRE RS registry</gco:CharacterString>
+               </gmd:codeSpace>
+            </gmd:RS_Identifier>
+         </gmd:referenceSystemIdentifier>
+      </gmd:MD_ReferenceSystem>
+  </gmd:referenceSystemInfo>
+  {% endif -%}
     <gmd:identificationInfo>
         <gmd:MD_DataIdentification>
             <gmd:citation>
@@ -60,7 +76,7 @@
                                 <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()",type = "date", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
                             </gmd:date>
                             <gmd:dateType>
-                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ d.type }}{# tag="d.type" , group= "Temporal" ,object="CI_Date()",type = "CI_DateTypeCode", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation",database="dateType" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
+                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ d.type }}{# tag="d.type" , group= "Temporal" ,object="CI_Date()",type = "CI_DateTypeCode", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
                             </gmd:dateType>
                         </gmd:CI_Date>
                     </gmd:date>
@@ -122,10 +138,10 @@
                             <gmd:date>
                                 <gmd:CI_Date>
                                     <gmd:date>
-                                        <gco:Date>{{ k["thesaurus"]["date"] }}{# tag='k["thesaurus"]["date"]', name ="Reference date", desc ="This citation shall include at least the title a reference date(publication, revision, creation." , type = "date",inboxmulti=1, multi = 0, group = "Keywords", multiline=False, inbox="Free keywords",database="keywords" #}</gco:Date>
+                                        <gco:Date>{{ k["thesaurus"]["date"] }}{# tag='k["thesaurus"]["date"]', name ="Reference date", desc ="This citation shall include at least the title a reference date(publication, revision, creation." , type = "date",inboxmulti=1, multi = 0, group = "Keywords", multiline=False, inbox="Free keywords",database="keywords.date" #}</gco:Date>
                                     </gmd:date>
                                     <gmd:dateType>
-                                        <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ k["thesaurus"]["datetype"] }}{{ k["thesaurus"]["datetype"] }}{# tag='k["thesaurus"]["datetype"]', type = "CI_DateTypeCode",name ="Date type",inboxmulti=1, desc ="Options Date of creation, Date of last revision, date of publication" , multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" ,database="dateType" #}" >{{ k["thesaurus"]["datetype"] }}</gmd:CI_DateTypeCode>
+                                        <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ k["thesaurus"]["datetype"] }}{{ k["thesaurus"]["datetype"] }}{# tag='k["thesaurus"]["datetype"]', type = "CI_DateTypeCode",name ="Date type",inboxmulti=1, desc ="Options Date of creation, Date of last revision, date of publication" , multi = 0, group = "Keywords", multiline=False, inbox="Free keywords" ,database="keywords.datetype" #}" >{{ k["thesaurus"]["datetype"] }}</gmd:CI_DateTypeCode>
                                     </gmd:dateType>
                                 </gmd:CI_Date>
                             </gmd:date>
@@ -178,9 +194,9 @@
                 <gmd:LanguageCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ lan }}{# tag="lan" , name="Metadata language" , ref= "Part B 10.3" , desc= "Language used for documenting metadata." , example = "eng" , type ="LanguageCode (ISO/TS 19139)" ,multi=0,inbox='Languages',inboxmulti=1, group= "Identification" , multiline= False, database="language" #}">{{ lan }}</gmd:LanguageCode>
             </gmd:language>
       {% endfor -%}
-      {% for tc in md.identification.topiccategory -%}{# tag="for tc in md.identification.topiccategory", inbox='Topic category',group= "Classification", multiline= False, database="topicCategory" #}
+      {% for tc in md.identification.topiccategory -%}{# tag="for tc in md.identification.topiccategory", inbox='Topic category',group= "Classification", multiline= False #}
             <gmd:topicCategory>
-                <gmd:MD_TopicCategoryCode>{{ tc }}{# tag="tc" , name="Topic" , ref= "Part B 2.1" , desc= "Main theme(s) of the dataset" ,inbox='Topic category', example = "imageryBaseMapsEarthCover" , type ="MD_TopicCategory" , group= "Classification" ,  multi=0 , multiline= False, database="topicCategory" #}</gmd:MD_TopicCategoryCode>
+                <gmd:MD_TopicCategoryCode>{{ tc }}{# tag="tc" , name="Topic" , ref= "Part B 2.1" , desc= "Main theme(s) of the dataset" ,inbox='Topic category', example = "imageryBaseMapsEarthCover" , type ="MD_TopicCategory" , group= "Classification" ,  multi=0 , multiline= False #}</gmd:MD_TopicCategoryCode>
             </gmd:topicCategory>
       {% endfor -%}
 {% for (u,d) in zip(md.identification.uom,md.identification.distance) -%}{# tag="for (u,d) in zip(md.identification.uom,md.identification.distance)", group = "Quality and Validity", inbox="Spatial resolution-distance",inboxmulti= 1 #}
@@ -289,7 +305,7 @@
                                                 <gco:Date>{{ d }}{# tag="d" , name="Date" , ref= "Part B 7.1" , desc= "citation of the product specification or user requirement against which data is being evaluated." , example = "2010-04-26" , type ="date" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Date>
                                             </gmd:date>
                                             <gmd:dateType>
-                                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue={{ "\"%s\"" % dt }}>{{ dt }}{# tag="dt" , name="Date type" , ref= "Part B 7.1" , desc= "a date type: creation, revision or publication." , example = "publication" , type ="dateType" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False,database="dateType" #}</gmd:CI_DateTypeCode>
+                                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue={{ "\"%s\"" % dt }}>{{ dt }}{# tag="dt" , name="Date type" , ref= "Part B 7.1" , desc= "a date type: creation, revision or publication." , example = "publication" , type ="dateType" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gmd:CI_DateTypeCode>
                                             </gmd:dateType>
                                         </gmd:CI_Date>
                                     </gmd:date>
@@ -299,7 +315,7 @@
                                 <gco:CharacterString>See the referenced specification</gco:CharacterString>
                             </gmd:explanation>
                             <gmd:pass>
-                                <gco:Boolean>{{ dg }}{# tag="dg" , name="Degree/Pass" , ref= "Part B 7.2" , desc= "indication of the conformance result" , example = "True." , type ="boolean" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False, database="degree" #}</gco:Boolean>
+                                <gco:Boolean>{{ dg }}{# tag="dg" , name="Degree/Pass" , ref= "Part B 7.2" , desc= "indication of the conformance result" , example = "True." , type ="boolean" , group= "Conformity" , inbox= "Conformity", multi=0 , inboxmulti= 1, multiline= False #}</gco:Boolean>
                             </gmd:pass>
                         </gmd:DQ_ConformanceResult>
                     </gmd:result>
@@ -315,4 +331,4 @@
       </gmd:lineage>
     </gmd:DQ_DataQuality>
   </gmd:dataQualityInfo>
-</gmd:MD_Metadata>
+</gmd:MD_Metadata>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml
___________________________________________________________________
Added: svn:mime-type
   + text/xml
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/Makefile
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/Makefile	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/Makefile	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = t.info.iso
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.html
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.html	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.html	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <title></title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.py	2015-08-10 13:13:38 UTC (rev 65871)
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+ at module  r.info.iso
+ at brief   Module for creating metadata based on ISO for raster maps
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Matej Krejci <matejkrejci gmail.com> (GSoC 2015)
+"""
+#%module
+#% description: Lists information about space time datasets and maps.
+#% keyword: temporal
+#% keyword: metadata
+#% keyword: extent
+#%end
+
+#%option G_OPT_STDS_INPUT
+#% description: Name of an existing space time dataset or map
+#%end
+
+#%option G_OPT_STDS_TYPE
+#% guidependency: input
+#% guisection: Required
+#% options: strds, str3ds, stvds, raster, raster_3d, vector
+#%end
+
+#%option G_OPT_F_OUTPUT
+#% required: no
+#%end
+
+
+import os
+import sys
+
+import grass.temporal as tgis
+import grass.script as grass
+from grass.script import parser, fatal
+from grass.pygrass.utils import get_lib_path
+from core.gcmd import GError, GMessage,GException
+
+def load_mdlib():
+    path = get_lib_path(modname='mdlib', libname='mdgrass')
+    if path is None:
+        fatal("Not able to find the metadata library directory")
+    sys.path.append(path)
+
+
+def main():
+    load_mdlib()
+    from mdgrass import GrassMD
+
+    if not options['output']:
+        destination = None
+        name = None
+    else:
+        destination, name = os.path.split(options['output'])
+
+    name = options["input"]
+    type_ = options["type"]
+
+
+    # Make sure the temporal database exists
+    tgis.init()
+
+    dbif, connected = tgis.init_dbif(None)
+
+    if name.find("@") >= 0:
+        id_ = name
+    else:
+        id_ = name + "@" + grass.gisenv()["MAPSET"]
+
+    dataset = tgis.dataset_factory(type_, id_)
+
+    if dataset.is_in_db(dbif) == False:
+        grass.fatal(_("Dataset <%s> not found in temporal database") % (id_))
+
+    md = GrassMD(id_, type=type_)
+    md.createTemporalISO()
+    md.saveXML(path=destination,
+              xml_out_name=name,
+              overwrite=os.getenv('GRASS_OVERWRITE', False))
+
+
+
+if __name__ == "__main__":
+    options, flags = parser()
+    main()


Property changes on: grass-addons/grass7/gui/wxpython/wx.metadata/t.info.iso/t.info.iso.py
___________________________________________________________________
Added: svn:mime-type
   + text/x-python
Added: svn:eol-style
   + native



More information about the grass-commit mailing list