qwc2 2025.10.16 → 2025.10.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/actions/locate.js +3 -2
  2. package/components/AttributeTableWidget.js +24 -15
  3. package/components/FeatureAttributesWindow.js +178 -0
  4. package/components/IdentifyViewer.js +80 -39
  5. package/components/LocationRecorder.js +138 -0
  6. package/components/NumericInputWindow.js +30 -22
  7. package/components/PickFeature.js +87 -26
  8. package/components/PluginsContainer.js +16 -3
  9. package/components/map/OlLayer.js +2 -1
  10. package/components/map/layers/MVTLayer.js +3 -0
  11. package/components/map/layers/VectorLayer.js +66 -65
  12. package/components/map3d/HeightProfile3D.js +2 -0
  13. package/components/map3d/drawtool/EditTool3D.js +1 -1
  14. package/components/style/App.css +14 -0
  15. package/components/style/AttributeTableWidget.css +1 -1
  16. package/components/style/FeatureAttributesWindow.css +16 -0
  17. package/components/style/IdentifyViewer.css +5 -0
  18. package/components/style/LocationRecorder.css +10 -0
  19. package/components/style/NumericInputWindow.css +22 -0
  20. package/components/style/PluginsContainer.css +16 -0
  21. package/components/widgets/LayerCatalogWidget.js +40 -16
  22. package/components/widgets/NavBar.js +10 -3
  23. package/components/widgets/TextInput.js +4 -2
  24. package/icons/circle_full.svg +75 -0
  25. package/package.json +1 -1
  26. package/plugins/AttributeTable.js +4 -0
  27. package/plugins/GeometryDigitizer.js +3 -0
  28. package/plugins/HeightProfile.js +5 -1
  29. package/plugins/Identify.js +7 -3
  30. package/plugins/ObjectList.js +116 -0
  31. package/plugins/Redlining.js +21 -56
  32. package/plugins/map/EditingSupport.js +22 -1
  33. package/plugins/map/LocateSupport.js +8 -1
  34. package/plugins/map/RedliningSupport.js +374 -224
  35. package/plugins/map/SnappingSupport.js +11 -6
  36. package/plugins/map/style/SnappingSupport.css +2 -13
  37. package/reducers/locate.js +4 -2
  38. package/reducers/redlining.js +7 -4
  39. package/scripts/updateTranslations.js +1 -1
  40. package/static/translations/bg-BG.json +15 -2
  41. package/static/translations/ca-ES.json +15 -2
  42. package/static/translations/cs-CZ.json +15 -2
  43. package/static/translations/de-CH.json +15 -2
  44. package/static/translations/de-DE.json +15 -2
  45. package/static/translations/en-US.json +15 -2
  46. package/static/translations/es-ES.json +15 -2
  47. package/static/translations/fi-FI.json +15 -2
  48. package/static/translations/fr-FR.json +15 -2
  49. package/static/translations/hu-HU.json +15 -2
  50. package/static/translations/it-IT.json +15 -2
  51. package/static/translations/ja-JP.json +15 -2
  52. package/static/translations/nl-NL.json +15 -2
  53. package/static/translations/no-NO.json +15 -2
  54. package/static/translations/pl-PL.json +15 -2
  55. package/static/translations/pt-BR.json +15 -2
  56. package/static/translations/pt-PT.json +15 -2
  57. package/static/translations/ro-RO.json +15 -2
  58. package/static/translations/ru-RU.json +15 -2
  59. package/static/translations/sv-SE.json +15 -2
  60. package/static/translations/tr-TR.json +15 -2
  61. package/static/translations/tsconfig.json +12 -2
  62. package/static/translations/uk-UA.json +15 -2
  63. package/utils/EditingInterface.js +18 -4
  64. package/utils/EditingUtils.js +3 -1
  65. package/utils/LayerUtils.js +16 -6
  66. package/utils/MiscUtils.js +65 -0
  67. package/utils/expr_grammar/grammar.js +104 -22
  68. package/utils/expr_grammar/grammar.ne +2 -0
  69. package/utils/expr_grammar/test.js +21 -4
@@ -1,6 +1,10 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
2
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
3
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
4
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
5
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
7
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
4
8
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
9
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
10
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -20,38 +24,37 @@ import ol from 'openlayers';
20
24
  import FeatureStyles from '../../../utils/FeatureStyles';
