diff --git a/CenRa_METABASE/CenRa_Metabase.py b/CenRa_METABASE/CenRa_Metabase.py
new file mode 100644
index 0000000..d1e265a
--- /dev/null
+++ b/CenRa_METABASE/CenRa_Metabase.py
@@ -0,0 +1,217 @@
+__copyright__ = "Copyright 2021, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+
+
+from qgis.core import QgsApplication
+from qgis.PyQt.QtCore import Qt, QUrl, QSettings
+from qgis.PyQt.QtGui import QDesktopServices, QIcon
+from qgis.PyQt.QtWidgets import QAction
+from qgis.utils import iface
+import qgis
+
+# include
+'''
+from pg_metadata.connection_manager import (
+ store_connections,
+ validate_connections_names,
+)
+
+
+from pg_metadata.locator import LocatorFilter
+from pg_metadata.processing.provider import PgMetadataProvider
+from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
+'''
+import os
+from .about_form import MetabaseAboutDialog
+from .tools.resources import (
+ # plugin_path,
+ pyperclip,
+ resources_path,
+ maj_verif,
+)
+pyperclip()
+from .dock import CenRa_Metabase
+from .editor import Metabase_Editor
+
+# from CenRa_Metabase.issues import CenRa_Issues
+
+
+class PgMetadata:
+ def __init__(self):
+ """ Constructor. """
+ self.dock = None
+ self.editor = None
+# self.issues = None
+ self.provider = None
+ self.locator_filter = None
+ self.dock_action = None
+ self.help_action = None
+ plugin_dir = os.path.dirname(__file__)
+ end_find = plugin_dir.rfind('\\') + 1
+ global NAME
+ NAME = plugin_dir[end_find:]
+ maj_verif(NAME)
+
+ # Display About window on first use
+ version = qgis.utils.pluginMetadata('CenRa_METABASE', 'version')
+ s = QSettings()
+ versionUse = s.value("metadata/version", 1, type=str)
+ if str(versionUse) != str(version):
+ s.setValue("metadata/version", str(version))
+ print(versionUse, version)
+ self.open_about_dialog()
+# setup_logger('pg_metadata')
+
+ # locale, file_path = setup_translation(
+ # folder=plugin_path("i18n"), file_pattern="CenRa_Metabase_{}.qm")
+ # if file_path:
+ # self.translator = QTranslator()
+ # self.translator.load(file_path)
+ # noinspection PyCallByClass,PyArgumentList
+ # QCoreApplication.installTranslator(self.translator)
+
+ # noinspection PyPep8Naming
+ # def initProcessing(self):
+ # """ Add the QGIS Processing provider. """
+ # if not self.provider:
+ # self.provider = PgMetadataProvider()
+ # QgsApplication.processingRegistry().addProvider(self.provider)
+
+ # noinspection PyPep8Naming
+ def initGui(self):
+ """ Build the plugin GUI. """
+ # self.initProcessing()
+
+ # self.check_invalid_connection_names()
+
+ self.toolBar = iface.addToolBar("CenRa_Metabase")
+ self.toolBar.setObjectName("CenRa_Metabase")
+
+ icon = QIcon(resources_path('icons', 'icon.png'))
+ icon2 = QIcon(resources_path('icons', 'icon_2.png'))
+
+ # Open the online help
+ self.help_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
+ iface.pluginHelpMenu().addAction(self.help_action)
+ self.help_action.triggered.connect(self.open_help)
+ if not self.editor:
+ self.editor = Metabase_Editor()
+
+ self.editor_action = QAction(icon2, 'CenRa_Metabase', None)
+ self.toolBar.addAction(self.editor_action)
+ self.editor_action.triggered.connect(self.open_editor)
+
+ if not self.dock:
+ self.dock = CenRa_Metabase()
+ iface.addDockWidget(Qt.DockWidgetArea(0x2), self.dock)
+
+ # Open/close the dock from plugin menu
+ self.dock_action = QAction(icon, 'CenRa_Metabase', iface.mainWindow())
+ iface.pluginMenu().addAction(self.dock_action)
+ self.dock_action.triggered.connect(self.open_dock)
+# if not self.issues:
+# self.issues = CenRa_Issues()
+
+
+# self.issues_action = QAction(icon, 'CenRa_Metabase',None)
+# self.toolBar.addAction(self.issues_action)
+# self.issues_action.triggered.connect(self.open_issues)
+ '''
+ if not self.locator_filter:
+ self.locator_filter = LocatorFilter(iface)
+ iface.registerLocatorFilter(self.locator_filter)
+
+ @staticmethod
+ def check_invalid_connection_names():
+ """ Check for invalid connection names in the QgsSettings. """
+ valid, invalid = validate_connections_names()
+ n_invalid = len(invalid)
+
+ if n_invalid == 0:
+ return
+
+ invalid_text = ', '.join(invalid)
+ msg = QMessageBox()
+ msg.setIcon(QMessageBox.Warning)
+ msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
+ msg.setText(tr(
+ f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
+ f'no longer available: {invalid_text}'))
+ msg.setInformativeText(tr(
+ 'Do you want to remove these connection(s) from the PgMetadata settings? '
+ '(You can also do this later with the “Set Connections” tool.)'))
+ msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+ clicked = msg.exec()
+
+ if clicked == QMessageBox.Yes:
+ iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
+ store_connections(valid)
+ if clicked == QMessageBox.No:
+ iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
+ '''
+ def open_about_dialog(self):
+ """
+ About dialog
+ """
+ dialog = MetabaseAboutDialog(iface)
+ dialog.exec()
+
+ def open_help():
+ """ Open the online help. """
+ QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
+
+ def open_dock(self):
+ """ Open the dock. """
+ self.dock.show()
+ self.dock.raise_()
+
+ def open_editor(self):
+ self.editor.show()
+ self.editor.raise_()
+
+# def open_issues(self):
+# self.issues.show()
+# self.issues.raise_()
+
+ def unload(self):
+ """ Unload the plugin. """
+ # if self.editor:
+ # iface.removePluginMenu('CenRa_Metabase',self.editor_action)
+ # self.editor.removeToolBarIcon(self.editor_action)
+
+ if self.dock:
+ iface.removeDockWidget(self.dock)
+ self.dock.deleteLater()
+
+ if self.provider:
+ QgsApplication.processingRegistry().removeProvider(self.provider)
+ del self.provider
+
+ if self.locator_filter:
+ iface.deregisterLocatorFilter(self.locator_filter)
+ del self.locator_filter
+
+ if self.help_action:
+ iface.pluginHelpMenu().removeAction(self.help_action)
+ del self.help_action
+
+ if self.dock_action:
+ iface.pluginMenu().removeAction(self.dock_action)
+ del self.dock_action
+
+ @staticmethod
+ def run_tests(pattern='test_*.py', package=None):
+ """Run the test inside QGIS."""
+ try:
+ from pathlib import Path
+
+ from pg_metadata.qgis_plugin_tools.infrastructure.test_runner import (
+ test_package,
+ )
+ if package is None:
+ package = '{}.__init__'.format(Path(__file__).parent.name)
+ test_package(package, pattern)
+ except (AttributeError, ModuleNotFoundError):
+ message = 'Could not load tests. Are you using a production package?'
+ print(message) # NOQA
diff --git a/CenRa_METABASE/README.md b/CenRa_METABASE/README.md
new file mode 100644
index 0000000..86abd18
--- /dev/null
+++ b/CenRa_METABASE/README.md
@@ -0,0 +1 @@
+# CenRa_Metabase
\ No newline at end of file
diff --git a/CenRa_METABASE/__init__.py b/CenRa_METABASE/__init__.py
new file mode 100644
index 0000000..4eaf7d0
--- /dev/null
+++ b/CenRa_METABASE/__init__.py
@@ -0,0 +1,10 @@
+__copyright__ = "Copyright 2021, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+
+
+# noinspection PyPep8Naming
+def classFactory(iface): # pylint: disable=invalid-name
+ _ = iface
+ from CenRa_METABASE.CenRa_Metabase import PgMetadata
+ return PgMetadata()
diff --git a/CenRa_METABASE/about_form.py b/CenRa_METABASE/about_form.py
new file mode 100644
index 0000000..b9fa5a7
--- /dev/null
+++ b/CenRa_METABASE/about_form.py
@@ -0,0 +1,46 @@
+import os.path
+
+from pathlib import Path
+
+from qgis.PyQt import uic
+# from qgis.PyQt.QtGui import QPixmap
+from qgis.PyQt.QtWidgets import QDialog
+
+from .tools.resources import devlog
+
+ABOUT_FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(
+ str(Path(__file__).resolve().parent),
+ 'tools/ui',
+ 'CenRa_about_form.ui'
+ )
+)
+
+
+class MetabaseAboutDialog(QDialog, ABOUT_FORM_CLASS):
+
+ """ About - Let the user display the about dialog. """
+
+ def __init__(self, iface, parent=None):
+ super().__init__(parent)
+ self.iface = iface
+ self.setupUi(self)
+
+ self.viewer.setHtml(devlog('CenRa_METABASE'))
+
+ self.rejected.connect(self.onReject)
+ self.buttonBox.rejected.connect(self.onReject)
+ self.buttonBox.accepted.connect(self.onAccept)
+
+ def onAccept(self):
+ """
+ Save options when pressing OK button
+ """
+ self.accept()
+
+ def onReject(self):
+ """
+ Run some actions when
+ the user closes the dialog
+ """
+ self.close()
diff --git a/CenRa_METABASE/dock.py b/CenRa_METABASE/dock.py
new file mode 100644
index 0000000..a2979e2
--- /dev/null
+++ b/CenRa_METABASE/dock.py
@@ -0,0 +1,453 @@
+"""Dock file."""
+
+__copyright__ = 'Copyright 2020, 3Liz'
+__license__ = 'GPL version 3'
+__email__ = 'info@3liz.org'
+
+import logging
+import os
+
+from collections import namedtuple
+from enum import Enum
+from functools import partial
+from pathlib import Path
+from xml.dom.minidom import parseString
+
+from qgis.core import (
+ QgsApplication,
+ QgsProviderRegistry,
+ QgsSettings,
+)
+from qgis.PyQt.QtCore import QLocale, QUrl
+from qgis.PyQt.QtGui import QDesktopServices, QIcon
+from qgis.PyQt.QtPrintSupport import QPrinter
+# from qgis.PyQt.QtWebKitWidgets import QWebPage
+from qgis.PyQt.QtWidgets import (
+ QAction,
+ QDockWidget,
+ QFileDialog,
+ QMenu,
+ QToolButton,
+)
+from qgis.utils import iface
+import qgis
+from .tools.resources import (
+ load_ui,
+ resources_path,
+)
+try:
+ from .tools.PythonSQL import login_base
+except ValueError:
+ print('Pas de fichier PythonSQL')
+
+DOCK_CLASS = load_ui('CenRa_Metabase_dockwidget_base.ui')
+LOGGER = logging.getLogger('CenRa_Metabase')
+
+
+class Format(namedtuple('Format', ['label', 'ext'])):
+ """ Format available for exporting metadata. """
+ pass
+
+
+class OutputFormats(Format, Enum):
+ """ Output format for a metadata sheet. """
+ PDF = Format(label='PDF', ext='pdf')
+ HTML = Format(label='HTML', ext='html')
+ DCAT = Format(label='DCAT', ext='xml')
+
+
+class CenRa_Metabase(QDockWidget, DOCK_CLASS):
+
+ def __init__(self, parent=None):
+ _ = parent
+ super().__init__()
+ self.setupUi(self)
+ self.settings = QgsSettings()
+
+ self.current_datasource_uri = None
+ self.current_connection = None
+
+ # self.viewer.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
+ # self.viewer.page().linkClicked.connect(self.open_link)
+
+ # Help button
+ self.external_help.setText('')
+ self.external_help.setIcon(QIcon(QgsApplication.iconPath('mActionHelpContents.svg')))
+ self.external_help.clicked.connect(self.open_external_help)
+
+ # Flat table button
+ self.flatten_dataset_table.setText('')
+ # self.flatten_dataset_table.setToolTip(tr("Add the catalog table"))
+ self.flatten_dataset_table.setIcon(QgsApplication.getThemeIcon("/mActionAddHtml.svg"))
+ # self.flatten_dataset_table.clicked.connect(self.add_flatten_dataset_table)
+
+ # Settings menu
+ self.config.setAutoRaise(True)
+ # self.config.setToolTip(tr("Settings"))
+ self.config.setPopupMode(QToolButton.ToolButtonPopupMode(2))
+ self.config.setIcon(QgsApplication.getThemeIcon("/mActionOptions.svg"))
+
+ self.auto_open_dock_action = QAction(
+ ("Dommage, cette option n'existe pas encore."),
+ iface.mainWindow())
+ self.auto_open_dock_action.setCheckable(True)
+ self.auto_open_dock_action.setChecked(
+ self.settings.value("pgmetadata/auto_open_dock", True, type=bool)
+ )
+ self.auto_open_dock_action.triggered.connect(self.save_auto_open_dock)
+ menu = QMenu()
+ menu.addAction(self.auto_open_dock_action)
+ self.config.setMenu(menu)
+
+ # Setting PDF/HTML menu
+ self.save_button.setAutoRaise(True)
+ # self.save_button.setToolTip(tr("Save metadata"))
+ self.save_button.setPopupMode(QToolButton.ToolButtonPopupMode(2))
+ self.save_button.setIcon(QIcon(QgsApplication.iconPath('mActionFileSave.svg')))
+
+ self.save_as_pdf = QAction(
+ ('Enregistrer en PDF') + '…',
+ iface.mainWindow())
+ self.save_as_pdf.triggered.connect(partial(self.export_dock_content, OutputFormats.PDF))
+
+ self.save_as_html = QAction(
+ ('Enregistrer en HTML') + '…',
+ iface.mainWindow())
+ self.save_as_html.triggered.connect(partial(self.export_dock_content, OutputFormats.HTML))
+ self.save_as_dcat = QAction(
+ ('Enregistrer en DCAT') + '…',
+ iface.mainWindow())
+ self.save_as_dcat.triggered.connect(partial(self.export_dock_content, OutputFormats.DCAT))
+
+ self.menu_save = QMenu()
+ self.menu_save.addAction(self.save_as_pdf)
+ self.menu_save.addAction(self.save_as_html)
+ self.menu_save.addAction(self.save_as_dcat)
+ self.save_button.setMenu(self.menu_save)
+ self.save_button.setEnabled(False)
+
+ self.metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
+
+ # Display message in the dock
+ # if not settings_connections_names():
+ # self.default_html_content_not_installed()
+ # else:
+ self.default_html_content_not_pg_layer()
+ iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
+ try:
+ login_base()
+ iface.layerTreeView().currentLayerChanged.connect(self.layer_changed)
+ except ValueError:
+ # qgis.utils.plugins['CenRa_METABASE'].initGui()
+ qgis.utils.plugins['CenRa_METABASE'].unload()
+ # self.default_html_content_not_pg_layer()
+
+ if iface.activeLayer():
+ layer = iface.activeLayer()
+ iface.layerTreeView().setCurrentLayer(None)
+ iface.layerTreeView().setCurrentLayer(layer)
+
+ def export_dock_content(self, output_format: OutputFormats):
+ """ Export the current displayed metadata sheet to the given format. """
+ layer_name = iface.activeLayer().name()
+
+ file_path = os.path.join(
+ os.environ['USERPROFILE'],
+ 'Desktop\\{name}.{ext}'.format(name=layer_name, ext=output_format.ext)
+ )
+ output_file = QFileDialog.getSaveFileName(
+ self,
+ ("Enregistrer en {format}").format(format=output_format.label),
+ file_path,
+ "{label} (*.{ext})".format(
+ label=output_format.label,
+ ext=output_format.ext,
+ )
+ )
+ if output_file[0] == '':
+ return
+
+ self.settings.setValue("UI/lastFileNameWidgetDir", os.path.dirname(output_file[0]))
+
+ output_file_path = output_file[0]
+ parent_folder = str(Path(output_file_path).parent)
+
+ if output_format == OutputFormats.PDF:
+ printer = QPrinter()
+ printer.setOutputFormat(QPrinter.OutputFormat(1))
+ # printer.setPageMargins(20,20,20,20,QPrinter.Unit(0))
+ printer.setOutputFileName(output_file_path)
+ self.viewer.print(printer)
+ iface.messageBar().pushSuccess(
+ ("Export PDF"),
+ (
+ "The metadata has been exported as PDF successfully in "
+ "{}").format(parent_folder, output_file_path)
+ )
+
+ elif output_format in [OutputFormats.HTML, OutputFormats.DCAT]:
+ if output_format == OutputFormats.HTML:
+ data_str = self.viewer.page().currentFrame().toHtml()
+ else:
+ layer = iface.activeLayer()
+ uri = layer.dataProvider().uri()
+ dataall = self.sql_info(uri)
+ data = self.sql_to_xml(dataall)
+
+ with open(resources_path('xml', 'dcat.xml'), encoding='utf8') as xml_file:
+ xml_template = xml_file.read()
+
+ xml = parseString(xml_template.format(language=data[0][0], content=data[0][1]))
+
+ data_str = xml.toprettyxml()
+
+ with open(output_file[0], "w", encoding='utf8') as file_writer:
+ file_writer.write(data_str)
+ iface.messageBar().pushSuccess(
+ ("Export") + ' ' + output_format.label,
+ (
+ "The metadata has been exported as {format} successfully in "
+ "{path}").format(
+ format=output_format.label, folder=parent_folder, path=output_file_path)
+ )
+
+ def save_auto_open_dock(self):
+ """ Save settings about the dock. """
+ self.settings.setValue("pgmetadata/auto_open_dock", self.auto_open_dock_action.isChecked())
+
+ def sql_to_xml(self, dataall):
+ distribution = ''
+ for y in dataall[1]:
+ distribution = distribution + ('' + '' + '{data}'.format(data=y[0]) + '{data}'.format(data=y[1]) + '{data}'.format(data=y[2]) + '{data}'.format(data=y[3]) + '{data}'.format(data=y[4]) + '' + '')
+ publisher = ''
+ for z in dataall[2]:
+ publisher = publisher + ('' + '' + '{data}'.format(data=z[1]) + '{data}'.format(data=z[3]) + '' + '')
+ data_str = [[dataall[0][26], '{data}'.format(data=dataall[0][1]) + '{data}'.format(data=dataall[0][4]) + '{data}'.format(data=dataall[0][5]) + '{data}'.format(data=dataall[0][26]) + '{data}'.format(data=dataall[0][28]) + '{data}'.format(data=dataall[0][20]) + '{data}'.format(data=dataall[0][11]) + '{data}'.format(data=dataall[0][21]) + '{data}'.format(data=dataall[0][13]) + distribution + publisher + '{data}'.format(data=", ".join(str(x) for x in dataall[0][24])) + '{data}'.format(data=", ".join(str(x) for x in dataall[0][6])) + '{data}'.format(data=dataall[0][12])]]
+
+ return data_str
+
+ @staticmethod
+ def sql_for_layer(uri, output_format: OutputFormats):
+ """ Get the SQL query for a given layer and output format. """
+ locale = QgsSettings().value("locale/userLocale", QLocale().name())
+ locale = locale.split('_')[0].lower()
+
+ if output_format == [OutputFormats.HTML, OutputFormats.DCAT]:
+ sql = (
+ "SELECT pgmetadata.get_dataset_item_html_content('{schema}', '{table}', '{locale}');"
+ ).format(schema=uri.schema(), table=uri.table(), locale=locale)
+ else:
+ raise NotImplementedError('Output format is not yet implemented.')
+
+ return sql
+
+ def layer_changed(self, layer):
+ """ When the layer has changed in the legend, we must check this new layer. """
+ self.current_datasource_uri = None
+ self.current_connection = None
+ self.ce_trouve_dans_psql(layer)
+
+ def add_flatten_dataset_table(self):
+ """ Add a flatten dataset table with all links and contacts. """
+ '''
+ connections, message = connections_list()
+ if not connections:
+ LOGGER.critical(message)
+ self.set_html_content('PgMetadata', message)
+ return
+
+ if len(connections) > 1:
+ dialog = QInputDialog()
+ dialog.setComboBoxItems(connections)
+ dialog.setWindowTitle(tr("Database"))
+ dialog.setLabelText(tr("Choose the database to add the catalog"))
+ if not dialog.exec_():
+ return
+ connection_name = dialog.textValue()
+ else:
+ connection_name = connections[0]
+
+ metadata = QgsProviderRegistry.instance().providerMetadata('postgres')
+ connection = metadata.findConnection(connection_name)
+
+ locale = QgsSettings().value("locale/userLocale", QLocale().name())
+ locale = locale.split('_')[0].lower()
+
+ uri = QgsDataSourceUri(connection.uri())
+ uri.setTable(f'(SELECT * FROM pgmetadata.export_datasets_as_flat_table(\'{locale}\'))')
+ uri.setKeyColumn('uid')
+
+ layer = QgsVectorLayer(uri.uri(), '{} - {}'.format(tr("Catalog"), connection_name), 'postgres')
+ QgsProject.instance().addMapLayer(layer)
+ '''
+
+ @staticmethod
+ def open_external_help():
+ QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
+
+ @staticmethod
+ def open_link(url):
+ QDesktopServices.openUrl(url)
+
+ def set_html_content(self, title=None, body=None):
+ """ Set the content in the dock. """
+ # ink_logo=resources_path('icons', 'CEN_RA.png')
+ css_file = resources_path('css', 'dock.css')
+ with open(css_file, 'r', encoding='utf8') as f:
+ css = f.read()
+
+ html = ''
+ # html += ''
+ html += ''.format(css=css)
+ # html += ''
+ # html += ''
+ # html += ''
+ if title:
+ html += '{title} 
'.format(title=title)
+ if body:
+ html += body
+
+ html += ''
+
+ # It must be a file, even if it does not exist on the file system.
+ # base_url = QUrl.fromLocalFile(resources_path('images', 'must_be_a_file.png'))
+ self.viewer.setHtml(html)
+
+ def ce_trouve_dans_psql(self, layer):
+ try:
+ uri = layer.dataProvider().uri()
+ except AttributeError:
+ self.default_html_content_not_pg_layer()
+ self.save_button.setEnabled(False)
+ uri = ''
+ if uri != '':
+ if not uri.table():
+ layertype = layer.providerType().lower()
+ if layertype == 'wms' or layertype == 'wfs':
+ self.set_html_to_wms(layer)
+ else:
+ self.default_html_content_not_pg_layer()
+ self.save_button.setEnabled(False)
+ else:
+ data_count = self.sql_check(uri)
+ # print(data_count)
+ if data_count == 0:
+ self.default_html_content_not_metadata()
+ self.save_button.setEnabled(False)
+ else:
+ self.build_html_content(layer, uri)
+ self.save_button.setEnabled(True)
+
+ def build_html_content(self, layer, uri):
+ body = ''
+
+ dataall = self.sql_info(uri)
+ data = dataall[0]
+ data_url = dataall[1]
+ data_contact = dataall[2]
+ # print(len(data_url))
+ # data_collonne = [field.name() for field in layer.dataProvider().fields()]
+
+ body += 'Identification
'
+ body += '| Titre | {data[4]} |
'.format(data=data)
+ body += '| Description | {data[5]} |
'.format(data=data)
+ body += '| Categories | {data} |
'.format(data=(", ".join(str(x) for x in data[6])))
+ body += '| Thèmes | {data} |
'.format(data=(", ".join(str(x) for x in data[24])))
+ body += '| Mots-clés | {data[7]} |
'.format(data=data)
+ body += '| Dernier mise à jour | {data[23]} |
'.format(data=data)
+ body += '| Langue | {data[26]} |
'.format(data=data)
+ body += '
'
+
+ body += 'Properties spatial
'
+ body += '| Niveau | {data[8]} |
'.format(data=data)
+ body += '| Echelle minimum | {data[9]} |
'.format(data=data)
+ body += '| Echelle maximum | {data[10]} |
'.format(data=data)
+ body += '| Nombre d\'entités | {data[15]} |
'.format(data=data)
+ body += '| Type de géométrie | {data[16]} |
'.format(data=data)
+ body += '| Nom de projection | {data[17]} |
'.format(data=data)
+ body += '| ID de projection | {data[18]} |
'.format(data=data)
+ body += '| Emprise | {data[28]} |
'.format(data=data)
+ body += '
'
+
+ # body += ''
+
+ body += 'Publication
'
+ body += '| Date | {data[11]} |
'.format(data=data)
+ body += '| Fréquence de mise à jour | {data[12]} |
'.format(data=data)
+ body += '| Licence | {data[13]} |
'.format(data=data)
+ body += '| Licence attribué | {data[25]} |
'.format(data=data)
+ body += '| Restriction | {data[14]} |
'.format(data=data)
+ body += '
'
+
+ body += 'Lien
'
+ body += '| Type | URL | Type MIME | Format | Taille |
'
+ for value_url in data_url:
+ body += '| {value_url[0]} | {value_url[1]} | {value_url[2]} | {value_url[3]} | {value_url[4]} |
'.format(value_url=value_url)
+ body += '
'
+ '''
+ body += 'Liste des champs
'
+ for collonne in data_collonne:
+ body += '| {collonne} | {defini} |
'.format(collonne=collonne,defini='')
+ body += '
'
+ '''
+ body += 'Contacts
'
+ body += '| Rôle | Nom | Organisation | Email | Télèphone |
'
+ for value_contact in data_contact:
+ body += '| {value_contact[0]} | {value_contact[1]} | {value_contact[2]} | {value_contact[3]} | {value_contact[4]} |
'.format(value_contact=value_contact)
+ body += '
'
+
+ body += 'Metadata
'
+ body += '| Table | {data[2]} |
'.format(data=data)
+ body += '| Schema | {data[3]} |
'.format(data=data)
+ body += '| Date de création | {data[20]} |
'.format(data=data)
+ body += '| Date de modification | {data[21]} |
'.format(data=data)
+ body += '| Encodage | {data[27]} |
'.format(data=data)
+ body += '| UUID | {data[1]} |
'.format(data=data)
+ body += '
'
+
+ self.set_html_content(
+ layer.name(), body)
+
+ def set_html_to_wms(self, layer):
+ self.set_html_content(
+ 'CenRa Metadata', (layer.htmlMetadata()))
+
+ def default_html_content_not_pg_layer(self):
+ """ When it's not a PostgreSQL layer. """
+ self.set_html_content(
+ 'CenRa Metadata', ('Vous devez cliquer sur une couche dans la légende qui est stockée dans PostgreSQL.'))
+
+ def default_html_content_not_metadata(self):
+ self.set_html_content(
+ 'CenRa Metadata', ('La couche ne contien pas de métadonnée.'))
+
+ def sql_check(self, uri):
+ cur = login_base()
+ table = uri.table()
+ schema = uri.schema()
+
+ sql_count = """SELECT count(uid) FROM metadata.dataset
+ WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+
+ cur.execute(sql_count)
+ data_count = cur.fetchall()
+ cur.close()
+ return data_count[0][0]
+
+ def sql_info(self, uri):
+ cur = login_base()
+ table = uri.table()
+ schema = uri.schema()
+ # [s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
+ sql_find = """SELECT *,right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
+ WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_find)
+ data_general = cur.fetchall()
+ sql_findurl = """SELECT type,url,mime,format,taille FROM metadata.dataurl WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_findurl)
+ data_url = cur.fetchall()
+ sql_findcontact = """SELECT role,nom,organisation,email,telephone FROM metadata.datacontact WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_findcontact)
+ data_contact = cur.fetchall()
+ cur.close()
+ return data_general[0], data_url, data_contact
diff --git a/CenRa_METABASE/editor.py b/CenRa_METABASE/editor.py
new file mode 100644
index 0000000..7896e2d
--- /dev/null
+++ b/CenRa_METABASE/editor.py
@@ -0,0 +1,775 @@
+import logging
+import os
+
+# from collections import namedtuple
+# from enum import Enum
+# from functools import partial
+# from pathlib import Path
+# from xml.dom.minidom import parseString
+# from qgis.gui import *
+from qgis.core import (
+ QgsApplication,
+ QgsSettings,
+ QgsGeometry,
+ QgsWkbTypes,
+ Qgis,
+)
+from qgis.PyQt import QtGui, QtCore
+from qgis.PyQt.QtGui import QIcon
+# from qgis.PyQt.QtPrintSupport import QPrinter
+# from qgis.PyQt.QtWebKitWidgets import QWebPage
+import psycopg2
+from qgis.PyQt.QtWidgets import (
+ QDialog,
+ QFileDialog,
+ QTableWidgetItem,
+)
+from qgis.utils import iface
+
+try:
+ from .tools.PythonSQL import login_base
+except ValueError:
+ print('Pas de fichier PythonSQL')
+
+from .tools.resources import (
+ load_ui,
+ resources_path,
+ # send_issues,
+)
+# from .issues import CenRa_Issues
+
+EDITOR_CLASS = load_ui('CenRa_Metabase_editorwidget_base.ui')
+LOGGEr = logging.getLogger('CenRa_Metabase')
+
+
+class Metabase_Editor(QDialog, EDITOR_CLASS):
+ def __init__(self, parent=None):
+ _ = parent
+ super().__init__()
+ self.setupUi(self)
+ self.settings = QgsSettings()
+ self.setWindowIcon(QtGui.QIcon(resources_path('icons', 'icon.png')))
+ self.import_xml.setAutoRaise(True)
+ self.import_xml.setText('')
+ self.import_xml.setIcon(QIcon(QgsApplication.iconPath('mActionAddHtml.svg')))
+ self.import_xml.clicked.connect(self.py_import_xml)
+ self.issues_app.setAutoRaise(True)
+ self.issues_app.setText('')
+ self.issues_app.setIcon(QIcon(QgsApplication.iconPath('mIconInfo.svg')))
+ self.auto_adding.setIcon(QtGui.QIcon(resources_path('icons', 'auto_add.png')))
+ self.auto_adding.hide()
+ if os.getlogin() == 'tlaveille' or 'lpoulin' or 'rclement':
+ self.auto_adding.show()
+
+ self.auto_adding.clicked.connect(self.auto_run)
+ # self.issues_app.clicked.connect(self.issues_open)
+ self.categories_select_view.itemDoubleClicked.connect(self.add_categories_view)
+ self.categories_view.itemDoubleClicked.connect(self.deleter_categories_view)
+ self.themes_select_view.itemDoubleClicked.connect(self.add_themes_view)
+ self.themes_view.itemDoubleClicked.connect(self.deleter_themes_view)
+
+ self.annuler_button.clicked.connect(self.close)
+ self.ok_button.clicked.connect(self.add_metadata)
+
+ self.add_lien_button.clicked.connect(self.add_lien)
+ self.add_contact_button.clicked.connect(self.add_contact)
+ self.delete_lien_button.clicked.connect(self.delete_lien)
+ self.delete_contact_button.clicked.connect(self.delete_contact)
+
+ def auto_run(self):
+ self.role_box.setCurrentIndex(1)
+ self.nom_line.setText('LAVEILLE')
+ self.organisation_box.setCurrentIndex(1)
+ self.email_line.setText('tom.laveille@cen-rhonealpes.fr')
+ self.telephone_line.setText('0451260811')
+ self.add_contact()
+
+ self.type_box.setCurrentIndex(16)
+ self.url_line.setText('www.cen-rhonealpes.fr')
+ self.mime_box.setCurrentIndex(16)
+ self.format_box.setCurrentIndex(0)
+ self.taille_line.setText('45')
+ self.add_lien()
+
+ def add_metadata(self):
+ table_name = layer.dataProvider().uri().table()
+ schema_name = layer.dataProvider().uri().schema()
+ text_titre = self.titre_line.text()
+ text_description = self.description_text.toPlainText()
+ text_mots_cles = self.mots_cles_text.toPlainText()
+ text_date_maj = str(self.date_maj_date.date().toPyDate())
+ text_langue = self.langue_box.currentText()
+
+ row_count_categories = self.categories_view.rowCount()
+ row_count_themes = self.themes_view.rowCount()
+ row = 1
+ array_categories = '{'
+ while row_count_categories >= row:
+ if row_count_categories != row:
+ array_categories += (self.categories_view.item(row - 1, 0).text()) + ', '
+ else:
+ array_categories += (self.categories_view.item(row - 1, 0).text())
+ row = row + 1
+ array_categories += '}'
+ row = 1
+ array_themes = '{'
+ while row_count_themes >= row:
+ if row_count_themes != row:
+ array_themes += (self.themes_view.item(row - 1, 0).text()) + ', '
+ else:
+ array_themes += (self.themes_view.item(row - 1, 0).text())
+ row = row + 1
+ array_themes += '}'
+
+ text_date_creation = str(self.date_creation_date.date().toPyDate())
+ text_date_modification = str(self.date_modification_date.date().toPyDate())
+ text_encode = self.encodage_box.currentText()
+ text_extend = self.extend_plaintext.toPlainText()
+ int_nbr_entites = (self.nbr_layers.toPlainText())
+ text_geomtype = self.typegeom_plaintext.toPlainText()
+ text_crsname = self.crsname_plaintext.toPlainText()
+ text_crscode = self.crscode_plaintext.toPlainText()
+ text_niveau = self.niveau_plain.toPlainText()
+
+ text_echelle_min = self.echelle_min_plain.toPlainText()
+ text_echelle_max = self.echelle_max_plain.toPlainText()
+ if text_echelle_min == '':
+ text_echelle_min = 'NULL'
+ if text_echelle_max == '':
+ text_echelle_max = 'NULL'
+
+ text_date_publication = str(self.date_publication_date.date().toPyDate())
+
+ text_frequence = self.frequence_box.currentText()
+ text_restriction = self.restriction_box.currentText()
+ text_licence = self.licence_box.currentText()
+ text_licence_attrib = self.licence_attrib_box.currentText()
+
+ '''
+ row_count_link = self.table_lien.rowCount()
+ row = 1
+ array_link = ''
+ while row_count_link >= row:
+ if row_count_link != row:
+ array_link += "('" + table_name + "', '" + schema_name + "', '" + (self.table_lien.item(row - 1,1).text()) + "', '" + (self.table_lien.item(row - 1,2).text()) + "', '" + (self.table_lien.item(row - 1,3).text()) + "', '" + (self.table_lien.item(row - 1,4).text()) + "', '" + (self.table_lien.item(row - 1,5).text()) + "')" + ', '
+ else:
+ array_link += "('" + table_name + "', '" + schema_name + "', '" + (self.table_lien.item(row - 1,1).text()) + "', '" + (self.table_lien.item(row - 1,2).text()) + "', '" + (self.table_lien.item(row - 1,3).text()) + "', '" + (self.table_lien.item(row - 1,4).text()) + "', '" + (self.table_lien.item(row - 1,5).text()) + "')"
+ row = row + 1
+
+ row_count_contact = self.table_contact.rowCount()
+ row = 1
+ array_contact = ''
+ while row_count_contact >= row:
+ if row_count_contact != row:
+ array_contact += "('" + table_name + "', '" + schema_name + "', '" + (self.table_contact.item(row - 1,1).text()) + "', '" + (self.table_contact.item(row - 1,2).text()) + "', '" + (self.table_contact.item(row - 1,3).text()) + "', '" + (self.table_contact.item(row - 1,4).text()) + "', '" + (self.table_contact.item(row - 1,5).text()) + "')" + ', '
+ else:
+ array_contact += "('" + table_name + "', '" + schema_name + "', '" + (self.table_contact.item(row - 1,1).text()) + "', '" + (self.table_contact.item(row - 1,2).text()) + "', '" + (self.table_contact.item(row - 1,3).text()) + "', '" + (self.table_contact.item(row - 1,4).text()) + "', '" + (self.table_contact.item(row - 1,5).text()) + "')"
+ row = row + 1
+ '''
+
+ exist = self.status_metadata(layer)
+ cur_con = login_base(take=True)
+ cur = cur_con[0]
+ con = cur_con[1]
+ list_champs_sql = ''
+ values_sql_add = ''
+ if exist:
+ SQL_uid = """SELECT uid from metadata.dataset where table_name like '""" + table_name + """' and schema_name like '""" + schema_name + """';"""
+ cur.execute(SQL_uid)
+ text_uid = (cur.fetchall())[0][0]
+
+ SQL_delete = """DELETE from metadata.dataset where table_name like '""" + table_name + """' and schema_name like '""" + schema_name + """';"""
+ cur.execute(SQL_delete)
+ values_sql_add += "'" + text_uid + "',"
+
+ list_champs_sql += 'uid,'
+ global uid_delete_list_link, uid_delete_list_contact
+ if len(uid_delete_list_link) >= 35:
+ SQL_delete_link = """DELETE FROM metadata.dataurl WHERE uid IN (""" + uid_delete_list_link[:- 1] + """);"""
+ cur.execute(SQL_delete_link)
+ uid_delete_list_link = ''
+ if len(uid_delete_list_contact) >= 35:
+ SQL_delete_contact = """DELETE FROM metadata.datacontact WHERE uid IN (""" + uid_delete_list_contact[:- 1] + """);"""
+ cur.execute(SQL_delete_contact)
+ uid_delete_list_contact = ''
+
+ list_champs_sql += 'table_name, schema_name, title, abstract, keywords, data_last_update, langue, categories, themes, creation_date, update_date, encode, geom, spatial_extent, feature_count, geometry_type, projection_name, projection_authid, spatial_level, minimum_optimal_scale, maximum_optimal_scale, publication_date, publication_frequency, confidentiality, license, license_attribution'
+ values_sql_add += "'" + table_name + "', '" + schema_name + "', '" + text_titre + "', '" + text_description + "', '" + text_mots_cles + "', '" + text_date_maj + "', '" + text_langue + "', '" + array_categories + "', '" + array_themes + "', '" + text_date_creation + "', '" + text_date_modification + "', '" + text_encode + "', '" + text_extend + "', '" + text_extend + "', '" + int_nbr_entites + "', '" + text_geomtype + "', '" + text_crsname + "', '" + text_crscode + "', '" + text_niveau + "'," + text_echelle_min + "," + text_echelle_max + ",'" + text_date_publication + "', '" + text_frequence + "', '" + text_restriction + "', '" + text_licence + "', '" + text_licence_attrib + "'"
+
+ SQL_add = """INSERT INTO metadata.dataset (""" + list_champs_sql + """) VALUES (""" + values_sql_add + """);"""
+
+ cur.execute(SQL_add)
+
+ global array_link, array_contact
+ if len(array_link) >= 25:
+ array_link = array_link[:- 1]
+ SQL_add_link = """INSERT INTO metadata.dataurl (table_name, schema_name, type, url, mime, format, taille) VALUES """ + array_link + """;"""
+ cur.execute(SQL_add_link)
+ array_link = ''
+
+ if len(array_contact) >= 25:
+ array_contact = array_contact[0:- 1]
+ SQL_add_contact = """INSERT INTO metadata.datacontact (table_name, schema_name, role, nom, organisation, email, telephone) VALUES """ + array_contact + """;"""
+ cur.execute(SQL_add_contact)
+ array_contact = ''
+
+ con.commit()
+ cur.close()
+ self.close()
+
+ iface.layerTreeView().setCurrentLayer(None)
+ iface.layerTreeView().setCurrentLayer(layer)
+
+ def raise_(self):
+ self.activateWindow()
+ global layer
+ layer = iface.activeLayer()
+ global uid_delete_list_link, uid_delete_list_contact, array_link, array_contact
+ uid_delete_list_link = ''
+ uid_delete_list_contact = ''
+ array_link = ''
+ array_contact = ''
+
+ is_ok = self.is_in_psql(layer)
+ if is_ok:
+ exist = self.status_metadata(layer)
+ if exist:
+ self.reload_data(layer)
+ else:
+ self.new_data(layer)
+ else:
+ self.close()
+ iface.messageBar().pushMessage("Information:", "Cette couche n'est pas stockée dans PostgreSQL", level=Qgis.Warning, duration=30)
+
+ def is_in_psql(self, layer):
+ try:
+ uri = layer.dataProvider().uri()
+ except AttributeError:
+ uri = ''
+ return False
+ if uri != '':
+ if not uri.table():
+ return False
+ else:
+ return True
+
+ def status_metadata(self, layer):
+ uri = layer.dataProvider().uri()
+ table = uri.table()
+ schema = uri.schema()
+
+ cur = login_base()
+ count_sql = """ SELECT count(uid) FROM metadata.dataset WHERE table_name LIKE '""" + table + """' AND schema_name LIKE '""" + schema + """';"""
+
+ cur.execute(count_sql)
+ data_count = (cur.fetchall())[0][0]
+ if data_count == 1:
+ return True
+ else:
+ return False
+ cur.close()
+
+ def new_data(self, layer):
+ # print(layer.name(),'is new data')
+ reloader = False
+ self.interface_view(layer, reloader)
+
+ def reload_data(self, layer):
+ # print(layer.name(),'reload data')
+ reloader = True
+ self.interface_view(layer, reloader)
+
+ def interface_view(self, layer, reloader):
+
+ self.description_text.setText(None)
+ self.mots_cles_text.setText(None)
+ self.uuid_ligne.setText(None)
+ self.niveau_plain.setPlainText(None)
+ self.echelle_min_plain.setPlainText(None)
+ self.echelle_max_plain.setPlainText(None)
+ self.url_line.setText(None)
+ self.taille_line.setText(None)
+ self.nom_line.setText(None)
+ self.email_line.setText(None)
+ self.telephone_line.setText(None)
+ self.encodage_box.clear()
+ self.frequence_box.clear()
+ self.licence_box.clear()
+ self.licence_attrib_box.clear()
+ self.restriction_box.clear()
+
+ all_list = self.fletch_ref()
+
+ categories_list = all_list[0]
+ themes_list = all_list[1]
+ langue_list = all_list[2]
+ encodage_list = all_list[3]
+ frequency_list = all_list[4]
+ confidentiality_list = all_list[5]
+ license_list = all_list[6]
+ type_list = all_list[7]
+ mime_list = all_list[8]
+ format_list = all_list[9]
+ role_list = all_list[10]
+ organisation_list = all_list[11]
+
+ # langue_box
+ self.langue_box.clear()
+ self.langue_box.addItem('')
+ # self.langue_box.addItem('Fr')
+ # self.langue_box.addItem('En')
+ for langue_list_data in langue_list:
+ self.langue_box.addItem(langue_list_data[0])
+
+ for encodage_list_data in encodage_list:
+ self.encodage_box.addItem(encodage_list_data[0])
+
+ self.table_ligne.setText(layer.dataProvider().uri().table())
+ self.schema_ligne.setText(layer.dataProvider().uri().schema())
+
+ # categories_select_view
+ self.categories_select_view.setColumnCount(1)
+ self.categories_select_view.setColumnWidth(0, 230)
+ self.categories_select_view.setHorizontalHeaderLabels(['List des categories'])
+ # categories_view
+ self.categories_view.setRowCount(0)
+ self.categories_view.setColumnCount(1)
+ self.categories_view.setColumnWidth(0, 230)
+ self.categories_view.setHorizontalHeaderLabels(['Categories'])
+
+ # themes_select_view
+ self.themes_select_view.setColumnCount(1)
+ self.themes_select_view.setColumnWidth(0, 230)
+ self.themes_select_view.setHorizontalHeaderLabels(['List des thèmes'])
+ # themes_view
+ self.themes_view.setRowCount(0)
+ self.themes_view.setColumnCount(1)
+ self.themes_view.setColumnWidth(0, 230)
+ self.themes_view.setHorizontalHeaderLabels(['Thèmes'])
+
+ # lien_view
+ self.table_lien.setRowCount(0)
+ self.table_lien.setColumnCount(6)
+ self.table_lien.setColumnWidth(0, 0)
+ self.table_lien.setHorizontalHeaderLabels(['', 'Type', 'URL', 'MIME', 'Format', 'Taille'])
+
+ # contact_view
+ self.table_contact.setRowCount(0)
+ self.table_contact.setColumnCount(6)
+ self.table_contact.setColumnWidth(0, 0)
+ self.table_contact.setHorizontalHeaderLabels(['', 'Rôle', 'Nom', 'Organisation', 'Email', 'Telephone'])
+
+ # print(self.date_maj_date.date().toPyDate())
+ vector_extend = layer.extent()
+ polygone_extend = QgsGeometry.fromRect(vector_extend).asWkt()
+ self.extend_plaintext.setPlainText(str(polygone_extend))
+
+ qgstype = str(layer.type())[10:]
+
+ if qgstype != 'Raster':
+ count_layers = str(layer.featureCount())
+ geomtype = QgsWkbTypes.displayString(layer.wkbType())
+ elif qgstype == 'Raster':
+ count_layers = str(layer.dataProvider().bandCount())
+ geomtype = qgstype
+
+ self.nbr_layers.setPlainText(count_layers)
+ self.typegeom_plaintext.setPlainText(geomtype)
+ crs_name = str(layer.crs().description())
+ self.crsname_plaintext.setPlainText(crs_name)
+ crs_code = str(layer.crs().authid())
+ self.crscode_plaintext.setPlainText(crs_code)
+
+ self.frequence_box.addItem('')
+ self.restriction_box.addItem('')
+ self.licence_box.addItem('')
+ self.licence_attrib_box.addItem('')
+ for frequency_list_data in frequency_list:
+ self.frequence_box.addItem(frequency_list_data[0])
+ for confidentiality_list_data in confidentiality_list:
+ self.restriction_box.addItem(confidentiality_list_data[0])
+ for license_list_data in license_list:
+ self.licence_box.addItem(license_list_data[0])
+
+ self.type_box.clear()
+ self.mime_box.clear()
+ self.format_box.clear()
+ self.role_box.clear()
+ self.organisation_box.clear()
+
+ self.type_box.addItem('')
+ self.mime_box.addItem('')
+ self.format_box.addItem('')
+ self.role_box.addItem('')
+ self.organisation_box.addItem('')
+
+ for type_list_data in type_list:
+ self.type_box.addItem(type_list_data[0])
+ for mime_list_data in mime_list:
+ self.mime_box.addItem(mime_list_data[0])
+ for format_list_data in format_list:
+ self.format_box.addItem(format_list_data[0])
+ for role_list_data in role_list:
+ self.role_box.addItem(role_list_data[0])
+ for organisation_list_data in organisation_list:
+ self.organisation_box.addItem(organisation_list_data[0])
+
+ if reloader:
+ sql_dataload = self.sql_info(layer.dataProvider().uri())
+ sql_contactlink = self.sql_infoother(layer.dataProvider().uri())
+ sql_datalink = sql_contactlink[0]
+ sql_datacontact = sql_contactlink[1]
+
+ # print(sql_dataload)
+ self.titre_line.setText(sql_dataload[4])
+ self.date_maj_date.setDateTime(sql_dataload[23])
+ self.date_publication_date.setDateTime(sql_dataload[11])
+ self.description_text.setText(sql_dataload[5])
+ self.mots_cles_text.setText(sql_dataload[7])
+ array_langue_box = [self.langue_box.itemText(i) for i in range(self.langue_box.count())]
+ self.langue_box.setCurrentIndex(array_langue_box.index(sql_dataload[26]))
+ self.uuid_ligne.setText(sql_dataload[1])
+
+ self.categories_view.setRowCount(len(sql_dataload[6]))
+ i = 0
+ for categorie_data in sql_dataload[6]:
+ self.categories_view.setItem(i, 0, QTableWidgetItem(categorie_data))
+ i = i + 1
+ self.themes_view.setRowCount(len(sql_dataload[24]))
+ i = 0
+ for themes_data in sql_dataload[24]:
+ self.themes_view.setItem(i, 0, QTableWidgetItem(themes_data))
+ i = i + 1
+
+ self.categories_select_view.setRowCount(len(categories_list) - len(sql_dataload[6]))
+ self.themes_select_view.setRowCount(len(themes_list) - len(sql_dataload[24]))
+ i = 0
+ for categorie_select_data in categories_list:
+ try:
+ in_index = sql_dataload[6].index(categorie_select_data[0])
+ in_index = False
+ except ValueError:
+ in_index = True
+ if in_index:
+ self.categories_select_view.setItem(i, 0, QTableWidgetItem(categorie_select_data[0]))
+ i = i + 1
+ i = 0
+ for themes_select_data in themes_list:
+ try:
+ in_index = sql_dataload[24].index(themes_select_data[0])
+ in_index = False
+ except ValueError:
+ in_index = True
+ if in_index:
+ self.themes_select_view.setItem(i, 0, QTableWidgetItem(themes_select_data[0]))
+ i = i + 1
+
+ array_encodage_box = [self.encodage_box.itemText(i) for i in range(self.encodage_box.count())]
+ self.encodage_box.setCurrentIndex(array_encodage_box.index(sql_dataload[27]))
+
+ self.niveau_plain.setPlainText(sql_dataload[8])
+
+ if str(sql_dataload[9]) == 'None':
+ value_echelle_min = ''
+ else:
+ value_echelle_min = str(sql_dataload[9])
+
+ if str(sql_dataload[10]) == 'None':
+ value_echelle_max = ''
+ else:
+ value_echelle_max = str(sql_dataload[10])
+
+ self.echelle_min_plain.setPlainText(value_echelle_min)
+ self.echelle_max_plain.setPlainText(value_echelle_max)
+
+ array_frequence_box = [self.frequence_box.itemText(i) for i in range(self.frequence_box.count())]
+ self.frequence_box.setCurrentIndex(array_frequence_box.index(sql_dataload[12]))
+ array_licence_box = [self.licence_box.itemText(i) for i in range(self.licence_box.count())]
+ self.licence_box.setCurrentIndex(array_licence_box.index(sql_dataload[13]))
+ array_confidentiality_box = [self.restriction_box.itemText(i) for i in range(self.restriction_box.count())]
+ self.restriction_box.setCurrentIndex(array_confidentiality_box.index(sql_dataload[14]))
+ array_licence_attrib_box = [self.licence_attrib_box.itemText(i) for i in range(self.licence_attrib_box.count())]
+ self.licence_attrib_box.setCurrentIndex(array_licence_attrib_box.index(sql_dataload[25]))
+
+ c = 0
+ # self.table_lien.setRowCount(len(sql_datalink))
+ for lien_data in sql_datalink:
+ self.table_lien.insertRow(c)
+ self.table_lien.setItem(c, 0, QTableWidgetItem(lien_data[1]))
+ self.table_lien.setItem(c, 1, QTableWidgetItem(lien_data[4]))
+ self.table_lien.setItem(c, 2, QTableWidgetItem(lien_data[5]))
+ self.table_lien.setItem(c, 3, QTableWidgetItem(lien_data[6]))
+ self.table_lien.setItem(c, 4, QTableWidgetItem(lien_data[7]))
+ self.table_lien.setItem(c, 5, QTableWidgetItem(lien_data[8]))
+ c = c + 1
+ c = 0
+ # self.table_contact.setRowCount(len(sql_datacontact))
+ for contact_data in sql_datacontact:
+ self.table_contact.insertRow(c)
+ self.table_contact.setItem(c, 0, QTableWidgetItem(contact_data[1]))
+ self.table_contact.setItem(c, 1, QTableWidgetItem(contact_data[4]))
+ self.table_contact.setItem(c, 2, QTableWidgetItem(contact_data[5]))
+ self.table_contact.setItem(c, 3, QTableWidgetItem(contact_data[6]))
+ self.table_contact.setItem(c, 4, QTableWidgetItem(contact_data[7]))
+ self.table_contact.setItem(c, 5, QTableWidgetItem(contact_data[8]))
+ c = c + 1
+
+ else:
+
+ # titre_line
+ self.titre_line.setText(layer.name())
+ self.langue_box.setCurrentIndex(1)
+ # date_maj_date
+ now = QtCore.QDateTime.currentDateTime()
+ self.date_maj_date.setDateTime(now)
+ self.date_creation_date.setDateTime(now)
+ self.date_modification_date.setDateTime(now)
+ self.date_publication_date.setDateTime(now)
+ self.categories_select_view.setRowCount(len(categories_list))
+ self.themes_select_view.setRowCount(len(themes_list))
+ i = 0
+ for categorie_select_data in categories_list:
+ self.categories_select_view.setItem(i, 0, QTableWidgetItem(categorie_select_data[0]))
+ i = i + 1
+ i = 0
+ for themes_select_data in themes_list:
+ self.themes_select_view.setItem(i, 0, QTableWidgetItem(themes_select_data[0]))
+ i = i + 1
+
+ # print(self.langue_box.currentText())
+
+ def sql_info(self, uri):
+ cur = login_base()
+ table = uri.table()
+ schema = uri.schema()
+ # [s for s in iface.activeLayer().source().split(" ") if "dbname" in s][0].split("'")[1]
+ sql_find = """SELECT *, right(left(st_astext(geom,2),-2),-9) FROM metadata.dataset
+ WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_find)
+ data_general = cur.fetchall()
+ cur.close()
+ return data_general[0]
+
+ def sql_infoother(self, uri):
+ cur = login_base()
+ table = uri.table()
+ schema = uri.schema()
+
+ sql_findlink = """SELECT * FROM metadata.dataurl
+ WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_findlink)
+ data_link = cur.fetchall()
+
+ sql_findcontact = """SELECT * FROM metadata.datacontact
+ WHERE schema_name LIKE '""" + schema + """' AND table_name LIKE '""" + table + """';"""
+ cur.execute(sql_findcontact)
+ data_contact = cur.fetchall()
+
+ cur.close()
+ return data_link, data_contact
+
+ def add_categories_view(self):
+ values_add_categories = self.categories_select_view.selectedItems()[0].text()
+ self.categories_select_view.removeRow(self.categories_select_view.currentRow())
+ self.categories_view.insertRow(0)
+ self.categories_view.setItem(0, 0, QTableWidgetItem(values_add_categories))
+
+ def deleter_categories_view(self):
+ values_deleter_categories = self.categories_view.selectedItems()[0].text()
+ self.categories_view.removeRow(self.categories_view.currentRow())
+ self.categories_select_view.insertRow(0)
+ self.categories_select_view.setItem(0, 0, QTableWidgetItem(values_deleter_categories))
+
+ def add_themes_view(self):
+ values_add_themes = self.themes_select_view.selectedItems()[0].text()
+ self.themes_select_view.removeRow(self.themes_select_view.currentRow())
+ self.themes_view.insertRow(0)
+ self.themes_view.setItem(0, 0, QTableWidgetItem(values_add_themes))
+
+ def deleter_themes_view(self):
+ values_deleter_themes = self.themes_view.selectedItems()[0].text()
+ self.themes_view.removeRow(self.themes_view.currentRow())
+ self.themes_select_view.insertRow(0)
+ self.themes_select_view.setItem(0, 0, QTableWidgetItem(values_deleter_themes))
+
+ def add_lien(self):
+ cur = login_base()
+ maxrow = self.table_lien.rowCount()
+ self.table_lien.insertRow(maxrow)
+
+ table = layer.dataProvider().uri().table()
+ schema = layer.dataProvider().uri().schema()
+
+ if self.taille_line.text() == '':
+ sql_sizefile = """SELECT pg_size_pretty(pg_total_relation_size('""" + schema + '.' + table + """'));"""
+ try:
+ cur.execute(sql_sizefile)
+ boolean = True
+
+ except psycopg2.errors.UndefinedTable:
+ boolean = False
+
+ if boolean is True:
+ size_file = (cur.fetchall())[0][0]
+ else:
+ size_file = ''
+
+ else:
+ size_file = self.taille_line.text()
+
+ self.table_lien.setItem(maxrow, 0, QTableWidgetItem('new_value'))
+ self.table_lien.setItem(maxrow, 1, QTableWidgetItem(self.type_box.currentText()))
+ self.table_lien.setItem(maxrow, 2, QTableWidgetItem(self.url_line.text()))
+ self.table_lien.setItem(maxrow, 3, QTableWidgetItem(self.mime_box.currentText()))
+ self.table_lien.setItem(maxrow, 4, QTableWidgetItem(self.format_box.currentText()))
+ self.table_lien.setItem(maxrow, 5, QTableWidgetItem(str(size_file)))
+
+ global array_link
+ array_link += "('" + table + "', '" + schema + "', '" + self.type_box.currentText() + "', '" + self.url_line.text() + "', '" + self.mime_box.currentText() + "', '" + self.format_box.currentText() + "', '" + size_file + "'),"
+
+ cur.close()
+
+ def add_contact(self):
+ maxrow = self.table_contact.rowCount()
+ self.table_contact.insertRow(maxrow)
+
+ self.table_contact.setItem(maxrow, 0, QTableWidgetItem('new_value'))
+ self.table_contact.setItem(maxrow, 1, QTableWidgetItem(self.role_box.currentText()))
+ self.table_contact.setItem(maxrow, 2, QTableWidgetItem(self.nom_line.text()))
+ self.table_contact.setItem(maxrow, 3, QTableWidgetItem(self.organisation_box.currentText()))
+ self.table_contact.setItem(maxrow, 4, QTableWidgetItem(self.email_line.text()))
+ self.table_contact.setItem(maxrow, 5, QTableWidgetItem(self.telephone_line.text()))
+
+ table = layer.dataProvider().uri().table()
+ schema = layer.dataProvider().uri().schema()
+
+ global array_contact
+ array_contact += "('" + table + "', '" + schema + "', '" + self.role_box.currentText() + "', '" + self.nom_line.text() + "', '" + self.organisation_box.currentText() + "', '" + self.email_line.text() + "', '" + self.telephone_line.text() + "'),"
+
+ def delete_lien(self):
+ fin = ''
+ global uid_delete_list_link, array_link
+ try:
+ lien_uid = self.table_lien.item(self.table_lien.currentRow(), 0).text()
+ except AttributeError:
+ lien_uid = True
+ self.table_lien.removeRow(self.table_lien.currentRow())
+ if lien_uid == 'new_value':
+ position = self.table_lien.currentRow()
+ if position < 0:
+ position = position + 1
+ run_x = 0
+ while position >= run_x:
+ # print(position, run_x)
+ if run_x == 0:
+ debut = array_link.find("(")
+ else:
+ debut = array_link.find("(", fin + 1)
+ fin = array_link.find(")", debut)
+ # print(debut, fin)
+ if run_x == 50:
+ break
+ run_x += 1
+ # print(array_link[fin + 1:])
+ if debut <= 0:
+ debut = 1
+ fin += 1
+ array_link = array_link[:debut - 1] + array_link[fin + 1:]
+ # print('a:', array_link)
+ elif lien_uid is True:
+ print('Pas de ligne "Lien"')
+ else:
+ uid_delete_list_link += "'" + lien_uid + "',"
+
+ def delete_contact(self):
+ fin = ''
+ global uid_delete_list_contact, array_contact
+ try:
+ contact_uid = self.table_contact.item(self.table_contact.currentRow(), 0).text()
+ except AttributeError:
+ contact_uid = True
+ self.table_contact.removeRow(self.table_contact.currentRow())
+ if contact_uid == 'new_value':
+ position = self.table_contact.currentRow()
+ if position < 0:
+ position = position + 1
+ # print('p:', position)
+ run_x = 0
+ while position >= run_x:
+ if run_x == 0:
+ debut = array_contact.find("(")
+ else:
+ debut = array_contact.find("(", fin + 1)
+ fin = array_contact.find(")", debut)
+ # print(debut, fin)
+ if run_x == 50:
+ break
+ run_x += 1
+ # print(array_contact[fin + 1:])
+ if debut <= 0:
+ debut = 1
+ fin += 1
+ array_contact = array_contact[:debut - 1] + array_contact[fin + 1:]
+ # print('a:', array_contact)
+ elif contact_uid is True:
+ print('Pas de ligne "Contact"')
+ else:
+ uid_delete_list_contact += "'" + contact_uid + "',"
+
+ def fletch_ref(self):
+ cur = login_base()
+
+ SQL_categories = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.categories' ORDER BY code, item_order;"""
+ SQL_themes = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.themes' ORDER BY label_fr;"""
+ SQL_langue = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.langue';"""
+ SQL_encodage = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.encodage';"""
+ SQL_frequency = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.publication_frequency' ORDER BY label_fr;"""
+ SQL_confidentiality = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.confidentiality' ORDER BY label_fr;"""
+ SQL_license = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'dataset.license' ORDER BY label_fr;"""
+ SQL_type = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.type' ORDER BY label_fr;"""
+ SQL_mime = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.mime' ORDER BY label_fr;"""
+ SQL_format = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'link.format' ORDER BY label_fr;"""
+ SQL_role = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.contact_role' ORDER BY label_fr;"""
+ SQL_organisation = """SELECT label_fr FROM metadata.glossary WHERE field LIKE 'contact.organisation' ORDER BY label_fr;"""
+
+ cur.execute(SQL_categories)
+ categories_list = cur.fetchall()
+ cur.execute(SQL_themes)
+ themes_list = cur.fetchall()
+ cur.execute(SQL_langue)
+ langue_list = cur.fetchall()
+ cur.execute(SQL_encodage)
+ encodage_list = cur.fetchall()
+
+ cur.execute(SQL_frequency)
+ frequency_list = cur.fetchall()
+ cur.execute(SQL_confidentiality)
+ confidentiality_list = cur.fetchall()
+ cur.execute(SQL_license)
+ license_list = cur.fetchall()
+
+ cur.execute(SQL_type)
+ type_list = cur.fetchall()
+ cur.execute(SQL_mime)
+ mime_list = cur.fetchall()
+ cur.execute(SQL_format)
+ format_list = cur.fetchall()
+ cur.execute(SQL_role)
+ role_list = cur.fetchall()
+ cur.execute(SQL_organisation)
+ organisation_list = cur.fetchall()
+
+ return categories_list, themes_list, langue_list, encodage_list, frequency_list, confidentiality_list, license_list, type_list, mime_list, format_list, role_list, organisation_list
+
+ cur.close()
+
+ def py_import_xml(self):
+ folder = QFileDialog.getOpenFileName()
+ if folder:
+ folder = folder[0]
+ if folder[len(folder) - 4:] == '.xml':
+ print('is .xml')
+
+ # def issues_open(self):
+ # self.issues = CenRa_Issues()
+ # self.issues.show()
diff --git a/CenRa_METABASE/icon.png b/CenRa_METABASE/icon.png
new file mode 100644
index 0000000..d53a910
Binary files /dev/null and b/CenRa_METABASE/icon.png differ
diff --git a/CenRa_METABASE/issues.py b/CenRa_METABASE/issues.py
new file mode 100644
index 0000000..0d6416a
--- /dev/null
+++ b/CenRa_METABASE/issues.py
@@ -0,0 +1,89 @@
+import os
+plugin_dir = os.path.dirname(__file__)
+end_find = plugin_dir.rfind('\\')+1
+
+NAME = plugin_dir[end_find:]
+#print(NAME)
+
+from qgis.gui import *
+
+from qgis.core import (
+ NULL,
+ QgsApplication,
+ QgsDataSourceUri,
+ QgsProject,
+ QgsProviderConnectionException,
+ QgsProviderRegistry,
+ QgsRasterLayer,
+ QgsSettings,
+ QgsVectorLayer,
+ QgsGeometry,
+)
+from qgis.PyQt.QtWidgets import (
+ QDialog,
+ QAction,
+ QDockWidget,
+ QFileDialog,
+ QInputDialog,
+ QMenu,
+ QToolButton,
+ QTableWidget,
+ QTableWidgetItem,
+)
+from qgis.utils import iface
+
+
+from .tools.resources import (
+ load_ui,
+ resources_path,
+ send_issues,
+)
+
+EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
+
+class CenRa_Issues(QDialog, EDITOR_CLASS):
+
+ def __init__(self, parent=None):
+ _ = parent
+ super().__init__()
+ self.setupUi(self)
+ self.settings = QgsSettings()
+
+ #place connect here
+ self.annuler_button.clicked.connect(self.close)
+ self.ok_button.clicked.connect(self.run_sendissues)
+
+ def run_sendissues(self):
+ text_titre = self.titre_line.text()
+ text_message = self.messages_plain.toPlainText()
+ statu_bug = self.check_bug.isChecked()
+ statu_aide = self.check_aide.isChecked()
+ statu_question = self.check_question.isChecked()
+ statu_amelioration = self.check_amelioration.isChecked()
+ statu_autre = self.check_autre.isChecked()
+
+ statu = []
+ if statu_bug == True : statu = statu + [1]
+ if statu_aide == True : statu = statu + [3]
+ if statu_question == True : statu = statu + [5]
+ if statu_amelioration == True : statu = statu + [2]
+ if statu_autre == True : statu = statu + [6]
+
+ if len(statu) >= 1:
+ import qgis
+ url = qgis.utils.pluginMetadata(NAME,'tracker')
+ print(text_message)
+ send_info = send_issues(url,text_titre,text_message,statu)
+ code = send_info.status_code
+ print(code)
+ else:
+ code = 423
+ if code == 201:
+ iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
+ self.close()
+ elif code == 422:
+ iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
+ elif code == 423:
+ iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
+ elif code == 404:
+ iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
diff --git a/CenRa_METABASE/metadata.txt b/CenRa_METABASE/metadata.txt
new file mode 100644
index 0000000..8c689d1
--- /dev/null
+++ b/CenRa_METABASE/metadata.txt
@@ -0,0 +1,49 @@
+# This file contains metadata for your plugin.
+
+# This file should be included when you package your plugin.# Mandatory items:
+
+[general]
+name=CenRa_Metabase
+qgisMinimumVersion=3.0
+supportsQt6=True
+description=CenRa_METABASE
+version=0.3.1
+author=Conservatoire d'Espaces Naturels de Rhône-Alpes
+email=si_besoin@cen-rhonealpes.fr
+
+about=Permet de saisire et de visualisé les information lier à la metadonné d'une couche ce trouvent sur PostgreSQL
+
+repository=https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS
+homepage=https://plateformesig.cenra-outils.org/
+tracker=https://gitea.cenra-outils.org/api/v1/repos/CEN-RA/Plugin_QGIS/issues
+# End of mandatory metadata
+
+# Recommended items:
+
+hasProcessingProvider=no
+# Uncomment the following line and add your changelog:
+changelog=CenRa_METABASE:
30/07/2025 - Version 0.3.1:
- Correctife de bug.
19/05/2025 - Version 0.3.0:
- Compatible PyQt5 et PyQt609/04/2025 - Version 0.2.3:
- Correctif bug en TT.09/04/2025 - Version 0.2.2:
- Optimisation pour le TT.03/04/2025 - Version 0.2.1:
- Mise a jour de securite.07/01/2025 - Version 0.2.0:
- Deployment sur serveur SIG.07/01/2025 - Version 0.1.6:
- ByPass du certif ssl ci erreur19/12/2024 - Version 0.1.5:
- Fix les problem de lenteur qu'en la base est down.12/12/2024 - Version 0.1.4:
- Crash Fix .08/10/2024 - Version 0.1.3:
- Lecture de métadonnée des flux WMS/WFS.07/10/2024 - Version 0.1.2:
- Correctif de bug.03/10/2024 - Version 0.1.1:
- Remonte la fênetre dans la pille.26/08/2024 - Version 0.1.0:
- Lancement du plugin CenRa_Metabase
+
+# Tags are comma separated with spaces allowed
+tags=python
+
+
+category=Plugins
+icon=icon.png
+# experimental flag
+experimental=True
+
+# deprecated flag (applies to the whole plugin, not just a single version)
+deprecated=False
+
+# Since QGIS 3.8, a comma separated list of plugins to be installed
+# (or upgraded) can be specified.
+# Check the documentation for more information.
+# plugin_dependencies=
+
+Category of the plugin: Raster, Vector, Database or Web
+# category=cenra,database,metadata
+
+# If the plugin can run on QGIS Server.
+server=False
+
diff --git a/CenRa_METABASE/tools/css/dock.css b/CenRa_METABASE/tools/css/dock.css
new file mode 100644
index 0000000..f05b850
--- /dev/null
+++ b/CenRa_METABASE/tools/css/dock.css
@@ -0,0 +1,61 @@
+body {
+ font-family: Ubuntu, Lucida Grande, Segoe UI, Arial, sans-serif;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-top: 0px;
+ font-size: 14px;
+}
+img {
+ max-width: 100%;
+}
+img.logo{
+ display: inline-block;
+ margin-left:0px;
+ margin-right: 0px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ vertical-align: top;
+ width:25%
+}
+h2, h3 {
+ color: #fff;
+ background-color: #8cb63c;
+ line-height: 2;
+ padding-left:5px;
+}
+
+table {
+ border-collapse: collapse;
+ width: 100%;
+ font-size: 13px;
+}
+th{
+ color: #2c4491
+}
+table tr th, table tr td {
+ text-align: left;
+ padding: 5px;
+}
+
+table.table-striped {
+ border: 1px solid #BBB;
+}
+table.table-striped tr td {
+ border: 1px solid #BBB;
+}
+table.table-striped tr th {
+ border: 1px solid #BBB;
+}
+table.table-striped tr:nth-child(even) {
+ background: #EEE;
+}
+table.table-striped tr:nth-child(odd) {
+ background: #FFF;
+}
+
+#map {
+ padding: 5px;
+ width: 400px;
+ height: 400px;
+ box-shadow: 0 0 10px #999;
+}
diff --git a/CenRa_METABASE/tools/html/contact.html b/CenRa_METABASE/tools/html/contact.html
new file mode 100644
index 0000000..a6cda01
--- /dev/null
+++ b/CenRa_METABASE/tools/html/contact.html
@@ -0,0 +1,7 @@
+
+ | [% contact_role %] |
+ [% name %] |
+ [% organisation_name %] ([% organisation_unit %]) |
+ [% email %] |
+ [% phone %] |
+
diff --git a/CenRa_METABASE/tools/html/link.html b/CenRa_METABASE/tools/html/link.html
new file mode 100644
index 0000000..cdcdabe
--- /dev/null
+++ b/CenRa_METABASE/tools/html/link.html
@@ -0,0 +1,7 @@
+
+ | [% type %] |
+ [% name %] |
+ [% mime %] |
+ [% format %] |
+ [% size %] |
+
diff --git a/CenRa_METABASE/tools/html/main.html b/CenRa_METABASE/tools/html/main.html
new file mode 100644
index 0000000..f7ff4a0
--- /dev/null
+++ b/CenRa_METABASE/tools/html/main.html
@@ -0,0 +1,123 @@
+
+
Identification
+
+
+ | Title | [% title %] |
+
+
+ | Abstract | [% abstract %] |
+
+
+ | Categories | [% categories %] |
+
+
+ | Themes | [% themes %] |
+
+
+ | Keywords | [% keywords %] |
+
+
+ | Data last update | [% data_last_update %] |
+
+
+
+
+
+
Spatial properties
+
+
+ | Level | [% spatial_level %] |
+
+
+ | Minimum scale | [% minimum_optimal_scale %] |
+
+
+ | Maximum scale | [% maximum_optimal_scale %] |
+
+
+ | Feature count | [% feature_count %] |
+
+
+ | Geometry | [% geometry_type %] |
+
+
+ | Extent | [% spatial_extent %] |
+
+
+ | Projection name | [% projection_name %] |
+
+
+ | Projection ID | [% projection_authid %] |
+
+
+
+
+
+
Publication
+
+
+ | Date | [% publication_date %] |
+
+
+ | Frequency | [% publication_frequency %] |
+
+
+ | License | [% license %] |
+
+
+ | License attribution / number | [% license_attribution %] |
+
+
+ | Confidentiality | [% confidentiality %] |
+
+
+
+
+
+
Links
+
+
+ | Type |
+ Name |
+ MIME |
+ Format |
+ Size |
+
+ [% meta_links %]
+
+
+
+
+
Contacts
+
+
+ | Role |
+ Name |
+ Organisation |
+ Email |
+ Phone |
+
+ [% meta_contacts %]
+
+
+
+
+
Metadata
+
+
+ | Table | [% table_name %] |
+
+
+ | Schema | [% schema_name %] |
+
+
+ | Creation | [% creation_date %] |
+
+
+ | Update | [% update_date %] |
+
+
+ | UUID | [% uid %] |
+
+
+
diff --git a/CenRa_METABASE/tools/icons/CEN_RA.png b/CenRa_METABASE/tools/icons/CEN_RA.png
new file mode 100644
index 0000000..95ead1c
Binary files /dev/null and b/CenRa_METABASE/tools/icons/CEN_RA.png differ
diff --git a/CenRa_METABASE/tools/icons/auto_add.png b/CenRa_METABASE/tools/icons/auto_add.png
new file mode 100644
index 0000000..021f85b
Binary files /dev/null and b/CenRa_METABASE/tools/icons/auto_add.png differ
diff --git a/CenRa_METABASE/tools/icons/icon.png b/CenRa_METABASE/tools/icons/icon.png
new file mode 100644
index 0000000..96a568e
Binary files /dev/null and b/CenRa_METABASE/tools/icons/icon.png differ
diff --git a/CenRa_METABASE/tools/icons/icon_2.png b/CenRa_METABASE/tools/icons/icon_2.png
new file mode 100644
index 0000000..5e21f30
Binary files /dev/null and b/CenRa_METABASE/tools/icons/icon_2.png differ
diff --git a/CenRa_METABASE/tools/images/must_be_a_file.png b/CenRa_METABASE/tools/images/must_be_a_file.png
new file mode 100644
index 0000000..7062995
Binary files /dev/null and b/CenRa_METABASE/tools/images/must_be_a_file.png differ
diff --git a/CenRa_METABASE/tools/resources.py b/CenRa_METABASE/tools/resources.py
new file mode 100644
index 0000000..a37d55b
--- /dev/null
+++ b/CenRa_METABASE/tools/resources.py
@@ -0,0 +1,184 @@
+"""Tools to work with resource files."""
+
+import configparser
+import shutil
+import tempfile
+# import base64
+# import psycopg2
+# import psycopg2.extras
+import os
+from os.path import abspath, join, pardir, dirname
+
+from qgis.PyQt import uic
+
+__copyright__ = "Copyright 2019, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+__revision__ = "$Format:%H$"
+
+
+def plugin_path(*args):
+ """Get the path to plugin root folder.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Absolute path to the plugin path.
+ :rtype: str
+ """
+ path = dirname(dirname(__file__))
+ path = abspath(abspath(join(path, pardir)))
+ for item in args:
+ path = abspath(join(path, item))
+
+ return path
+
+
+def plugin_name():
+ """Return the plugin name according to metadata.txt.
+
+ :return: The plugin name.
+ :rtype: basestring
+ """
+ metadata = metadata_config()
+ name = metadata["general"]["name"]
+ return name
+
+
+def metadata_config() -> configparser:
+ """Get the INI config parser for the metadata file.
+
+ :return: The config parser object.
+ :rtype: ConfigParser
+ """
+ path = plugin_path("metadata.txt")
+ config = configparser.ConfigParser()
+ config.read(path, encoding='utf8')
+ return config
+
+
+def plugin_test_data_path(*args, copy=False):
+ """Get the path to the plugin test data path.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :param copy: If the file must be copied into a temporary directory first.
+ :type copy: bool
+
+ :return: Absolute path to the resources folder.
+ :rtype: str
+ """
+ path = abspath(abspath(join(plugin_path(), "test", "data")))
+ for item in args:
+ path = abspath(join(path, item))
+
+ if copy:
+ temp = tempfile.mkdtemp()
+ shutil.copy(path, temp)
+ return join(temp, args[-1])
+ else:
+ return path
+
+
+def resources_path(*args):
+ """Get the path to our resources folder.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Absolute path to the resources folder.
+ :rtype: str
+ """
+ path = abspath(abspath(join(plugin_path(), "CenRa_METABASE\\tools")))
+ for item in args:
+ path = abspath(join(path, item))
+ return path
+
+
+def load_ui(*args):
+ """Get compile UI file.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Compiled UI file.
+ """
+ ui_class, _ = uic.loadUiType(resources_path("ui", *args))
+
+ return ui_class
+
+
+def pyperclip():
+ dst = dirname(dirname(__file__)) + "\\tools\\"
+ if os.access('N:/', os.R_OK):
+ src = 'N:/SI_Systeme d information/Z_QGIS/PLUGIN/PythonSQL.py'
+ try:
+ shutil.copy(src, dst)
+ except FileNotFoundError:
+ print('404')
+ except UnboundLocalError:
+ print('404')
+
+
+def send_issues(url, titre, body, labels):
+ import requests
+ import urllib.request
+ import json
+ # import os
+ # import qgis
+
+ # usr = os.environ['USERNAME']
+ token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
+ url = url + '?token=' + token
+
+ headers = {'Authorization': 'token ' + token, 'accept': 'application/json', 'Content-Type': 'application/json'}
+
+ payload = {'title': titre, 'body': body, 'labels': labels}
+ try:
+ urllib.request.urlopen('https://google.com')
+ binar = True
+ except ValueError:
+ binar = False
+ r = ''
+ if binar:
+ r = requests.post(url, data=json.dumps(payload), headers=headers)
+ return r
+
+
+def maj_verif(NAME):
+ import qgis
+ import urllib.request
+ iface = qgis.utils.iface
+ from qgis.core import Qgis
+
+ # url = qgis.utils.pluginMetadata(NAME, 'repository')
+ # URL = url+'/raw/branch/main/plugins.xml'
+ URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
+ # print(URL)
+ version = qgis.utils.pluginMetadata(NAME, 'version')
+ len_version = len(version)
+ try:
+ urllib.request.urlopen('https://google.com')
+ binar = True
+ except urllib.error.URLError:
+ binar = False
+ if binar:
+ try:
+ version_web = str(urllib.request.urlopen(URL).read())
+ plugin_num = version_web.find(NAME)
+ valeur_version_web = version_web.find('', plugin_num) + 9
+ version_plugin = version_web[valeur_version_web:valeur_version_web + len_version]
+ if version_plugin != version:
+ iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
+ except urllib.error.URLError:
+ print("error gitea version ssl")
+ else:
+ iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
+
+
+def devlog(NAME):
+ import qgis
+ devmaj = ''
+ devmaj = devmaj + qgis.utils.pluginMetadata(NAME, 'changelog')
+ return devmaj
diff --git a/CenRa_METABASE/tools/ui/CenRa_IssuesSend.ui b/CenRa_METABASE/tools/ui/CenRa_IssuesSend.ui
new file mode 100644
index 0000000..14d923e
--- /dev/null
+++ b/CenRa_METABASE/tools/ui/CenRa_IssuesSend.ui
@@ -0,0 +1,332 @@
+
+
+ CenRa_IssuesSend
+
+
+
+ 0
+ 0
+ 810
+ 587
+
+
+
+ CEN-RA Metabase
+
+
+
+ icon.svgicon.svg
+
+
+
+
+ 0
+ 550
+ 811
+ 31
+
+
+
+ -
+
+
+ Annuler
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Envoyer
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 791
+ 531
+
+
+
+ Issues
+
+
+
+
+ 240
+ 40
+ 321
+ 41
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 10
+ 101
+ 571
+ 421
+
+
+
+
+
+
+ 589
+ 100
+ 191
+ 431
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 9
+ 9
+ 341
+ 411
+
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Bug
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Aide
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Question
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Amélioration
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Autre
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+ 250
+ 20
+ 51
+ 21
+
+
+
+
+ Arial
+ 14
+
+
+
+ Titre:
+
+
+
+
+
+ 20
+ 70
+ 91
+ 31
+
+
+
+
+ Arial
+ 12
+
+
+
+ Messages:
+
+
+
+
+
+ 600
+ 70
+ 91
+ 31
+
+
+
+
+ Arial
+ 12
+
+
+
+ Sujet:
+
+
+
+
+
+ ok_button
+ annuler_button
+
+
+
+
diff --git a/CenRa_METABASE/tools/ui/CenRa_Metabase_dockwidget_base.ui b/CenRa_METABASE/tools/ui/CenRa_Metabase_dockwidget_base.ui
new file mode 100644
index 0000000..78010ec
--- /dev/null
+++ b/CenRa_METABASE/tools/ui/CenRa_Metabase_dockwidget_base.ui
@@ -0,0 +1,74 @@
+
+
+ CenRa_MetabaseDockWidgetBase
+
+
+
+ 0
+ 0
+ 329
+ 515
+
+
+
+ CenRa MetaBase
+
+
+
+ -
+
+
-
+
+
+ ...
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ ...
+
+
+ Qt::NoArrow
+
+
+
+ -
+
+
+ ...
+
+
+
+ -
+
+
+ help
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/CenRa_METABASE/tools/ui/CenRa_Metabase_editorwidget_base.ui b/CenRa_METABASE/tools/ui/CenRa_Metabase_editorwidget_base.ui
new file mode 100644
index 0000000..ac91920
--- /dev/null
+++ b/CenRa_METABASE/tools/ui/CenRa_Metabase_editorwidget_base.ui
@@ -0,0 +1,1946 @@
+
+
+ CenRa_Metabase_editorwidget_base
+
+
+
+ 0
+ 0
+ 818
+ 741
+
+
+
+ CEN-RA Metabase
+
+
+
+ icon.svgicon.svg
+
+
+
+
+ 0
+ 0
+ 821
+ 711
+
+
+
+
+ Myriad Pro Black
+ 10
+ 75
+ false
+ true
+
+
+
+ Qt::DefaultContextMenu
+
+
+ Qt::LeftToRight
+
+
+ false
+
+
+ QTabWidget::North
+
+
+ QTabWidget::Rounded
+
+
+ 0
+
+
+
+ 40
+ 40
+
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+ Identification
+
+
+
+
+ 30
+ 110
+ 751
+ 99
+
+
+
+ -
+
+
+ Description
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Myriad Pro Black'; font-size:10pt; font-weight:600; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400;"><br /></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400;"><br /></p></body></html>
+
+
+
+
+
+
+
+
+ 30
+ 220
+ 751
+ 101
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ Categories :
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectItems
+
+
+
+
+
+
+
+
+ 30
+ 330
+ 751
+ 101
+
+
+
+ -
+
+
+ Thèmes :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+
+
+
+
+
+ 30
+ 440
+ 751
+ 101
+
+
+
+ -
+
+
+ -
+
+
+ Mots-clés :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 30
+ 550
+ 751
+ 51
+
+
+
+ -
+
+
+ Dernier mise à jour :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractSpinBox::NoButtons
+
+
+
+ 2024
+ 12
+ 24
+
+
+
+ QDateTimeEdit::MonthSection
+
+
+ dd/MM/yyyy
+
+
+ true
+
+
+ 1
+
+
+ Qt::UTC
+
+
+
+
+
+
+
+
+ 30
+ 30
+ 751
+ 61
+
+
+
+ -
+
+
+ -
+
+
+ Titre :
+
+
+
+
+
+
+
+
+ 30
+ 620
+ 751
+ 51
+
+
+
+ -
+
+
+ Langue :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ Spatial properties
+
+
+
+
+ 220
+ 20
+ 540
+ 39
+
+
+
+
+
+
+ 34
+ 20
+ 170
+ 39
+
+
+
+ Niveau :
+
+
+
+
+
+ 34
+ 70
+ 170
+ 39
+
+
+
+ Echelle minimum :
+
+
+
+
+
+ 220
+ 70
+ 540
+ 39
+
+
+
+
+
+
+ 34
+ 120
+ 170
+ 39
+
+
+
+ Echelle maximum :
+
+
+
+
+
+ 220
+ 120
+ 540
+ 39
+
+
+
+
+
+
+ 34
+ 170
+ 170
+ 39
+
+
+
+ Nombre d'entités :
+
+
+
+
+ false
+
+
+
+ 220
+ 170
+ 540
+ 39
+
+
+
+
+
+
+ 34
+ 220
+ 170
+ 39
+
+
+
+ Type de géométrie :
+
+
+
+
+ false
+
+
+
+ 220
+ 220
+ 540
+ 39
+
+
+
+
+
+ false
+
+
+
+ 220
+ 320
+ 540
+ 39
+
+
+
+
+
+
+ 34
+ 270
+ 170
+ 39
+
+
+
+ Nom de projection :
+
+
+
+
+
+ 34
+ 370
+ 170
+ 39
+
+
+
+ Emprise :
+
+
+
+
+
+ 34
+ 320
+ 170
+ 39
+
+
+
+ ID de projection :
+
+
+
+
+ false
+
+
+
+ 220
+ 270
+ 540
+ 39
+
+
+
+
+
+ false
+
+
+
+ 221
+ 370
+ 540
+ 39
+
+
+
+
+
+
+ Publication
+
+
+
+
+ 30
+ 390
+ 751
+ 61
+
+
+
+ -
+
+
+ Restriction :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 30
+ 210
+ 751
+ 61
+
+
+
+ -
+
+
+ Licence :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 30
+ 30
+ 751
+ 61
+
+
+
+ -
+
+
+ Date :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractSpinBox::NoButtons
+
+
+
+ 2024
+ 12
+ 22
+
+
+
+ QDateTimeEdit::MonthSection
+
+
+ dd/MM/yyyy
+
+
+ true
+
+
+ 1
+
+
+ Qt::UTC
+
+
+
+
+
+
+
+
+ 30
+ 300
+ 751
+ 61
+
+
+
+ -
+
+
+ Licence attribué :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 30
+ 120
+ 751
+ 61
+
+
+
+ -
+
+
+ Fréquence de mise à jour :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ Lien
+
+
+
+
+ 10
+ 120
+ 791
+ 511
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+
+
+
+
+
+ 20
+ 20
+ 771
+ 61
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+ -
+
+
+ Taille :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Type :
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ URL :
+
+
+
+ -
+
+
+ Type MIME :
+
+
+
+ -
+
+
+ Format :
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Ajouter
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+ 10
+ 640
+ 791
+ 31
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Delete
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 10
+ 90
+ 790
+ 3
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 20
+ 790
+ 3
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 20
+ 3
+ 70
+
+
+
+ Qt::Vertical
+
+
+
+
+
+ 800
+ 20
+ 3
+ 70
+
+
+
+ Qt::Vertical
+
+
+
+
+
+ Contacts
+
+
+
+
+ 20
+ 20
+ 771
+ 61
+
+
+
+ -
+
+
+ Nom :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ Ajouter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Email :
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Organisation :
+
+
+
+ -
+
+
+ Telephone
+
+
+
+ -
+
+
+ Rôle :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+ 10
+ 120
+ 791
+ 511
+
+
+
+ -
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+
+
+
+
+
+ 10
+ 640
+ 791
+ 31
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Delete
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+ 800
+ 20
+ 3
+ 70
+
+
+
+ Qt::Vertical
+
+
+
+
+
+ 10
+ 20
+ 790
+ 3
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 90
+ 790
+ 3
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ 10
+ 20
+ 3
+ 70
+
+
+
+ Qt::Vertical
+
+
+
+
+
+ Metadata
+
+
+
+
+ 30
+ 30
+ 751
+ 61
+
+
+
+ -
+
+
+ Table :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
+
+ 30
+ 300
+ 751
+ 61
+
+
+
+ -
+
+
+ Date de modification :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractSpinBox::NoButtons
+
+
+
+ 2024
+ 12
+ 23
+
+
+
+ QDateTimeEdit::MonthSection
+
+
+ dd/MM/yyyy
+
+
+ true
+
+
+ 1
+
+
+ Qt::UTC
+
+
+
+
+
+
+
+
+ 30
+ 390
+ 751
+ 61
+
+
+
+ -
+
+
+ Encodage :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+
+
+
+
+ 30
+ 210
+ 751
+ 61
+
+
+
+ -
+
+
+ Date de création :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractSpinBox::NoButtons
+
+
+
+ 2024
+ 12
+ 23
+
+
+
+ QDateTimeEdit::MonthSection
+
+
+ dd/MM/yyyy
+
+
+ true
+
+
+ 1
+
+
+ Qt::UTC
+
+
+
+
+
+
+
+
+ 30
+ 120
+ 751
+ 61
+
+
+
+ -
+
+
+ Schema :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
+
+ 30
+ 480
+ 751
+ 61
+
+
+
+ -
+
+
+ UUID :
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ 0
+ 710
+ 821
+ 31
+
+
+
+ -
+
+
+ Annuler
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ OK
+
+
+
+
+
+
+
+
+ 780
+ 20
+ 25
+ 19
+
+
+
+ ...
+
+
+
+ 32
+ 32
+
+
+
+ Qt::NoArrow
+
+
+
+
+
+ 780
+ 2
+ 25
+ 19
+
+
+
+ ...
+
+
+
+ 32
+ 32
+
+
+
+ Qt::NoArrow
+
+
+
+
+ true
+
+
+
+ 550
+ 10
+ 41
+ 41
+
+
+
+ ...
+
+
+
+ 32
+ 32
+
+
+
+ Qt::NoArrow
+
+
+
+
+ titre_line
+ description_text
+ ok_button
+ annuler_button
+ tabWidget
+ langue_box
+ niveau_plain
+ echelle_min_plain
+ echelle_max_plain
+ nbr_layers
+ typegeom_plaintext
+ crscode_plaintext
+ crsname_plaintext
+ extend_plaintext
+ restriction_box
+ licence_box
+ licence_attrib_box
+ frequence_box
+ table_lien
+ add_lien_button
+ format_box
+ mime_box
+ type_box
+ delete_lien_button
+ organisation_box
+ add_contact_button
+ role_box
+ table_contact
+ delete_contact_button
+ table_ligne
+ encodage_box
+ schema_ligne
+ uuid_ligne
+ mots_cles_text
+
+
+
+
diff --git a/CenRa_METABASE/tools/ui/CenRa_about_form.ui b/CenRa_METABASE/tools/ui/CenRa_about_form.ui
new file mode 100644
index 0000000..6ec4843
--- /dev/null
+++ b/CenRa_METABASE/tools/ui/CenRa_about_form.ui
@@ -0,0 +1,81 @@
+
+
+ CenRa_Metabase_editorwidget_base
+
+
+
+ 0
+ 0
+ 471
+ 594
+
+
+
+ Journal des modifications
+
+
+
+ ../../CenRa_Metabase/tools/ui/icon.svg../../CenRa_Metabase/tools/ui/icon.svg
+
+
+ -
+
+
+ true
+
+
+ Qt::NoFocus
+
+
+ QFrame::NoFrame
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 453
+ 570
+
+
+
+
+
+ 0
+ 0
+ 451
+ 541
+
+
+
+ DevLog
+
+
+
+
+ 10
+ 20
+ 431
+ 511
+
+
+
+
+
+
+
+ -
+
+
+ QDialogButtonBox::NoButton
+
+
+
+
+
+
+
+
diff --git a/CenRa_METABASE/tools/xml/dcat.xml b/CenRa_METABASE/tools/xml/dcat.xml
new file mode 100644
index 0000000..852508d
--- /dev/null
+++ b/CenRa_METABASE/tools/xml/dcat.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ CEN-RA DCAT RDF catalog
+ {language}
+ CEN-RA Metadata
+
+
+
+ {content}
+
+
+
+
+
+
diff --git a/CenRa_METABASE/tools/xml/distribution.xml b/CenRa_METABASE/tools/xml/distribution.xml
new file mode 100644
index 0000000..2ff86b0
--- /dev/null
+++ b/CenRa_METABASE/tools/xml/distribution.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CenRa_METABASE/tools/xml/publisher.xml b/CenRa_METABASE/tools/xml/publisher.xml
new file mode 100644
index 0000000..1cda931
--- /dev/null
+++ b/CenRa_METABASE/tools/xml/publisher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CenRa_PAGERENDER/CenRa_PageRender.py b/CenRa_PAGERENDER/CenRa_PageRender.py
new file mode 100644
index 0000000..46e9d24
--- /dev/null
+++ b/CenRa_PAGERENDER/CenRa_PageRender.py
@@ -0,0 +1,141 @@
+__copyright__ = "Copyright 2021, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+
+
+from qgis.core import QgsApplication
+from qgis.PyQt.QtCore import QUrl, QSettings
+from qgis.PyQt.QtGui import QDesktopServices, QIcon
+from qgis.PyQt.QtWidgets import QAction
+from qgis.utils import iface
+import qgis
+
+
+# include
+'''
+from pg_metadata.connection_manager import (
+ store_connections,
+ validate_connections_names,
+)
+
+
+from pg_metadata.locator import LocatorFilter
+from pg_metadata.processing.provider import PgMetadataProvider
+from pg_metadata.qgis_plugin_tools.tools.custom_logging import setup_logger
+'''
+import os
+from .tools.resources import (
+ # plugin_path,
+ resources_path,
+ maj_verif,
+)
+from .canvas_editor import PageRender_Editor
+from .about_form import AboutDialog
+
+
+class PgPageRender:
+ def __init__(self):
+ """ Constructor. """
+ self.canvas_editor = None
+# self.issues = None
+ self.provider = None
+ self.locator_filter = None
+ self.dock_action = None
+ self.help_action = None
+ plugin_dir = os.path.dirname(__file__)
+ end_find = plugin_dir.rfind('\\') + 1
+ global NAME
+ NAME = plugin_dir[end_find:]
+ maj_verif(NAME)
+
+ # Display About window on first use
+ version = qgis.utils.pluginMetadata('CenRa_PAGERENDER', 'version')
+ s = QSettings()
+ versionUse = s.value("pagerender/version", 1, type=str)
+ if str(versionUse) != str(version):
+ s.setValue("pagerender/version", str(version))
+ print(versionUse, version)
+ self.open_about_dialog()
+
+ def initGui(self):
+ """ Build the plugin GUI. """
+
+ self.toolBar = iface.addToolBar("CenRa_PAGERENDER")
+ self.toolBar.setObjectName("CenRa_PAGERENDER")
+
+ icon = QIcon(resources_path('icons', 'icon.png'))
+
+ # Open the online help
+ self.help_action = QAction(icon, 'CenRa_PAGERENDER', iface.mainWindow())
+ iface.pluginHelpMenu().addAction(self.help_action)
+ self.help_action.triggered.connect(self.open_help)
+ if not self.canvas_editor:
+ self.canvas_editor = PageRender_Editor()
+
+ self.pagerender_action = QAction(icon, 'CenRa_PAGERENDER', None)
+ self.toolBar.addAction(self.pagerender_action)
+ self.pagerender_action.triggered.connect(self.open_editor)
+ '''
+ if not self.locator_filter:
+ self.locator_filter = LocatorFilter(iface)
+ iface.registerLocatorFilter(self.locator_filter)
+
+ @staticmethod
+ def check_invalid_connection_names():
+ """ Check for invalid connection names in the QgsSettings. """
+ valid, invalid = validate_connections_names()
+ n_invalid = len(invalid)
+
+ if n_invalid == 0:
+ return
+
+ invalid_text = ', '.join(invalid)
+ msg = QMessageBox()
+ msg.setIcon(QMessageBox.Warning)
+ msg.setWindowTitle(tr('PgMetadata: Database connection(s) not available'))
+ msg.setText(tr(
+ f'{n_invalid} connection(s) listed in PgMetadata’s settings are invalid or '
+ f'no longer available: {invalid_text}'))
+ msg.setInformativeText(tr(
+ 'Do you want to remove these connection(s) from the PgMetadata settings? '
+ '(You can also do this later with the “Set Connections” tool.)'))
+ msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
+ clicked = msg.exec()
+
+ if clicked == QMessageBox.Yes:
+ iface.messageBar().pushSuccess('PgMetadata', tr(f'{n_invalid} invalid connection(s) removed.'))
+ store_connections(valid)
+ if clicked == QMessageBox.No:
+ iface.messageBar().pushInfo('PgMetadata', tr(f'Keeping {n_invalid} invalid connections.'))
+ '''
+ def open_about_dialog(self):
+ """
+ About dialog
+ """
+ dialog = AboutDialog(iface)
+ dialog.exec()
+
+ def open_help():
+ """ Open the online help. """
+ QDesktopServices.openUrl(QUrl('https://plateformesig.cenra-outils.org/'))
+
+ def open_editor(self):
+ self.canvas_editor.show()
+ self.canvas_editor.raise_()
+
+ def unload(self):
+ """ Unload the plugin. """
+ if self.canvas_editor:
+ iface.removePluginMenu('CenRa_PAGERENDER', self.pagerender_action)
+
+ if self.provider:
+ QgsApplication.processingRegistry().removeProvider(self.provider)
+ del self.provider
+
+ if self.locator_filter:
+ iface.deregisterLocatorFilter(self.locator_filter)
+ del self.locator_filter
+
+ if self.help_action:
+ iface.pluginHelpMenu().removeAction(self.help_action)
+ del self.help_action
diff --git a/CenRa_PAGERENDER/README.md b/CenRa_PAGERENDER/README.md
new file mode 100644
index 0000000..80ccffe
--- /dev/null
+++ b/CenRa_PAGERENDER/README.md
@@ -0,0 +1 @@
+# CenRa_AutoMap
\ No newline at end of file
diff --git a/CenRa_PAGERENDER/__init__.py b/CenRa_PAGERENDER/__init__.py
new file mode 100644
index 0000000..365e090
--- /dev/null
+++ b/CenRa_PAGERENDER/__init__.py
@@ -0,0 +1,10 @@
+__copyright__ = "Copyright 2021, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+
+
+# noinspection PyPep8Naming
+def classFactory(iface): # pylint: disable=invalid-name
+ _ = iface
+ from CenRa_PAGERENDER.CenRa_PageRender import PgPageRender
+ return PgPageRender()
diff --git a/CenRa_PAGERENDER/about_form.py b/CenRa_PAGERENDER/about_form.py
new file mode 100644
index 0000000..8828a44
--- /dev/null
+++ b/CenRa_PAGERENDER/about_form.py
@@ -0,0 +1,46 @@
+import os.path
+
+from pathlib import Path
+
+from qgis.PyQt import uic
+# from qgis.PyQt.QtGui import QPixmap
+from qgis.PyQt.QtWidgets import QDialog
+
+from .tools.resources import devlog
+
+ABOUT_FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(
+ str(Path(__file__).resolve().parent),
+ 'tools/ui',
+ 'CenRa_about_form.ui'
+ )
+)
+
+
+class AboutDialog(QDialog, ABOUT_FORM_CLASS):
+
+ """ About - Let the user display the about dialog. """
+
+ def __init__(self, iface, parent=None):
+ super().__init__(parent)
+ self.iface = iface
+ self.setupUi(self)
+
+ self.viewer.setHtml(devlog('CenRa_PAGERENDER'))
+
+ self.rejected.connect(self.onReject)
+ self.buttonBox.rejected.connect(self.onReject)
+ self.buttonBox.accepted.connect(self.onAccept)
+
+ def onAccept(self):
+ """
+ Save options when pressing OK button
+ """
+ self.accept()
+
+ def onReject(self):
+ """
+ Run some actions when
+ the user closes the dialog
+ """
+ self.close()
diff --git a/CenRa_PAGERENDER/canvas_editor.py b/CenRa_PAGERENDER/canvas_editor.py
index 01fb22e..66bba0e 100644
--- a/CenRa_PAGERENDER/canvas_editor.py
+++ b/CenRa_PAGERENDER/canvas_editor.py
@@ -11,7 +11,6 @@ from qgis.core import QgsSettings
from qgis.PyQt.QtCore import Qt
# from qgis.PyQt.QtPrintSupport import QPrinter
# from qgis.PyQt.QtWebKitWidgets import QWebPage
-# test de push
from qgis.PyQt.QtWidgets import (
QDialog,
QFileDialog,
diff --git a/CenRa_PAGERENDER/demoV2.py b/CenRa_PAGERENDER/demoV2.py
new file mode 100644
index 0000000..df678af
--- /dev/null
+++ b/CenRa_PAGERENDER/demoV2.py
@@ -0,0 +1,169 @@
+
+from qgis.core import (
+ QgsLayoutSize,
+ QgsUnitTypes,
+ QgsLayoutPoint,
+)
+
+
+def fletch_canvas(self):
+ if self.radioButton_6.isChecked():
+ values_page = 'A4'
+ else:
+ values_page = 'A3'
+ if self.radioButton_7.isChecked():
+ page_rotate = 'Portrait'
+ else:
+ page_rotate = 'Landscape'
+
+ if page_rotate == 'Portrait':
+ if values_page == 'A4':
+ self.template_parameters['Carte_size'] = QgsLayoutSize(200.0, 200, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_locals'] = QgsLayoutPoint(6, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_rotate'] = 0
+ self.template_parameters['Carte_2_size'] = QgsLayoutSize(85.71428571428571, 69, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(209, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_rotate'] = 0
+ self.template_parameters['Legande_size'] = QgsLayoutSize(85.71428571428571, 131, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_locals'] = QgsLayoutPoint(209, 74, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_rotate'] = 0
+ self.template_parameters['Arrow_size'] = QgsLayoutSize(14.285714285714286, 14, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_locals'] = QgsLayoutPoint(189, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_rotate'] = 0
+ self.template_parameters['Echelle_size'] = QgsLayoutSize(51.42857142857143, 7, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_locals'] = QgsLayoutPoint(9, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_rotate'] = 0
+ self.template_parameters['Logo_size'] = QgsLayoutSize(45.714285714285715, 11, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_locals'] = QgsLayoutPoint(3, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_rotate'] = 0
+ self.template_parameters['Titre_size'] = QgsLayoutSize(154.28571428571428, 11, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_locals'] = QgsLayoutPoint(51, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_rotate'] = 0
+ self.template_parameters['Credit_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_locals'] = QgsLayoutPoint(151, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_rotate'] = 0
+ self.template_parameters['Source_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_locals'] = QgsLayoutPoint(229, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_rotate'] = 0
+ self.template_parameters['Sous_titre_size'] = QgsLayoutSize(125.71428571428571, 14, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(60, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_rotate'] = 0
+ self.template_parameters['Echelle_2_size'] = QgsLayoutSize(51.42857142857143, 13, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(9, 184, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_rotate'] = 0
+ self.template_parameters['Logo_2_size'] = QgsLayoutSize(28.571428571428573, 29, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(9, 151, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_rotate'] = 0
+ if values_page == 'A3':
+ self.template_parameters['Carte_size'] = QgsLayoutSize(282, 282, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_locals'] = QgsLayoutPoint(8, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_rotate'] = 0
+ self.template_parameters['Carte_2_size'] = QgsLayoutSize(121, 97, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(294, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_rotate'] = 0
+ self.template_parameters['Legande_size'] = QgsLayoutSize(121, 185, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_locals'] = QgsLayoutPoint(294, 105, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_rotate'] = 0
+ self.template_parameters['Arrow_size'] = QgsLayoutSize(20, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_locals'] = QgsLayoutPoint(266, 28, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_rotate'] = 0
+ self.template_parameters['Echelle_size'] = QgsLayoutSize(73, 10, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_locals'] = QgsLayoutPoint(12, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_rotate'] = 0
+ self.template_parameters['Logo_size'] = QgsLayoutSize(64, 16, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_locals'] = QgsLayoutPoint(4, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_rotate'] = 0
+ self.template_parameters['Titre_size'] = QgsLayoutSize(218, 16, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_locals'] = QgsLayoutPoint(73, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_rotate'] = 0
+ self.template_parameters['Credit_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_locals'] = QgsLayoutPoint(214, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_rotate'] = 0
+ self.template_parameters['Source_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_locals'] = QgsLayoutPoint(322, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_rotate'] = 0
+ self.template_parameters['Sous_titre_size'] = QgsLayoutSize(177, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(85, 28, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_rotate'] = 0
+ self.template_parameters['Echelle_2_size'] = QgsLayoutSize(73, 18, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(12, 260, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_rotate'] = 0
+ self.template_parameters['Logo_2_size'] = QgsLayoutSize(40, 40, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(12, 214, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_rotate'] = 0
+ if page_rotate == 'Landscape':
+ if values_page == 'A4':
+ self.template_parameters['Carte_size'] = QgsLayoutSize(200.0, 200, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_locals'] = QgsLayoutPoint(6, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_rotate'] = 0
+ self.template_parameters['Carte_2_size'] = QgsLayoutSize(85.71428571428571, 69, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(209, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_rotate'] = 0
+ self.template_parameters['Legande_size'] = QgsLayoutSize(85.71428571428571, 131, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_locals'] = QgsLayoutPoint(209, 74, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_rotate'] = 0
+ self.template_parameters['Arrow_size'] = QgsLayoutSize(14.285714285714286, 14, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_locals'] = QgsLayoutPoint(189, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_rotate'] = 0
+ self.template_parameters['Echelle_size'] = QgsLayoutSize(51.42857142857143, 7, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_locals'] = QgsLayoutPoint(9, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_rotate'] = 0
+ self.template_parameters['Logo_size'] = QgsLayoutSize(45.714285714285715, 11, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_locals'] = QgsLayoutPoint(3, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_rotate'] = 0
+ self.template_parameters['Titre_size'] = QgsLayoutSize(154.28571428571428, 11, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_locals'] = QgsLayoutPoint(51, 3, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_rotate'] = 0
+ self.template_parameters['Credit_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_locals'] = QgsLayoutPoint(151, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_rotate'] = 0
+ self.template_parameters['Source_size'] = QgsLayoutSize(51.42857142857143, 6, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_locals'] = QgsLayoutPoint(229, 197, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_rotate'] = 0
+ self.template_parameters['Sous_titre_size'] = QgsLayoutSize(125.71428571428571, 14, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(60, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_rotate'] = 0
+ self.template_parameters['Echelle_2_size'] = QgsLayoutSize(51.42857142857143, 13, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(9, 184, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_rotate'] = 0
+ self.template_parameters['Logo_2_size'] = QgsLayoutSize(28.571428571428573, 29, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(9, 151, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_rotate'] = 0
+ if values_page == 'A3':
+ self.template_parameters['Carte_size'] = QgsLayoutSize(282, 282, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_locals'] = QgsLayoutPoint(8, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_rotate'] = 0
+ self.template_parameters['Carte_2_size'] = QgsLayoutSize(121, 97, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_locals'] = QgsLayoutPoint(294, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Carte_2_rotate'] = 0
+ self.template_parameters['Legande_size'] = QgsLayoutSize(121, 185, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_locals'] = QgsLayoutPoint(294, 105, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Legande_rotate'] = 0
+ self.template_parameters['Arrow_size'] = QgsLayoutSize(20, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_locals'] = QgsLayoutPoint(266, 28, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Arrow_rotate'] = 0
+ self.template_parameters['Echelle_size'] = QgsLayoutSize(73, 10, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_locals'] = QgsLayoutPoint(12, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_rotate'] = 0
+ self.template_parameters['Logo_size'] = QgsLayoutSize(64, 16, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_locals'] = QgsLayoutPoint(4, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_rotate'] = 0
+ self.template_parameters['Titre_size'] = QgsLayoutSize(218, 16, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_locals'] = QgsLayoutPoint(73, 4, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Titre_rotate'] = 0
+ self.template_parameters['Credit_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_locals'] = QgsLayoutPoint(214, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Credit_rotate'] = 0
+ self.template_parameters['Source_size'] = QgsLayoutSize(73, 8, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_locals'] = QgsLayoutPoint(322, 278, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Source_rotate'] = 0
+ self.template_parameters['Sous_titre_size'] = QgsLayoutSize(177, 20, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_locals'] = QgsLayoutPoint(85, 28, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Sous_titre_rotate'] = 0
+ self.template_parameters['Echelle_2_size'] = QgsLayoutSize(73, 18, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_locals'] = QgsLayoutPoint(12, 260, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Echelle_2_rotate'] = 0
+ self.template_parameters['Logo_2_size'] = QgsLayoutSize(40, 40, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_locals'] = QgsLayoutPoint(12, 214, QgsUnitTypes.LayoutMillimeters)
+ self.template_parameters['Logo_2_rotate'] = 0
+ return self.template_parameters
diff --git a/CenRa_PAGERENDER/icon.png b/CenRa_PAGERENDER/icon.png
new file mode 100644
index 0000000..d53a910
Binary files /dev/null and b/CenRa_PAGERENDER/icon.png differ
diff --git a/CenRa_PAGERENDER/issues.py b/CenRa_PAGERENDER/issues.py
new file mode 100644
index 0000000..0d6416a
--- /dev/null
+++ b/CenRa_PAGERENDER/issues.py
@@ -0,0 +1,89 @@
+import os
+plugin_dir = os.path.dirname(__file__)
+end_find = plugin_dir.rfind('\\')+1
+
+NAME = plugin_dir[end_find:]
+#print(NAME)
+
+from qgis.gui import *
+
+from qgis.core import (
+ NULL,
+ QgsApplication,
+ QgsDataSourceUri,
+ QgsProject,
+ QgsProviderConnectionException,
+ QgsProviderRegistry,
+ QgsRasterLayer,
+ QgsSettings,
+ QgsVectorLayer,
+ QgsGeometry,
+)
+from qgis.PyQt.QtWidgets import (
+ QDialog,
+ QAction,
+ QDockWidget,
+ QFileDialog,
+ QInputDialog,
+ QMenu,
+ QToolButton,
+ QTableWidget,
+ QTableWidgetItem,
+)
+from qgis.utils import iface
+
+
+from .tools.resources import (
+ load_ui,
+ resources_path,
+ send_issues,
+)
+
+EDITOR_CLASS = load_ui('CenRa_IssuesSend.ui')
+
+class CenRa_Issues(QDialog, EDITOR_CLASS):
+
+ def __init__(self, parent=None):
+ _ = parent
+ super().__init__()
+ self.setupUi(self)
+ self.settings = QgsSettings()
+
+ #place connect here
+ self.annuler_button.clicked.connect(self.close)
+ self.ok_button.clicked.connect(self.run_sendissues)
+
+ def run_sendissues(self):
+ text_titre = self.titre_line.text()
+ text_message = self.messages_plain.toPlainText()
+ statu_bug = self.check_bug.isChecked()
+ statu_aide = self.check_aide.isChecked()
+ statu_question = self.check_question.isChecked()
+ statu_amelioration = self.check_amelioration.isChecked()
+ statu_autre = self.check_autre.isChecked()
+
+ statu = []
+ if statu_bug == True : statu = statu + [1]
+ if statu_aide == True : statu = statu + [3]
+ if statu_question == True : statu = statu + [5]
+ if statu_amelioration == True : statu = statu + [2]
+ if statu_autre == True : statu = statu + [6]
+
+ if len(statu) >= 1:
+ import qgis
+ url = qgis.utils.pluginMetadata(NAME,'tracker')
+ print(text_message)
+ send_info = send_issues(url,text_titre,text_message,statu)
+ code = send_info.status_code
+ print(code)
+ else:
+ code = 423
+ if code == 201:
+ iface.messageBar().pushMessage("Envoyer :", "Votre messages à bien été envoyer.", level=Qgis.Success, duration=20)
+ self.close()
+ elif code == 422:
+ iface.messageBar().pushMessage("Erreur :", "Erreur dans le contenu du messages.", level=Qgis.Critical, duration=20)
+ elif code == 423:
+ iface.messageBar().pushMessage("Erreur :", "Pas de sujet sélectionné.", level=Qgis.Critical, duration=20)
+ elif code == 404:
+ iface.messageBar().pushMessage("Missing :", "Le serveur de messagerie est injoignable.", level=Qgis.Warning, duration=20)
diff --git a/CenRa_PAGERENDER/tools/icons/CEN_RA.png b/CenRa_PAGERENDER/tools/icons/CEN_RA.png
new file mode 100644
index 0000000..95ead1c
Binary files /dev/null and b/CenRa_PAGERENDER/tools/icons/CEN_RA.png differ
diff --git a/CenRa_PAGERENDER/tools/icons/icon.png b/CenRa_PAGERENDER/tools/icons/icon.png
new file mode 100644
index 0000000..63569ff
Binary files /dev/null and b/CenRa_PAGERENDER/tools/icons/icon.png differ
diff --git a/CenRa_PAGERENDER/tools/resources.py b/CenRa_PAGERENDER/tools/resources.py
new file mode 100644
index 0000000..bdd8c41
--- /dev/null
+++ b/CenRa_PAGERENDER/tools/resources.py
@@ -0,0 +1,174 @@
+"""Tools to work with resource files."""
+
+import configparser
+import shutil
+import tempfile
+# import base64
+# import psycopg2
+# import psycopg2.extras
+from os.path import abspath, join, pardir, dirname
+from qgis.PyQt.QtWidgets import QApplication
+from qgis.PyQt import uic
+
+__copyright__ = "Copyright 2019, 3Liz"
+__license__ = "GPL version 3"
+__email__ = "info@3liz.org"
+__revision__ = "$Format:%H$"
+
+
+def plugin_path(*args):
+ """Get the path to plugin root folder.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Absolute path to the plugin path.
+ :rtype: str
+ """
+ path = dirname(dirname(__file__))
+ path = abspath(abspath(join(path, pardir)))
+ for item in args:
+ path = abspath(join(path, item))
+
+ return path
+
+
+def plugin_name():
+ """Return the plugin name according to metadata.txt.
+
+ :return: The plugin name.
+ :rtype: basestring
+ """
+ metadata = metadata_config()
+ name = metadata["general"]["name"]
+ return name
+
+
+def metadata_config() -> configparser:
+ """Get the INI config parser for the metadata file.
+
+ :return: The config parser object.
+ :rtype: ConfigParser
+ """
+ path = plugin_path("metadata.txt")
+ config = configparser.ConfigParser()
+ config.read(path, encoding='utf8')
+ return config
+
+
+def plugin_test_data_path(*args, copy=False):
+ """Get the path to the plugin test data path.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :param copy: If the file must be copied into a temporary directory first.
+ :type copy: bool
+
+ :return: Absolute path to the resources folder.
+ :rtype: str
+ """
+ path = abspath(abspath(join(plugin_path(), "test", "data")))
+ for item in args:
+ path = abspath(join(path, item))
+
+ if copy:
+ temp = tempfile.mkdtemp()
+ shutil.copy(path, temp)
+ return join(temp, args[-1])
+ else:
+ return path
+
+
+def resources_path(*args):
+ """Get the path to our resources folder.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Absolute path to the resources folder.
+ :rtype: str
+ """
+ path = abspath(abspath(join(plugin_path(), "CenRa_PAGERENDER\\tools")))
+ for item in args:
+ path = abspath(join(path, item))
+ return path
+
+
+def load_ui(*args):
+ """Get compile UI file.
+
+ :param args List of path elements e.g. ['img', 'logos', 'image.png']
+ :type args: str
+
+ :return: Compiled UI file.
+ """
+ ui_class, _ = uic.loadUiType(resources_path("ui", *args))
+
+ return ui_class
+
+
+def send_issues(url, titre, body, labels):
+ import requests
+ import urllib.request
+ import json
+ # import os
+
+ # usr = os.environ['USERNAME']
+ token = '9d0a4e0bea561710e0728f161f7edf4e5201e112'
+ url = url + '?token=' + token
+
+ headers = {'Authorization': 'token ' + token, 'accept': 'application/json', 'Content-Type': 'application/json'}
+
+ payload = {'title': titre, 'body': body, 'labels': labels}
+ try:
+ urllib.request.urlopen('https://google.com')
+ binar = True
+ except urllib.requests.URLError:
+ binar = False
+ r = ''
+ if binar:
+ r = requests.post(url, data=json.dumps(payload), headers=headers)
+ return r
+
+
+def maj_verif(NAME):
+ import qgis
+ import urllib.request
+ iface = qgis.utils.iface
+ from qgis.core import Qgis
+
+ # url = qgis.utils.pluginMetadata(NAME, 'repository')
+ # URL = url+'/raw/branch/main/plugins.xml'
+ URL = 'https://gitea.cenra-outils.org/CEN-RA/Plugin_QGIS/releases/download/latest/plugins.xml'
+# print(URL)
+ version = qgis.utils.pluginMetadata(NAME, 'version')
+ len_version = len(version)
+ try:
+ urllib.request.urlopen('https://google.com')
+ binar = True
+ except urllib.requests.URLError:
+ binar = False
+ if binar:
+ try:
+ version_web = str(urllib.request.urlopen(URL).read())
+ plugin_num = version_web.find(NAME)
+ valeur_version_web = version_web.find('', plugin_num) + 9
+ version_plugin = version_web[valeur_version_web:valeur_version_web + len_version]
+ if version_plugin != version:
+ iface.messageBar().pushMessage("MAJ :", "Des mise à jour de plugin sont disponibles.", level=Qgis.Info, duration=30)
+ except urllib.requests.URLError:
+ print("error gitea version ssl")
+ else:
+ iface.messageBar().pushMessage("WiFi :", "Pas de connection à internet.", level=Qgis.Warning, duration=30)
+
+
+def tr(text, context="@default"):
+ return QApplication.translate(context, text)
+
+
+def devlog(NAME):
+ import qgis
+ devmaj = ''
+ devmaj = devmaj + qgis.utils.pluginMetadata(NAME, 'changelog')
+ return devmaj
diff --git a/CenRa_PAGERENDER/tools/ui/CenRa_IssuesSend.ui b/CenRa_PAGERENDER/tools/ui/CenRa_IssuesSend.ui
new file mode 100644
index 0000000..14d923e
--- /dev/null
+++ b/CenRa_PAGERENDER/tools/ui/CenRa_IssuesSend.ui
@@ -0,0 +1,332 @@
+
+
+ CenRa_IssuesSend
+
+
+
+ 0
+ 0
+ 810
+ 587
+
+
+
+ CEN-RA Metabase
+
+
+
+ icon.svgicon.svg
+
+
+
+
+ 0
+ 550
+ 811
+ 31
+
+
+
+ -
+
+
+ Annuler
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Envoyer
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 791
+ 531
+
+
+
+ Issues
+
+
+
+
+ 240
+ 40
+ 321
+ 41
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ 10
+ 101
+ 571
+ 421
+
+
+
+
+
+
+ 589
+ 100
+ 191
+ 431
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 9
+ 9
+ 341
+ 411
+
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Bug
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Aide
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Question
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Amélioration
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Autre
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+ 250
+ 20
+ 51
+ 21
+
+
+
+
+ Arial
+ 14
+
+
+
+ Titre:
+
+
+
+
+
+ 20
+ 70
+ 91
+ 31
+
+
+
+
+ Arial
+ 12
+
+
+
+ Messages:
+
+
+
+
+
+ 600
+ 70
+ 91
+ 31
+
+
+
+
+ Arial
+ 12
+
+
+
+ Sujet:
+
+
+
+
+
+ ok_button
+ annuler_button
+
+
+
+
diff --git a/CenRa_PAGERENDER/tools/ui/CenRa_PageRender_base.ui b/CenRa_PAGERENDER/tools/ui/CenRa_PageRender_base.ui
index 3c96170..884a749 100644
--- a/CenRa_PAGERENDER/tools/ui/CenRa_PageRender_base.ui
+++ b/CenRa_PAGERENDER/tools/ui/CenRa_PageRender_base.ui
@@ -78,7 +78,7 @@
296
- Qt::Orientation::Horizontal
+ Qt::Horizontal
@@ -100,7 +100,7 @@
0
- Qt::Orientation::Vertical
+ Qt::Vertical
true
@@ -118,12 +118,6 @@
QFrame#frame{background-color: rgb(255, 255, 255, 170);}
-
- QFrame::Shape::StyledPanel
-
-
- QFrame::Shadow::Raised
-
@@ -139,24 +133,9 @@
background-color: rgba(10, 10, 10, 50)
-
- QFrame::Shape::NoFrame
-
-
- QFrame::Shadow::Plain
-
-
- 5
-
-
- 2
-
-
- Qt::AlignmentFlag::AlignCenter
-
5
@@ -176,9 +155,6 @@
background-color: rgba(10, 10, 10, 50)
-
- QFrame::Shadow::Plain
-
@@ -277,27 +253,12 @@
background-color: rgba(10, 10, 10, 50)
-
- QFrame::Shape::NoFrame
-
-
- QFrame::Shadow::Raised
-
-
- -1
-
-
- 0
-
false
-
- Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignTrailing
-
false
@@ -364,27 +325,12 @@
background-color: rgba(10, 10, 10, 50)
-
- QFrame::Shape::NoFrame
-
-
- QFrame::Shadow::Raised
-
-
- -1
-
-
- 0
-
false
-
- Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignTrailing
-
false
@@ -446,12 +392,6 @@
QFrame#frame_2{background-color: rgb(255, 255, 255, 170);}
-
- QFrame::Shape::StyledPanel
-
-
- QFrame::Shadow::Raised
-
@@ -465,13 +405,13 @@
1
- Qt::ScrollBarPolicy::ScrollBarAlwaysOff
+ Qt::ScrollBarAsNeeded
- QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow
+ QAbstractScrollArea::AdjustIgnored
- QAbstractItemView::EditTrigger::NoEditTriggers
+ QAbstractItemView::NoEditTriggers
false
@@ -483,19 +423,19 @@
false
- QAbstractItemView::DragDropMode::NoDragDrop
+ QAbstractItemView::NoDragDrop
- Qt::DropAction::IgnoreAction
+ Qt::IgnoreAction
true
- QAbstractItemView::SelectionMode::SingleSelection
+ QAbstractItemView::NoSelection
- QAbstractItemView::SelectionBehavior::SelectRows
+ QAbstractItemView::SelectItems
@@ -504,7 +444,7 @@
- Qt::TextElideMode::ElideMiddle
+ Qt::ElideLeft
true
@@ -590,13 +530,13 @@
1
- Qt::ScrollBarPolicy::ScrollBarAlwaysOff
+ Qt::ScrollBarAsNeeded
- QAbstractScrollArea::SizeAdjustPolicy::AdjustToContentsOnFirstShow
+ QAbstractScrollArea::AdjustIgnored
- QAbstractItemView::EditTrigger::DoubleClicked
+ QAbstractItemView::NoEditTriggers
false
@@ -608,19 +548,19 @@
false
- QAbstractItemView::DragDropMode::NoDragDrop
+ QAbstractItemView::NoDragDrop
- Qt::DropAction::IgnoreAction
+ Qt::IgnoreAction
true
- QAbstractItemView::SelectionMode::SingleSelection
+ QAbstractItemView::NoSelection
- QAbstractItemView::SelectionBehavior::SelectRows
+ QAbstractItemView::SelectItems
@@ -629,7 +569,7 @@
- Qt::TextElideMode::ElideMiddle
+ Qt::ElideLeft
true
@@ -707,16 +647,16 @@
- Qt::FocusPolicy::NoFocus
+ Qt::NoFocus
- Qt::LayoutDirection::LeftToRight
+ Qt::LeftToRight
false
- Qt::InputMethodHint::ImhNone
+ Qt::ImhNone
@@ -741,7 +681,7 @@
- QAbstractSpinBox::ButtonSymbols::NoButtons
+ QAbstractSpinBox::UpDownArrows
@@ -763,7 +703,7 @@
- QAbstractSpinBox::ButtonSymbols::NoButtons
+ QAbstractSpinBox::UpDownArrows
@@ -812,9 +752,6 @@
40
-
- Qt::Orientation::Vertical
-
true
diff --git a/CenRa_PAGERENDER/tools/ui/CenRa_about_form.ui b/CenRa_PAGERENDER/tools/ui/CenRa_about_form.ui
new file mode 100644
index 0000000..6ec4843
--- /dev/null
+++ b/CenRa_PAGERENDER/tools/ui/CenRa_about_form.ui
@@ -0,0 +1,81 @@
+
+
+ CenRa_Metabase_editorwidget_base
+
+
+
+ 0
+ 0
+ 471
+ 594
+
+
+
+ Journal des modifications
+
+
+
+ ../../CenRa_Metabase/tools/ui/icon.svg../../CenRa_Metabase/tools/ui/icon.svg
+
+
+ -
+
+
+ true
+
+
+ Qt::NoFocus
+
+
+ QFrame::NoFrame
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 453
+ 570
+
+
+
+
+
+ 0
+ 0
+ 451
+ 541
+
+
+
+ DevLog
+
+
+
+
+ 10
+ 20
+ 431
+ 511
+
+
+
+
+
+
+
+ -
+
+
+ QDialogButtonBox::NoButton
+
+
+
+
+
+
+
+
diff --git a/CenRa_PAGERENDER/tools/ui/rotate.png b/CenRa_PAGERENDER/tools/ui/rotate.png
new file mode 100644
index 0000000..85826ed
Binary files /dev/null and b/CenRa_PAGERENDER/tools/ui/rotate.png differ
diff --git a/CenRa_PAGERENDER/tools/ui/size.png b/CenRa_PAGERENDER/tools/ui/size.png
new file mode 100644
index 0000000..7cd2a08
Binary files /dev/null and b/CenRa_PAGERENDER/tools/ui/size.png differ
diff --git a/CenRa_PAGERENDER/tools/ui/size_0.png b/CenRa_PAGERENDER/tools/ui/size_0.png
new file mode 100644
index 0000000..571076b
Binary files /dev/null and b/CenRa_PAGERENDER/tools/ui/size_0.png differ