00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <QBitmap>
00021 #include <QDir>
00022 #include <QFile>
00023 #include <QFileInfo>
00024 #include <QFont>
00025 #include <QMessageBox>
00026 #include <QPixmap>
00027 #include <QLocale>
00028 #include <QSettings>
00029 #include <QSplashScreen>
00030 #include <QString>
00031 #include <QStringList>
00032 #include <QStyle>
00033 #include <QPlastiqueStyle>
00034 #include <QTranslator>
00035 #include <QImageReader>
00036
00037 #include <cstdio>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040
00041 #ifdef WIN32
00042
00043 #include <fcntl.h>
00044 #ifdef MSVC
00045 #undef _fmode
00046 int _fmode = _O_BINARY;
00047 #endif
00048 #ifndef _MSC_VER
00049
00050
00051
00052 #undef _fmode
00053 int _fmode = _O_BINARY;
00054 #endif//_MSC_VER
00055 #else
00056 #include <getopt.h>
00057 #endif
00058
00059 #ifdef Q_OS_MACX
00060 #include <ApplicationServices/ApplicationServices.h>
00061 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
00062 typedef SInt32 SRefCon;
00063 #endif
00064 #endif
00065
00066 #include "qgisapp.h"
00067 #include "qgsapplication.h"
00068 #include <qgsconfig.h>
00069 #include <qgssvnversion.h>
00070 #include "qgsexception.h"
00071 #include "qgsproject.h"
00072 #include "qgsrect.h"
00073 #include "qgslogger.h"
00074
00075 static const char * const ident_ = "$Id: main.cpp 9150 2008-08-24 14:07:06Z jef $";
00076
00079 void usage( std::string const & appName )
00080 {
00081 std::cerr << "Quantum GIS - " << VERSION << " '" << RELEASE_NAME << "' ("
00082 << QGSSVNVERSION << ")\n"
00083 << "Quantum GIS (QGIS) is a viewer for spatial data sets, including\n"
00084 << "raster and vector data.\n"
00085 << "Usage: " << appName << " [options] [FILES]\n"
00086 << " options:\n"
00087 << "\t[--snapshot filename]\temit snapshot of loaded datasets to given file\n"
00088 << "\t[--lang language]\tuse language for interface text\n"
00089 << "\t[--project projectfile]\tload the given QGIS project\n"
00090 << "\t[--extent xmin,ymin,xmax,ymax]\tset initial map extent\n"
00091 << "\t[--help]\t\tthis text\n\n"
00092 << " FILES:\n"
00093 << " Files specified on the command line can include rasters,\n"
00094 << " vectors, and QGIS project files (.qgs): \n"
00095 << " 1. Rasters - Supported formats include GeoTiff, DEM \n"
00096 << " and others supported by GDAL\n"
00097 << " 2. Vectors - Supported formats include ESRI Shapefiles\n"
00098 << " and others supported by OGR and PostgreSQL layers using\n"
00099 << " the PostGIS extension\n" ;
00100
00101
00102 }
00103
00104
00106
00108
00109
00110
00111
00112
00113 static QString myProjectFileName = "";
00114
00115
00116 static QStringList myFileList;
00117
00118
00119 #ifdef Q_OS_MACX
00120
00121
00122
00123
00124 OSErr openDocumentsAEHandler( const AppleEvent *event, AppleEvent *reply, SRefCon refCon )
00125 {
00126 AEDescList docs;
00127 if ( AEGetParamDesc( event, keyDirectObject, typeAEList, &docs ) == noErr )
00128 {
00129
00130 long count = 0;
00131 AECountItems( &docs, &count );
00132
00133
00134 myProjectFileName.truncate( 0 );
00135 myFileList.clear();
00136 for ( int i = 0; i < count; i++ )
00137 {
00138 FSRef ref;
00139 UInt8 strBuffer[256];
00140 if ( AEGetNthPtr( &docs, i + 1, typeFSRef, 0, 0, &ref, sizeof( ref ), 0 ) == noErr &&
00141 FSRefMakePath( &ref, strBuffer, 256 ) == noErr )
00142 {
00143 QString fileName( QString::fromUtf8( reinterpret_cast<char *>( strBuffer ) ) );
00144 if ( fileName.endsWith( ".qgs" ) )
00145 {
00146
00147 if ( myProjectFileName.isEmpty() )
00148 {
00149 myProjectFileName = fileName;
00150 }
00151 }
00152 else
00153 {
00154
00155 myFileList.append( fileName );
00156 }
00157 }
00158 }
00159
00160
00161
00162
00163 QgisApp *qgis = QgisApp::instance();
00164 if ( qgis && qgis->objectName() == "QgisApp" )
00165 {
00166 if ( !myProjectFileName.isEmpty() )
00167 {
00168 qgis->openProject( myProjectFileName );
00169 }
00170 for ( QStringList::Iterator myIterator = myFileList.begin();
00171 myIterator != myFileList.end(); ++myIterator )
00172 {
00173 QString fileName = *myIterator;
00174 qgis->openLayer( fileName );
00175 }
00176 }
00177 }
00178 return noErr;
00179 }
00180 #endif
00181
00182
00183
00184
00185
00186
00187
00188 bool bundleclicked( int argc, char *argv[] )
00189 {
00190 return ( argc > 1 && memcmp( argv[1], "-psn_", 5 ) == 0 );
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 void myMessageOutput( QtMsgType type, const char *msg )
00206 {
00207 switch ( type )
00208 {
00209 case QtDebugMsg:
00210 fprintf( stderr, "Debug: %s\n", msg );
00211 break;
00212 case QtCriticalMsg:
00213 fprintf( stderr, "Critical: %s\n", msg );
00214 break;
00215 case QtWarningMsg:
00216 fprintf( stderr, "Warning: %s\n", msg );
00217
00218
00219 if ( 0 == strncmp( msg, "libpng error:", 13 ) )
00220 {
00221
00222 QMessageBox::warning( 0, "libpng Error", msg );
00223 }
00224
00225 break;
00226 case QtFatalMsg:
00227 fprintf( stderr, "Fatal: %s\n", msg );
00228 abort();
00229 }
00230 }
00231
00232
00233 int main( int argc, char *argv[] )
00234 {
00235 #ifdef _MSC_VER
00236 _set_fmode( _O_BINARY );
00237 #endif
00238
00239 #ifndef _MSC_VER
00240
00241 qInstallMsgHandler( myMessageOutput );
00242 #endif
00243
00245
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 QString mySnapshotFileName = "";
00257
00258
00259
00260
00261
00262 QString myInitialExtent = "";
00263 if ( argc == 1 )
00264 myInitialExtent = "-1,-1,1,1";
00265
00266
00267
00268 QString myTranslationCode;
00269
00270 #ifndef WIN32
00271 if ( !bundleclicked( argc, argv ) )
00272 {
00273
00275
00276
00278 int optionChar;
00279 while ( 1 )
00280 {
00281 static struct option long_options[] =
00282 {
00283
00284 {"help", no_argument, 0, 'h'},
00285
00286
00287 {"snapshot", required_argument, 0, 's'},
00288 {"lang", required_argument, 0, 'l'},
00289 {"project", required_argument, 0, 'p'},
00290 {"extent", required_argument, 0, 'e'},
00291 {0, 0, 0, 0}
00292 };
00293
00294
00295 int option_index = 0;
00296
00297 optionChar = getopt_long( argc, argv, "slpe",
00298 long_options, &option_index );
00299
00300
00301 if ( optionChar == -1 )
00302 break;
00303
00304 switch ( optionChar )
00305 {
00306 case 0:
00307
00308 if ( long_options[option_index].flag != 0 )
00309 break;
00310 printf( "option %s", long_options[option_index].name );
00311 if ( optarg )
00312 printf( " with arg %s", optarg );
00313 printf( "\n" );
00314 break;
00315
00316 case 's':
00317 mySnapshotFileName = QDir::convertSeparators( QFileInfo( QFile::decodeName( optarg ) ).absoluteFilePath() );
00318 break;
00319
00320 case 'l':
00321 myTranslationCode = optarg;
00322 break;
00323
00324 case 'p':
00325 myProjectFileName = QDir::convertSeparators( QFileInfo( QFile::decodeName( optarg ) ).absoluteFilePath() );
00326 break;
00327
00328 case 'e':
00329 myInitialExtent = optarg;
00330 break;
00331
00332 case 'h':
00333 case '?':
00334 usage( argv[0] );
00335 return 2;
00336 break;
00337
00338 default:
00339 QgsDebugMsg( QString( "%1: getopt returned character code %2" ).arg( argv[0] ).arg( optionChar ) );
00340 return 1;
00341 }
00342 }
00343
00344
00345
00346 QgsDebugMsg( QString( "Files specified on command line: %1" ).arg( optind ) );
00347 if ( optind < argc )
00348 {
00349 while ( optind < argc )
00350 {
00351 #ifdef QGISDEBUG
00352 int idx = optind;
00353 QgsDebugMsg( QString( "%1: %2" ).arg( idx ).arg( argv[idx] ) );
00354 #endif
00355 myFileList.append( QDir::convertSeparators( QFileInfo( QFile::decodeName( argv[optind++] ) ).absoluteFilePath() ) );
00356 }
00357 }
00358 }
00359 #endif //WIN32
00360
00362
00364
00366
00368
00369 #ifdef Q_WS_X11
00370 bool myUseGuiFlag = getenv( "DISPLAY" ) != 0;
00371 #else
00372 bool myUseGuiFlag = TRUE;
00373 #endif
00374 if ( !myUseGuiFlag )
00375 {
00376 QgsDebugMsg( "QGIS starting in non-interactive mode not supported.\n You "
00377 "are seeing this message most likely because you have no DISPLAY "
00378 "environment variable set." );
00379 exit( 1 );
00380 }
00381 QgsApplication myApp( argc, argv, myUseGuiFlag );
00382
00383
00384 QCoreApplication::setOrganizationName( "QuantumGIS" );
00385 QCoreApplication::setOrganizationDomain( "qgis.org" );
00386 QCoreApplication::setApplicationName( "QGIS" );
00387 #ifdef Q_OS_MACX
00388
00389
00390
00391
00392
00393 AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, openDocumentsAEHandler, 0, false );
00394
00395
00396
00397 QString gdalPlugins( QCoreApplication::applicationDirPath().append( "/lib/gdalplugins" ) );
00398 if ( QFile::exists( gdalPlugins ) && !getenv( "GDAL_DRIVER_PATH" ) )
00399 {
00400 setenv( "GDAL_DRIVER_PATH", gdalPlugins.toUtf8(), 1 );
00401 }
00402 #endif
00403
00404 #ifdef Q_WS_WIN
00405
00406 QApplication::setStyle( new QPlastiqueStyle );
00407 #endif
00408
00409
00410
00411
00412
00413 QString appDir = qApp->applicationDirPath();
00414
00415 if ( appDir.endsWith( "/src/app" ) )
00416 {
00417 QMessageBox::critical( 0, "QGIS Not Installed",
00418 "You appear to be running QGIS from the source directory.\n"
00419 "You must install QGIS using make install and run it from the "
00420 "installed directory." );
00421 exit( 1 );
00422 }
00423
00424
00425
00426
00427 QString i18nPath = QgsApplication::i18nPath();
00428
00429
00430
00431
00432 QSettings mySettings;
00433 QString myUserLocale = mySettings.value( "locale/userLocale", "" ).toString();
00434 bool myLocaleOverrideFlag = mySettings.value( "locale/overrideFlag", false ).toBool();
00435 QString myLocale;
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 if ( !myTranslationCode.isNull() && !myTranslationCode.isEmpty() )
00446 {
00447 mySettings.setValue( "locale/userLocale", myTranslationCode );
00448 }
00449 else
00450 {
00451 if ( !myLocaleOverrideFlag || myUserLocale.isEmpty() )
00452 {
00453 myTranslationCode = QLocale::system().name();
00454
00455
00456 mySettings.setValue( "locale/userLocale", myTranslationCode );
00457 }
00458 else
00459 {
00460 myTranslationCode = myUserLocale;
00461 }
00462 }
00463
00464 #ifdef QGISDEBUG
00465
00466 #endif
00467 QTranslator qgistor( 0 );
00468 if ( qgistor.load( QString( "qgis_" ) + myTranslationCode, i18nPath ) )
00469 {
00470 myApp.installTranslator( &qgistor );
00471 }
00472
00473
00474
00475
00476
00477 QTranslator qttor( 0 );
00478 if ( qttor.load( QString( "qt_" ) + myTranslationCode, i18nPath ) )
00479 {
00480 myApp.installTranslator( &qttor );
00481 }
00482
00483
00484 QString mySplashPath( QgsApplication::splashPath() );
00485 QPixmap myPixmap( mySplashPath + QString( "splash.png" ) );
00486 QSplashScreen *mypSplash = new QSplashScreen( myPixmap );
00487 if ( mySettings.value( "/qgis/hideSplash" ).toBool() )
00488 {
00489
00490 }
00491 else
00492 {
00493 #if defined(Q_OS_MACX) && QT_VERSION < 0x040300
00494
00495
00496 QPixmap myMaskPixmap( mySplashPath + QString( "splash_mask.png" ), 0, Qt::ThresholdDither | Qt::ThresholdAlphaDither | Qt::AvoidDither );
00497 mypSplash->setMask( myMaskPixmap.createHeuristicMask() );
00498 #else
00499
00500 mypSplash->setMask( myPixmap.mask() );
00501 #endif
00502 mypSplash->show();
00503 }
00504
00505
00506
00507
00508
00509 #ifdef Q_WS_WIN
00510 QCoreApplication::addLibraryPath( QApplication::applicationDirPath()
00511 + QDir::separator() + "plugins" );
00512 #endif
00513 #ifdef Q_OS_MACX
00514
00515 CFURLRef myBundleRef = CFBundleCopyBundleURL( CFBundleGetMainBundle() );
00516 CFStringRef myMacPath = CFURLCopyFileSystemPath( myBundleRef, kCFURLPOSIXPathStyle );
00517 const char *mypPathPtr = CFStringGetCStringPtr( myMacPath, CFStringGetSystemEncoding() );
00518 CFRelease( myBundleRef );
00519 CFRelease( myMacPath );
00520 QString myPath( mypPathPtr );
00521
00522
00523
00524
00525 QFileInfo myInfo( myPath );
00526 if ( myInfo.isBundle() )
00527 {
00528
00529
00530 QStringList myPathList;
00531 QCoreApplication::setLibraryPaths( myPathList );
00532
00533 myPath += "/Contents/plugins";
00534 QCoreApplication::addLibraryPath( myPath );
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 }
00548 #endif
00549
00550
00551
00552 QgisApp *qgis = new QgisApp( mypSplash );
00553 qgis->setObjectName( "QgisApp" );
00554
00555
00557
00558
00559
00560
00562 if ( myProjectFileName.isEmpty() )
00563 {
00564
00565 for ( int i = 0; i < argc; i++ )
00566 {
00567 QString arg = QDir::convertSeparators( QFileInfo( QFile::decodeName( argv[i] ) ).absoluteFilePath() );
00568 if ( arg.contains( ".qgs" ) )
00569 {
00570 myProjectFileName = arg;
00571 break;
00572 }
00573 }
00574 }
00575
00577
00579 if ( ! myProjectFileName.isEmpty() )
00580 {
00581 qgis->openProject( myProjectFileName );
00582 }
00583
00584
00586
00588 QgsDebugMsg( QString( "Number of files in myFileList: %1" ).arg( myFileList.count() ) );
00589 for ( QStringList::Iterator myIterator = myFileList.begin(); myIterator != myFileList.end(); ++myIterator )
00590 {
00591
00592
00593 QgsDebugMsg( QString( "Trying to load file : %1" ).arg(( *myIterator ) ) );
00594 QString myLayerName = *myIterator;
00595
00596 if ( !myLayerName.contains( ".qgs" ) )
00597 {
00598 qgis->openLayer( myLayerName );
00599 }
00600 }
00601
00602
00604
00606 if ( ! myInitialExtent.isEmpty() )
00607 {
00608 double coords[4];
00609 int pos, posOld = 0;
00610 bool ok = true;
00611
00612
00613
00614
00615
00616 for ( int i = 0; i < 3; i++ )
00617 {
00618
00619 pos = myInitialExtent.indexOf( ',', posOld );
00620 if ( pos == -1 )
00621 {
00622 ok = false;
00623 break;
00624 }
00625
00626 coords[i] = QString( myInitialExtent.mid( posOld, pos - posOld ) ).toDouble( &ok );
00627 if ( !ok )
00628 break;
00629
00630 posOld = pos + 1;
00631 }
00632
00633
00634 if ( ok )
00635 coords[3] = QString( myInitialExtent.mid( posOld ) ).toDouble( &ok );
00636
00637 if ( !ok )
00638 {
00639 QgsDebugMsg( "Error while parsing initial extent!" );
00640 }
00641 else
00642 {
00643
00644 QgsRect rect( coords[0], coords[1], coords[2], coords[3] );
00645 qgis->setExtent( rect );
00646 }
00647 }
00648
00650
00652 if ( mySnapshotFileName != "" )
00653 {
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 myApp.processEvents();
00666 QPixmap * myQPixmap = new QPixmap( 800, 600 );
00667 myQPixmap->fill();
00668 qgis->saveMapAsImage( mySnapshotFileName, myQPixmap );
00669 myApp.processEvents();
00670 qgis->hide();
00671 return 1;
00672 }
00673
00674
00676
00678 qgis->show();
00679 myApp.connect( &myApp, SIGNAL( lastWindowClosed() ), &myApp, SLOT( quit() ) );
00680
00681 mypSplash->finish( qgis );
00682 delete mypSplash;
00683 return myApp.exec();
00684
00685 }