21
25
  export function createFeatures(options, mapCrs) {
22
26
  var format = new ol.format.GeoJSON();
23
- return (options.features || []).reduce(function (collection, feature) {
24
- var featureObject = format.readFeatures(_objectSpread(_objectSpread({}, feature), {}, {
27
+ return (options.features || []).reduce(function (collection, featureObj) {
28
+ var _ref, _featureObj$crs;
29
+ var feature = format.readFeature(_objectSpread(_objectSpread({}, featureObj), {}, {
25
30
  type: "Feature"
26
31
  }));
27
- featureObject.forEach(function (f) {
28
- var _ref, _feature$crs;
29
- var featureCrs = (_ref = (_feature$crs = feature.crs) !== null && _feature$crs !== void 0 ? _feature$crs : options.projection) !== null && _ref !== void 0 ? _ref : mapCrs;
30
- if (featureCrs.type === "name") {
31
- featureCrs = featureCrs.properties.name;
32
- }
33
- if (featureCrs !== mapCrs) {
34
- var _f$getGeometry;
35
- (_f$getGeometry = f.getGeometry()) === null || _f$getGeometry === void 0 || _f$getGeometry.transform(featureCrs, mapCrs);
36
- }
37
- var featureStyleName = feature.styleName || options.styleName;
38
- var featureStyleOptions = _objectSpread(_objectSpread({}, options.styleOptions), feature.styleOptions);
39
- f.set('styleName', featureStyleName);
40
- f.set('styleOptions', featureStyleOptions);
41
- if (feature.circleParams) {
42
- f.set('circleParams', feature.circleParams);
43
- }
44
- if (feature.shape) {
45
- f.set('shape', feature.shape);
46
- }
47
- if (feature.measurements) {
48
- f.set('measurements', feature.measurements);
49
- }
50
- if (featureStyleName) {
51
- f.setStyle(FeatureStyles[featureStyleName](f, featureStyleOptions));
52
- }
53
- });
54
- return collection.concat(featureObject);
32
+ var featureCrs = (_ref = (_featureObj$crs = featureObj.crs) !== null && _featureObj$crs !== void 0 ? _featureObj$crs : options.projection) !== null && _ref !== void 0 ? _ref : mapCrs;
33
+ if (featureCrs.type === "name") {
34
+ featureCrs = featureCrs.properties.name;
35
+ }
36
+ if (featureCrs !== mapCrs) {
37
+ var _feature$getGeometry;
38
+ (_feature$getGeometry = feature.getGeometry()) === null || _feature$getGeometry === void 0 || _feature$getGeometry.transform(featureCrs, mapCrs);
39
+ }
40
+ var featureStyleName = featureObj.styleName || options.styleName;
41
+ var featureStyleOptions = _objectSpread(_objectSpread({}, options.styleOptions), featureObj.styleOptions);
42
+ feature.set('styleName', featureStyleName);
43
+ feature.set('styleOptions', featureStyleOptions);
44
+ if (featureObj.circleParams) {
45
+ feature.set('circleParams', featureObj.circleParams);
46
+ feature.setGeometry(new ol.geom.Circle(featureObj.circleParams.center, featureObj.circleParams.radius));
47
+ }
48
+ if (featureObj.shape) {
49
+ feature.set('shape', featureObj.shape);
50
+ }
51
+ if (featureObj.measurements) {
52
+ feature.set('measurements', featureObj.measurements);
53
+ }
54
+ if (featureStyleName) {
55
+ feature.setStyle(FeatureStyles[featureStyleName](feature, featureStyleOptions));
56
+ }
57
+ return [].concat(_toConsumableArray(collection), [feature]);
55
58
  }, []);
56
59
  }
57
60
  export function updateFeatures(source, newOptions, oldOptions, mapCrs) {
@@ -85,60 +88,58 @@ export function updateFeatures(source, newOptions, oldOptions, mapCrs) {
85
88
  } finally {
86
89
  _iterator.f();
87
90
  }
88
- var newFeatureObjects = [];
91
+ var newFeatures = [];
89
92
  var _iterator2 = _createForOfIteratorHelper(newOptions.features),
90
93
  _step2;
91
94
  try {
92
- var _loop = function _loop() {
93
- var feature = _step2.value;
94
- if (oldFeaturesMap[feature.id] && oldFeaturesMap[feature.id] === feature) {
95
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
96
+ var _ref2, _featureObj$crs2;
97
+ var featureObj = _step2.value;
98
+ if (oldFeaturesMap[featureObj.id] && oldFeaturesMap[featureObj.id] === featureObj) {
95
99
  // Unchanged, continue
96
- return 1; // continue
100
+ continue;
97
101
  }
98
- if (oldFeaturesMap[feature.id] && oldFeaturesMap[feature.id] !== feature) {
102
+ if (oldFeaturesMap[featureObj.id] && oldFeaturesMap[featureObj.id] !== featureObj) {
99
103
  // Changed, remove
100
- var oldFeature = source.getFeatureById(feature.id);
104
+ var oldFeature = source.getFeatureById(featureObj.id);
101
105
  if (oldFeature) {
102
106
  source.removeFeature(oldFeature);
103
107
  }
104
108
  }
105
109
  // Add new
106
- var featureObject = format.readFeatures(_objectSpread(_objectSpread({}, feature), {}, {
110
+ var _feature = format.readFeature(_objectSpread(_objectSpread({}, featureObj), {}, {
107
111
  type: "Feature"
108
112
  }));
109
- featureObject.forEach(function (f) {
110
- var _ref2, _feature$crs2;
111
- var featureCrs = (_ref2 = (_feature$crs2 = feature.crs) !== null && _feature$crs2 !== void 0 ? _feature$crs2 : newOptions.projection) !== null && _ref2 !== void 0 ? _ref2 : mapCrs;
112
- if (featureCrs.type === "name") {
113
- featureCrs = featureCrs.properties.name;
114
- }
115
- if (featureCrs !== mapCrs) {
116
- var _f$getGeometry2;
117
- (_f$getGeometry2 = f.getGeometry()) === null || _f$getGeometry2 === void 0 || _f$getGeometry2.transform(featureCrs, mapCrs);
118
- }
119
- var featureStyleName = feature.styleName || newOptions.styleName;
120
- var featureStyleOptions = _objectSpread(_objectSpread({}, newOptions.styleOptions), feature.styleOptions);
121
- f.set('styleName', featureStyleName);
122
- f.set('styleOptions', featureStyleOptions);
123
- f.set('circleParams', feature.circleParams);
124
- f.set('shape', feature.shape);
125
- f.set('measurements', feature.measurements);
126
- if (featureStyleName) {
127
- f.setStyle(FeatureStyles[featureStyleName](f, featureStyleOptions));
128
- }
129
- });
130
- newFeatureObjects = newFeatureObjects.concat(featureObject);
131
- };
132
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
133
- if (_loop()) continue;
113
+ var featureCrs = (_ref2 = (_featureObj$crs2 = featureObj.crs) !== null && _featureObj$crs2 !== void 0 ? _featureObj$crs2 : newOptions.projection) !== null && _ref2 !== void 0 ? _ref2 : mapCrs;
114
+ if (featureCrs.type === "name") {
115
+ featureCrs = featureCrs.properties.name;
116
+ }
117
+ if (featureCrs !== mapCrs) {
118
+ var _feature$getGeometry2;
119
+ (_feature$getGeometry2 = _feature.getGeometry()) === null || _feature$getGeometry2 === void 0 || _feature$getGeometry2.transform(featureCrs, mapCrs);
120
+ }
121
+ if (featureObj.circleParams) {
122
+ _feature.setGeometry(new ol.geom.Circle(featureObj.circleParams.center, featureObj.circleParams.radius));
123
+ }
124
+ var featureStyleName = featureObj.styleName || newOptions.styleName;
125
+ var featureStyleOptions = _objectSpread(_objectSpread({}, newOptions.styleOptions), featureObj.styleOptions);
126
+ _feature.set('styleName', featureStyleName);
127
+ _feature.set('styleOptions', featureStyleOptions);
128
+ _feature.set('circleParams', featureObj.circleParams);
129
+ _feature.set('shape', featureObj.shape);
130
+ _feature.set('measurements', featureObj.measurements);
131
+ if (featureStyleName) {
132
+ _feature.setStyle(FeatureStyles[featureStyleName](_feature, featureStyleOptions));
133
+ }
134
+ newFeatures.push(_feature);
134
135
  }
135
136
  } catch (err) {
136
137
  _iterator2.e(err);
137
138
  } finally {
138
139
  _iterator2.f();
139
140
  }
140
- if (newFeatureObjects) {
141
- source.addFeatures(newFeatureObjects);
141
+ if (newFeatures) {
142
+ source.addFeatures(newFeatures);
142
143
  }
143
144
  }
144
145
  export function featureStyleFunction(options) {
@@ -102,6 +102,8 @@ var HeightProfilePrintDialog = /*#__PURE__*/function (_React$PureComponent) {
102
102
  value: function componentDidMount() {
103
103
  var templatePath = MiscUtils.resolveAssetsPath(this.props.templatePath);
104
104
  this.externalWindow = window.open(templatePath, LocaleUtils.tr("heightprofile.title"), "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes");
105
+ // Inherit API
106
+ this.externalWindow.qwc2 = window.qwc2;
105
107
  this.externalWindow.addEventListener('load', this.setWindowContent, false);
106
108
  this.externalWindow.addEventListener('resize', this.windowResized, false);
107
109
  window.addEventListener('beforeunload', this.closePrintWindow);
@@ -552,7 +552,7 @@ var EditTool3D = /*#__PURE__*/function (_React$Component) {
552
552
  }) : null), this.state.selectCount === 0 ? /*#__PURE__*/React.createElement("div", {
553
553
  className: "redlining-message",
554
554
  key: "CtrlHint"
555
- }, LocaleUtils.tr("draw3d.ctrlhint")) : null, this.state.selectCount === 1 ? /*#__PURE__*/React.createElement("div", {
555
+ }, LocaleUtils.tr("redlining.ctrlhint")) : null, this.state.selectCount === 1 ? /*#__PURE__*/React.createElement("div", {
556
556
  className: "redlining-controlsbar",
557
557
  key: "Label"
558
558
  }, /*#__PURE__*/React.createElement("div", {
@@ -169,6 +169,20 @@ button.button > div.spinner {
169
169
  height: 1.5em;
170
170
  }
171
171
 
172
+ button.selected {
173
+ position: relative;
174
+ }
175
+ button.selected:after {
176
+ position: absolute;
177
+ left: 0;
178
+ right: 0;
179
+ bottom: 0;
180
+ height: 3px;
181
+ background-color: var(--color-active);
182
+ border-top: 1px solid var(--border-color);
183
+ content: "";
184
+ }
185
+
172
186
  div.controlgroup {
173
187
  display: flex;
174
188
  align-items: center;
@@ -182,7 +182,7 @@ table.attribtable-table td > div.TextInput > pre {
182
182
  min-height: 2em;
183
183
  }
184
184
 
185
- table.attribtable-table td > *:disabled,
185
+ table.attribtable-table tr.row-disabled td > *:disabled,
186
186
  table.attribtable-table tr.row-disabled,
187
187
  table.attribtable-table tr.row-disabled * {
188
188
  color: var(--text-color-disabled);
@@ -0,0 +1,16 @@
1
+ div.feature-attributes-body table {
2
+ width: 100%;
3
+ }
4
+
5
+ div.feature-attributes-body table td:first-child {
6
+ width: 25%
7
+ }
8
+
9
+ div.feature-attributes-body table td:last-child {
10
+ width: 1%;
11
+ }
12
+
13
+ div.feature-attributes-body table td > input {
14
+ min-width: 0;
15
+ width: 100%;
16
+ }
@@ -76,6 +76,7 @@ div.identify-body div.identify-result-frame:hover {
76
76
 
77
77
  div.identify-body .identify-result-title {
78
78
  background-color: var(--list-section-bg-color);
79
+ color: var(--list-section-text-color);
79
80
  padding: 0.25em;
80
81
  font-weight: bold;
81
82
  flex: 0 0 auto;
@@ -94,6 +95,10 @@ div.identify-body .identify-result-title > span.icon {
94
95
  flex: 0 0 auto;
95
96
  }
96
97
 
98
+ span.identify-result-checkbox {
99
+ background-color: white;
100
+ }
101
+
97
102
  div.identify-body .identify-result-title > span:not(:first-child) {
98
103
  margin-left: 0.5em;
99
104
  }
@@ -0,0 +1,10 @@
1
+ div.LocationRecorder {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ padding: 0.25em 0.5em;
5
+ background-color: var(--container-bg-color);
6
+ box-shadow: 0px -2px 4px rgba(136, 136, 136, 0.5);
7
+ border-bottom: 1px solid rgba(136, 136, 136, 0.5);
8
+ column-gap: 0.25em;
9
+ order: 1;
10
+ }
@@ -2,10 +2,32 @@ div.numeric-input-widget-body > table {
2
2
  width: 100%;
3
3
  }
4
4
 
5
+ div.numeric-input-widget-body > table td {
6
+ padding: 1px 0;
7
+ }
8
+
5
9
  div.numeric-input-widget-body > table input {
6
10
  width: 100%;
7
11
  }
8
12
 
9
13
  div.numeric-input-widget-body > table tr:hover {
10
14
  background-color: var(--list-item-bg-color-hover);
15
+ }
16
+
17
+ div.numeric-input-widget-body > table td:not(:has(> div.TextInput)) {
18
+ width: 1%;
19
+ }
20
+
21
+ div.numeric-input-widget-body > table td:not(:has(> div.TextInput)):not(:first-child) {
22
+ padding-left: 2px;
23
+ }
24
+
25
+ div.numeric-input-widget-body > table td > span {
26
+ display: inline-flex;
27
+ width: 100%;
28
+ border: 1px solid var(--border-color);
29
+ border-right-width: 0;
30
+ height: 2em;
31
+ align-items: center;
32
+ padding: 0 0.25em;
11
33
  }
@@ -25,6 +25,22 @@ div.app-infos-container {
25
25
  row-gap: 0.25em;
26
26
  }
27
27
 
28
+ div.map-bottom-tool-container {
29
+ z-index: 3;
30
+ position: absolute;
31
+ pointer-events: none;
32
+ display: flex;
33
+ flex-direction: column-reverse;
34
+ align-items: center;
35
+ align-content: flex-start;
36
+ justify-content: flex-start;
37
+ margin-bottom: -1px;
38
+ }
39
+
40
+ div.map-bottom-tool-container > * {
41
+ pointer-events: initial;
42
+ }
43
+
28
44
  div.app-info {
29
45
  z-index: 1;
30
46
  color: var(--panel-text-color);
@@ -38,6 +38,7 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
38
38
  _this = _callSuper(this, LayerCatalogWidget, [props]);
39
39
  _defineProperty(_this, "state", {
40
40
  catalog: [],
41
+ filteredCatalog: null,
41
42
  filter: ""
42
43
  });
43
44
  _defineProperty(_this, "toggleLayerListEntry", function (path) {
@@ -64,6 +65,35 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
64
65
  };
65
66
  });
66
67
  });
68
+ _defineProperty(_this, "setFilter", function (text) {
69
+ _this.setState(function (state) {
70
+ if (!text) {
71
+ return {
72
+ filter: text,
73
+ filteredCatalog: null
74
+ };
75
+ }
76
+ var filter = new RegExp(removeDiacritics(text).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i");
77
+ var _filterCatalogEntry = function filterCatalogEntry(res, entry) {
78
+ if (entry.sublayers) {
79
+ var newEntry = _objectSpread(_objectSpread({}, entry), {}, {
80
+ sublayers: entry.sublayers.reduce(_filterCatalogEntry, []),
81
+ expanded: true
82
+ });
83
+ return newEntry.sublayers.length > 0 ? [].concat(_toConsumableArray(res), [newEntry]) : res;
84
+ } else if (removeDiacritics(entry.title).match(filter)) {
85
+ return [].concat(_toConsumableArray(res), [entry]);
86
+ } else {
87
+ return res;
88
+ }
89
+ };
90
+ var filteredCatalog = state.catalog.reduce(_filterCatalogEntry, []);
91
+ return {
92
+ filter: text,
93
+ filteredCatalog: filteredCatalog
94
+ };
95
+ });
96
+ });
67
97
  _defineProperty(_this, "addServiceLayer", function (entry) {
68
98
  var asGroup = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
69
99
  if (entry.resource) {
@@ -116,19 +146,14 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
116
146
  }
117
147
  }, {
118
148
  key: "renderCatalogEntry",
119
- value: function renderCatalogEntry(entry, filter, path) {
149
+ value: function renderCatalogEntry(entry, path) {
120
150
  var _this2 = this;
121
- var level = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
122
- var idx = arguments.length > 4 ? arguments[4] : undefined;
151
+ var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
152
+ var idx = arguments.length > 3 ? arguments[3] : undefined;
123
153
  var hasSublayers = !isEmpty(entry.sublayers);
124
154
  var sublayers = hasSublayers ? entry.sublayers.map(function (sublayer, i) {
125
- return _this2.renderCatalogEntry(sublayer, filter, [].concat(_toConsumableArray(path), [i]), level + 1, i);
155
+ return _this2.renderCatalogEntry(sublayer, [].concat(_toConsumableArray(path), [i]), level + 1, i);
126
156
  }) : [];
127
- if (sublayers.filter(function (item) {
128
- return item;
129
- }).length === 0 && filter && !removeDiacritics(entry.title).match(filter)) {
130
- return null;
131
- }
132
157
  var type = entry.resource ? entry.resource.slice(0, entry.resource.indexOf(":")) : entry.type;
133
158
  var key = (entry.resource || entry.type + ":" + entry.name) + ":" + idx;
134
159
  var indentSize = !this.props.levelBasedIndentSize && level > 0 ? 1.5 : level;
@@ -164,8 +189,8 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
164
189
  }, {
165
190
  key: "render",
166
191
  value: function render() {
167
- var _this3 = this;
168
- var filter = new RegExp(removeDiacritics(this.state.filter).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i");
192
+ var _this$state$filteredC,
193
+ _this3 = this;
169
194
  var emptyEntry = null;
170
195
  if (isEmpty(this.state.catalog) && this.props.pendingRequests === 0) {
171
196
  emptyEntry = /*#__PURE__*/React.createElement("div", {
@@ -177,15 +202,14 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
177
202
  }, LocaleUtils.tr("importlayer.loading"));
178
203
  }
179
204
  var filterplaceholder = LocaleUtils.tr("importlayer.filter");
205
+ var catalog = (_this$state$filteredC = this.state.filteredCatalog) !== null && _this$state$filteredC !== void 0 ? _this$state$filteredC : this.state.catalog;
180
206
  return /*#__PURE__*/React.createElement("div", {
181
207
  className: "layer-catalog-widget"
182
208
  }, /*#__PURE__*/React.createElement(InputContainer, {
183
209
  className: "layer-catalog-widget-filter"
184
210
  }, /*#__PURE__*/React.createElement("input", {
185
211
  onChange: function onChange(ev) {
186
- return _this3.setState({
187
- filter: ev.target.value
188
- });
212
+ return _this3.setFilter(ev.target.value);
189
213
  },
190
214
  placeholder: filterplaceholder,
191
215
  role: "input",
@@ -201,8 +225,8 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
201
225
  role: "suffix"
202
226
  })), /*#__PURE__*/React.createElement("div", {
203
227
  className: "layer-catalog-widget-body"
204
- }, this.state.catalog.map(function (entry, idx) {
205
- return _this3.renderCatalogEntry(entry, filter, [idx], 0, idx);
228
+ }, catalog.map(function (entry, idx) {
229
+ return _this3.renderCatalogEntry(entry, [idx], 0, idx);
206
230
  }), emptyEntry));
207
231
  }
208
232
  }]);
@@ -21,6 +21,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
21
21
  */
22
22
 
23
23
  import React from 'react';
24
+ import classNames from 'classnames';
24
25
  import PropTypes from 'prop-types';
25
26
  import LocaleUtils from '../../utils/LocaleUtils';
26
27
  import Icon from '../Icon';
@@ -40,7 +41,11 @@ var NavBar = /*#__PURE__*/function (_React$Component) {
40
41
  key: idx
41
42
  }, "...");
42
43
  }
43
- var className = "button" + (page === _this.props.currentPage ? " pressed" : "");
44
+ var className = classNames({
45
+ button: true,
46
+ pressed: page === _this.props.currentPage,
47
+ selected: _this.props.selectedPages.includes(page)
48
+ });
44
49
  return /*#__PURE__*/React.createElement("button", {
45
50
  className: className,
46
51
  disabled: _this.props.disabled,
@@ -116,9 +121,11 @@ _defineProperty(NavBar, "propTypes", {
116
121
  pageChanged: PropTypes.func,
117
122
  pageSize: PropTypes.number,
118
123
  pageSizeChanged: PropTypes.func,
119
- pageSizes: PropTypes.array
124
+ pageSizes: PropTypes.array,
125
+ selectedPages: PropTypes.array
120
126
  });
121
127
  _defineProperty(NavBar, "defaultProps", {
122
- pageSizes: [10, 25, 50, 100]
128
+ pageSizes: [10, 25, 50, 100],
129
+ selectedPages: []
123
130
  });
124
131
  export { NavBar as default };
@@ -225,7 +225,7 @@ var TextInput = /*#__PURE__*/function (_React$Component) {
225
225
  "text-input-readonly": this.props.readOnly || !this.state.curValue,
226
226
  "text-input-invalid": this.props.required && !this.state.curValue
227
227
  });
228
- var showClear = this.state.focus && !this.props.multiline && !this.props.disabled && !this.props.readOnly && this.state.curValue;
228
+ var showClear = this.props.showClear && this.state.focus && !this.props.multiline && !this.props.disabled && !this.props.readOnly && this.state.curValue;
229
229
  var style = _objectSpread({}, this.props.style);
230
230
  if (showClear) {
231
231
  style.marginRight = '1.5em';
@@ -303,11 +303,13 @@ _defineProperty(TextInput, "propTypes", {
303
303
  placeholder: PropTypes.string,
304
304
  readOnly: PropTypes.bool,
305
305
  required: PropTypes.bool,
306
+ showClear: PropTypes.bool,
306
307
  style: PropTypes.object,
307
308
  value: PropTypes.string
308
309
  });
309
310
  _defineProperty(TextInput, "defaultProps", {
310
311
  clearValue: "",
311
- placeholder: ""
312
+ placeholder: "",
313
+ showClear: true
312
314
  });
313
315
  export { TextInput as default };
@@ -0,0 +1,75 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Generated by IcoMoon.io -->
3
+
4
+ <svg
5
+ version="1.1"
6
+ width="24"
7
+ height="24"
8
+ viewBox="0 0 24 24"
9
+ id="svg6"
10
+ sodipodi:docname="record.svg"
11
+ inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
12
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ xmlns:svg="http://www.w3.org/2000/svg"
16
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
17
+ xmlns:cc="http://creativecommons.org/ns#"
18
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
19
+ <metadata
20
+ id="metadata12">
21
+ <rdf:RDF>
22
+ <cc:Work
23
+ rdf:about="">
24
+ <dc:format>image/svg+xml</dc:format>
25
+ <dc:type
26
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
27
+ <dc:title>uniE250</dc:title>
28
+ </cc:Work>
29
+ </rdf:RDF>
30
+ </metadata>
31
+ <defs
32
+ id="defs10" />
33
+ <sodipodi:namedview
34
+ pagecolor="#ffffff"
35
+ bordercolor="#666666"
36
+ borderopacity="1"
37
+ objecttolerance="10"
38
+ gridtolerance="10"
39
+ guidetolerance="10"
40
+ inkscape:pageopacity="0"
41
+ inkscape:pageshadow="2"
42
+ inkscape:window-width="1920"
43
+ inkscape:window-height="1172"
44
+ id="namedview8"
45
+ showgrid="true"
46
+ inkscape:zoom="20.85965"
47
+ inkscape:cx="11.697224"
48
+ inkscape:cy="10.810344"
49
+ inkscape:window-x="0"
50
+ inkscape:window-y="0"
51
+ inkscape:window-maximized="1"
52
+ inkscape:current-layer="svg6"
53
+ inkscape:pagecheckerboard="0"
54
+ inkscape:showpageshadow="2"
55
+ inkscape:deskcolor="#d1d1d1">
56
+ <inkscape:grid
57
+ type="xygrid"
58
+ id="grid823"
59
+ originx="0"
60
+ originy="0"
61
+ spacingy="1"
62
+ spacingx="1"
63
+ units="px" />
64
+ </sodipodi:namedview>
65
+ <title
66
+ id="title2">uniE250</title>
67
+ <rect
68
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stop-color:#000000"
69
+ id="rect866"
70
+ width="18"
71
+ height="18"
72
+ x="3"
73
+ y="3"
74
+ ry="9" />
75
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2025.10.16",
3
+ "version": "2025.10.25",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -75,6 +75,7 @@ var AttributeTable = /*#__PURE__*/function (_React$Component) {
75
75
  allowAddForGeometryLayers: this.props.allowAddForGeometryLayers,
76
76
  iface: this.props.iface,
77
77
  initialLayer: (_this$props$taskData = this.props.taskData) === null || _this$props$taskData === void 0 ? void 0 : _this$props$taskData.layer,
78
+ limitToExtent: this.props.limitToExtent,
78
79
  role: "body",
79
80
  showEditFormButton: this.props.showEditFormButton,
80
81
  showHiddenFields: this.props.showHiddenFields,
@@ -90,6 +91,8 @@ _defineProperty(AttributeTable, "propTypes", {
90
91
  allowAddForGeometryLayers: PropTypes.bool,
91
92
  blocked: PropTypes.bool,
92
93
  iface: PropTypes.object,
94
+ /** Whether to limit to the extent by default. */
95
+ limitToExtent: PropTypes.bool,
93
96
  setCurrentTask: PropTypes.func,
94
97
  /** Whether to show a button to open the edit form for selected layer. Requires the Editing plugin to be enabled. */
95
98
  showEditFormButton: PropTypes.bool,
@@ -102,6 +105,7 @@ _defineProperty(AttributeTable, "propTypes", {
102
105
  zoomLevel: PropTypes.number
103
106
  });
104
107
  _defineProperty(AttributeTable, "defaultProps", {
108
+ limitToExtent: false,
105
109
  zoomLevel: 1000,
106
110
  showEditFormButton: true,
107
111
  showHiddenFields: true,
@@ -622,6 +622,9 @@ var GeometryDigitizer = /*#__PURE__*/function (_React$Component) {
622
622
  }), this.renderOutputWindow(), this.state.pickGeomType ? /*#__PURE__*/React.createElement(PickFeature, {
623
623
  featurePicked: this.selectFeature,
624
624
  key: "FeaturePicker",
625
+ layerFilterFunc: function layerFilterFunc(layer) {
626
+ return !layer.id.startsWith("__geomdigitizer");
627
+ },
625
628
  pickGeomType: this.state.pickGeomType
626
629
  }) : null];
627
630
  }
@@ -109,7 +109,8 @@ var HeightProfilePrintDialog_ = /*#__PURE__*/function (_React$PureComponent) {
109
109
  fillColor: [255, 255, 255, 1],
110
110
  strokeColor: [255, 0, 0, 1],
111
111
  strokeWidth: 2,
112
- circleRadius: 6
112
+ circleRadius: 6,
113
+ strokeDash: []
113
114
  }
114
115
  };
115
116
  })), [{
@@ -121,6 +122,7 @@ var HeightProfilePrintDialog_ = /*#__PURE__*/function (_React$PureComponent) {
121
122
  styleOptions: {
122
123
  strokeColor: [255, 0, 0, 1],
123
124
  strokeWidth: 4,
125
+ strokeDash: [],
124
126
  headmarker: _this.props.measurement.lineHeadMarker,
125
127
  tailmarker: _this.props.measurement.lineTailMarker
126
128
  },
@@ -208,6 +210,8 @@ var HeightProfilePrintDialog_ = /*#__PURE__*/function (_React$PureComponent) {
208
210
  value: function componentDidMount() {
209
211
  var templatePath = MiscUtils.resolveAssetsPath(this.props.templatePath);
210
212
  this.externalWindow = window.open(templatePath, LocaleUtils.tr("heightprofile.title"), "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes");
213
+ // Inherit API
214
+ this.externalWindow.qwc2 = window.qwc2;
211
215
  this.externalWindow.addEventListener('load', this.setWindowContent, false);
212
216
  this.externalWindow.addEventListener('resize', this.windowResized, false);
213
217
  window.addEventListener('beforeunload', this.closePrintWindow);