📄 qgsgrassmodule.cpp
字号:
/*************************************************************************** qgsgrasstools.cpp ------------------- begin : March, 2005 copyright : (C) 2005 by Radim Blazek email : blazek@itc.it ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <q3cstring.h>#include <q3groupbox.h>#include <q3listbox.h>#include <q3listview.h>#include <q3painter.h>#include <q3picture.h>#include <q3pointarray.h>#include <q3process.h>#include <q3progressbar.h>#include <q3stylesheet.h>#include <q3table.h>#include <q3textbrowser.h>#include <qapplication.h>#include <qcolordialog.h>#include <QComboBox>#include <qcursor.h>#include <qdir.h>#include <qdom.h>#include <QDoubleValidator>#include <qevent.h>#include <QFileDialog>#include <qfile.h>#include <QGridLayout>#include <QGroupBox>#include <QHBoxLayout>#include <qimage.h>#include <qinputdialog.h>#include <QIntValidator>#include <qlabel.h>#include <qlayout.h>#include <qlineedit.h>#include <qmessagebox.h>#include <qnamespace.h>#include <qpainter.h>#include <qpen.h>#include <qpixmap.h>#include <qpoint.h>#include <QProcess>#include <QPushButton>#include <qpushbutton.h>#include <qregexp.h>#include <QRegExpValidator>#include <qsettings.h>#include <qsize.h>#include <qspinbox.h>#include <qstatusbar.h>#include <qstringlist.h>#include <qtabwidget.h>#include <QUrl>#include <QVBoxLayout>#include "qgis.h"#include "qgslogger.h"#include "qgisinterface.h"#include "qgsapplication.h"#include "qgsmapcanvas.h"#include "qgsmaplayer.h"#include "qgsvectorlayer.h"#include <qgsrasterlayer.h>#include "qgsdatasourceuri.h"#include "qgsdataprovider.h"#include "qgsfield.h"#include "qgsfeature.h"#include <typeinfo>extern "C" {#include <grass/gis.h>#include <grass/Vect.h>}#include "../../src/providers/grass/qgsgrass.h"#include "../../src/providers/grass/qgsgrassprovider.h"#include "qgsgrassattributes.h"#include "qgsgrassmodule.h"#include "qgsgrassmapcalc.h"#include "qgsgrasstools.h"#include "qgsgrassselect.h"#include <gdal.h> // to collect version information#if defined(WIN32)#include <windows.h>static QString getShortPath(const QString &path){ TCHAR buf[MAX_PATH]; GetShortPathName( path.ascii(), buf, MAX_PATH); return buf;}#endifbool QgsGrassModule::mExecPathInited = 0;QStringList QgsGrassModule::mExecPath;QString QgsGrassModule::findExec ( QString file ){ QgsDebugMsg("called."); // Init mExecPath // Windows searches first in current directory if ( !mExecPathInited ) { QString path = getenv("PATH"); QgsDebugMsg("path = " + path);#ifdef WIN32 mExecPath = path.split ( ";" ); mExecPath.prepend ( getShortPath(QgsApplication::applicationDirPath()) );#else mExecPath = path.split ( ":" ); mExecPath.prepend ( QgsApplication::applicationDirPath() );#endif mExecPathInited = true; } if ( QFile::exists ( file ) ) return file; // full path // Search for module for ( QStringList::iterator it = mExecPath.begin(); it != mExecPath.end(); ++it ) { QString full = *it + "/" + file; if ( QFile::exists ( full ) ) { return full; } } // Not found try with .exe#ifdef WIN32 for ( QStringList::iterator it = mExecPath.begin(); it != mExecPath.end(); ++it ) { QString full = *it + "/" + file + ".exe"; if ( QFile::exists ( full ) ) { return full; } }#endif return QString();}bool QgsGrassModule::inExecPath ( QString file ){ if ( findExec(file).isNull() ) return false; return true;}QStringList QgsGrassModule::execArguments ( QString module ){ QString exe; QStringList arguments; exe = QgsGrassModule::findExec ( module ); if ( exe.isNull() ) { return arguments; }#if defined(WIN32) QFileInfo fi ( exe ); if ( fi.isExecutable() ) { arguments.append(exe); } else // script { QString cmd = getShortPath(QgsApplication::applicationDirPath()) + "/msys/bin/sh"; arguments.append ( cmd ); // Important! Otherwise it does not find DLL even if it is in PATH arguments.append ( "--login" ); arguments.append ( exe ); }#else arguments.append(exe);#endif return arguments;}QgsGrassModule::QgsGrassModule ( QgsGrassTools *tools, QString moduleName, QgisInterface *iface, QString path, QWidget * parent, const char * name, Qt::WFlags f ) :QgsGrassModuleBase ( ), mSuccess(false){ QgsDebugMsg("called"); setupUi(this); lblModuleName->setText(tr("Module") + ": " + moduleName); mPath = path; mTools = tools; mIface = iface; mCanvas = mIface->getMapCanvas(); mParent = parent; //mAppDir = QgsApplication::applicationDirPath(); mAppDir = mTools->appDir(); /* Read module description and create options */ // Open QGIS module description QString mpath = mPath + ".qgm"; QFile qFile ( mpath ); if ( !qFile.exists() ) { QMessageBox::warning( 0, tr("Warning"), tr("The module file (") + mpath + tr(") not found.") ); return; } if ( ! qFile.open( QIODevice::ReadOnly ) ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot open module file (") + mpath + tr(")") ); return; } QDomDocument qDoc ( "qgisgrassmodule" ); QString err; int line, column; if ( !qDoc.setContent( &qFile, &err, &line, &column ) ) { QString errmsg = tr("Cannot read module file (") + mpath + tr("):\n") + err + tr("\nat line ") + QString::number(line) + " column " + QString::number(column); QgsDebugMsg(errmsg); QMessageBox::warning( 0, tr("Warning"), errmsg ); qFile.close(); return; } qFile.close(); QDomElement qDocElem = qDoc.documentElement(); // Read GRASS module description QString xName = qDocElem.attribute("module"); // Binary modules on windows has .exe extension // but not all modules have to be binary (can be scripts) // => test if the module is in path and if it is not // add .exe and test again#ifdef WIN32 if ( inExecPath ( xName ) ) { mXName = xName; } else if ( inExecPath ( xName + ".exe" ) ) { mXName = xName + ".exe"; } else { QgsDebugMsg("Module " + xName + " not found"); QMessageBox::warning( 0, tr("Warning"), tr("Module ") + xName + tr(" not found") ); return; }#else mXName = xName;#endif if ( xName == "r.mapcalc" ) { QGridLayout *layout = new QGridLayout ( mTabWidget->page(0), 1, 1 ); mOptions = new QgsGrassMapcalc ( mTools, this, mIface, mTabWidget->page(0) ); QWidget *w = dynamic_cast<QWidget *>(mOptions); layout->addWidget ( dynamic_cast<QWidget *>(mOptions), 0, 0 ); } else { mOptions = new QgsGrassModuleStandardOptions ( mTools, this, mIface, mXName, qDocElem, mTabWidget->page(0) ); } // Hide display if there is no output if ( mOptions->output(QgsGrassModuleOption::Vector).size() == 0 && mOptions->output(QgsGrassModuleOption::Raster).size() == 0 ) { mViewButton->hide(); } mViewButton->setEnabled(false); // Create manual if available QString gisBase = getenv("GISBASE"); QString manPath = gisBase + "/docs/html/" + xName + ".html"; QFile manFile ( manPath ); if ( manFile.exists() ) { mManualTextBrowser->setSource ( QUrl::fromLocalFile( manPath ) ); } else { QMessageBox::warning( 0, tr("Warning"), tr("Cannot find man page ") + manPath ); } connect ( &mProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdout())); connect ( &mProcess, SIGNAL(readyReadStandardError()), this, SLOT(readStderr())); connect ( &mProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus))); const char *env = "GRASS_MESSAGE_FORMAT=gui"; char *envstr = new char[strlen(env)+1]; strcpy ( envstr, env ); putenv( envstr ); mOutputTextBrowser->setTextFormat(Qt::RichText); mOutputTextBrowser->setReadOnly(TRUE);}/******************* QgsGrassModuleOptions *******************/QgsGrassModuleOptions::QgsGrassModuleOptions ( QgsGrassTools *tools, QgsGrassModule *module, QgisInterface *iface ){ QgsDebugMsg("called."); mTools = tools; mModule = module; mIface = iface; mCanvas = mIface->getMapCanvas(); //mAppDir = QgsApplication::applicationDirPath(); mAppDir = mTools->appDir();}QgsGrassModuleOptions::~QgsGrassModuleOptions(){}QStringList QgsGrassModuleOptions::arguments(){ return QStringList();}/*************** QgsGrassModuleStandardOptions ***********************/QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions ( QgsGrassTools *tools, QgsGrassModule *module, QgisInterface *iface, QString xname, QDomElement qDocElem, QWidget * parent, const char * name, Qt::WFlags f ) : QgsGrassModuleOptions( tools, module, iface), QWidget ( parent, name, f ){ QgsDebugMsg("called."); QgsDebugMsg(QString("PATH = %1").arg( getenv("PATH") ) ); // Attention!: sh.exe (MSYS) sets $0 in scripts to file name // without full path. Strange because when run from msys.bat // $0 is set to full path. GRASS scripts call // exec g.parser "$0" "$@" // and it fails -> find and run with full path mXName = xname; mParent = parent; QStringList arguments = QgsGrassModule::execArguments(mXName); if ( arguments.size() == 0 ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot find module ") + mXName ); return; } QString cmd = arguments.takeFirst(); arguments.append ( "--interface-description" ); QProcess process( this ); process.start ( cmd, arguments ); // ? Does binary on Win need .exe extention ? // Return code 255 (-1) was correct in GRASS < 6.1.0 if ( !process.waitForFinished() || (process.exitCode() != 0 && process.exitCode() != 255) ) { QgsDebugMsg("process.exitCode() = " + QString::number(process.exitCode()) ); QMessageBox::warning( 0, tr("Warning"), tr("Cannot start module ") + mXName + "<br>" + cmd + " " + arguments.join(" ") + "<br>" + QString(process.readAllStandardOutput()) + "<br>" + QString(process.readAllStandardError()) ); return; } QByteArray gDescArray = process.readAllStandardOutput(); QByteArray errArray = process.readAllStandardError(); QDomDocument gDoc ( "task" ); QString err; int line, column; if ( !gDoc.setContent( (QByteArray)gDescArray, &err, &line, &column ) ) { QString errmsg = tr("Cannot read module description (") + mXName + tr("):\n") + err + tr("\nat line ") + QString::number(line) + tr(" column ") + QString::number(column); QgsDebugMsg(errmsg); QgsDebugMsg(QString(gDescArray)); QgsDebugMsg(QString(errArray)); QMessageBox::warning( 0, tr("Warning"), errmsg ); return; } QDomElement gDocElem = gDoc.documentElement(); // Read QGIS options and create controls QDomNode n = qDocElem.firstChild(); //QVBoxLayout *layout = new QVBoxLayout ( mTabWidget->page(0), 10 ); QVBoxLayout *layout = new QVBoxLayout ( mParent, 10 ); while( !n.isNull() ) { QDomElement e = n.toElement(); if( !e.isNull() ) { QString optionType = e.tagName(); QgsDebugMsg("optionType = " + optionType); QString key = e.attribute("key"); QgsDebugMsg("key = " + key); QDomNode gnode = QgsGrassModule::nodeByKey ( gDocElem, key ); if ( gnode.isNull() ) { QMessageBox::warning( 0, tr("Warning"), tr("Cannot find key ") + key ); return; } if ( optionType == "option" ) { bool created = false; // Check option type and create appropriate control QDomNode promptNode = gnode.namedItem ( "gisprompt" ); if ( !promptNode.isNull() ) { QDomElement promptElem = promptNode.toElement(); QString element = promptElem.attribute("element"); QString age = promptElem.attribute("age"); //QgsDebugMsg("element = " + element + " age = " + age); if ( age == "old" && ( element == "vector" || element == "cell") ) { QgsGrassModuleInput *mi = new QgsGrassModuleInput ( mModule, this, key, e, gDocElem, gnode, mParent ); layout->addWidget ( mi ); created = true; mItems.push_back(mi); } } if ( !created ) { QgsGrassModuleOption *so = new QgsGrassModuleOption ( mModule, key, e, gDocElem, gnode, mParent ); layout->addWidget ( so ); created = true; mItems.push_back(so); } } else if ( optionType == "ogr" ) { QgsGrassModuleGdalInput *mi = new QgsGrassModuleGdalInput ( mModule, QgsGrassModuleGdalInput::Ogr, key, e, gDocElem, gnode, mParent ); layout->addWidget ( mi ); mItems.push_back(mi); } else if ( optionType == "gdal" ) { QgsGrassModuleGdalInput *mi = new QgsGrassModuleGdalInput ( mModule, QgsGrassModuleGdalInput::Gdal, key, e, gDocElem, gnode, mParent ); layout->addWidget ( mi );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -