Skip to content

Commit e14b7e4

Browse files
committedNov 29, 2014
Reform qgis.uitls file
1 parent 902b932 commit e14b7e4

File tree

1 file changed

+361
-335
lines changed

1 file changed

+361
-335
lines changed
 

‎python/utils.py

Lines changed: 361 additions & 335 deletions
Original file line numberDiff line numberDiff line change
@@ -41,61 +41,73 @@
4141
import codecs
4242
import time
4343

44-
#######################
44+
# ######################
4545
# ERROR HANDLING
4646

4747
warnings.simplefilter('default')
4848
warnings.filterwarnings("ignore", "the sets module is deprecated")
4949

50+
5051
def showWarning(message, category, filename, lineno, file=None, line=None):
51-
stk = ""
52-
for s in traceback.format_stack()[:-2]:
53-
stk += s.decode('utf-8', 'replace')
54-
QgsMessageLog.logMessage(
55-
"warning:%s\ntraceback:%s" % ( warnings.formatwarning(message, category, filename, lineno), stk),
56-
QCoreApplication.translate( "Python", "Python warning" )
57-
)
52+
stk = ""
53+
for s in traceback.format_stack()[:-2]:
54+
stk += s.decode('utf-8', 'replace')
55+
QgsMessageLog.logMessage(
56+
"warning:%s\ntraceback:%s" % ( warnings.formatwarning(message, category, filename, lineno), stk),
57+
QCoreApplication.translate("Python", "Python warning")
58+
)
59+
60+
5861
warnings.showwarning = showWarning
5962

63+
6064
def showException(type, value, tb, msg):
61-
lst = traceback.format_exception(type, value, tb)
62-
if msg == None:
63-
msg = QCoreApplication.translate('Python', 'An error has occured while executing Python code:')
64-
txt = '<font color="red">%s</font><br><br><pre>' % msg
65-
for s in lst:
66-
txt += s.decode('utf-8', 'replace')
67-
txt += '</pre><br>%s<br>%s<br><br>' % (QCoreApplication.translate('Python','Python version:'), sys.version)
68-
txt += '<br>%s<br>%s %s, %s<br><br>' % (QCoreApplication.translate('Python','QGIS version:'), QGis.QGIS_VERSION, QGis.QGIS_RELEASE_NAME, QGis.QGIS_DEV_VERSION)
69-
txt += '%s %s' % (QCoreApplication.translate('Python','Python path:'), str(sys.path))
70-
txt = txt.replace('\n', '<br>')
71-
txt = txt.replace(' ', '&nbsp; ') # preserve whitespaces for nicer output
72-
73-
from qgis.core import QgsMessageOutput
74-
msg = QgsMessageOutput.createMessageOutput()
75-
msg.setTitle(QCoreApplication.translate('Python', 'Python error'))
76-
msg.setMessage(txt, QgsMessageOutput.MessageHtml)
77-
msg.showMessage()
65+
lst = traceback.format_exception(type, value, tb)
66+
if msg == None:
67+
msg = QCoreApplication.translate('Python', 'An error has occured while executing Python code:')
68+
txt = '<font color="red">%s</font><br><br><pre>' % msg
69+
for s in lst:
70+
txt += s.decode('utf-8', 'replace')
71+
txt += '</pre><br>%s<br>%s<br><br>' % (QCoreApplication.translate('Python', 'Python version:'), sys.version)
72+
txt += '<br>%s<br>%s %s, %s<br><br>' % (
73+
QCoreApplication.translate('Python', 'QGIS version:'), QGis.QGIS_VERSION, QGis.QGIS_RELEASE_NAME,
74+
QGis.QGIS_DEV_VERSION)
75+
txt += '%s %s' % (QCoreApplication.translate('Python', 'Python path:'), str(sys.path))
76+
txt = txt.replace('\n', '<br>')
77+
txt = txt.replace(' ', '&nbsp; ') # preserve whitespaces for nicer output
78+
79+
from qgis.core import QgsMessageOutput
80+
81+
msg = QgsMessageOutput.createMessageOutput()
82+
msg.setTitle(QCoreApplication.translate('Python', 'Python error'))
83+
msg.setMessage(txt, QgsMessageOutput.MessageHtml)
84+
msg.showMessage()
85+
7886

7987
def qgis_excepthook(type, value, tb):
80-
showException(type, value, tb, None)
88+
showException(type, value, tb, None)
89+
8190

