Skip to content

Commit

Permalink
UI cleanups, add setting to control whether raw or styled rasters are…
Browse files Browse the repository at this point in the history
… uploaded (#55)

* Move privacy/terms/contact up to header

* Move user login details to footer

* Remove 'select map' label

* Remove unwanted label background color

* Move logout to settings button

* Closer match for setting button appearance to mockup

As close as we can get!

* Lock button color to a light color

* Hardcode menu color

* Add setting to control whether raw or styled rasters are uploaded

* Lint

* Absolutely force dialog button boxes to the same height

* Hide qt triangle icon on tool button

* Move triangle drop down to svg graphic

* Lint
  • Loading branch information
nyalldawson authored Nov 27, 2023
1 parent 1f558b0 commit 78749ad
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 107 deletions.
43 changes: 12 additions & 31 deletions felt/core/layer_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ def generate_file_name(self, suffix: str) -> str:
def export_layer_for_felt(
self,
layer: QgsMapLayer,
feedback: Optional[QgsFeedback] = None
feedback: Optional[QgsFeedback] = None,
upload_raster_as_styled: bool = True
) -> ZippedExportResult:
"""
Exports a layer into a format acceptable for Felt
Expand All @@ -276,7 +277,9 @@ def export_layer_for_felt(
if isinstance(layer, QgsVectorLayer):
res = self.export_vector_layer(layer, feedback)
elif isinstance(layer, QgsRasterLayer):
res = self.export_raster_layer(layer, feedback)
res = self.export_raster_layer(
layer, feedback,
upload_raster_as_styled)
else:
assert False

Expand Down Expand Up @@ -504,17 +507,17 @@ def run_raster_writer(self,
def export_raster_layer(
self,
layer: QgsRasterLayer,
feedback: Optional[QgsFeedback] = None) -> LayerExportDetails:
feedback: Optional[QgsFeedback] = None,
upload_raster_as_styled: bool = True) -> LayerExportDetails:
"""
Exports a raster layer into a format acceptable for Felt
"""
raw_dest_file = self.generate_file_name('.tif')
styled_dest_file = raw_dest_file.replace('.tif', '_styled.tif')
dest_file = self.generate_file_name('.tif')

layer_export_result, error_message = self.run_raster_writer(
layer,
file_name=styled_dest_file,
use_style=True,
file_name=dest_file,
use_style=upload_raster_as_styled,
feedback=feedback)

if error_message:
Expand All @@ -526,31 +529,9 @@ def export_raster_layer(
)
raise LayerPackagingException(error_message)

filenames = [styled_dest_file]
if layer_export_result != LayerExportResult.Canceled:
# also write raw raster

layer_export_result, error_message = self.run_raster_writer(
layer,
file_name=raw_dest_file,
use_style=False,
feedback=feedback)

if error_message:
Logger.instance().log_error_json(
{
'type': Logger.PACKAGING_RASTER,
'error': 'Error packaging layer: {}'.format(
error_message)
}
)
raise LayerPackagingException(error_message)

filenames.append(raw_dest_file)

return LayerExportDetails(
representative_filename=raw_dest_file,
filenames=filenames,
representative_filename=dest_file,
filenames=[dest_file],
result=layer_export_result,
error_message=error_message,
qgis_style_xml=self._get_original_style_xml(layer)
Expand Down
10 changes: 8 additions & 2 deletions felt/core/map_uploader.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
QgsTask,
QgsFeedback,
QgsBlockingNetworkRequest,
QgsReferencedRectangle
QgsReferencedRectangle,
QgsSettings
)
from qgis.utils import iface

Expand Down Expand Up @@ -250,6 +251,10 @@ def run(self):

self.feedback = QgsFeedback()

upload_raster_as_styled = QgsSettings().value(
"felt/upload_raster_as_styled", True, bool, QgsSettings.Plugins
)

multi_step_feedback = MultiStepFeedback(
total_steps, self.feedback
)
Expand Down Expand Up @@ -342,7 +347,8 @@ def run(self):
try:
result = exporter.export_layer_for_felt(
layer,
multi_step_feedback
multi_step_feedback,
upload_raster_as_styled=upload_raster_as_styled
)
except LayerPackagingException as e:
layer.moveToThread(None)
Expand Down
133 changes: 114 additions & 19 deletions felt/gui/create_map_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,30 @@
from qgis.PyQt import uic
from qgis.PyQt.QtCore import (
Qt,
QUrl
QUrl,
QSize
)
from qgis.PyQt.QtGui import (
QDesktopServices,
QFontMetrics,
QColor
QColor,
QPalette
)
from qgis.PyQt.QtWidgets import (
QWidget,
QDialog,
QDialogButtonBox,
QVBoxLayout
QVBoxLayout,
QLabel,
QMenu,
QAction,
QToolButton
)
from qgis.core import (
QgsMapLayer,
QgsApplication,
QgsProject
QgsProject,
QgsSettings
)
from qgis.gui import QgsGui

Expand All @@ -47,12 +54,12 @@
PRIVACY_POLICY_URL,
TOS_URL
)
from .workspaces_combo import WorkspacesComboBox
from .felt_dialog_header import FeltDialogHeader
from .gui_utils import (
GuiUtils,
FELT_STYLESHEET
)
from .workspaces_combo import WorkspacesComboBox
from ..core import (
MapUploaderTask,
Map
Expand Down Expand Up @@ -92,10 +99,33 @@ def __init__(self, # pylint: disable=too-many-statements

vl = QVBoxLayout()
vl.setContentsMargins(0, 0, 0, 0)
vl.addWidget(FeltDialogHeader())
self.widget_logo.setStyleSheet('background: solid #3d521e;')
header = FeltDialogHeader()
vl.addWidget(header)
self.widget_logo.setLayout(vl)

self.header_label = QLabel(
"""<style> a { text-decoration: none; }</style>"""
"""<a href="privacy_policy">Privacy</a>&nbsp;&nbsp;&nbsp;"""
"""<a href="terms_of_use">Terms</a>&nbsp;&nbsp;&nbsp;"""
"""<a href="mailto:[email protected]">Contact us</a></p>"""
)
self.header_label.setMouseTracking(True)
self.header_label.linkActivated.connect(self._link_activated)
self.header_label.setText(
GuiUtils.set_link_color(self.header_label.text(),
color='rgba(255,255,255,.7)')
)

header_label_vl = QVBoxLayout()
header_label_vl.setContentsMargins(0, 0, 0, 0)
header_label_vl.addStretch()
header_label_vl.addWidget(self.header_label)

header_label_widget = QWidget()
header_label_widget.setLayout(header_label_vl)

header.push_widget(header_label_widget)

self.setWindowTitle(self.tr('Add to Felt'))

self.footer_label.setMinimumWidth(
Expand Down Expand Up @@ -124,6 +154,73 @@ def __init__(self, # pylint: disable=too-many-statements
GuiUtils.set_link_color(self.footer_label.text())
)

self.setting_menu = QMenu(self)
palette = self.setting_menu.palette()
palette.setColor(QPalette.Active, QPalette.Base, QColor(255, 255, 255))
palette.setColor(QPalette.Active, QPalette.Text, QColor(0, 0, 0))
palette.setColor(QPalette.Active, QPalette.Highlight,
QColor('#3d521e'))
palette.setColor(QPalette.Active, QPalette.HighlightedText,
QColor(255, 255, 255))
self.setting_menu.setPalette(palette)

self.upload_raster_as_styled_action = QAction(
self.tr('Upload Raster Layers as Styled Images'),
self.setting_menu)
self.upload_raster_as_styled_action.setCheckable(True)
self.upload_raster_as_styled_action.setChecked(
QgsSettings().value(
"felt/upload_raster_as_styled", True, bool, QgsSettings.Plugins
)
)

def upload_raster_as_styled_toggled():
"""
Called when upload raster as style action is toggled
"""
QgsSettings().setValue(
"felt/upload_raster_as_styled",
self.upload_raster_as_styled_action.isChecked(),
QgsSettings.Plugins
)

self.upload_raster_as_styled_action.toggled.connect(
upload_raster_as_styled_toggled)
self.setting_menu.addAction(self.upload_raster_as_styled_action)

self.setting_menu.addSeparator()
self.logout_action = QAction(self.tr('Log Out'), self.setting_menu)
self.setting_menu.addAction(self.logout_action)
self.logout_action.triggered.connect(self._logout)

palette = self.setting_button.palette()
palette.setColor(QPalette.Active, QPalette.Button, QColor('#ececec'))
self.setting_button.setPalette(palette)

self.setting_button.setMenu(self.setting_menu)
self.setting_button.setIcon(GuiUtils.get_icon('setting_icon.svg'))
self.setting_button.setPopupMode(QToolButton.InstantPopup)
self.setting_button.setStyleSheet(
"""QToolButton::menu-indicator { image: none }"""
)
self.setting_button.setFixedHeight(
self.button_box.button(QDialogButtonBox.Cancel).height()
)
self.setting_button.setFixedWidth(
int(self.setting_button.size().height() * 1.8)
)
self.setting_button.setIconSize(
QSize(int(self.setting_button.size().width() * 0.6),
int(self.setting_button.size().height() * 0.6)
))
# setting the setting button to a fixed height doesn't always
# guarantee that the height exactly matches the Close/Add buttons.
# So let's play it safe and force them to match always:
for b in (QDialogButtonBox.Cancel, QDialogButtonBox.Ok):
self.button_box.button(b).setFixedHeight(
self.setting_button.size().height()
)

# pylint: disable=import-outside-toplevel
from .recent_maps_list_view import RecentMapsWidget
# pylint: enable=import-outside-toplevel
Expand Down Expand Up @@ -163,17 +260,9 @@ def __init__(self, # pylint: disable=too-many-statements
self.progress_bar.setValue(0)

if AUTHORIZATION_MANAGER.user:
self.label_user.setText(
GuiUtils.set_link_color(
self.tr(
'{} ({})'
).format(AUTHORIZATION_MANAGER.user.name,
AUTHORIZATION_MANAGER.user.email) +
' <a href="logout">' + self.tr('Log out') + '</a>',
wrap_color=False
)
self.footer_label.setText(
AUTHORIZATION_MANAGER.user.email
)
self.label_user.linkActivated.connect(self._link_activated)

self.started = False
self._validate()
Expand Down Expand Up @@ -224,6 +313,13 @@ def _cancel(self):
else:
self.reject()

def _logout(self):
"""
Triggers a logout
"""
AUTHORIZATION_MANAGER.deauthorize()
self.close()

def _link_activated(self, link: str):
"""
Called when a hyperlink is clicked in dialog labels
Expand All @@ -233,8 +329,7 @@ def _link_activated(self, link: str):
elif link == 'terms_of_use':
url = QUrl(TOS_URL)
elif link == 'logout':
AUTHORIZATION_MANAGER.deauthorize()
self.close()
self._logout()
return
else:
url = QUrl(link)
Expand Down
23 changes: 19 additions & 4 deletions felt/gui/felt_dialog_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
from qgis.PyQt.QtWidgets import (
QWidget,
QVBoxLayout,
QSizePolicy
QSizePolicy,
QHBoxLayout
)

from .gui_utils import (
Expand All @@ -53,22 +54,36 @@ def __init__(self, parent: Optional[QWidget] = None):
QSizePolicy.Fixed
)

self.setStyleSheet('background: solid #3d521e;')
svg_logo_widget = QSvgWidget()
fixed_size = QSize(self.LOGO_WIDTH_PIXELS,
self.LOGO_HEIGHT_PIXELS)
svg_logo_widget.setFixedSize(fixed_size)
svg_logo_widget.load(GuiUtils.get_icon_svg('felt_logo_white.svg'))
svg_logo_widget.setStyleSheet('background: transparent;')
svg_logo_container = QVBoxLayout()
svg_logo_container.setContentsMargins(0, 0, 0, 4)
svg_logo_container.addWidget(svg_logo_widget)
vl = QVBoxLayout()
vl.setContentsMargins(12, 0, 0, 19)
vl.setContentsMargins(12, 0, 12, 15)
vl.addStretch(1)
vl.addWidget(svg_logo_widget)

self.header_layout = QHBoxLayout()
self.header_layout.setContentsMargins(0, 0, 0, 0)
self.header_layout.addLayout(svg_logo_container)
self.header_layout.addStretch()

vl.addLayout(self.header_layout)
self.setLayout(vl)

# QWidget interface
# pylint: disable=missing-function-docstring

def push_widget(self, widget: QWidget):
"""
Pushes a new widget into the right section of the header
"""
self.header_layout.addWidget(widget)

def sizeHint(self):
return QSize(0, self.FIXED_HEIGHT_PIXELS)

Expand Down
12 changes: 9 additions & 3 deletions felt/gui/gui_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
import math
import os
import re
from typing import Optional
from typing import (
Optional,
Union
)

from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import (
Expand Down Expand Up @@ -76,12 +79,15 @@ class GuiUtils:
@staticmethod
def set_link_color(html: str,
wrap_color=True,
color: Optional[QColor] = None) -> str:
color: Optional[Union[QColor, str]] = None) -> str:
"""
Adds style tags to links in a HTML string for the standard link color
"""
if color:
color_string = color.name()
if isinstance(color, str):
color_string = color
else:
color_string = color.name()
else:
color_string = 'rgba(0,0,0,.3)'
res = re.sub(r'(<a href.*?)>',
Expand Down
Loading

0 comments on commit 78749ad

Please sign in to comment.