@@ -61,9 +61,6 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
61
61
// also add path to plugins
62
62
runString ( " sys.path = [\" " + pythonPath () + " \" , \" " + homePluginsPath () + " \" , \" " + pluginsPath () + " \" ] + sys.path" );
63
63
64
- runString ( " import traceback" ); // for formatting stack traces
65
- runString ( " import __main__" ); // to access explicitly global variables
66
-
67
64
// import SIP
68
65
if ( !runString ( " from sip import wrapinstance, unwrapinstance" ,
69
66
QObject::tr ( " Couldn't load SIP module." ) + " \n " + QObject::tr ( " Python support will be disabled." ) ) )
@@ -88,49 +85,16 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
88
85
return ;
89
86
}
90
87
91
- // hook that will show information and traceback in message box
92
- runString (
93
- " def qgis_except_hook_msg(type, value, tb, msg):\n "
94
- " lst = traceback.format_exception(type, value, tb)\n "
95
- " if msg == None: msg = '" + QObject::tr ( " An error has occured while executing Python code:" ).replace ( " '" , " \\ '" ) + " '\n "
96
- " txt = '<font color=\" red\" >'+msg+'</font><br><br>'\n "
97
- " for s in lst:\n "
98
- " txt += s\n "
99
- " txt += '<br>" + QObject::tr ( " Python version:" ).replace ( " '" , " \\ '" ) + " <br>' + sys.version + '<br><br>'\n "
100
- " txt += '" + QObject::tr ( " Python path:" ).replace ( " '" , " \\ '" ) + " ' + str(sys.path)\n "
101
- " txt = txt.replace('\\ n', '<br>')\n "
102
- " txt = txt.replace(' ', ' ')\n " // preserve whitespaces for nicer output
103
- " \n "
104
- " msg = QgsMessageOutput.createMessageOutput()\n "
105
- " msg.setTitle('" + QObject::tr ( " Python error" ).replace ( " '" , " \\ '" ) + " ')\n "
106
- " msg.setMessage(txt, QgsMessageOutput.MessageHtml)\n "
107
- " msg.showMessage()\n " );
108
- runString (
109
- " def qgis_except_hook(type, value, tb):\n "
110
- " qgis_except_hook_msg(type, value, tb, None)\n " );
111
- runString (
112
- " class QgisOutputCatcher:\n "
113
- " def __init__(self):\n "
114
- " self.data = ''\n "
115
- " def write(self, stuff):\n "
116
- " self.data += stuff\n "
117
- " def get_and_clean_data(self):\n "
118
- " tmp = self.data\n "
119
- " self.data = ''\n "
120
- " return tmp\n " );
121
-
122
- // hook for python console so all output will be redirected
123
- // and then shown in console
124
- runString (
125
- " def console_display_hook(obj):\n "
126
- " __main__.__result = obj\n " );
127
-
128
- installErrorHook ();
88
+ // import QGIS utils
89
+ error_msg = QObject::tr ( " Couldn't load QGIS utils." ) + " \n " + QObject::tr ( " Python support will be disabled." );
90
+ if ( !runString (" import qgis.utils" , error_msg) )
91
+ {
92
+ exitPython ();
93
+ return ;
94
+ }
129
95
130
96
// initialize 'iface' object
131
- runString ( " iface = wrapinstance(" + QString::number (( unsigned long ) interface ) + " , QgisInterface)" );
132
- runString ( " plugins = {}" );
133
-
97
+ runString ( " qgis.utils.initInterface(" + QString::number (( unsigned long ) interface ) + " )" );
134
98
}
135
99
136
100
void QgsPythonUtilsImpl::exitPython ()
@@ -149,26 +113,22 @@ bool QgsPythonUtilsImpl::isEnabled()
149
113
150
114
void QgsPythonUtilsImpl::installErrorHook ()
151
115
{
152
- runString ( " sys.excepthook = qgis_except_hook " );
116
+ runString ( " qgis.utils.installErrorHook() " );
153
117
}
154
118
155
119
void QgsPythonUtilsImpl::uninstallErrorHook ()
156
120
{
157
- runString ( " sys.excepthook = sys.__excepthook__ " );
121
+ runString ( " qgis.utils.uninstallErrorHook() " );
158
122
}
159
123
160
124
void QgsPythonUtilsImpl::installConsoleHooks ()
161
125
{
162
- runString ( " sys.displayhook = console_display_hook\n " );
163
-
164
- runString ( " _old_stdout = sys.stdout\n " );
165
- runString ( " sys.stdout = QgisOutputCatcher()\n " );
126
+ runString ( " qgis.utils.installConsoleHooks()" );
166
127
}
167
128
168
129
void QgsPythonUtilsImpl::uninstallConsoleHooks ()
169
130
{
170
- runString ( " sys.displayhook = sys.__displayhook__" );
171
- runString ( " sys.stdout = _old_stdout" );
131
+ runString ( " qgis.utils.uninstallConsoleHooks()" );
172
132
}
173
133
174
134
@@ -193,6 +153,8 @@ bool QgsPythonUtilsImpl::runString( const QString& command, QString msgOnError )
193
153
msgOnError = QObject::tr ( " An error occured during execution of following code:" ) + " \n <tt>" + command + " </tt>" ;
194
154
}
195
155
156
+ // TODO: use python implementation
157
+
196
158
QString traceback = getTraceback ();
197
159
QString path, version;
198
160
evalString ( " str(sys.path)" , path );
@@ -339,7 +301,7 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
339
301
340
302
QString QgsPythonUtilsImpl::getResult ()
341
303
{
342
- return getVariableFromMain ( " __result " );
304
+ return getVariableFromMain ( " qgis.utils.console_output " );
343
305
}
344
306
345
307
QString QgsPythonUtilsImpl::PyObjectToQString ( PyObject* obj )
@@ -425,6 +387,8 @@ bool QgsPythonUtilsImpl::evalString( const QString& command, QString& result )
425
387
{
426
388
PyObject* res = PyRun_String ( command.toUtf8 ().data (), Py_eval_input, mMainDict , mMainDict );
427
389
390
+ // TODO: error handling
391
+
428
392
if ( res != NULL )
429
393
{
430
394
result = PyObjectToQString ( res );
@@ -472,106 +436,33 @@ QStringList QgsPythonUtilsImpl::pluginList()
472
436
473
437
QString QgsPythonUtilsImpl::getPluginMetadata ( QString pluginName, QString function )
474
438
{
475
- QString command = pluginName + " ." + function + " ()" ;
476
- QString retval = " ???" ;
477
-
478
- // temporary disable error hook - UI will handle this gracefully
479
- uninstallErrorHook ();
480
- PyObject* obj = PyRun_String ( command.toUtf8 ().data (), Py_eval_input, mMainDict , mMainDict );
481
-
482
- if ( PyErr_Occurred () )
483
- {
484
- PyErr_Print (); // just print it to console
485
- PyErr_Clear ();
486
- retval = " __error__" ;
487
- }
488
- else if ( PyUnicode_Check ( obj ) )
489
- {
490
- PyObject* utf8 = PyUnicode_AsUTF8String ( obj );
491
- if ( utf8 )
492
- retval = QString::fromUtf8 ( PyString_AS_STRING ( utf8 ) );
493
- else
494
- retval = " __error__" ;
495
- Py_XDECREF ( utf8 );
496
- }
497
- else if ( PyString_Check ( obj ) )
498
- {
499
- retval = PyString_AS_STRING ( obj );
500
- }
501
- else
502
- {
503
- // bad python return value
504
- retval = " __error__" ;
505
- }
506
- Py_XDECREF ( obj );
507
-
508
- installErrorHook ();
509
- return retval;
439
+ QString res;
440
+ QString str = " qgis.utils.pluginMetadata('" + pluginName + " ', '" +function+" ')" ;
441
+ evalString (str, res);
442
+ // QgsDebugMsg("metadata "+pluginName+" - '"+function+"' = "+res);
443
+ return res;
510
444
}
511
445
512
446
513
447
bool QgsPythonUtilsImpl::loadPlugin ( QString packageName )
514
448
{
515
- // load plugin's package and ensure that plugin is reloaded when changed
516
- runString (
517
- " try:\n "
518
- " import " + packageName + " \n "
519
- " __main__.__plugin_result = 'OK'\n "
520
- " except:\n "
521
- " __main__.__plugin_result = 'ERROR'\n " );
522
-
523
- if ( getVariableFromMain ( " __plugin_result" ) == " OK" )
524
- return true ;
525
-
526
- // snake in the grass, we know it's there
527
- runString ( " sys.path_importer_cache.clear()" );
528
-
529
- // retry
530
- runString (
531
- " try:\n "
532
- " import " + packageName + " \n "
533
- " reload(" + packageName + " )\n "
534
- " __main__.__plugin_result = 'OK'\n "
535
- " except:\n "
536
- " qgis_except_hook_msg(sys.exc_type, sys.exc_value, sys.exc_traceback, "
537
- " 'Couldn\\ 't load plugin \" " + packageName + " \" from [\\ '' + '\\ ', \\ ''.join(sys.path) + '\\ ']')\n "
538
- " __main__.__plugin_result = 'ERROR'\n " );
539
-
540
- return getVariableFromMain ( " __plugin_result" ) == " OK" ;
449
+ QString output;
450
+ evalString (" qgis.utils.loadPlugin('" + packageName + " ')" , output);
451
+ return (output == " True" );
541
452
}
542
453
543
454
544
455
bool QgsPythonUtilsImpl::startPlugin ( QString packageName )
545
456
{
546
- QString pluginPythonVar = " plugins['" + packageName + " ']" ;
547
-
548
- QString errMsg = QObject::tr ( " Couldn't load plugin %1" ).arg ( packageName );
549
-
550
- // create an instance of the plugin
551
- if ( !runString ( pluginPythonVar + " = " + packageName + " .classFactory(iface)" ,
552
- QObject::tr ( " %1 due an error when calling its classFactory() method" ).arg ( errMsg ) ) )
553
- return false ;
554
-
555
- // initGui
556
- if ( !runString ( pluginPythonVar + " .initGui()" ,
557
- QObject::tr ( " %1 due an error when calling its initGui() method" ).arg ( errMsg ) ) )
558
- return false ;
559
-
560
- return true ;
457
+ QString output;
458
+ evalString (" qgis.utils.startPlugin('" + packageName + " ')" , output);
459
+ return (output == " True" );
561
460
}
562
461
563
462
564
463
bool QgsPythonUtilsImpl::unloadPlugin ( QString packageName )
565
464
{
566
- // unload and delete plugin!
567
- QString varName = " plugins['" + packageName + " ']" ;
568
-
569
- QString errMsg = QObject::tr ( " Error while unloading plugin %1" ).arg ( packageName );
570
-
571
- if ( !runString ( varName + " .unload()" , errMsg ) )
572
- return false ;
573
- if ( !runString ( " del " + varName, errMsg ) )
574
- return false ;
575
-
576
- return true ;
465
+ QString output;
466
+ evalString (" qgis.utils.unloadPlugin('" + packageName + " ')" , output);
467
+ return (output == " True" );
577
468
}
0 commit comments