8291
def installErrorHook():
83-
sys.excepthook = qgis_excepthook
92+
sys.excepthook = qgis_excepthook
93+
8494

8595
def uninstallErrorHook():
86-
sys.excepthook = sys.__excepthook__
96+
sys.excepthook = sys.__excepthook__
8797

8898
# install error hook() on module load
8999
installErrorHook()
90100

91101
# initialize 'iface' object
92102
iface = None
93103

104+
94105
def initInterface(pointer):
95-
from qgis.gui import QgisInterface
96-
from sip import wrapinstance
97-
global iface
98-
iface = wrapinstance(pointer, QgisInterface)
106+
from qgis.gui import QgisInterface
107+
from sip import wrapinstance
108+
109+
global iface
110+
iface = wrapinstance(pointer, QgisInterface)
99111

100112
#######################
101113
# PLUGINS
@@ -118,333 +130,343 @@ def initInterface(pointer):
118130
# key = plugin package name, value = config parser instance
119131
plugins_metadata_parser = {}
120132

133+
121134
def findPlugins(path):
122-
""" for internal use: return list of plugins in given path """
123-
for plugin in glob.glob(path + "/*"):
124-
if not os.path.isdir(plugin):
125-
continue
126-
if not os.path.exists(os.path.join(plugin, '__init__.py')):
127-
continue
135+
""" for internal use: return list of plugins in given path """
136+
for plugin in glob.glob(path + "/*"):
137+
if not os.path.isdir(plugin):
138+
continue
139+
if not os.path.exists(os.path.join(plugin, '__init__.py')):
140+
continue
128141

129-
metadataFile = os.path.join(plugin, 'metadata.txt')
130-
if not os.path.exists(metadataFile):
131-
continue
142+
metadataFile = os.path.join(plugin, 'metadata.txt')
143+
if not os.path.exists(metadataFile):
144+
continue
132145

133-
cp = ConfigParser.ConfigParser()
146+
cp = ConfigParser.ConfigParser()
134147

135-
try:
136-
cp.readfp(codecs.open(metadataFile, "r", "utf8"))
137-
except:
138-
cp = None
148+
try:
149+
cp.readfp(codecs.open(metadataFile, "r", "utf8"))
150+
except:
151+
cp = None
139152

140-
pluginName = os.path.basename(plugin)
141-
yield (pluginName, cp)
153+
pluginName = os.path.basename(plugin)
154+
yield (pluginName, cp)
142155

143156

144157
def updateAvailablePlugins():
145-
""" Go through the plugin_paths list and find out what plugins are available. """
146-
# merge the lists
147-
plugins = []
148-
metadata_parser = {}
149-
for pluginpath in plugin_paths:
150-
for pluginName, parser in findPlugins(pluginpath):
151-
if parser is None: continue
152-
if pluginName not in plugins:
153-
plugins.append(pluginName)
154-
metadata_parser[pluginName] = parser
155-
156-
global available_plugins
157-
available_plugins = plugins
158-
global plugins_metadata_parser
159-
plugins_metadata_parser = metadata_parser
158+
""" Go through the plugin_paths list and find out what plugins are available. """
159+
# merge the lists
160+
plugins = []
161+
metadata_parser = {}
162+
for pluginpath in plugin_paths:
163+
for pluginName, parser in findPlugins(pluginpath):
164+
if parser is None: continue
165+
if pluginName not in plugins:
166+
plugins.append(pluginName)
167+
metadata_parser[pluginName] = parser
168+
169+
global available_plugins
170+
available_plugins = plugins
171+
global plugins_metadata_parser
172+
plugins_metadata_parser = metadata_parser
160173

161174

162175
def pluginMetadata(packageName, fct):
163-
""" fetch metadata from a plugin - use values from metadata.txt """
164-
try:
165-
return plugins_metadata_parser[packageName].get('general', fct)
166-
except Exception:
167-
return "__error__"
176+
""" fetch metadata from a plugin - use values from metadata.txt """
177+
try:
178+
return plugins_metadata_parser[packageName].get('general', fct)
179+
except Exception:
180+
return "__error__"
168181

169182

170183
def loadPlugin(packageName):
171-
""" load plugin's package """
184+
""" load plugin's package """
172185

173-
try:
174-
__import__(packageName)
175-
return True
176-
except:
177-
pass # continue...
186+
try:
187+
__import__(packageName)
188+
return True
189+
except:
190+
pass # continue...
178191

