Skip to content

Commit

Permalink
Merge pull request #174 from opengisch/nolocalpath
Browse files Browse the repository at this point in the history
Revert "Merge pull request #171 from opengisch/localized"
  • Loading branch information
m-kuhn authored Aug 22, 2020
2 parents 0eb45fc + b295735 commit 6bff8bc
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ install:
jobs:
include:
- stage: test
name: Test on QGIS LTR 3.10
name: Test on QGIS 3.4
env:
QGIS_TEST_VERSION="final-3_10_9"
QGIS_TEST_VERSION="release-3_4"
script: docker-compose -f .docker/docker-compose.travis.yml run qgis /usr/src/.docker/run-docker-tests.sh

- stage: test
Expand Down
88 changes: 34 additions & 54 deletions qfieldsync/core/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
from qgis.core import (
QgsDataSourceUri,
QgsMapLayer,
QgsReadWriteContext,
QgsProject,
QgsProviderRegistry,
QgsProviderMetadata,
Qgis
QgsReadWriteContext
)

from qfieldsync.utils.file_utils import slugify
Expand Down Expand Up @@ -78,17 +74,6 @@ def __init__(self, layer):
self._is_geometry_locked = None
self.read_layer()

self.storedInlocalizedDataPath = False
if self.layer.dataProvider() is not None:
pathResolver = QgsProject.instance().pathResolver()
metadata = QgsProviderRegistry.instance().providerMetadata(self.layer.dataProvider().name())
if metadata is not None:
decoded = metadata.decodeUri(self.layer.source())
if "path" in decoded:
path = pathResolver.writePath(decoded["path"])
if path.startswith("localized:"):
self.storedInlocalizedDataPath = True

def read_layer(self):
self._action = self.layer.customProperty('QFieldSync/action')
self._photo_naming = json.loads(self.layer.customProperty('QFieldSync/photo_naming') or '{}')
Expand Down Expand Up @@ -138,20 +123,19 @@ def is_configured(self):

@property
def is_file(self):
if self.layer.dataProvider() is not None:
metadata = QgsProviderRegistry.instance().providerMetadata(self.layer.dataProvider().name())
if metadata is not None:
decoded = metadata.decodeUri(self.layer.source())
if "path" in decoded:
if os.path.isfile(decoded["path"]):
return True
return False
# reading the part before | so it's valid when gpkg
if os.path.isfile(self.layer.source().split('|')[0]):
return True
elif os.path.isfile(QgsDataSourceUri(self.layer.dataProvider().dataSourceUri()).database()):
return True
else:
return False

@property
def available_actions(self):
actions = list()

if self.is_file and not self.storedInlocalizedDataPath:
if self.is_file:
actions.append((SyncAction.NO_ACTION, QCoreApplication.translate('LayerAction', 'copy')))
actions.append((SyncAction.KEEP_EXISTENT, QCoreApplication.translate('LayerAction', 'keep existent (copy if missing)')))
else:
Expand Down Expand Up @@ -216,19 +200,14 @@ def copy(self, target_path, copied_files, keep_existent=False):
# Copy will also be called on non-file layers like WMS. In this case, just do nothing.
return

file_path = ''
layer_name = ''

if self.layer.dataProvider() is not None:
metadata = QgsProviderRegistry.instance().providerMetadata(self.layer.dataProvider().name())
if metadata is not None:
decoded = metadata.decodeUri(self.layer.source())
if "path" in decoded:
file_path = decoded["path"]
if "layerName" in decoded:
layer_name = decoded["layerName"]
if file_path == '':
file_path = self.layer.source()
layer_name_suffix = ''
# Shapefiles and GeoPackages have the path in the source
uri_parts = self.layer.source().split('|', 1)
file_path = uri_parts[0]
if len(uri_parts) > 1:
layer_name_suffix = uri_parts[1]
# Spatialite have the path in the table part of the uri
uri = QgsDataSourceUri(self.layer.dataProvider().dataSourceUri())

if os.path.isfile(file_path):
source_path, file_name = os.path.split(file_path)
Expand All @@ -239,23 +218,24 @@ def copy(self, target_path, copied_files, keep_existent=False):
(keep_existent is False or not os.path.isfile(dest_file)):
shutil.copy(os.path.join(source_path, basename + ext), dest_file)

