Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

omgui.cpp

Go to the documentation of this file.
00001  /***************************************************************************
00002  *   Copyright (C) 2005 by Tim Sutton   *
00003  *   tim@linfiniti.com   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "omgui.h"
00021 #include "omggdal.h"
00022 #include "omgmodellerplugininterface.h"
00023 #include "omgscraperpluginregistry.h"
00024 #include "omglocality.h"
00025 #include <omgversion.h> //software version no e.g. 1.0.6
00026 #include <omgsvnversion.h>  //svn revision no e.g. 3002M
00027 
00028 #include <QApplication>
00029 #include <QDir>
00030 #include <QDomDocument>
00031 #include <QDomElement>
00032 #include <QDirIterator>
00033 #include <QFile>
00034 #include <QMap>
00035 #include <QPluginLoader>
00036 #include <QSettings>
00037 #include <QString>
00038 #include <QStringList>
00039 #include <QTextStream>
00040 #include <QVector>
00041 #include <QColor>
00042 #include <QUrl>
00043 #include <QPainter>
00044 #include <QRadialGradient>
00045 //
00046 // OSX includes
00047 // Important:  keep this include before qgis includes
00048 // otherwise you will get a name conflix on Point
00049 //
00050 #ifdef Q_OS_MACX
00051 //for getting app bundle path
00052 #include <ApplicationServices/ApplicationServices.h>
00053 #endif
00054 
00055 //
00056 // Qgis includes
00057 //
00058 #include <qgsvectorlayer.h> //defines QgsFieldMap 
00059 #include <qgsvectorfilewriter.h> //logic for writing shpfiles
00060 #include <qgsfeature.h> //we will need to pass a bunch of these for each rec
00061 #include <qgsgeometry.h> //each feature needs a geometry
00062 #include <qgspoint.h> //we will use point geometry
00063 #include <qgsspatialrefsys.h> //needed for creating a srs
00064 #include <qgsapplication.h> //search path for srs.db
00065 #include <qgsfield.h>
00066 #include <qgis.h> //defines GEOWKT
00067 
00068 
00069 
00070 /* 
00071  * Returns the path to the settings directory in user's home dir
00072  */
00073 const QString Omgui::userSettingsDirPath()
00074 {
00075   QSettings mySettings;
00076   QString myPath=
00077       mySettings.value("dataDirs/dataDir", QDir::homePath() + QDir::separator() + QString(".omgui")).toString();
00078   //  Make sure the users settings dir actually exists
00079   //qDebug("Omgui::userSettingsDirPath() = " + myPath.toLocal8Bit());
00080   QDir().mkpath(myPath);
00081   return myPath;
00082 }
00083 const QString Omgui::getModelOutputDir()
00084 {
00085   QString myPath = userSettingsDirPath()+QDir::separator()+"modelOutputs"+QDir::separator();
00086   QDir().mkpath(myPath);
00087   return myPath;
00088 }
00089 const QString Omgui::userAlgorithmProfilesDirPath()
00090 {
00091   //alg profiles are always saved in the users home dir under .omgui/
00092   QString myPath = QDir::homePath() + QDir::separator() + QString(".omgui") + 
00093     QDir::separator()+"algorithmProfiles"+QDir::separator();
00094   QDir().mkpath(myPath);
00095   return myPath;
00096 }
00097 const QString Omgui::fileSelectorCachePath()
00098 {
00099   //cached fileSelector documents are always saved in the users home dir under .omgui/
00100   //and then in subdirectories based on the modeller adapter type
00101   QSettings mySettings;
00102   QString mySubDir = mySettings.value("openModeller/modellerPluginType", "Local Modeller Plugin" ).toString();
00103   if (mySubDir=="Web Services Modeller Plugin")
00104   {
00105     QString myWSUrl=mySettings.value("openModeller/webServicesPlugin/url", "").toString();
00106     QUrl myUrl(myWSUrl);
00107     mySubDir += QDir::separator() + myUrl.host();
00108   }
00109   mySubDir=mySubDir.replace(" ","");
00110   QString myPath = QDir::homePath() + QDir::separator() + QString(".omgui") + 
00111                    QDir::separator() +
00112                    "fileSelectorCache" +
00113                    QDir::separator() +
00114                    mySubDir +
00115                    QDir::separator();
00116   QDir().mkpath(myPath);
00117   return myPath;
00118 }
00119 const QString Omgui::userLayersetDirPath()
00120 {
00121   //layersets  are always saved in the users home dir under .omgui/
00122   //and then in subdirectories based on the modeller adapter type
00123   QSettings mySettings;
00124   QString mySubDir = mySettings.value("openModeller/modellerPluginType", "Local Modeller Plugin" ).toString();
00125   if (mySubDir=="Web Services Modeller Plugin")
00126   {
00127     QString myWSUrl=mySettings.value("openModeller/webServicesPlugin/url", "").toString();
00128     QUrl myUrl(myWSUrl);
00129     mySubDir += QDir::separator() + myUrl.host();
00130   }
00131   mySubDir=mySubDir.replace(" ","");
00132   QString myPath = QDir::homePath() + QDir::separator() + QString(".omgui") + 
00133                    QDir::separator() +
00134                    "layersets" +
00135                    QDir::separator() +
00136                    mySubDir +
00137                    QDir::separator();
00138   QDir().mkpath(myPath);
00139   return myPath;
00140 }
00141 
00142 
00143 const QString Omgui::pluginDirPath()
00144 {
00145 #if defined(Q_OS_WIN)
00146   QDir myPluginsDir = QDir(qApp->applicationDirPath());
00147   myPluginsDir.cd("plugins");
00148   return myPluginsDir.absolutePath();
00149 #elif defined(Q_OS_MAC)
00150   CFURLRef myPluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
00151   CFStringRef myMacPath = CFURLCopyFileSystemPath(myPluginRef, kCFURLPOSIXPathStyle);
00152   const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
00153   CFRelease(myPluginRef);
00154   CFRelease(myMacPath);
00155   QString myPath(mypPathPtr);
00156   //do some magick so unit tests work - if the application is
00157   //not running in a bundle use a relative path to the build tree
00158   if (myPath.contains(".app"))
00159   {
00160     myPath += "/Contents/MacOS/lib/openModellerDesktop/";
00161     return myPath;
00162   }
00163   else //must be running from unit tests
00164   {
00165     QDir myPluginsDir = QDir(qApp->applicationDirPath());
00166     myPluginsDir.cd("lib");
00167     myPluginsDir.cd("plugins");
00168     myPath = myPluginsDir.absolutePath();
00169     qDebug("Running in unit test mode so Omgui::pluginDirPath() is using:");
00170     qDebug(myPath);
00171     return myPath;
00172   }
00173 #else //linux
00174   if (!qApp->applicationDirPath().isEmpty())
00175   {
00176     QDir myPluginsDir = QDir(qApp->applicationDirPath());
00177     myPluginsDir.cd("..");
00178     myPluginsDir.cd("lib");
00179     myPluginsDir.cd("openModellerDesktop");
00180     return myPluginsDir.absolutePath();
00181   }
00182   else
00183   {
00184     //maybe we are using Wt??
00185     return "/var/www/wt/plugins/";
00186   }
00187 #endif
00188 }
00189 
00190 
00191 
00192 
00193 
00194 Omgui::LayerSetMap Omgui::getAvailableLayerSets()
00195 {
00196   Omgui::LayerSetMap myMap;
00197   QDir myDirectory(userLayersetDirPath());
00198   myDirectory.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks );
00199   QFileInfoList myList = myDirectory.entryInfoList();
00200   for (unsigned int i = 0; i < static_cast<unsigned int>(myList.size()); ++i) 
00201   {
00202     QFileInfo myFileInfo = myList.at(i);
00203     //Ignore directories
00204     if(myFileInfo.fileName() == "." ||myFileInfo.fileName() == ".." ) 
00205     {
00206       continue;
00207     }
00208     //if the filename ends in .xml try to load it into our layerSets listing
00209     if(myFileInfo.completeSuffix()=="xml")
00210     {
00211       //qDebug("Loading layerset: " + myList.at(i).absoluteFilePath().toLocal8Bit());
00212       OmgLayerSet myLayerSet;
00213       myLayerSet.fromXmlFile(myFileInfo.absoluteFilePath());
00214       if (myLayerSet.name().isEmpty())
00215       {
00216         continue;
00217       }
00218       myMap[myLayerSet.name()]=myLayerSet;
00219     }
00220   }
00221   return myMap;
00222 }
00223 
00224 QStringList Omgui::sortList(QStringList theList)
00225 {
00226     //sort the taxon list alpabetically descending order
00227     theList.sort(); //this sorts ascending!
00228     //flip the sort order
00229     QStringList mySortedList;
00230     QStringList::Iterator myIterator= theList.end();
00231     while( myIterator!=theList.begin() )
00232     {
00233       myIterator--;
00234       mySortedList << *myIterator;
00235     }
00236     return mySortedList;
00237 }
00238 
00239 QStringList Omgui::uniqueList(QStringList theList)
00240 {
00241     //remove any duplicates from a sorted list
00242     QStringList myUniqueList;
00243     QString myLast = "";
00244     QStringListIterator myIterator( theList );
00245     while( myIterator.hasNext() )
00246     {
00247       QString myCurrent = myIterator.next();
00248       if (myCurrent!=myLast)
00249       {
00250         myUniqueList << myCurrent;
00251       }
00252       myLast=myCurrent;
00253     }
00254     return myUniqueList;
00255 }
00256 
00257 
00258 QString Omgui::getLayers(QString theBaseDir)
00259 {
00260   // @TODO check theBaseDir exists
00261   
00262   QDomDocument myDocument("OmguiLayersTree");
00263   QDomElement myRoot = myDocument.createElement("AvailableLayers");
00264   myRoot.setAttribute("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation","http://openmodeller.cria.org.br/xml/1.0 http://openmodeller.cria.org.br/xml/1.0/openModeller.xsd");
00265   myDocument.appendChild(myRoot);
00266   //append the start dir as a layerset
00267   QDomElement myElement = myDocument.createElement("LayersGroup");
00268   myElement.setAttribute("Id",theBaseDir);
00269   myElement.setAttribute("Type","DIR");
00270   //set the label
00271   QDomElement myLabelElement = myDocument.createElement("Label");
00272   QDomText myLabelText = myDocument.createTextNode(theBaseDir);
00273   myLabelElement.appendChild(myLabelText);
00274   myElement.appendChild(myLabelElement);
00275   //add to parent
00276   myRoot.appendChild(myElement);
00277   //now proceed to traverse all dirs below the base dir
00278   traverseDirectories(theBaseDir,myDocument,myElement);
00279   QString myString = myDocument.toString();
00280   return myString;
00281 }
00282 
00283 void Omgui::traverseDirectories(const QString theDirName, QDomDocument &theDocument, QDomElement &theParentElement)
00284 {
00285   if (theDirName.isEmpty()) return;
00286   //std::cout << "Recursing into : " << theDirName << std::endl;
00287   QDir myDirectory(theDirName);
00288   myDirectory.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks );
00289   //std::cout << "Current directory is: " << theDirName.toAscii() << std::endl;
00290   QString myInvalidFileList;
00291   QString myInvalidFileProjList;
00292   QFileInfoList myList = myDirectory.entryInfoList();
00293   for (unsigned int i = 0; i < static_cast<unsigned int>(myList.size()); ++i) 
00294   {
00295     QFileInfo myFileInfo = myList.at(i);
00296     //qDebug("Traverse Directories Scanning : " + myFileInfo.fileName().toLocal8Bit());
00297     if(myFileInfo.fileName() == "." ||myFileInfo.fileName() == ".." ) 
00298     {
00299       continue;
00300     }
00301     //if this is an empty dir, just skip it...
00302     if (myFileInfo.absoluteDir().count() < 1)
00303     {
00304       continue;
00305     }
00306     //check to see if entry is a directory - if so iterate through it (recursive function)
00307     //a new tree node will be created each time
00308     bool myFileFlag=false;
00309     bool myProjFlag=false;
00310     myFileFlag=OmgGdal::isValidGdalFile(myFileInfo.absoluteFilePath());
00311     /*
00312     if (myFileFlag)
00313     {
00314       qDebug(myFileInfo.absoluteFilePath().toLocal8Bit() + " is a valid gdal file");
00315     }
00316     else
00317     {
00318       qDebug(myFileInfo.absoluteFilePath().toLocal8Bit() + " is NOT a valid gdal file");
00319     }
00320     */
00321     if (myFileFlag)
00322     {
00323       myProjFlag=OmgGdal::isValidGdalProj(myFileInfo.absoluteFilePath());
00324     }
00325     if(myFileInfo.isDir() && myFileInfo.isReadable() && !myFileFlag )
00326     {
00327       QDomElement myElement = theDocument.createElement("LayersGroup");
00328       myElement.setAttribute("Id",myFileInfo.absoluteFilePath());
00329       myElement.setAttribute("Type","DIR");
00330       //set the label
00331       QDomElement myLabelElement = theDocument.createElement("Label");
00332       QDomText myLabelText = theDocument.createTextNode(myFileInfo.baseName());
00333       myLabelElement.appendChild(myLabelText);
00334       myElement.appendChild(myLabelElement);
00335       //add to parent
00336       theParentElement.appendChild(myElement);
00337       traverseDirectories(myFileInfo.absoluteFilePath(),theDocument, myElement );
00338     }
00340     else if (myFileInfo.isDir() && myFileInfo.isReadable() && myFileFlag)
00341     {
00342       if ( myFileFlag && myProjFlag )
00343       {
00344         //GOOD FILE AND GOOD PROJ
00345         //std::cout <<myFileInfo->absoluteFilePath().ascii() << " is a valid GDAL file and contains projection info" << std::endl;
00346         QDomElement myElement = theDocument.createElement("Layer");
00347         myElement.setAttribute("Id",myFileInfo.absoluteFilePath());
00348         myElement.setAttribute("HasProjection","1");
00349         myElement.setAttribute("Type","AIG");
00350         //set the label
00351         QDomElement myLabelElement = theDocument.createElement("Label");
00352         QDomText myLabelText = theDocument.createTextNode(myFileInfo.baseName());
00353         myLabelElement.appendChild(myLabelText);
00354         myElement.appendChild(myLabelElement);
00355         //add to parent
00356         theParentElement.appendChild(myElement);
00357       }
00358       else if (myFileFlag && !myProjFlag)
00359       {
00360         //GOOD FILE AND BAD PROJ
00361         //std::cout <<myFileInfo->absoluteFilePath().ascii() << " is a valid GDAL file but contains no projection info" << std::endl;
00362         QDomElement myElement = theDocument.createElement("Layer");
00363         myElement.setAttribute("Id",myFileInfo.absoluteFilePath());
00364         myElement.setAttribute("HasProjection","0");
00365         myElement.setAttribute("Type","AIG");
00366         //set the label
00367         QDomElement myLabelElement = theDocument.createElement("Label");
00368         QDomText myLabelText = theDocument.createTextNode(myFileInfo.baseName());
00369         myLabelElement.appendChild(myLabelText);
00370         myElement.appendChild(myLabelElement);
00371         //add to parent
00372         theParentElement.appendChild(myElement);
00373       }
00374     }
00375     //check to see if entry is of the other required file types
00376     else if ((myFileInfo.suffix()=="tif") ||
00377             (myFileInfo.suffix()=="asc") ||
00378             (myFileInfo.suffix()=="bil") ||
00379             (myFileInfo.suffix()=="img") ||
00380             (myFileInfo.suffix()=="jpg")   )
00381     {      
00382       
00383       //test whether the file is GDAL compatible
00384       if ( myFileFlag && myProjFlag )
00385       {
00386         //GOOD FILE AND GOOD PROJ
00387         //std::cout <<myFileInfo->absoluteFilePath().ascii() << " is a valid GDAL file and contains projection info" << std::endl;
00388         QDomElement myElement = theDocument.createElement("Layer");
00389         myElement.setAttribute("Id",myFileInfo.absoluteFilePath());
00390         myElement.setAttribute("HasProjection","1");
00391         myElement.setAttribute("Type",myFileInfo.suffix());
00392         //set the label
00393         QDomElement myLabelElement = theDocument.createElement("Label");
00394         QDomText myLabelText = theDocument.createTextNode(myFileInfo.fileName());
00395         myLabelElement.appendChild(myLabelText);
00396         myElement.appendChild(myLabelElement);
00397         //add to parent
00398         theParentElement.appendChild(myElement);
00399       }
00400       else if (myFileFlag && !myProjFlag)
00401       {
00402         //GOOD FILE AND BAD PROJ
00403         //std::cout <<myFileInfo->absoluteFilePath().ascii() << " is a valid GDAL file but contains no projection info" << std::endl;
00404         QDomElement myElement = theDocument.createElement("Layer");
00405         myElement.setAttribute("Id",myFileInfo.absoluteFilePath());
00406         myElement.setAttribute("HasProjection","0");
00407         myElement.setAttribute("Type",myFileInfo.suffix());
00408         //set the label
00409         QDomElement myLabelElement = theDocument.createElement("Label");
00410         QDomText myLabelText = theDocument.createTextNode(myFileInfo.fileName());
00411         myLabelElement.appendChild(myLabelText);
00412         myElement.appendChild(myLabelElement);
00413         //add to parent
00414         theParentElement.appendChild(myElement);
00415       }
00416       else 
00417       {
00418         //BAD FILE AND/OR BAD PROJ
00419         //do nothing
00420       } 
00421     }  
00422   }
00423 }   
00424 
00425 //return a string list of all the experiment files
00426 QStringList Omgui::getExperimentsList()
00427 {
00428   QStringList myExperimentList;
00429   QSettings mySettings;
00430   QString myWorkDir = mySettings.value("dataDirs/dataDir",
00431       QDir::homePath() + QDir::separator() + ".omgui").toString() + 
00432                      QDir::separator() + "modelOutputs";
00433   QDir myDirectory(myWorkDir);
00434   if (!myDirectory.exists())
00435   {
00436     qDebug("Error the experiment working directory does not exist");
00437     qDebug("Directory we tried to use is : " +  myWorkDir.toAscii());
00438     return QStringList();
00439   }
00440   myDirectory.setFilter( QDir::Dirs | QDir::NoDotAndDotDot );
00441 
00442   QStringList myList = myDirectory.entryList();
00443   for (unsigned int i = 0; i < static_cast<unsigned int>(myList.size()); ++i) 
00444   {
00445     QString mySubDirectoryName = myWorkDir + QDir::separator() + myList.at(i);
00446     //qDebug("Get ExperimentsList Checking: " + mySubDirectoryName.toLocal8Bit());
00447     //Now look in each dir under the workdir for the xml experiment file
00448     //It should be the first one found since there should only be
00449     //one experiment per directory.
00450     //the experiment file should be named <long guid>.xml
00451     QDir mySubDirectory( mySubDirectoryName );
00452     mySubDirectory.setFilter( QDir::NoDotAndDotDot | QDir::Files );
00453     QStringList myFilters;
00454     myFilters << "*.xml";
00455     mySubDirectory.setNameFilters(myFilters);
00456     //qDebug ("Current directory is: " +  myWorkDir.toAscii());
00457     QStringList myExperimentFileList = mySubDirectory.entryList();
00458     if (myExperimentFileList.count() < 1)
00459     {
00460       continue;
00461     }
00462     QString myFileName = mySubDirectoryName + QDir::separator() +  myExperimentFileList.at(0);
00463 
00464     //qDebug("Get ExperimentsList Checking: " + myFileName.toLocal8Bit());
00465     if (QFile::exists(myFileName))
00466     {
00467       myExperimentList << myFileName;
00468       //qDebug("Get ExperimentsList Adding: " + myFileName.toLocal8Bit());
00469     }
00470   }
00471   return myExperimentList;
00472 }
00473 
00474 QHash<QString,QString> Omgui::getOutputFormats()
00475 {
00476   //later this should be something provided by the modeller adapter
00477   QHash<QString,QString> myHash;
00478   myHash.insert("GreyTiff",QObject::tr("Tagged Image Format (Integer)"  ));
00479   myHash.insert("GreyTiff100",QObject::tr("Tagged Image Format 100 (Integer)"  ));
00480   myHash.insert("FloatingTiff",QObject::tr("Tagged Image Format (Floating Point)" ));
00481   myHash.insert("GreyBMP",QObject::tr("Bitmap (Integer)" ));
00482   myHash.insert("FloatingHFA",QObject::tr("Erdas Imagine (Floating Point)" ));
00483   myHash.insert("ByteHFA",QObject::tr("Erdas Imagine (Integer)" ));
00484   return myHash;
00485 
00486 }
00487 QHash<QString,QString> Omgui::getOutputFormatNotes()
00488 {
00489   //later this should be something provided by the modeller adapter
00490   QHash<QString,QString> myHash;
00491   myHash.insert("GreyTiff",QObject::tr("Tagged Image Format (Integer), Range: 0-254, Nodata: 255"  ));
00492   myHash.insert("GreyTiff100",QObject::tr("Tagged Image Format (Integer), Range: 0-100, Nodata: 127"  ));
00493   myHash.insert("FloatingTiff",QObject::tr("Tagged Image Format (Floating Point), Range:0-1, Nodata: -1" ));
00494   myHash.insert("GreyBMP",QObject::tr("Bitmap (Integer), Range: 1-255, Nodata: 0" ));
00495   myHash.insert("FloatingHFA",QObject::tr("Erdas Imagine (Floating Point), Range: 0-1, Nodata: -1" ));
00496   myHash.insert("ByteHFA",QObject::tr("Erdas Imagine (Integer), Range: 0-100, Nodata: 0" ));
00497   return myHash;
00498 
00499 }
00500 
00501 QHash<QString,QPair<double,double> > Omgui::getOutputFormatRanges()
00502 {
00503   //later this should be something provided by the modeller adapter
00504   QHash<QString,QPair<double,double> > myHash;
00505   myHash.insert("GreyTiff",qMakePair(0.0,254.0));
00506   myHash.insert("GreyTiff100",qMakePair(0.0,100.0));
00507   myHash.insert("FloatingTiff",qMakePair(0.0,1.0));
00508   myHash.insert("GreyBMP",qMakePair(1.0,255.0));
00509   myHash.insert("FloatingHFA",qMakePair(0.0,1.0));
00510   myHash.insert("ByteHFA",qMakePair(0.0,100.0));
00511   return myHash;
00512 }
00513 
00514 QHash<QString,float> Omgui::getOutputFormatNoData()
00515 {
00516   //later this should be something provided by the modeller adapter
00517   QHash<QString,float> myHash;
00518   myHash.insert("GreyTiff",255);
00519   myHash.insert("GreyTiff100",127);
00520   myHash.insert("FloatingTiff",-1);
00521   myHash.insert("GreyBMP",0);
00522   myHash.insert("FloatingHFA",-1);
00523   myHash.insert("ByteHFA",0);
00524   return myHash;
00525 }
00526 
00527 QString Omgui::getOutputFormatExtension()
00528 {
00529   QSettings mySettings;
00530   QString myFormat = mySettings.value("outputFormat","GreyTiff").toString();
00531   if (myFormat.contains("Tiff")) return "tif";
00532   if (myFormat.contains("HFA")) return "img";
00533   if (myFormat.contains("BMP")) return "bmp";
00534   //qDebug("Omgui::getOutputFormatExtension Warning unknown extension!!!");
00535   //qDebug("Defaulting to img!!!");
00536   return "img";
00537 }
00538 
00539 bool Omgui::createTextFile(QString theFileName, QString theData)
00540 {
00541   //create the txt file
00542   QFile myFile( theFileName );
00543   if ( myFile.open( QIODevice::WriteOnly ) )
00544   {
00545     QTextStream myQTextStream( &myFile );
00546     myQTextStream << theData;
00547   }
00548   else
00549   {
00550     return false;
00551   }
00552   myFile.close();
00553   return true ;
00554 }
00555 
00556 QString Omgui::readTextFile(QString theFileName)
00557 {
00558   QString myString;
00559   QFile myFile( theFileName );
00560   if ( myFile.open( QIODevice::ReadOnly ) )
00561   {
00562     myString=myFile.readAll();
00563     myFile.close();
00564   }
00565   return myString;
00566 }
00567 
00568 QString Omgui::xmlEncodeAmpersands(QString theString)
00569 {
00570   theString.replace("&","&amp;");
00571   return theString;
00572 }
00573 
00574 QString Omgui::xmlEncode(QString theString)
00575 {
00576   theString.replace("<","&lt;");
00577   theString.replace(">","&gt;");
00578   theString.replace("&","&amp;");
00579   return theString;
00580 }
00581 
00582 void Omgui::xmlEncodeInPlace(QString &theString)
00583 {
00584   theString.replace("<","&lt;");
00585   theString.replace(">","&gt;");
00586   theString.replace("&","&amp;");
00587 }
00588 
00589 QString Omgui::xmlDecode(QString theString)
00590 {
00591   theString.replace("&lt;","<");
00592   theString.replace("&gt;",">");
00593   theString.replace("&amp;","&");
00594   return theString;
00595 }
00596 
00597 void Omgui::xmlDecodeInPlace(QString &theString)
00598 {
00599   theString.replace("&lt;","<");
00600   theString.replace("&gt;",">");
00601   theString.replace("&amp;","&");
00602 }
00603 
00604 QString Omgui::i18nPath()
00605 {
00606   QString myI18nPath;
00607 #ifdef Q_OS_MACX 
00608   CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
00609   CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
00610   const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
00611   CFRelease(myBundleRef);
00612   CFRelease(myMacPath);
00613   QString myPath(mypPathPtr);
00614   //do some magick so that we can still find i18n dir if
00615   //openModellerDesktop was not built as a bundle
00616   if (myPath.contains(".app"))
00617   {
00618     myI18nPath = myPath + "/Contents/MacOS/share/openModellerDesktop/i18n";
00619   }
00620   else //must be running from a non .app bundle
00621   {
00622     QString myI18nPath = QApplication::applicationDirPath()+"/../share/openModellerDesktop/i18n";
00623   }
00624 #elif WIN32  
00625   myI18nPath = QApplication::applicationDirPath()+"/i18n";
00626 #else
00627   myI18nPath = QApplication::applicationDirPath()+"/../share/openModellerDesktop/i18n";
00628 #endif
00629   
00630   return myI18nPath;
00631 }
00632 
00633 QStringList Omgui::i18nList()
00634 {
00635   QStringList myList;
00636   myList << "en_US"; //there is no qm file for this so we add it manually
00637   QString myI18nPath = i18nPath();
00638   QDirIterator myIterator(myI18nPath, QDirIterator::Subdirectories);
00639   while (myIterator.hasNext()) 
00640   {
00641     QString myEntry = myIterator.next();
00642     QFileInfo myFileInfo(myEntry);
00643     if (!myFileInfo.isFile()) continue;
00644     QString myFileName = myFileInfo.fileName();
00645     myList << myFileName.replace("openModellerDesktop_","").replace(".qm","");
00646   }
00647   return myList;
00648 }
00649 
00650 QColor Omgui::randomColour()
00651 {
00652   //get a random record from the resultset
00653   srand(QTime::currentTime().msec());
00654   int myRand = rand();
00655   int myValue1 = static_cast<int> (myRand % 256); //range 0-255
00656   myRand = rand();
00657   int myValue2 = static_cast<int> (myRand % 256); //range 0-255
00658   myRand = rand();
00659   int myValue3 = static_cast<int> (myRand % 256); //range 0-255
00660   //QString myString = "Random colour: " + 
00661   //  QString::number(myValue1) +
00662   //  "," + QString::number(myValue2) +
00663   //  "," + QString::number(myValue3);
00664   //qDebug(myString);
00665   QColor myColour(myValue1,myValue2,myValue3,190);
00666   return myColour;
00667 }
00668 
00669 QString Omgui::defaultStyleSheet()
00670 {
00671   QString myStyle;
00672   myStyle += ".glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565); color: white; padding-left: 4px; padding-top: 20px; padding-bottom: 8px;  border: 1px solid #6c6c6c; }";
00673   myStyle += ".glossyBlue{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #3087d3, stop: 0.5 #3794e2, stop: 0.6 #43a6f9, stop:1 #2f87d1); color: white; padding-left: 4px; padding-top: 20px; padding-bottom: 8px;  border: 1px solid #44a7fb; }";
00674   myStyle += "h1 {font-size : 22pt; }";
00675   myStyle += "h2 {font-size : 18pt; }";
00676   myStyle += "h3 {font-size : 14pt; }";
00677   myStyle += ".glossyh3{ "
00678     "background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565);"
00679     "color: white; "
00680     "padding-left: 4px; "
00681     "padding-top: 20px;"
00682     "padding-bottom: 8px;  "
00683     "border: 1px solid #6c6c6c; }";
00684   myStyle += ".headerCell {color:#466aa5; "
00685     "font-size : 12pt; "
00686     "font-weight: bold; "
00687     "}";
00688   myStyle += ".parameterHeader {font-weight: bold;}";
00689   myStyle += ".largeCell {color:#000000; font-size : 12pt;}";
00690   myStyle += ".alternateCell {font-weight: bold;}";
00691   myStyle += ".rocTable "
00692   "{"
00693   "  border-width: 1px 1px 1px 1px;"
00694   "  border-spacing: 2px;"
00695   "  border-style: solid solid solid solid;" //unsupported
00696   "  border-color: black black black black;" //unsupported
00697   "  border-collapse: separate;"
00698   "  background-color: white;"
00699   "}";
00700   return myStyle;
00701 }
00702 
00703 
00704 QString Omgui::getHtmlHeader()
00705 {
00706  // Use xhtml transitional
00707  QString myHtml = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"";
00708   myHtml += "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
00709   myHtml += "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\">";
00710   myHtml += "<head>";
00711   myHtml += " <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />";
00712   myHtml += "</head>";
00713   myHtml += "<body>";
00714   return myHtml;
00715 }
00716 
00717 QString Omgui::getHtmlFooter()
00718 {
00719  QString myHtml = "</body>";
00720     myHtml += "</html>";
00721  return myHtml;
00722 }
00723 
00724 
00725 bool Omgui::deleteShapeFile(QString theFileName)
00726 {
00727   theFileName.replace(".shp","");
00728   QFileInfo myInfo(theFileName + ".shp");
00729   if (myInfo.exists())
00730   {
00731     if(!QFile::remove(theFileName + ".shp"))
00732     {
00733       qDebug("Removing file failed : " + theFileName.toLocal8Bit() + ".shp");
00734       return false;
00735     }
00736   }
00737   myInfo.setFile(theFileName + ".shx");
00738   if (myInfo.exists())
00739   {
00740     if(!QFile::remove(theFileName + ".shx"))
00741     {
00742       qDebug("Removing file failed : " + theFileName.toLocal8Bit() + ".shx");
00743       return false;
00744     }
00745   }
00746   myInfo.setFile(theFileName + ".dbf");
00747   if (myInfo.exists())
00748   {
00749     if(!QFile::remove(theFileName + ".dbf"))
00750     {
00751       qDebug("Removing file failed : " + theFileName.toLocal8Bit() + ".dbf");
00752       return false;
00753     }
00754   }
00755   myInfo.setFile(theFileName + ".prj");
00756   if (myInfo.exists())
00757   {
00758     if(!QFile::remove(theFileName + ".prj"))
00759     {
00760       qDebug("Removing file failed : " + theFileName.toLocal8Bit() + ".prj");
00761       return false;
00762     }
00763   }
00764   return true;
00765 }
00766 
00767 bool Omgui::localitiesToShapefile(QString theShapefileName,
00768     OmgLocalities const &theLocalities) 
00769 {
00770   if (theLocalities.size() < 1)
00771   {
00772     qDebug("Writing " + theShapefileName.toLocal8Bit() + " failed (no locs)");
00773     return false;
00774   }
00775   //
00776   //    Note: if you get a message like 
00777   //    ERROR 1: /tmp/foo.shp is not a directory.
00778   //    It is caused by the /tmp/testshp.* files already existing
00779   //    (the ERROR comes from OGR and is not very intuitive)
00780   QString myEncoding = "UTF-8";
00781   QgsVectorFileWriter::WriterError myError;
00782   QgsField myIdField("accession",QVariant::String,"String",10,0,"Accession code");
00783   QgsField myLonField("lon",QVariant::String,"String",10,0,"longitude");
00784   QgsField myLatField("lat",QVariant::String,"String",10,0,"latitude");
00785   QgsField myStatusField("status",QVariant::String,"String",10,0,"Present or absent");
00786   QgsFieldMap myFields;
00787   myFields.insert(0, myIdField);
00788   myFields.insert(1, myLonField);
00789   myFields.insert(2, myLatField);
00790   myFields.insert(3, myStatusField);
00791   QgsSpatialRefSys mySRS = QgsSpatialRefSys(GEOWKT);
00792 
00793   Omgui::deleteShapeFile(theShapefileName);
00794   QgsVectorFileWriter myWriter (theShapefileName,
00795       myEncoding,
00796       myFields,
00797       QGis::WKBPoint,
00798       &mySRS);
00799   for (int myIteratorInt = 0; myIteratorInt < theLocalities.size(); ++myIteratorInt)
00800   {
00801     OmgLocality myLocality = theLocalities[myIteratorInt];
00802     QgsPoint myPoint(static_cast<double>(myLocality.longitude()), 
00803         static_cast<double>(myLocality.latitude()));
00804     //
00805     // Create a feature
00806     //
00807     //
00808     // NOTE: dont delete this pointer again - 
00809     // ownership is passed to the feature which will
00810     // delete it in its dtor!
00811     QgsGeometry * mypPointGeometry = QgsGeometry::fromPoint(myPoint);
00812     QgsFeature myFeature;
00813     myFeature.setGeometry(mypPointGeometry);
00814     myFeature.addAttribute(0,myLocality.id());
00815     myFeature.addAttribute(1,myLocality.longitude());
00816     myFeature.addAttribute(2,myLocality.latitude());
00817     if (myLocality.abundance() > 0)
00818     {
00819       if (myLocality.samples().size() == 0)
00820       {
00821         myFeature.addAttribute(3,"Present - Not Used");
00822       }
00823       else //was actually used in a model
00824       {
00825         myFeature.addAttribute(3,"Present");
00826       }
00827     }
00828     else
00829     {
00830       if (myLocality.samples().size() == 0)
00831       {
00832         myFeature.addAttribute(3,"Absent - Not Used");
00833       }
00834       else //was actually used in a model
00835       {
00836         myFeature.addAttribute(3,"Absent");
00837       }
00838     }
00839     //
00840     // Write the feature to the filewriter
00841     // and check for errors
00842     //
00843     if (!myWriter.addFeature(myFeature))
00844     {
00845       return false;
00846     }
00847     myError = myWriter.hasError();
00848     if(myError==QgsVectorFileWriter::ErrDriverNotFound)
00849     {
00850       qDebug("Driver not found error");
00851       return false;
00852     }
00853     else if (myError==QgsVectorFileWriter::ErrCreateDataSource)
00854     {
00855       qDebug("Create data source error");
00856       return false;
00857     }
00858     else if (myError==QgsVectorFileWriter::ErrCreateLayer)
00859     {
00860       qDebug("Create layer error");
00861       return false;
00862     }
00863   }
00864   return true;
00865 }
00866 
00867 QString Omgui::version()
00868 {
00869   QString myOmgVersion;
00870 #ifdef OMGMAJORVERSION
00871   myOmgVersion = 
00872     QString::number(OMGMAJORVERSION) + "." +
00873     QString::number(OMGMINORVERSION) + "." +
00874     QString::number(OMGRELEASEVERSION);
00875 
00876 #endif
00877 
00878 #ifdef OMGSVNVERSION
00879   QString myVersionString = QObject::tr("Version: ") + 
00880     myOmgVersion + " (" + 
00881     OMGSVNVERSION + ")";  
00882 #else
00883   QString myVersionString = QObject::tr("Version: ") + 
00884     myOmgVersion ;  
00885 #endif
00886   return myVersionString;
00887 }
00888 
00889 void Omgui::createThumbnail(QString theTopLabel,
00890                                QString theBottomLabel,
00891                                QString theSourceImageFileName,
00892                                QString theOutputFileName)
00893 {
00894   
00895   //  +-------------------+
00896   //  |                   | <- vertical space 1
00897   //  |     Top Label     |
00898   //  |                   | <- vertical space 2
00899   //  | +---------------+ |
00900   //  | |               | |
00901   //  | |     IMAGE     | |
00902   //  | |               | |
00903   //  | |               | |
00904   //  | +---------------+ |
00905   //  |                   | <- vertical space 3
00906   //  |   Bottom Label    |
00907   //  |                   | <- vertical space 4
00908   //  +-------------------+
00909   //   ^                 ^
00910   //   +-----------------+---- horizontal spaces 1 and 2
00911 
00912   
00913   int myX = 160;
00914   int myY = 180;
00915   int mySpacing = 10; //px
00916   QFont myFont("arial", 10, QFont::Normal);
00917   QFontMetrics myMetrics(myFont);
00918   int myResizeX = myX - (2*mySpacing); //leave space on each side
00919   int myResizeY = myY - ((4*mySpacing)+(2*myMetrics.height())); //spaces above and below each label
00920  
00921   QImage myImage(myX, myY, QImage::Format_ARGB32);
00922   myImage.fill(qRgba(0,0,0,0)); 
00923   QPainter myPainter(&myImage);
00924   myPainter.setRenderHint(QPainter::Antialiasing);
00925   QPen myPen;
00926   
00927   //
00928   // draw the drop shadow first
00929   //
00930   myPen.setWidth(0);
00931   myPen.setColor(Qt::transparent);
00932   myPainter.setPen(myPen);
00933   //gradient bavkground shadow for the thumbnail
00934   //radial gradient starting in top left corner
00935   QRadialGradient myGradient(QPointF(0,0), myX/2);
00936   myGradient.setColorAt(0, Qt::darkGray);
00937   myGradient.setColorAt(0.99, Qt::darkGray);
00938   myGradient.setColorAt(1, Qt::gray);
00939   myPainter.setBrush(myGradient);
00940   myPainter.drawRoundRect ( QRect(1,1,myX,myY),25,25 );
00941   //
00942   // Now draw the rounded rect - it will overpaint
00943   // most of the above and just leave a little
00944   // shadow sticking out below and right
00945   //
00946 
00947   //make a glossygradient for the thumbnail background
00948   QGradientStops myStops;
00949   myStops << QGradientStop(0.0,QColor("#3087d3"));
00950   myStops << QGradientStop(0.5,QColor("#3794e2"));
00951   myStops << QGradientStop(0.6,QColor("#43a6f9"));
00952   myStops << QGradientStop(1.0,QColor("#2f87d1"));
00953   QLinearGradient myGlossyGradientTop(QPointF(0,0), QPointF(0,myY/2));
00954   myGlossyGradientTop.setStops(myStops);
00955   QLinearGradient myGlossyGradientBottom(QPointF(0,myY/2), QPointF(0,0));
00956   myGlossyGradientBottom.setStops(myStops);
00957   
00958   myPen.setWidth(2);
00959   myPen.setColor("#43a6f9");
00960   myPainter.setPen(myPen);
00961   myPainter.setBrush(myGlossyGradientTop);
00962   myPainter.drawRoundRect ( QRect(1,1,myX-4,myY-4),25,25 );
00963   //myPainter.setBrush(myGlossyGradientBottom);
00964   //myPainter.drawRoundRect ( QRect(1,1,myX-4,myY-4),25,25 );
00965   //
00966   //now paint the label for the bottom
00967   //
00968   myPainter.setFont(myFont);
00969   int myWidth = myMetrics.width(theBottomLabel); //width of text
00970   if (myWidth > (myX - (2*mySpacing)))
00971   {
00972     myWidth = myX - (2*mySpacing);
00973   }
00974   int myHeight = myMetrics.height();
00975   myPen.setColor(Qt::black);
00976   myPainter.setPen(myPen);
00977   QPointF myTopLeftPoint =QPointF(  mySpacing , mySpacing);
00978   QPointF myBottomRightPoint = QPointF( myX-mySpacing , mySpacing+myHeight );
00979   myPainter.drawText(QRectF(myTopLeftPoint,myBottomRightPoint),
00980                Qt::AlignCenter || Qt::AlignVCenter,theTopLabel);
00981   //
00982   // now get a thumbnail of the image and paste it into our
00983   // painter
00984   QFileInfo myFileInfo(theSourceImageFileName);
00985   QImage mySourceImage;
00986   if (!myFileInfo.exists())
00987   {
00988     //image will be blank
00989   }
00990   else 
00991   {
00992     mySourceImage.load(theSourceImageFileName);
00993   }
00994   QImage myThumbImage = mySourceImage.scaled(
00995         myResizeX,myResizeY,Qt::KeepAspectRatio,Qt::FastTransformation );
00996   myTopLeftPoint =QPointF(  mySpacing , (mySpacing*2)+myHeight);
00997   myBottomRightPoint = QPointF( myX-mySpacing , (mySpacing*2)+myHeight+myResizeY );
00998   myPainter.drawImage(QRectF(myTopLeftPoint,myBottomRightPoint),
00999                myThumbImage);
01000   //
01001   //now paint the bottom label
01002   //
01003   myWidth = myMetrics.width(theBottomLabel); //width of text
01004   if (myWidth > (myX - (2*mySpacing)))
01005   {
01006     myWidth = myX - (2*mySpacing);
01007   }
01008   myPen.setColor(Qt::white);
01009   myPainter.setPen(myPen);
01010   myTopLeftPoint =QPointF(  mySpacing , (mySpacing*3)+myHeight+myResizeY);
01011   myBottomRightPoint = QPointF( myX-mySpacing ,(mySpacing*3)+(myHeight*2)+myResizeY );
01012   myPainter.drawText(QRectF(myTopLeftPoint,myBottomRightPoint),
01013                Qt::AlignCenter || Qt::AlignVCenter,theBottomLabel);
01014   myPainter.end();
01015   //
01016   //finish up by saving our swish looking thumbnail to disk
01017   //
01018   myImage.save(theOutputFileName,"PNG");
01019 }

Generated on Mon Apr 28 15:09:19 2008 for openModellerDesktop by  doxygen 1.4.1-20050210