Skip to content

Commit

Permalink
Add custom sort order support for list widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanw-chartis committed May 10, 2022
1 parent f6f7e33 commit 758dc2e
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 52 deletions.
30 changes: 29 additions & 1 deletion src/configmanager/editorwidgets/listwidget.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from functools import partial

from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QWidget
from qgis.core import QgsMapLayer
Expand Down Expand Up @@ -35,6 +34,7 @@ def __init__(self, parent=None):
self.layerCombo.setModel(self.layermodel)
self.keyCombo.setModel(self.fieldmodel)
self.valueCombo.setModel(self.fieldmodel)
self.sortCombo.setModel(self.fieldmodel)
self.filterButton.pressed.connect(self.define_filter)

self.fieldmodel.setLayerFilter(self.layerCombo.view().selectionModel())
Expand All @@ -61,6 +61,7 @@ def reset(self):
self.layerCombo.setCurrentIndex(-1)
self.keyCombo.setCurrentIndex(-1)
self.valueCombo.setCurrentIndex(-1)
self.sortCombo.setCurrentIndex(-1)

def widgetchanged(self):
self.widgetdirty.emit(self.getconfig())
Expand Down Expand Up @@ -89,6 +90,18 @@ def list(self):
def filter(self):
return self.filterText.toPlainText()

@property
def sortAsNumber(self):
return self.sortByAsNumberCheck.isChecked()

@property
def sort_by(self):
if self.sortByValue.isChecked():
index_key = self.fieldmodel.index(self.sortCombo.currentIndex(), 0)
fieldname_key = self.fieldmodel.data(index_key, QgsFieldModel.FieldNameRole)
return fieldname_key
return "default"

@property
def layer(self):
return self.layerCombo.currentText()
Expand All @@ -115,6 +128,8 @@ def getconfig(self):
subconfig['key'] = self.key
subconfig['value'] = self.value
subconfig['filter'] = self.filter
subconfig['sort_by'] = self.sort_by
subconfig['sort_by_as_number'] = self.sortAsNumber
config['layer'] = subconfig
else:
config['list'] = {}
Expand All @@ -136,6 +151,7 @@ def setconfig(self, config):
self.listText.setPlainText('')
self.keyCombo.clear()
self.valueCombo.clear()
self.sortCombo.clear()
self.filterText.clear()
self.layermodel.refresh()

Expand All @@ -153,6 +169,8 @@ def setconfig(self, config):
subconfig = config.get('layer', {})
layer = subconfig.get('layer', '') or ''
key = subconfig.get('key', '') or ''
sortBy = subconfig.get('sort_by', 'default') or 'default'
sortByAsNumber = subconfig.get('sort_by_as_number', False) or False
value = subconfig.get('value', '') or ''
filter = subconfig.get('filter', None)
index = self.layerCombo.findData(layer, Qt.DisplayRole)
Expand All @@ -170,6 +188,16 @@ def setconfig(self, config):
if valueindex > -1:
self.valueCombo.setCurrentIndex(valueindex)

self.sortByAsNumberCheck.setChecked(sortByAsNumber)

if sortBy == "default":
self.sortDefault.setChecked(True)
else:
self.sortByValue.setChecked(True)
sortIndex = self.sortCombo.findData(sortBy.lower(), QgsFieldModel.FieldNameRole)
if sortIndex > -1:
self.sortCombo.setCurrentIndex(sortIndex)

self.filterText.setPlainText(filter)

self.allownullCheck.setChecked(self.allownull)
Expand Down
143 changes: 95 additions & 48 deletions src/configmanager/editorwidgets/uifiles/ui_listwidget_config.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,67 @@
<rect>
<x>0</x>
<y>0</y>
<width>439</width>
<height>382</height>
<width>471</width>
<height>424</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="layerRadio">
<property name="text">
<string>From layer</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="listRadio">
<property name="text">
<string>From pre-defined list</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="allownullCheck">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Allow Null Value</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="orderbyCheck">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Order By Value</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
Expand Down Expand Up @@ -78,14 +128,52 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="sortDefault">
<property name="text">
<string>Sort by data column</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="sortByValue">
<property name="text">
<string>Sort By column</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="sortCombo">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="modelColumn">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sortByAsNumberCheck">
<property name="text">
<string>As Number</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Filter</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
Expand All @@ -106,7 +194,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../ui/resources.qrc">
<iconset>
<normaloff>:/icons/Expression</normaloff>:/icons/Expression</iconset>
</property>
<property name="iconSize">
Expand All @@ -122,7 +210,7 @@
</item>
</layout>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QPlainTextEdit" name="filterText"/>
</item>
</layout>
Expand Down Expand Up @@ -153,47 +241,6 @@
</widget>
</widget>
</item>
<item row="2" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="layerRadio">
<property name="text">
<string>From layer</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="listRadio">
<property name="text">
<string>From pre-defined list</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="allownullCheck">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Allow Null Value</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="orderbyCheck">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Order By Value</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
Expand Down
21 changes: 18 additions & 3 deletions src/roam/editorwidgets/listwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from qgis.PyQt.QtCore import QSize, Qt, QEvent
from qgis.PyQt.QtGui import QStandardItem, QStandardItemModel, QIcon
from qgis.PyQt.QtWidgets import QComboBox
from qgis.core import QgsProject, QgsExpression, QgsFeatureRequest

import roam.utils
from roam.api import RoamEvents, utils
Expand Down Expand Up @@ -154,8 +153,24 @@ def _buildfromlayer(self, widget, layerconfig):
return

features = roam.api.utils.search_layer(layer, filterexp, fields, with_geometry=False)
# Sort the fields based on value field
features = sorted(features, key=lambda f: f[valuefield])
# Sort the fields based on config
sortBy = layerconfig.get('sort_by', 'default')
sortAsNumber = layerconfig.get('sort_by_as_number', False)
if sortBy == "default":
sortBy = valuefield

def custom_sort(feature):
value = feature[sortBy]
if sortAsNumber:
try:
value = float(str(value))
return False, value
except ValueError:
return True,
return False, value

features = sorted(features, key=custom_sort)

for feature in features:
keyvalue = nullconvert(feature[keyfieldindex])
valuvalue = nullconvert(feature[valuefield])
Expand Down

0 comments on commit 758dc2e

Please sign in to comment.