179-
# snake in the grass, we know it's there
180-
sys.path_importer_cache.clear()
192+
# snake in the grass, we know it's there
193+
sys.path_importer_cache.clear()
181194

182-
# retry
183-
try:
184-
__import__(packageName)
185-
return True
186-
except:
187-
msgTemplate = QCoreApplication.translate("Python", "Couldn't load plugin '%s' from ['%s']")
188-
msg = msgTemplate % (packageName, "', '".join(sys.path))
189-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
190-
return False
195+
# retry
196+
try:
197+
__import__(packageName)
198+
return True
199+
except:
200+
msgTemplate = QCoreApplication.translate("Python", "Couldn't load plugin '%s' from ['%s']")
201+
msg = msgTemplate % (packageName, "', '".join(sys.path))
202+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
203+
return False
191204

192205

193206
def startPlugin(packageName):
194-
""" initialize the plugin """
195-
global plugins, active_plugins, iface, plugin_times
207+
""" initialize the plugin """
208+
global plugins, active_plugins, iface, plugin_times
196209

197-
if packageName in active_plugins: return False
198-
if packageName not in sys.modules: return False
210+
if packageName in active_plugins: return False
211+
if packageName not in sys.modules: return False
199212

200-
package = sys.modules[packageName]
213+
package = sys.modules[packageName]
201214

202-
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin %s" ) % packageName
215+
errMsg = QCoreApplication.translate("Python", "Couldn't load plugin %s") % packageName
203216

204-
start = time.clock()
205-
# create an instance of the plugin
206-
try:
207-
plugins[packageName] = package.classFactory(iface)
208-
except:
209-
_unloadPluginModules(packageName)
210-
msg = QCoreApplication.translate("Python", "%s due to an error when calling its classFactory() method") % errMsg
211-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
212-
return False
217+
start = time.clock()
218+
# create an instance of the plugin
219+
try:
220+
plugins[packageName] = package.classFactory(iface)
221+
except:
222+
_unloadPluginModules(packageName)
223+
msg = QCoreApplication.translate("Python", "%s due to an error when calling its classFactory() method") % errMsg
224+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
225+
return False
213226

214-
# initGui
215-
try:
216-
plugins[packageName].initGui()
217-
except:
218-
del plugins[packageName]
219-
_unloadPluginModules(packageName)
220-
msg = QCoreApplication.translate("Python", "%s due to an error when calling its initGui() method" ) % errMsg
221-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
222-
return False
227+
# initGui
228+
try:
229+
plugins[packageName].initGui()
230+
except:
231+
del plugins[packageName]
232+
_unloadPluginModules(packageName)
233+
msg = QCoreApplication.translate("Python", "%s due to an error when calling its initGui() method") % errMsg
234+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
235+
return False
223236

224-
# add to active plugins
225-
active_plugins.append(packageName)
226-
end = time.clock()
227-
plugin_times[packageName] = "{0:02f}s".format(end - start)
237+
# add to active plugins
238+
active_plugins.append(packageName)
239+
end = time.clock()
240+
plugin_times[packageName] = "{0:02f}s".format(end - start)
228241

229-
return True
242+
return True
230243

231244

232245
def canUninstallPlugin(packageName):
233-
""" confirm that the plugin can be uninstalled """
234-
global plugins, active_plugins
235-
236-
if not plugins.has_key(packageName): return False
237-
if packageName not in active_plugins: return False
238-
239-
try:
240-
metadata = plugins[packageName]
241-
if "canBeUninstalled" not in dir(metadata):
242-
return True
243-
return bool(metadata.canBeUninstalled())
244-
except:
245-
msg = "Error calling "+packageName+".canBeUninstalled"
246-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
247-
return True
246+
""" confirm that the plugin can be uninstalled """
247+
global plugins, active_plugins
248+
249+
if not plugins.has_key(packageName): return False
250+
if packageName not in active_plugins: return False
251+
252+
try:
253+
metadata = plugins[packageName]
254+
if "canBeUninstalled" not in dir(metadata):
255+
return True
256+
return bool(metadata.canBeUninstalled())
257+
except:
258+
msg = "Error calling " + packageName + ".canBeUninstalled"
259+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
260+
return True
248261

249262

