Skip to content

Commit af8a62d

Browse files
volayaalexbruy
authored andcommittedMar 1, 2016
[processing] alg menus can now be configured from Processing options
1 parent 5df0ce0 commit af8a62d

File tree

6 files changed

+238
-285
lines changed

6 files changed

+238
-285
lines changed
 

‎python/plugins/processing/ProcessingPlugin.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
from PyQt4.QtGui import QMenu, QAction, QIcon
3535

3636
from processing.core.Processing import Processing
37-
from processing.core.ProcessingConfig import ProcessingConfig
3837
from processing.gui.ProcessingToolbox import ProcessingToolbox
3938
from processing.gui.HistoryDialog import HistoryDialog
4039
from processing.gui.ConfigDialog import ConfigDialog
4140
from processing.gui.ResultsDialog import ResultsDialog
4241
from processing.gui.CommanderWindow import CommanderWindow
4342
from processing.modeler.ModelerDialog import ModelerDialog
4443
from processing.tools.system import tempFolder
44+
from processing.gui.menus import removeMenus, initializeMenus, createMenus
4545

4646

4747
cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
@@ -120,7 +120,8 @@ def initGui(self):
120120
self.iface.registerMainWindowAction(self.commanderAction,
121121
self.tr('Ctrl+Alt+M'))
122122

123-
Processing.updateMenus()
123+
initializeMenus()
124+
createMenus()
124125

125126
def unload(self):
126127
self.toolbox.setVisible(False)
@@ -138,6 +139,8 @@ def unload(self):
138139
self.iface.unregisterMainWindowAction(self.resultsAction)
139140
self.iface.unregisterMainWindowAction(self.commanderAction)
140141