new_source = ''
if Qgis.QGIS_VERSION_INT >= 31200 and self.layer.dataProvider() is not None:
metadata = QgsProviderRegistry.instance().providerMetadata(self.layer.dataProvider().name())
if metadata is not None:
new_source = metadata.encodeUri({"path":os.path.join(target_path, file_name),"layerName":layer_name})
if new_source == '':
if self.layer.dataProvider() and self.layer.dataProvider().name == "spatialite":
uri = QgsDataSourceUri()
uri.setDatabase(os.path.join(target_path, file_name))
uri.setTable(layer_name)
new_source = uri.uri()
else:
new_source = os.path.join(target_path, file_name)
if layer_name != '':
new_source = "{}|{}".format(new_source, layer_name)

new_source = os.path.join(target_path, file_name)
if layer_name_suffix:
new_source = new_source + '|' + layer_name_suffix
self._change_data_source(new_source)
# Spatialite files have a uri
else:
file_path = uri.database()
if os.path.isfile(file_path):
source_path, file_name = os.path.split(file_path)
basename, extensions = get_file_extension_group(file_name)
for ext in extensions:
dest_file = os.path.join(target_path, basename + ext)
if os.path.exists(os.path.join(source_path, basename + ext)) and \
(keep_existent is False or not os.path.isfile(dest_file)):
shutil.copy(os.path.join(source_path, basename + ext),
dest_file)
uri.setDatabase(os.path.join(target_path, file_name))
self._change_data_source(uri.uri())
return copied_files

def _change_data_source(self, new_data_source):
Expand Down
14 changes: 0 additions & 14 deletions qfieldsync/core/offline_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@
QgsProcessingFeedback,
QgsProcessingContext,
QgsMapLayer,
QgsProviderRegistry,
QgsProviderMetadata,
QgsEditorWidgetSetup
)
import qgis
Expand Down Expand Up @@ -125,22 +123,10 @@ def convert(self):
self.project_configuration.base_map_mupp)

# Loop through all layers and copy/remove/offline them
pathResolver = QgsProject.instance().pathResolver()
copied_files = list()
for current_layer_index, layer in enumerate(self.__layers):
self.total_progress_updated.emit(current_layer_index - len(self.__offline_layers), len(self.__layers),
self.trUtf8('Copying layers…'))

if layer.dataProvider() is not None:
md = QgsProviderRegistry.instance().providerMetadata(layer.dataProvider().name())
if md is not None:
decoded = md.decodeUri(layer.source())
if "path" in decoded:
path = pathResolver.writePath(decoded["path"])
if path.startswith("localized:"):
# Layer stored in localized data path, skip
continue

layer_source = LayerSource(layer)