250263
def unloadPlugin(packageName):
251-
""" unload and delete plugin! """
252-
global plugins, active_plugins
264+
""" unload and delete plugin! """
265+
global plugins, active_plugins
253266

254-
if not plugins.has_key(packageName): return False
255-
if packageName not in active_plugins: return False
267+
if not plugins.has_key(packageName): return False
268+
if packageName not in active_plugins: return False
256269

257-
try:
258-
plugins[packageName].unload()
259-
del plugins[packageName]
260-
active_plugins.remove(packageName)
261-
_unloadPluginModules(packageName)
262-
return True
263-
except Exception, e:
264-
msg = QCoreApplication.translate("Python", "Error while unloading plugin %s") % packageName
265-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
266-
return False
270+
try:
271+
plugins[packageName].unload()
272+
del plugins[packageName]
273+
active_plugins.remove(packageName)
274+
_unloadPluginModules(packageName)
275+
return True
276+
except Exception, e:
277+
msg = QCoreApplication.translate("Python", "Error while unloading plugin %s") % packageName
278+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
279+
return False
267280

268281

269282
def _unloadPluginModules(packageName):
270-
""" unload plugin package with all its modules (files) """
271-
global _plugin_modules
272-
mods = _plugin_modules[packageName]
273-
274-
for mod in mods:
275-
# if it looks like a Qt resource file, try to do a cleanup
276-
# otherwise we might experience a segfault next time the plugin is loaded
277-
# because Qt will try to access invalid plugin resource data
278-
try:
279-
if hasattr(sys.modules[mod], 'qCleanupResources'):
280-
sys.modules[mod].qCleanupResources()
281-
except:
282-
pass
283-
# try to remove the module from python
284-
try:
285-
del sys.modules[mod]
286-
except:
287-
pass
288-
# remove the plugin entry
289-
del _plugin_modules[packageName]
283+
""" unload plugin package with all its modules (files) """
284+
global _plugin_modules
285+
mods = _plugin_modules[packageName]
286+
287+
for mod in mods:
288+
# if it looks like a Qt resource file, try to do a cleanup
289+
# otherwise we might experience a segfault next time the plugin is loaded
290+
# because Qt will try to access invalid plugin resource data
291+
try:
292+
if hasattr(sys.modules[mod], 'qCleanupResources'):
293+
sys.modules[mod].qCleanupResources()
294+
except:
295+
pass
296+
# try to remove the module from python
297+
try:
298+
del sys.modules[mod]
299+
except:
300+
pass
301+
# remove the plugin entry
302+
del _plugin_modules[packageName]
290303

291304

292305
def isPluginLoaded(packageName):
293-
""" find out whether a plugin is active (i.e. has been started) """
294-
global plugins, active_plugins
306+
""" find out whether a plugin is active (i.e. has been started) """
307+
global plugins, active_plugins
295308

296-
if not plugins.has_key(packageName): return False
297-
return (packageName in active_plugins)
309+
if not plugins.has_key(packageName): return False
310+
return (packageName in active_plugins)
298311

299312