142+
removeMenus()
143+
141144
def openCommander(self):
142145
if self.commander is None:
143146
self.commander = CommanderWindow(

‎python/plugins/processing/core/Processing.py

Lines changed: 0 additions & 270 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@
6060
from processing.tools import dataobjects
6161

6262

63-
algorithmsToolbar = None
64-
65-
6663
class Processing:
6764

6865
listeners = []
@@ -378,273 +375,6 @@ def runAlgorithm(algOrName, onFinish, *args, **kwargs):
378375
progress.close()
379376
return alg
380377

381-
@staticmethod
382-
def createVectorMenu():
383-
algs = ['qgis:distancematrix', 'qgis:sumlinelengths',
384-
'qgis:pointsinpolygon', 'qgis:listuniquevalues',
385-
'qgis:basicstatisticsfornumericfields',
386-
'qgis:basicstatisticsfortextfields',
387-
'qgis:nearestneighbouranalysis', 'qgis:meancoordinates',
388-
'qgis:lineintersecions']
389-
for alg in algs:
390-
Processing._addVectorAlgorithm(alg, Processing.tr('&Analysis Tools'))
391-
392-
algs = ['qgis:randomselection', 'qgis:randomselectionwithinsubsets',
393-
'qgis:randompointsinextent', 'qgis:randompointsinlayerbounds',
394-
'qgis:randompointsinsidepolygonsfixed',
395-
'qgis:randompointsinsidepolygonsvariable',
396-
'qgis:regularpoints', 'qgis:vectorgrid',
397-
'qgis:selectbylocation', 'qgis:polygonfromlayerextent']
398-
for alg in algs:
399-
Processing._addVectorAlgorithm(alg, Processing.tr('&Research Tools'))
400-
401-
algs = ['qgis:convexhull', 'qgis:fixeddistancebuffer',
402-
'qgis:variabledistancebuffer', 'qgis:intersection',
403-
'qgis:union', 'qgis:symmetricaldifference', 'qgis:clip',
404-
'qgis:difference', 'qgis:dissolve',
405-
'qgis:eliminatesliverpolygons']
406-
for alg in algs:
407-
Processing._addVectorAlgorithm(alg, Processing.tr('&Geoprocessing Tools'))
408-
409-
algs = ['qgis:checkvalidity', 'qgis:exportaddgeometrycolumns',
410-
'qgis:polygoncentroids', 'qgis:delaunaytriangulation',
411-
'qgis:voronoipolygons', 'qgis:simplifygeometries',
412-
'qgis:densifygeometries', 'qgis:multiparttosingleparts',
413-
'qgis:singlepartstomultipart', 'qgis:polygonstolines',
414-
'qgis:linestopolygons', 'qgis:extractnodes']
415-
for alg in algs:
416-
Processing._addVectorAlgorithm(alg, Processing.tr('G&eometry Tools'))
417-
418-
algs = ['qgis:definecurrentprojection',
419-
'qgis:joinattributesbylocation', 'qgis:splitvectorlayer',
420-
'qgis:mergevectorlayers','qgis:createspatialindex']
421-
for alg in algs:
422-
Processing._addVectorAlgorithm(alg, Processing.tr('&Data Management Tools'))
423-
424-
@staticmethod
425-
def createRasterMenu():
426-
algs = ['gdalogr:warpreproject', 'gdalogr:assignprojection', 'gdalogr:extractprojection']
427-
for alg in algs:
428-
Processing._addRasterAlgorithm(alg, Processing.tr('Projections'))
429-
430-
algs = ['gdalogr:rasterize', 'gdalogr:rasterize_over',
431-
'gdalogr:polygonize', 'gdalogr:translate', 'gdalogr:rgbtopct',
432-
'gdalogr:pcttorgb']
433-
for alg in algs:
434-
Processing._addRasterAlgorithm(alg, Processing.tr('Conversion'))
435-
436-
algs = ['gdalogr:contour', 'gdalogr:cliprasterbyextent',
437-
'gdalogr:cliprasterbymasklayer']
438-
for alg in algs:
439-
Processing._addRasterAlgorithm(alg, Processing.tr('Extraction'))
440-
441-
algs = ['gdalogr:sieve', 'gdalogr:nearblack', 'gdalogr:fillnodata',
442-
'gdalogr:proximity', 'gdalogr:griddatametrics',
443-
'gdalogr:gridaverage', 'gdalogr:gridinvdist',
444-
'gdalogr:gridnearestneighbor', 'gdalogr:aspect',
445-
'gdalogr:hillshade', 'gdalogr:roughness', 'gdalogr:slope',
446-
'gdalogr:tpi', 'gdalogr:tri']
447-
for alg in algs:
448-
Processing._addRasterAlgorithm(alg, Processing.tr('Analysis'))
449-
450-
algs = ['gdalogr:buildvirtualraster', 'gdalogr:merge',
451-
'gdalogr:rasterinfo', 'gdalogr:overviews', 'gdalogr:tileindex']
452-
for alg in algs:
453-
Processing._addRasterAlgorithm(alg, Processing.tr('Miscellaneous'))
454-
455-
@staticmethod
456-
def removeVectorMenu():
457-
algs = ['qgis:distancematrix', 'qgis:sumlinelengths',
458-
'qgis:pointsinpolygon', 'qgis:listuniquevalues',
459-
'qgis:basicstatisticsfornumericfields',
460-
'qgis:basicstatisticsfortextfields',
461-
'qgis:nearestneighbouranalysis', 'qgis:meancoordinates',
462-
'qgis:lineintersecions']
463-
for alg in algs:
464-
Processing._removeVectorAlgorithm(alg, Processing.tr('&Analysis Tools'))
465-
466-
algs = ['qgis:randomselection', 'qgis:randomselectionwithinsubsets',
467-
'qgis:randompointsinextent', 'qgis:randompointsinlayerbounds',
468-
'qgis:randompointsinsidepolygonsfixed',
469-
'qgis:randompointsinsidepolygonsvariable',
470-
'qgis:regularpoints', 'qgis:vectorgrid',
471-
'qgis:selectbylocation', 'qgis:polygonfromlayerextent']
472-
for alg in algs:
473-
Processing._removeVectorAlgorithm(alg, Processing.tr('&Research Tools'))
474-
475-
algs = ['qgis:convexhull', 'qgis:fixeddistancebuffer',
476-
'qgis:variabledistancebuffer', 'qgis:intersection',
477-
'qgis:union', 'qgis:symmetricaldifference', 'qgis:clip',
478-
'qgis:difference', 'qgis:dissolve',
479-
'qgis:eliminatesliverpolygons']
480-
for alg in algs:
481-
Processing._removeVectorAlgorithm(alg, Processing.tr('&Geoprocessing Tools'))
482-
483-
algs = ['qgis:checkvalidity', 'qgis:exportaddgeometrycolumns',
484-
'qgis:polygoncentroids', 'qgis:delaunaytriangulation',
485-
'qgis:voronoipolygons', 'qgis:simplifygeometries',
486-
'qgis:densifygeometries', 'qgis:multiparttosingleparts',
487-
'qgis:singlepartstomultipart', 'qgis:polygonstolines',
488-
'qgis:linestopolygons', 'qgis:extractnodes']
489-
for alg in algs:
490-
Processing._removeVectorAlgorithm(alg, Processing.tr('G&eometry Tools'))
491-
492-
algs = ['qgis:definecurrentprojection',
493-
'qgis:joinattributesbylocation', 'qgis:splitvectorlayer',
494-
'qgis:mergevectorlayers','qgis:createspatialindex']
495-
for alg in algs:
496-
Processing._removeVectorAlgorithm(alg, Processing.tr('&Data Management Tools'))
497-
498-
@staticmethod
499-
def removeRasterMenu():
500-
algs = ['gdalogr:warpreproject', 'gdalogr:assignprojection', 'gdalogr:extractprojection']
501-
for alg in algs:
502-
Processing._removeRasterAlgorithm(alg, Processing.tr('Projections'))
503-
504-
algs = ['gdalogr:rasterize', 'gdalogr:rasterize_over',
505-
'gdalogr:polygonize', 'gdalogr:translate', 'gdalogr:rgbtopct',
506-
'gdalogr:pcttorgb']
507-
for alg in algs:
508-
Processing._removeRasterAlgorithm(alg, Processing.tr('Conversion'))
509-
510-
algs = ['gdalogr:contour', 'gdalogr:cliprasterbyextent',
511-
'gdalogr:cliprasterbymasklayer']
512-
for alg in algs:
513-
Processing._removeRasterAlgorithm(alg, Processing.tr('Extraction'))
514-
515-
algs = ['gdalogr:sieve', 'gdalogr:nearblack', 'gdalogr:fillnodata',
516-
'gdalogr:proximity', 'gdalogr:griddatametrics',
517-
'gdalogr:gridaverage', 'gdalogr:gridinvdist',
518-
'gdalogr:gridnearestneighbor', 'gdalogr:aspect',
519-
'gdalogr:hillshade', 'gdalogr:roughness', 'gdalogr:slope',
520-
'gdalogr:tpi', 'gdalogr:tri']
521-
for alg in algs:
522-
Processing._removeRasterAlgorithm(alg, Processing.tr('Analysis'))
523-
524-
algs = ['gdalogr:buildvirtualraster', 'gdalogr:merge',
525-
'gdalogr:rasterinfo', 'gdalogr:overviews', 'gdalogr:tileindex']
526-
for alg in algs:
527-
Processing._removeRasterAlgorithm(alg, Processing.tr('Miscellaneous'))
528-
529-
@staticmethod
530-
def _addRasterAlgorithm(name, group):
531-
Processing.addAlgorithmEntry(name, Processing.tr('&Raster'), group)
532-
533-
@staticmethod
534-
def _addVectorAlgorithm( name, group):
535-
Processing.addAlgorithmEntry(name, Processing.tr('Vect&or'), group)
536-
537-
@staticmethod
538-
def _removeRasterAlgorithm(name, group):
539-
Processing.removeAlgorithmEntry(name, Processing.tr('&Raster'), group)
540-
541-
@staticmethod
542-
def _removeVectorAlgorithm( name, group):
543-
Processing.removeAlgorithmEntry(name, Processing.tr('Vect&or'), group)
544-
545-
@staticmethod
546-
def updateMenus():
547-
showVector = ProcessingConfig.getSetting(
548-
ProcessingConfig.SHOW_VECTOR_MENUS)
549-
if showVector:
550-
Processing.createVectorMenu()
551-
else:
552-
Processing.removeVectorMenu()
553-
554-
showRaster = ProcessingConfig.getSetting(
555-
ProcessingConfig.SHOW_RASTER_MENUS)
556-
if showRaster:
557-
Processing.createRasterMenu()
558-
else:
559-
Processing.removeRasterMenu()
560-
561-
@staticmethod
562-
def addAlgorithmEntry(algname, menuName, submenuName, actionText=None, icon=None, addButton=False):
563-
alg = Processing.getAlgorithm(algname)
564-
if alg is None:
565-
return
566-
567-
action = QAction(icon or alg.getIcon(), actionText or alg.name, iface.mainWindow())
568-
action.triggered.connect(lambda: Processing._executeAlgorithm(alg))
569-
570-
if menuName:
571-
menu = Processing.getMenu(menuName, iface.mainWindow().menuBar())
572-
submenu = Processing.getMenu(submenuName, menu)
573-
submenu.addAction(action)
574-
575-
if addButton:
576-
global algorithmsToolbar
577-
if algorithmsToolbar is None:
578-
algorithmsToolbar = iface.addToolBar('ProcessingAlgorithms')
579-
algorithmsToolbar.addAction(action)
580-
581-
@staticmethod
582-
def removeAlgorithmEntry(algname, menuName, submenuName, actionText=None, delButton=True):
583-
alg = Processing.getAlgorithm(algname)
584-
if alg is None:
585-
return
586-
587-
if menuName:
588-
menu = Processing.getMenu(menuName, iface.mainWindow().menuBar())
589-
subMenu = Processing.getMenu(submenuName, menu)
590-
action = Processing.findAction(subMenu.actions(), alg, actionText)
591-
if action is not None:
592-
subMenu.removeAction(action)
593-
594-
if len(subMenu.actions()) == 0:
595-
menu.removeAction(subMenu.menuAction())
596-
597-
if delButton:
598-
global algorithmsToolbar
599-
if algorithmsToolbar is not None:
600-
action = Processing.findAction(algorithmsToolbar.actions(), alg, actionText)
601-
if action is not None:
602-
algorithmsToolbar.removeAction(action)
603-
604-
@staticmethod
605-
def _executeAlgorithm(alg):
606-
message = alg.checkBeforeOpeningParametersDialog()
607-
if message:
608-
dlg = MessageDialog()
609-
dlg.setTitle(tr('Missing dependency'))
610-
dlg.setMessage(
611-
tr('<h3>Missing dependency. This algorithm cannot '
612-
'be run :-( </h3>\n%s') % message)
613-
dlg.exec_()
614-
return
615-
alg = alg.getCopy()
616-
dlg = alg.getCustomParametersDialog()
617-
if not dlg:
618-
dlg = AlgorithmDialog(alg)
619-
canvas = iface.mapCanvas()
620-
prevMapTool = canvas.mapTool()
621-
dlg.show()
622-
dlg.exec_()
623-
if canvas.mapTool() != prevMapTool:
624-
try:
625-
canvas.mapTool().reset()
626-
except:
627-
pass
628-
canvas.setMapTool(prevMapTool)
629-
630-
@staticmethod
631-
def getMenu(name, parent):
632-
menus = [c for c in parent.children() if isinstance(c, QMenu)]
633-
menusDict = {m.title(): m for m in menus}
634-
if name in menusDict:
635-
return menusDict[name]
636-
else:
637-
menu = QMenu(name, parent)
638-
parent.addMenu(menu)
639-
return menu
640-
641-
@staticmethod
642-
def findAction(actions, alg, actionText=None):
643-
for action in actions:
644-
if action.text() in [actionText, alg.name]:
645-
return action
646-
return None
647-
648378

649379
@staticmethod
650380
def tr(string, context=''):

‎python/plugins/processing/core/ProcessingConfig.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ class ProcessingConfig:
4141
VECTOR_LINE_STYLE = 'VECTOR_LINE_STYLE'
4242
VECTOR_POLYGON_STYLE = 'VECTOR_POLYGON_STYLE'
4343
SHOW_RECENT_ALGORITHMS = 'SHOW_RECENT_ALGORITHMS'
44-
SHOW_VECTOR_MENUS = 'SHOW_VECTOR_MENUS'
45-
SHOW_RASTER_MENUS = 'SHOW_RASTER_MENUS'
4644
USE_SELECTED = 'USE_SELECTED'
4745
USE_FILENAME_AS_LAYER_NAME = 'USE_FILENAME_AS_LAYER_NAME'
4846
KEEP_DIALOG_OPEN = 'KEEP_DIALOG_OPEN'
@@ -83,14 +81,6 @@ def initialize():
8381
ProcessingConfig.tr('General'),
8482
ProcessingConfig.SHOW_RECENT_ALGORITHMS,
8583
ProcessingConfig.tr('Show recently executed algorithms'), True))
86-
ProcessingConfig.addSetting(Setting(
87-
ProcessingConfig.tr('General'),
88-
ProcessingConfig.SHOW_VECTOR_MENUS,
89-
ProcessingConfig.tr('Add entries to the Vector menu'), True))
90-
ProcessingConfig.addSetting(Setting(
91-
ProcessingConfig.tr('General'),
92-
ProcessingConfig.SHOW_RASTER_MENUS,
93-
ProcessingConfig.tr('Add entries to the Raster menu'), True))
9484
ProcessingConfig.addSetting(Setting(
9585
ProcessingConfig.tr('General'),
9686
ProcessingConfig.SHOW_PROVIDERS_TOOLTIP,

‎python/plugins/processing/gui/ConfigDialog.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
***************************************************************************
1818
"""
1919

20-
2120
__author__ = 'Victor Olaya'
2221
__date__ = 'August 2012'
2322
__copyright__ = '(C) 2012, Victor Olaya'
@@ -38,6 +37,8 @@
3837

3938
from processing.core.ProcessingConfig import ProcessingConfig, Setting
4039
from processing.core.Processing import Processing
40+
from processing.gui.menus import updateMenus, defaultMenuEntries
41+
4142

4243
pluginPath = os.path.split(os.path.dirname(__file__))[0]
4344
WIDGET, BASE = uic.loadUiType(
@@ -92,7 +93,7 @@ def fillTree(self):
9293
emptyItem.setEditable(False)
9394
rootItem.insertRow(0, [groupItem, emptyItem])
9495
for setting in settings[group]:
95-
if setting.hidden:
96+
if setting.hidden or setting.name.startswith("MENU_"):
9697
continue
9798

9899
if text == '' or text.lower() in setting.description.lower():
@@ -135,6 +136,30 @@ def fillTree(self):
135136
emptyItem.setEditable(False)
136137
providersItem.appendRow([groupItem, emptyItem])
137138

139+
menusItem = QStandardItem(self.tr('Menus (requires restart)'))
140+
icon = QIcon(os.path.join(pluginPath, 'images', 'menu.png'))
141+
menusItem.setIcon(icon)
142+
menusItem.setEditable(False)
143+
emptyItem = QStandardItem()
144+
emptyItem.setEditable(False)
145+
rootItem.insertRow(0, [menusItem, emptyItem])
146+
providers = Processing.providers
147+
for provider in providers:
148+
groupItem = QStandardItem(provider.getDescription())
149+
icon = provider.getIcon()
150+
groupItem.setIcon(icon)
151+
groupItem.setEditable(False)
152+
for alg in provider.algs:
153+
labelItem = QStandardItem(alg.name)
154+
labelItem.setIcon(icon)
155+
labelItem.setEditable(False)
156+
setting = ProcessingConfig.settings["MENU_" + alg.commandLineName()]
157+
self.items[setting] = SettingItem(setting)
158+
groupItem.insertRow(0, [labelItem, self.items[setting]])
159+
emptyItem = QStandardItem()
160+
emptyItem.setEditable(False)
161+
menusItem.appendRow([groupItem, emptyItem])
162+
138163
self.tree.sortByColumn(0, Qt.AscendingOrder)
139164
self.adjustColumns()
140165

@@ -151,7 +176,7 @@ def accept(self):
151176
return
152177
setting.save()
153178
Processing.updateAlgsList()
154-
Processing.updateMenus()
179+
updateMenus()
155180

156181
QDialog.accept(self)
157182

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
from processing.core.Processing import Processing
2+
from processing.core.ProcessingConfig import ProcessingConfig, Setting
3+
from PyQt4.Qt import QAction, QMenu
4+
from processing.gui.MessageDialog import MessageDialog
5+
from processing.gui.AlgorithmDialog import AlgorithmDialog
6+
from qgis.utils import iface
7+
8+
algorithmsToolbar = None
9+
10+
defaultMenuEntries = {}
11+
vectorMenu = Processing.tr('Vect&or')
12+
analysisToolsMenu = vectorMenu + "/" + Processing.tr('&Analysis Tools')
13+
defaultMenuEntries.update({'qgis:distancematrix':analysisToolsMenu,
14+
'qgis:sumlinelengths':analysisToolsMenu,
15+
'qgis:pointsinpolygon':analysisToolsMenu,
16+
'qgis:listuniquevalues':analysisToolsMenu,
17+
'qgis:basicstatisticsfornumericfields':analysisToolsMenu,
18+
'qgis:basicstatisticsfortextfields':analysisToolsMenu,
19+
'qgis:nearestneighbouranalysis':analysisToolsMenu,
20+
'qgis:meancoordinates':analysisToolsMenu,
21+
'qgis:lineintersecions':analysisToolsMenu})
22+
researchToolsMenu = vectorMenu + "/" + Processing.tr('&Research Tools')
23+
defaultMenuEntries.update({'qgis:randomselection':researchToolsMenu,
24+
'qgis:randomselectionwithinsubsets':researchToolsMenu,
25+
'qgis:randompointsinextent':researchToolsMenu,
26+
'qgis:randompointsinlayerbounds':researchToolsMenu,
27+
'qgis:randompointsinsidepolygonsfixed':researchToolsMenu,
28+
'qgis:randompointsinsidepolygonsvariable':researchToolsMenu,
29+
'qgis:regularpoints':researchToolsMenu,
30+
'qgis:vectorgrid':researchToolsMenu,
31+
'qgis:selectbylocation':researchToolsMenu,
32+
'qgis:polygonfromlayerextent':researchToolsMenu})
33+
34+
geoprocessingToolsMenu = vectorMenu + "/" + Processing.tr('&Geoprocessing Tools')
35+
defaultMenuEntries.update({'qgis:convexhull':geoprocessingToolsMenu,
36+
'qgis:fixeddistancebuffer':geoprocessingToolsMenu,
37+
'qgis:variabledistancebuffer':geoprocessingToolsMenu,
38+
'qgis:intersection':geoprocessingToolsMenu,
39+
'qgis:union':geoprocessingToolsMenu,
40+
'qgis:symmetricaldifference':geoprocessingToolsMenu,
41+
'qgis:clip':geoprocessingToolsMenu,
42+
'qgis:difference':geoprocessingToolsMenu,
43+
'qgis:dissolve':geoprocessingToolsMenu,
44+
'qgis:eliminatesliverpolygons':geoprocessingToolsMenu})
45+
geometryToolsMenu = vectorMenu + "/" + Processing.tr('G&eometry Tools')
46+
defaultMenuEntries.update({'qgis:checkvalidity':geometryToolsMenu,
47+
'qgis:exportaddgeometrycolumns':geometryToolsMenu,
48+
'qgis:polygoncentroids':geometryToolsMenu,
49+
'qgis:delaunaytriangulation':geometryToolsMenu,
50+
'qgis:voronoipolygons':geometryToolsMenu,
51+
'qgis:simplifygeometries':geometryToolsMenu,
52+
'qgis:densifygeometries':geometryToolsMenu,
53+
'qgis:multiparttosingleparts':geometryToolsMenu,
54+
'qgis:singlepartstomultipart':geometryToolsMenu,
55+
'qgis:polygonstolines':geometryToolsMenu,
56+
'qgis:linestopolygons':geometryToolsMenu,
57+
'qgis:extractnodes':geometryToolsMenu})
58+
managementToolsMenu = vectorMenu + "/" + Processing.tr('&Data Management Tools')
59+
defaultMenuEntries.update({'qgis:definecurrentprojection':managementToolsMenu,
60+
'qgis:joinattributesbylocation':managementToolsMenu,
61+
'qgis:splitvectorlayer':managementToolsMenu,
62+
'qgis:mergevectorlayers':managementToolsMenu,
63+
'qgis:createspatialindex':managementToolsMenu})
64+
rasterMenu = Processing.tr('&Raster')
65+
projectionsMenu = rasterMenu + "/" + Processing.tr('Projections')
66+
defaultMenuEntries.update({'gdalogr:warpreproject':projectionsMenu,
67+
'gdalogr:assignprojection':projectionsMenu,
68+
'gdalogr:extractprojection':projectionsMenu})
69+
conversionMenu = rasterMenu + "/" + Processing.tr('Conversion')
70+
defaultMenuEntries.update({'gdalogr:rasterize':conversionMenu,
71+
'gdalogr:rasterize_over':conversionMenu,
72+
'gdalogr:polygonize':conversionMenu,
73+
'gdalogr:translate':conversionMenu,
74+
'gdalogr:rgbtopct':conversionMenu,
75+
'gdalogr:pcttorgb':conversionMenu})
76+
extractionMenu = rasterMenu + "/" + Processing.tr('Extraction')
77+
defaultMenuEntries.update({'gdalogr:contour':extractionMenu,
78+
'gdalogr:cliprasterbyextent':extractionMenu,
79+
'gdalogr:cliprasterbymasklayer':extractionMenu})
80+
analysisMenu = rasterMenu + "/" + Processing.tr('Analysis')
81+
defaultMenuEntries.update({'gdalogr:sieve':analysisMenu, 'gdalogr:nearblack':analysisMenu,
82+
'gdalogr:fillnodata':analysisMenu,
83+
'gdalogr:proximity':analysisMenu,
84+
'gdalogr:griddatametrics':analysisMenu,
85+
'gdalogr:gridaverage':analysisMenu,
86+
'gdalogr:gridinvdist':analysisMenu,
87+
'gdalogr:gridnearestneighbor':analysisMenu,
88+
'gdalogr:aspect':analysisMenu,
89+
'gdalogr:hillshade':analysisMenu,
90+
'gdalogr:roughness':analysisMenu,
91+
'gdalogr:slope':analysisMenu,
92+
'gdalogr:tpi':analysisMenu,
93+
'gdalogr:tri':analysisMenu})
94+
95+
miscMenu = rasterMenu + "/" + Processing.tr('Miscellaneous')
96+
defaultMenuEntries.update({'gdalogr:buildvirtualraster':miscMenu,
97+
'gdalogr:merge':miscMenu,
98+
'gdalogr:rasterinfo':miscMenu,
99+
'gdalogr:overviews':miscMenu,
100+
'gdalogr:tileindex':miscMenu})
101+
102+
103+
def initializeMenus():
104+
for provider in Processing.providers:
105+
for alg in provider.algs:
106+
d = defaultMenuEntries.get(alg.commandLineName(), "")
107+
setting = Setting("Menus", "MENU_" + alg.commandLineName(), alg.name, d)
108+
ProcessingConfig.addSetting(setting)
109+
110+
ProcessingConfig.readSettings()
111+
112+
def updateMenus():
113+
removeMenus()
114+
createMenus()
115+
116+
def createMenus():
117+
for provider in Processing.algs.values():
118+
for alg in provider.values():
119+
menuPath = ProcessingConfig.getSetting("MENU_" + alg.commandLineName())
120+
if menuPath:
121+
paths = menuPath.split("/")
122+
addAlgorithmEntry(alg, paths[0], paths[-1])
123+
124+
125+
def removeMenus():
126+
for provider in Processing.algs.values():
127+
for alg in provider.values():
128+
menuPath = ProcessingConfig.getSetting("MENU_" + alg.commandLineName())
129+
if menuPath:
130+
paths = menuPath.split("/")
131+
removeAlgorithmEntry(alg, paths[0], paths[-1])
132+
133+
def addAlgorithmEntry(alg, menuName, submenuName, actionText=None, icon=None, addButton=False):
134+
action = QAction(icon or alg.getIcon(), actionText or alg.name, iface.mainWindow())
135+
action.triggered.connect(lambda: _executeAlgorithm(alg))
136+
137+
if menuName:
138+
menu = getMenu(menuName, iface.mainWindow().menuBar())
139+
submenu = getMenu(submenuName, menu)
140+
submenu.addAction(action)
141+
142+
if addButton:
143+
global algorithmsToolbar
144+
if algorithmsToolbar is None:
145+
algorithmsToolbar = iface.addToolBar('ProcessingAlgorithms')
146+
algorithmsToolbar.addAction(action)
147+
148+
def removeAlgorithmEntry(alg, menuName, submenuName, actionText=None, delButton=True):
149+
if menuName:
150+
menu = getMenu(menuName, iface.mainWindow().menuBar())
151+
subMenu = getMenu(submenuName, menu)
152+
action = findAction(subMenu.actions(), alg, actionText)
153+
if action is not None:
154+
subMenu.removeAction(action)
155+
156+
if len(subMenu.actions()) == 0:
157+
subMenu.deleteLater()
158+
159+
if delButton:
160+
global algorithmsToolbar
161+
if algorithmsToolbar is not None:
162+
action = Processing.findAction(algorithmsToolbar.actions(), alg, actionText)
163+
if action is not None:
164+
algorithmsToolbar.removeAction(action)
165+
166+
def _executeAlgorithm(alg):
167+
message = alg.checkBeforeOpeningParametersDialog()
168+
if message:
169+
dlg = MessageDialog()
170+
dlg.setTitle(tr('Missing dependency'))
171+
dlg.setMessage(
172+
tr('<h3>Missing dependency. This algorithm cannot '
173+
'be run :-( </h3>\n%s') % message)
174+
dlg.exec_()
175+
return
176+
alg = alg.getCopy()
177+
dlg = alg.getCustomParametersDialog()
178+
if not dlg:
179+
dlg = AlgorithmDialog(alg)
180+
canvas = iface.mapCanvas()
181+
prevMapTool = canvas.mapTool()
182+
dlg.show()
183+
dlg.exec_()
184+
if canvas.mapTool() != prevMapTool:
185+
try:
186+
canvas.mapTool().reset()
187+
except:
188+
pass
189+
canvas.setMapTool(prevMapTool)
190+
191+
def getMenu(name, parent):
192+
menus = [c for c in parent.children() if isinstance(c, QMenu)]
193+
menusDict = {m.title(): m for m in menus}
194+
if name in menusDict:
195+
return menusDict[name]
196+
else:
197+
menu = QMenu(name, parent)
198+
parent.addMenu(menu)
199+
return menu
200+
201+
def findAction(actions, alg, actionText=None):
202+
for action in actions:
203+
if action.text() in [actionText, alg.name]:
204+
return action
205+
return None
358 Bytes
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.