if layer_source.action == SyncAction.OFFLINE:
Expand Down
56 changes: 17 additions & 39 deletions qfieldsync/gui/package_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
pyqtSlot,
Qt
)
from qgis.PyQt.QtGui import (
QIcon
)
from qgis.PyQt.QtWidgets import (
QDialogButtonBox,
QPushButton,
Expand All @@ -45,8 +42,6 @@
from qgis.core import (
QgsProject,
QgsApplication,
QgsProviderRegistry,
QgsProviderMetadata,
Qgis
)
from qgis.PyQt.uic import loadUiType
Expand All @@ -70,11 +65,9 @@ def __init__(self, iface, project, offline_editing, parent=None):
self.project = project
self.qfield_preferences = Preferences()
self.project_lbl.setText(get_project_title(self.project))
self.button_box.button(QDialogButtonBox.Save).setText(self.tr('Create'))
self.button_box.button(QDialogButtonBox.Save).clicked.connect(self.package_project)
self.button_box.button(QDialogButtonBox.Reset).setText(self.tr('Configure project...'))
self.button_box.button(QDialogButtonBox.Reset).setIcon(QIcon())
self.button_box.button(QDialogButtonBox.Reset).clicked.connect(self.show_settings)
self.push_btn = QPushButton(self.tr('Create'))
self.push_btn.clicked.connect(self.package_project)
self.button_box.addButton(self.push_btn, QDialogButtonBox.ActionRole)
self.iface.mapCanvas().extentsChanged.connect(self.extent_changed)
self.extent_changed()

Expand All @@ -99,14 +92,16 @@ def setup_gui(self):
self.manualDir.setText(export_folder_path)
self.manualDir_btn.clicked.connect(make_folder_selector(self.manualDir))
self.update_info_visibility()
self.infoLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
self.infoLabel.linkActivated.connect(lambda: self.show_settings())

def get_export_folder_from_dialog(self):
"""Get the export folder according to the inputs in the selected"""
# manual
return self.manualDir.text()

def package_project(self):
self.button_box.button(QDialogButtonBox.Save).setEnabled(False)
self.push_btn.setEnabled(False)
self.informationStack.setCurrentWidget(self.progressPage)

export_folder = self.get_export_folder_from_dialog()
Expand All @@ -133,41 +128,24 @@ def do_post_offline_convert_action(self):
"""
export_folder = self.get_export_folder_from_dialog()

result_message = self.tr('Finished creating the project at {result_folder}. Please copy this folder to '
'your QField device.').format(result_folder='<a href="{folder}">{folder}</a>'.format(folder=export_folder))
self.iface.messageBar().pushMessage(result_message, Qgis.Success, 0)
result_label = QLabel(self.tr('Finished creating the project at {result_folder}. Please copy this folder to '
'your QField device.').format(
result_folder='<a href="{folder}">{folder}</a>'.format(folder=export_folder)))
result_label.setTextFormat(Qt.RichText)
result_label.setTextInteractionFlags(Qt.TextBrowserInteraction)
result_label.linkActivated.connect(lambda: open_folder(export_folder))
result_label.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)

self.iface.messageBar().pushWidget(result_label, Qgis.Info, 0)

def update_info_visibility(self):
"""
Show the info label if there are unconfigured layers
"""
pathResolver = QgsProject.instance().pathResolver()
showInfoConfiguration = False
localizedDataPathLayers = []
self.infoGroupBox.hide()
for layer in list(self.project.mapLayers().values()):
if not LayerSource(layer).is_configured:
showInfoConfiguration = True
if layer.dataProvider() is not None:
metadata = QgsProviderRegistry.instance().providerMetadata(layer.dataProvider().name())
if metadata is not None:
decoded = metadata.decodeUri(layer.source())
if "path" in decoded:
path = pathResolver.writePath(decoded["path"])
if path.startswith("localized:"):
localizedDataPathLayers.append('- {} ({})'.format(layer.name(), path[10:]))

self.infoConfigurationLabel.setVisible(showInfoConfiguration)
if localizedDataPathLayers:
if len(localizedDataPathLayers) == 1:
self.infoLocalizedLayersLabel.setText(self.tr('The layer stored in a localized data path is:\n{}').format("\n".join(localizedDataPathLayers)))
else:
self.infoLocalizedLayersLabel.setText(self.tr('The layers stored in a localized data path are:\n{}').format("\n".join(localizedDataPathLayers)))
self.infoLocalizedLayersLabel.setVisible(True)
self.infoLocalizedPresentLabel.setVisible(True)
else:
self.infoLocalizedLayersLabel.setVisible(False)
self.infoLocalizedPresentLabel.setVisible(False)
self.infoGroupBox.setVisible(showInfoConfiguration or len(localizedDataPathLayers) > 0)
self.infoGroupBox.show()

project_configuration = ProjectConfiguration(self.project)

Expand Down
10 changes: 7 additions & 3 deletions qfieldsync/gui/synchronize_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,20 @@ def __init__(self, iface, offline_editing, parent=None):
self.iface = iface
self.preferences = Preferences()
self.offline_editing = offline_editing
self.button_box.button(QDialogButtonBox.Save).setText(self.tr('Synchronize'))
self.button_box.button(QDialogButtonBox.Save).clicked.connect(self.start_synchronization)
self.push_btn = QPushButton(self.tr('Synchronize'))
self.push_btn.clicked.connect(self.start_synchronization)
self.button_box.addButton(self.push_btn, QDialogButtonBox.ActionRole)
self.qfieldDir.setText(self.preferences.value('importDirectoryProject') or self.preferences.value('importDirectory'))
self.qfieldDir_button.clicked.connect(make_folder_selector(self.qfieldDir))

self.offline_editing_done = False

def start_synchronization(self):
self.button_box.button(QDialogButtonBox.Save).setEnabled(False)
self.push_btn.setEnabled(False)
qfield_folder = self.qfieldDir.text()
self.preferences.set_value('importDirectoryProject', qfield_folder)
try:
self.progress_group.setEnabled(True)
current_import_file_checksum = import_file_checksum(qfield_folder)
imported_files_checksums = import_checksums_of_project(qfield_folder)

Expand Down Expand Up @@ -97,6 +99,8 @@ def start_synchronization(self):
raise NoProjectFoundError(message)
except NoProjectFoundError as e:
self.iface.messageBar().pushWarning('QFieldSync', str(e))
finally:
self.progress_group.setEnabled(False)

@pyqtSlot(int, int)
def update_total(self, current, layer_count):
Expand Down
2 changes: 1 addition & 1 deletion qfieldsync/metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[general]
name=QField Sync
qgisMinimumVersion=3.10
qgisMinimumVersion=3.0
description=Sync your projects to QField
version=dev
author=OPENGIS.ch
Expand Down
Loading

0 comments on commit 6bff8bc

Please sign in to comment.