-
Notifications
You must be signed in to change notification settings - Fork 2
/
settingsdialogimpl.py
185 lines (144 loc) · 7.97 KB
/
settingsdialogimpl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
""" MultiLayer Select Settings Dialog
Allow to define:
- The selection color used for selected feature, icons and rubberbands
- Whether the plugin actions replace the default ones or not
- Whether the settings action (which launch this dialog) is available in the toolbar
- Whether selecting a feature changes the active layer
"""
from collections import Counter
from qgis.PyQt.QtCore import pyqtSignal, QSettings, Qt
from qgis.PyQt.QtGui import QColor, QIcon
from qgis.PyQt.QtWidgets import QDialog
from qgis.utils import iface
from qgis.core import QgsMapLayerProxyModel, QgsMapLayerModel, QgsProject
from .settingsdialog import Ui_SettingsDialog
from .utils import icon_from_layer
class LayerModel(QgsMapLayerProxyModel):
"""Checkable Layer Model to include / exclude vector layers from the multilayer
selection tools"""
def __init__(self, parent=None):
super().__init__(parent)
self.setFilters(QgsMapLayerProxyModel.VectorLayer)
def name_list(self):
"""Return the list of vector layer names"""
names = []
for i in range(self.rowCount()):
names.append(super().data(self.index(i, 0)))
return names
def non_unique_names(self):
"""Return the list of non-unique vector layer names"""
return [k for k, v in Counter(self.name_list()).items() if v > 1]
def include_all(self):
"""Include all layers in the multiselection tools (default behavior)
Remove the custom property from every layers"""
for layer in QgsProject.instance().mapLayers().values():
layer.removeCustomProperty("plugins/multilayerselect/excluded")
self.dataChanged.emit(self.index(0, 0), self.index(self.rowCount(), 0), [Qt.CheckStateRole])
def exlude_all(self):
"""Exclude all layers from the multiselection tools
This is done by addinf a custom property on the layers"""
for layer in QgsProject.instance().mapLayers().values():
layer.setCustomProperty("plugins/multilayerselect/excluded", True)
self.dataChanged.emit(self.index(0, 0), self.index(self.rowCount(), 0), [Qt.CheckStateRole])
def flags(self, index):
"""Make the model checkable"""
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
def setData(self, index, value, role=Qt.DisplayRole):
"""When checking an item, set the matching layer's custom property"""
layer = super().data(index, QgsMapLayerModel.LayerRole)
if not layer:
return super().setData(index, value, role)
if role == Qt.CheckStateRole:
layer.setCustomProperty("plugins/multilayerselect/excluded", value == Qt.Unchecked)
return True
return super().setData(index, value, role)
def data(self, index, role=Qt.DisplayRole):
"""Custom data function"""
layer = super().data(index, QgsMapLayerModel.LayerRole)
if not layer:
return super().data(index, role)
# If layer name is unique, returns <layerName>, else return <layerName> (<id>)
if role == Qt.DisplayRole:
original_name = super().data(index, role)
if original_name in self.non_unique_names():
return f"{original_name} ({super().data(index, QgsMapLayerModel.LayerIdRole)})"
# Get the icon from the layer tree view
if role == Qt.DecorationRole:
return icon_from_layer(layer)
if role == Qt.CheckStateRole:
excluded = layer.customProperty("plugins/multilayerselect/excluded", False) in (True, "true", "True", "1")
return 0 if excluded else 2
return super().data(index, role)
class SettingsDialog(QDialog, Ui_SettingsDialog):
"""Settings Dialog implementation"""
settingsChanged = pyqtSignal() # noqa: N815
colorChanged = pyqtSignal() # noqa: N815
def __init__(self, settings, parent=None):
super().__init__(parent)
self.setupUi(self)
self.settings = settings
self.setWindowIcon(QIcon(":/plugins/multilayerselect/icons/icon.svg"))
qgis_settings = QSettings()
red = qgis_settings.value("qgis/default_selection_color_red", 255, int)
green = qgis_settings.value("qgis/default_selection_color_green", 255, int)
blue = qgis_settings.value("qgis/default_selection_color_blue", 0, int)
alpha = qgis_settings.value("qgis/default_selection_color_alpha", 255, int)
self.selectionColorButton.setDefaultColor(QColor.fromRgb(red, green, blue, alpha))
self.selectionColorButton.setColor(iface.mapCanvas().selectionColor())
self.onlyVisibleCheckBox.setChecked(self.settings.value("only_visible", True, bool))
self.activeLayerCheckBox.setChecked(self.settings.value("set_active_layer", True, bool))
self.showSettingsCheckBox.setChecked(self.settings.value("show_settings", True, bool))
self.replaceActionsCheckBox.setChecked(self.settings.value("replace_actions", False, bool))
self.includeActiveLayerCheckBox.setChecked(self.settings.value("always_include_active_layer", True, bool))
self.layer_model = LayerModel(self)
self.view.setModel(self.layer_model)
# Connect signals
self.selectionColorButton.colorChanged.connect(self.on_color_changed)
self.onlyVisibleCheckBox.toggled.connect(self.on_only_visible_changed)
self.activeLayerCheckBox.toggled.connect(self.on_active_layer_changed)
self.showSettingsCheckBox.toggled.connect(self.on_show_settings_changed)
self.replaceActionsCheckBox.toggled.connect(self.on_replace_actions_changed)
self.includeActiveLayerCheckBox.toggled.connect(self.on_always_include_active_layer_changed)
self.excludeButton.clicked.connect(self.layer_model.exlude_all)
self.includeButton.clicked.connect(self.layer_model.include_all)
def on_project_color_changed(self):
"""Called to update the color button when the project selection color changes,
or when the project is read for QGIS < 3.10"""
try:
self.selectionColorButton.setColor(QgsProject.instance().selectionColor())
except AttributeError: # QGIS < 3.10
self.selectionColorButton.setColor(iface.mapCanvas().selectionColor())
def on_color_changed(self, color: QColor):
"""Set the project selection color from the color button"""
try:
QgsProject.instance().setSelectionColor(color)
# Mark the project dirty to make it "saveable"
QgsProject.instance().setDirty()
except AttributeError: # QGIS < 3.10
iface.mapCanvas().setSelectionColor(color)
QgsProject.instance().writeEntry("Gui", "SelectionColorRedPart", color.red())
QgsProject.instance().writeEntry("Gui", "SelectionColorBluePart", color.blue())
QgsProject.instance().writeEntry("Gui", "SelectionColorGreenPart", color.green())
QgsProject.instance().writeEntry("Gui", "SelectionColorAlphaPart", color.alpha())
# Will trigger the icon color change
self.colorChanged.emit()
def on_only_visible_changed(self, checked):
"""Update the only_visible setting"""
self.settings.setValue("only_visible", checked)
self.settingsChanged.emit()
def on_active_layer_changed(self, checked):
"""Update the set_active_layer setting"""
self.settings.setValue("set_active_layer", checked)
self.settingsChanged.emit()
def on_show_settings_changed(self, checked):
"""Update the show_settings setting"""
self.settings.setValue("show_settings", checked)
self.settingsChanged.emit()
def on_replace_actions_changed(self, checked):
"""Update the replace_actions setting"""
self.settings.setValue("replace_actions", checked)
self.settingsChanged.emit()
def on_always_include_active_layer_changed(self, checked):
"""Update the replace_actions setting"""
self.settings.setValue("always_include_active_layer", checked)
self.settingsChanged.emit()