300313
def reloadPlugin(packageName):
301-
""" unload and start again a plugin """
302-
global active_plugins
303-
if packageName not in active_plugins:
304-
return # it's not active
305-
306-
unloadPlugin(packageName)
307-
loadPlugin(packageName)
308-
startPlugin(packageName)
309-
310-
311-
def showPluginHelp(packageName=None,filename="index",section=""):
312-
""" show a help in the user's html browser. The help file should be named index-ll_CC.html or index-ll.html"""
313-
try:
314-
source = ""
315-
if packageName is None:
316-
import inspect
317-
source = inspect.currentframe().f_back.f_code.co_filename
318-
else:
319-
source = sys.modules[packageName].__file__
320-
except:
321-
return
322-
path = os.path.dirname(source)
323-
locale = str(QLocale().name())
324-
helpfile = os.path.join(path,filename+"-"+locale+".html")
325-
if not os.path.exists(helpfile):
326-
helpfile = os.path.join(path,filename+"-"+locale.split("_")[0]+".html")
327-
if not os.path.exists(helpfile):
328-
helpfile = os.path.join(path,filename+"-en.html")
329-
if not os.path.exists(helpfile):
330-
helpfile = os.path.join(path,filename+"-en_US.html")
331-
if not os.path.exists(helpfile):
332-
helpfile = os.path.join(path,filename+".html")
333-
if os.path.exists(helpfile):
334-
url = "file://"+helpfile
335-
if section != "":
336-
url = url + "#" + section
337-
iface.openURL(url,False)
314+
""" unload and start again a plugin """
315+
global active_plugins
316+
if packageName not in active_plugins:
317+
return # it's not active
318+
319+
unloadPlugin(packageName)
320+
loadPlugin(packageName)
321+
startPlugin(packageName)
322+
323+
324+
def showPluginHelp(packageName=None, filename="index", section=""):
325+
""" show a help in the user's html browser. The help file should be named index-ll_CC.html or index-ll.html"""
326+
try:
327+
source = ""
328+
if packageName is None:
329+
import inspect
330+
331+
source = inspect.currentframe().f_back.f_code.co_filename
332+
else:
333+
source = sys.modules[packageName].__file__
334+
except:
335+
return
336+
path = os.path.dirname(source)
337+
locale = str(QLocale().name())
338+
helpfile = os.path.join(path, filename + "-" + locale + ".html")
339+
if not os.path.exists(helpfile):
340+
helpfile = os.path.join(path, filename + "-" + locale.split("_")[0] + ".html")
341+
if not os.path.exists(helpfile):
342+
helpfile = os.path.join(path, filename + "-en.html")
343+
if not os.path.exists(helpfile):
344+
helpfile = os.path.join(path, filename + "-en_US.html")
345+
if not os.path.exists(helpfile):
346+
helpfile = os.path.join(path, filename + ".html")
347+
if os.path.exists(helpfile):
348+
url = "file://" + helpfile
349+
if section != "":
350+
url = url + "#" + section
351+
iface.openURL(url, False)
338352

339353

340354
def pluginDirectory(packageName):
341-
""" return directory where the plugin resides. Plugin must be loaded already """
342-
return os.path.dirname(sys.modules[packageName].__file__)
355+
""" return directory where the plugin resides. Plugin must be loaded already """
356+
return os.path.dirname(sys.modules[packageName].__file__)
357+
343358

344359
def reloadProjectMacros():
345-
# unload old macros
346-
unloadProjectMacros()
360+
# unload old macros
361+
unloadProjectMacros()
347362

348-
from qgis.core import QgsProject
349-
code, ok = QgsProject.instance().readEntry("Macros", "/pythonCode")
350-
if not ok or not code or code == '':
351-
return
363+
from qgis.core import QgsProject
352364

353-
# create a new empty python module
354-
import imp
355-
mod = imp.new_module("proj_macros_mod")
365+
code, ok = QgsProject.instance().readEntry("Macros", "/pythonCode")
366+
if not ok or not code or code == '':
367+
return
356368

357-
# set the module code and store it sys.modules
358-
exec unicode(code) in mod.__dict__
359-
sys.modules["proj_macros_mod"] = mod
369+
# create a new empty python module
370+
import imp
371+
372+
mod = imp.new_module("proj_macros_mod")
373+
374+
# set the module code and store it sys.modules
375+
exec unicode(code) in mod.__dict__
376+
sys.modules["proj_macros_mod"] = mod
377+
378+
# load new macros
379+
openProjectMacro()
360380

361-
# load new macros
362-
openProjectMacro()
363381

364382
def unloadProjectMacros():
365-
if "proj_macros_mod" not in sys.modules:
366-
return
367-
# unload old macros
368-
closeProjectMacro()
369-
# destroy the reference to the module
370-
del sys.modules["proj_macros_mod"]
383+
if "proj_macros_mod" not in sys.modules:
384+
return
385+
# unload old macros
386+
closeProjectMacro()
387+
# destroy the reference to the module
388+
del sys.modules["proj_macros_mod"]
371389

372390

373391
def openProjectMacro():
374-
if "proj_macros_mod" not in sys.modules:
375-
return
376-
mod = sys.modules["proj_macros_mod"]
377-
if hasattr(mod, 'openProject'):
378-
mod.openProject()
392+
if "proj_macros_mod" not in sys.modules:
393+
return
394+
mod = sys.modules["proj_macros_mod"]
395+
if hasattr(mod, 'openProject'):
396+
mod.openProject()
397+
379398

380399
def saveProjectMacro():
381-
if "proj_macros_mod" not in sys.modules:
382-
return
383-
mod = sys.modules["proj_macros_mod"]
384-
if hasattr(mod, 'saveProject'):
385-
mod.saveProject()
400+
if "proj_macros_mod" not in sys.modules:
401+
return
402+
mod = sys.modules["proj_macros_mod"]
403+
if hasattr(mod, 'saveProject'):
404+
mod.saveProject()
405+
386406

387407
def closeProjectMacro():
388-
if "proj_macros_mod" not in sys.modules:
389-
return
390-
mod = sys.modules["proj_macros_mod"]
391-
if hasattr(mod, 'closeProject'):
392-
mod.closeProject()
408+
if "proj_macros_mod" not in sys.modules:
409+
return
410+
mod = sys.modules["proj_macros_mod"]
411+
if hasattr(mod, 'closeProject'):
412+
mod.closeProject()
393413

394414

395415
def qgsfunction(args, group, **kwargs):
396-
"""
397-
Decorator function used to define a user expression function.
398-
399-
Custom functions should take (values, feature, parent) as args,
400-
they can also shortcut naming feature and parent args by using *args
401-
if they are not needed in the function.
402-
403-
Functions should return a value compatible with QVariant
404-
405-
Eval errors can be raised using parent.setEvalErrorString()
406-
407-
Functions must be unregistered when no longer needed using
408-
QgsExpression.unregisterFunction
409-
410-
Example:
411-
@qgsfunction(2, 'test'):
412-
def add(values, feature, parent):
413-
pass
414-
415-
Will create and register a function in QgsExpression called 'add' in the
416-
'test' group that takes two arguments.
417-
418-
or not using feature and parent:
419-
420-
@qgsfunction(2, 'test'):
421-
def add(values, *args):
422-
pass
423-
"""
424-
helptemplate = Template("""<h3>$name function</h3><br>$doc""")
425-
class QgsExpressionFunction(QgsExpression.Function):
426-
def __init__(self, name, args, group, helptext='', usesgeometry=False):
427-
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry)
428-
429-
def func(self, values, feature, parent):
430-
pass
431-
432-
def wrapper(func):
433-
name = kwargs.get('name', func.__name__)
434-
usesgeometry = kwargs.get('usesgeometry', False)
435-
help = func.__doc__ or ''
436-
help = help.strip()
437-
if args == 0 and not name[0] == '$':
438-
name = '${0}'.format(name)
439-
func.__name__ = name
440-
help = helptemplate.safe_substitute(name=name, doc=help)
441-
f = QgsExpressionFunction(name, args, group, help, usesgeometry)
442-
f.func = func
443-
register = kwargs.get('register', True)
444-
if register:
445-
QgsExpression.registerFunction(f)
446-
return f
447-
return wrapper
416+
"""
417+
Decorator function used to define a user expression function.
418+
419+
Custom functions should take (values, feature, parent) as args,
420+
they can also shortcut naming feature and parent args by using *args
421+
if they are not needed in the function.
422+
423+
Functions should return a value compatible with QVariant
424+
425+
Eval errors can be raised using parent.setEvalErrorString()
426+
427+
Functions must be unregistered when no longer needed using
428+
QgsExpression.unregisterFunction
429+
430+
Example:
431+
@qgsfunction(2, 'test'):
432+
def add(values, feature, parent):
433+
pass
434+
435+
Will create and register a function in QgsExpression called 'add' in the
436+
'test' group that takes two arguments.
437+
438+
or not using feature and parent:
439+
440+
@qgsfunction(2, 'test'):
441+
def add(values, *args):
442+
pass
443+
"""
444+
helptemplate = Template("""<h3>$name function</h3><br>$doc""")
445+
446+
class QgsExpressionFunction(QgsExpression.Function):
447+
def __init__(self, name, args, group, helptext='', usesgeometry=False):
448+
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry)
449+
450+
def func(self, values, feature, parent):
451+
pass
452+
453+
def wrapper(func):
454+
name = kwargs.get('name', func.__name__)
455+
usesgeometry = kwargs.get('usesgeometry', False)
456+
help = func.__doc__ or ''
457+
help = help.strip()
458+
if args == 0 and not name[0] == '$':
459+
name = '${0}'.format(name)
460+
func.__name__ = name
461+
help = helptemplate.safe_substitute(name=name, doc=help)
462+
f = QgsExpressionFunction(name, args, group, help, usesgeometry)
463+
f.func = func
464+
register = kwargs.get('register', True)
465+
if register:
466+
QgsExpression.registerFunction(f)
467+
return f
468+
469+
return wrapper
448470

449471
#######################
450472
# SERVER PLUGINS
@@ -464,37 +486,39 @@ def wrapper(func):
464486
# initialize 'serverIface' object
465487
serverIface = None
466488

489+
467490
def initServerInterface(pointer):
468-
from qgis.server import QgsServerInterface
469-
from sip import wrapinstance
470-
global serverIface
471-
serverIface = wrapinstance(pointer, QgsServerInterface)
491+
from qgis.server import QgsServerInterface
492+
from sip import wrapinstance
472493

494+
global serverIface
495+
serverIface = wrapinstance(pointer, QgsServerInterface)
473496

474497

475498
def startServerPlugin(packageName):
476-
""" initialize the plugin """
477-
global server_plugins, server_active_plugins, serverIface
499+
""" initialize the plugin """
500+
global server_plugins, server_active_plugins, serverIface
478501

479-
if packageName in server_active_plugins: return False
480-
if packageName not in sys.modules: return False
502+
if packageName in server_active_plugins: return False
503+
if packageName not in sys.modules: return False
481504

482-
package = sys.modules[packageName]
505+
package = sys.modules[packageName]
483506

484-
errMsg = QCoreApplication.translate("Python", "Couldn't load server plugin %s" ) % packageName
507+
errMsg = QCoreApplication.translate("Python", "Couldn't load server plugin %s") % packageName
485508

486-
# create an instance of the plugin
487-
try:
488-
server_plugins[packageName] = package.serverClassFactory(serverIface)
489-
except:
490-
_unloadPluginModules(packageName)
491-
msg = QCoreApplication.translate("Python", "%s due to an error when calling its serverClassFactory() method") % errMsg
492-
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
493-
return False
494-
495-
# add to active plugins
496-
server_active_plugins.append(packageName)
497-
return True
509+
# create an instance of the plugin
510+
try:
511+
server_plugins[packageName] = package.serverClassFactory(serverIface)
512+
except:
513+
_unloadPluginModules(packageName)
514+
msg = QCoreApplication.translate("Python",
515+
"%s due to an error when calling its serverClassFactory() method") % errMsg
516+
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
517+
return False
518+
519+
# add to active plugins
520+
server_active_plugins.append(packageName)
521+
return True
498522

499523

500524
#######################
@@ -503,27 +527,29 @@ def startServerPlugin(packageName):
503527
import __builtin__
504528

505529
_builtin_import = __builtin__.__import__
506-
_plugin_modules = { }
530+
_plugin_modules = {}
531+
507532

508533
def _import(name, globals={}, locals={}, fromlist=[], level=-1):
509-
""" wrapper around builtin import that keeps track of loaded plugin modules """
510-
mod = _builtin_import(name, globals, locals, fromlist, level)
511-
512-
if mod and '__file__' in mod.__dict__:
513-
module_name = mod.__name__
514-
package_name = module_name.split('.')[0]
515-
# check whether the module belongs to one of our plugins
516-
if package_name in available_plugins:
517-
if package_name not in _plugin_modules:
518-
_plugin_modules[package_name] = set()
519-
_plugin_modules[package_name].add(module_name)
520-
# check the fromlist for additional modules (from X import Y,Z)
521-
if fromlist:
522-
for fromitem in fromlist:
523-
frmod = module_name + "." + fromitem
524-
if frmod in sys.modules:
525-
_plugin_modules[package_name].add(frmod)
526-
527-
return mod
534+
""" wrapper around builtin import that keeps track of loaded plugin modules """
535+
mod = _builtin_import(name, globals, locals, fromlist, level)
536+
537+
if mod and '__file__' in mod.__dict__:
538+
module_name = mod.__name__
539+
package_name = module_name.split('.')[0]
540+
# check whether the module belongs to one of our plugins
541+
if package_name in available_plugins:
542+
if package_name not in _plugin_modules:
543+
_plugin_modules[package_name] = set()
544+
_plugin_modules[package_name].add(module_name)
545+
# check the fromlist for additional modules (from X import Y,Z)
546+
if fromlist:
547+
for fromitem in fromlist:
548+
frmod = module_name + "." + fromitem
549+
if frmod in sys.modules:
550+
_plugin_modules[package_name].add(frmod)
551+
552+
return mod
553+
528554

529555
__builtin__.__import__ = _import

0 commit comments

Comments
 (0)
Please sign in to comment.