Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qgsapplication.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsapplication.cpp - Accessors for application-wide data
3  --------------------------------------
4  Date : 02-Jan-2006
5  Copyright : (C) 2006 by Tom Elwertowski
6  Email : telwertowski at users dot sourceforge dot net
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 /* $Id$ */
16 
17 #include "qgsapplication.h"
18 #include "qgsmaplayerregistry.h"
19 #include "qgsproviderregistry.h"
20 #include "qgsexception.h"
21 
22 #include <QDir>
23 #include <QFileOpenEvent>
24 #include <QMessageBox>
25 #include <QPalette>
26 #include <QSettings>
27 
28 #ifndef Q_WS_WIN
29 #include <netinet/in.h>
30 #else
31 #include <winsock.h>
32 #endif
33 
34 #include "qgsconfig.h"
35 
36 #include <ogr_api.h>
37 
38 QObject * ABISYM( QgsApplication::mFileOpenEventReceiver );
39 QStringList ABISYM( QgsApplication::mFileOpenEventList );
40 QString ABISYM( QgsApplication::mPrefixPath );
41 QString ABISYM( QgsApplication::mPluginPath );
42 QString ABISYM( QgsApplication::mPkgDataPath );
43 QString ABISYM( QgsApplication::mThemeName );
44 QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
45 QString ABISYM( QgsApplication::mConfigPath ) = QDir::homePath() + QString( "/.qgis/" );
46 
60 QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath )
61  : QApplication( argc, argv, GUIenabled )
62 {
63 #if defined(Q_WS_MACX) || defined(Q_WS_WIN32) || defined(WIN32)
64  setPrefixPath( applicationDirPath(), true );
65 #else
66  QDir myDir( applicationDirPath() );
67  myDir.cdUp();
68  QString myPrefix = myDir.absolutePath();
69  setPrefixPath( myPrefix, true );
70 #endif
71 
72  if ( !customConfigPath.isEmpty() )
73  {
74  ABISYM( mConfigPath ) = customConfigPath + "/"; // make sure trailing slash is included
75  }
76 
77  ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
78 }
79 
81 {
82 }
83 
84 bool QgsApplication::event( QEvent * event )
85 {
86  bool done = false;
87  if ( event->type() == QEvent::FileOpen )
88  {
89  // handle FileOpen event (double clicking a file icon in Mac OS X Finder)
90  if ( ABISYM( mFileOpenEventReceiver ) )
91  {
92  // Forward event to main window.
93  done = notify( ABISYM( mFileOpenEventReceiver ), event );
94  }
95  else
96  {
97  // Store filename because receiver has not registered yet.
98  // If QGIS has been launched by double clicking a file icon, FileOpen will be
99  // the first event; the main window is not yet ready to handle the event.
100  ABISYM( mFileOpenEventList ).append( static_cast<QFileOpenEvent *>( event )->file() );
101  done = true;
102  }
103  }
104  else
105  {
106  // pass other events to base class
107  done = QApplication::event( event );
108  }
109  return done;
110 }
111 
112 bool QgsApplication::notify( QObject * receiver, QEvent * event )
113 {
114  // Send event to receiver and catch unhandled exceptions
115  bool done = true;
116  try
117  {
118  done = QApplication::notify( receiver, event );
119  }
120  catch ( QgsException & e )
121  {
122  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
123  }
124  catch ( std::exception & e )
125  {
126  QMessageBox::critical( activeWindow(), tr( "Exception" ), e.what() );
127  }
128  catch ( ... )
129  {
130  QMessageBox::critical( activeWindow(), tr( "Exception" ), tr( "unknown exception" ) );
131  }
132  return done;
133 }
134 
136 {
137  // Set receiver for FileOpen events
138  ABISYM( mFileOpenEventReceiver ) = receiver;
139  // Propagate any events collected before the receiver has registered.
140  if ( ABISYM( mFileOpenEventList ).count() > 0 )
141  {
142  QStringListIterator i( ABISYM( mFileOpenEventList ) );
143  while ( i.hasNext() )
144  {
145  QFileOpenEvent foe( i.next() );
146  QgsApplication::sendEvent( ABISYM( mFileOpenEventReceiver ), &foe );
147  }
148  ABISYM( mFileOpenEventList ).clear();
149  }
150 }
151 
152 void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefaultPaths )
153 {
154  ABISYM( mPrefixPath ) = thePrefixPath;
155 #if defined(_MSC_VER)
156  if ( ABISYM( mPrefixPath ).endsWith( "/bin" ) )
157  {
158  ABISYM( mPrefixPath ).chop( 4 );
159  }
160 #endif
161  if ( useDefaultPaths )
162  {
163  setPluginPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_PLUGIN_SUBDIR ) );
164  setPkgDataPath( ABISYM( mPrefixPath ) + "/" + QString( QGIS_DATA_SUBDIR ) );
165  }
166 }
167 
168 void QgsApplication::setPluginPath( const QString thePluginPath )
169 {
170  ABISYM( mPluginPath ) = thePluginPath;
171 }
172 
173 void QgsApplication::setPkgDataPath( const QString thePkgDataPath )
174 {
175  ABISYM( mPkgDataPath ) = thePkgDataPath;
176  QString svgPath = ABISYM( mPkgDataPath ) + QString( "/svg/" );
177  // avoid duplicate entries
178  if ( !ABISYM( mDefaultSvgPaths ).contains( svgPath ) )
179  ABISYM( mDefaultSvgPaths ) << svgPath;
180 }
181 
182 void QgsApplication::setDefaultSvgPaths( const QStringList& pathList )
183 {
184  ABISYM( mDefaultSvgPaths ) = pathList;
185 }
186 
188 {
189  return ABISYM( mPrefixPath );
190 }
192 {
193  return ABISYM( mPluginPath );
194 }
196 {
197  return ABISYM( mPkgDataPath );
198 }
200 {
201  return ":/images/themes/default/";
202 }
204 {
205  return ":/images/themes/" + ABISYM( mThemeName ) + "/";
206 }
207 
208 
209 QString QgsApplication::iconPath( QString iconFile )
210 {
211  // try active theme
212  QString path = activeThemePath();
213  if ( QFile::exists( path + iconFile ) )
214  return path + iconFile;
215 
216  // use default theme
217  return defaultThemePath() + iconFile;
218 }
219 
223 void QgsApplication::setThemeName( const QString theThemeName )
224 {
225  QString myPath = ":/images/themes/" + theThemeName + "/";
226  //check it exists and if not roll back to default theme
227  if ( QFile::exists( myPath ) )
228  {
229  ABISYM( mThemeName ) = theThemeName;
230  }
231  else
232  {
233  ABISYM( mThemeName ) = "default";
234  }
235 }
240 {
241  return ABISYM( mThemeName );
242 }
247 {
248  return ABISYM( mPkgDataPath ) + QString( "/doc/AUTHORS" );
249 }
254 {
255  return ABISYM( mPkgDataPath ) + QString( "/doc/CONTRIBUTORS" );
256 }
261 {
262  return ABISYM( mPkgDataPath ) + QString( "/doc/SPONSORS" );
263 }
264 
269 {
270  return ABISYM( mPkgDataPath ) + QString( "/doc/DONORS" );
271 }
272 
278 {
279  return ABISYM( mPkgDataPath ) + QString( "/doc/TRANSLATORS" );
280 }
285 {
286  return ABISYM( mPkgDataPath ) + QString( "/images/developers/" );
287 }
288 
293 {
294  QString helpAppPath;
295 #ifdef Q_OS_MACX
296  helpAppPath = applicationDirPath() + "/bin/qgis_help.app/Contents/MacOS";
297 #else
298  helpAppPath = prefixPath() + "/" QGIS_LIBEXEC_SUBDIR;
299 #endif
300  helpAppPath += "/qgis_help";
301  return helpAppPath;
302 }
307 {
308  return ABISYM( mPkgDataPath ) + QString( "/i18n/" );
309 }
310 
315 {
316  return ABISYM( mPkgDataPath ) + QString( "/resources/qgis.db" );
317 }
318 
323 {
324  return ABISYM( mConfigPath );
325 }
326 
331 {
332  return qgisSettingsDirPath() + QString( "qgis.db" );
333 }
334 
339 {
340  return ABISYM( mPkgDataPath ) + QString( "/images/splash/" );
341 }
342 
347 {
348  return ABISYM( mPkgDataPath ) + QString( "/images/icons/" );
349 }
354 {
355  return ABISYM( mPkgDataPath ) + QString( "/resources/srs.db" );
356 }
357 
361 const QStringList QgsApplication::svgPaths()
362 {
363  //local directories to search when looking for an SVG with a given basename
364  //defined by user in options dialog
365  QSettings settings;
366  QStringList myPathList;
367  QString myPaths = settings.value( "svg/searchPathsForSVG", "" ).toString();
368  if ( !myPaths.isEmpty() )
369  {
370  myPathList = myPaths.split( "|" );
371  }
372 
373  myPathList << ABISYM( mDefaultSvgPaths );
374  return myPathList;
375 }
376 
380 const QString QgsApplication::svgPath()
381 {
382  return ABISYM( mPkgDataPath ) + QString( "/svg/" );
383 }
384 
386 {
387  return qgisSettingsDirPath() + QString( "symbology-ng-style.xml" );
388 }
389 
391 {
392  return ABISYM( mPkgDataPath ) + QString( "/resources/symbology-ng-style.xml" );
393 }
394 
396 {
397  return ( htonl( 1 ) == 1 ) ? XDR : NDR ;
398 }
399 
401 {
402  // set the provider plugin path (this creates provider registry)
404 
405  // create map layer registry if doesn't exist
407 }
408 
410 {
413 }
414 
416 {
417  QString myState = QString( "Application state:\n"
418  "Prefix : %1\n"
419  "Plugin Path : %2\n"
420  "Package Data Path : %3\n"
421  "Active Theme Name : %4\n"
422  "Active Theme Path : %5\n"
423  "Default Theme Path : %6\n"
424  "SVG Search Paths : %7\n"
425  "User DB Path : %8\n" )
426  .arg( ABISYM( mPrefixPath ) )
427  .arg( ABISYM( mPluginPath ) )
428  .arg( ABISYM( mPkgDataPath ) )
429  .arg( themeName() )
430  .arg( activeThemePath() )
431  .arg( defaultThemePath() )
432  .arg( svgPaths().join( "\n" ) )
433  .arg( qgisMasterDbFilePath() );
434  return myState;
435 }
436 
438 {
439  //
440  // Make the style sheet desktop preferences aware by using qappliation
441  // palette as a basis for colors where appropriate
442  //
443  QColor myColor1 = palette().highlight().color();
444  QColor myColor2 = myColor1;
445  myColor2 = myColor2.lighter( 110 ); //10% lighter
446  QString myStyle;
447  myStyle = ".glossy{ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
448  "stop: 0 " + myColor1.name() + ","
449  "stop: 0.1 " + myColor2.name() + ","
450  "stop: 0.5 " + myColor1.name() + ","
451  "stop: 0.9 " + myColor2.name() + ","
452  "stop: 1 " + myColor1.name() + ");"
453  "color: white;"
454  "padding-left: 4px;"
455  "padding-top: 20px;"
456  "padding-bottom: 8px;"
457  "border: 1px solid #6c6c6c;"
458  "}"
459  ".overview{ font: 1.82em; font-weight: bold;}"
460  "body{ background: white;"
461  " color: black;"
462  " font-family: arial,sans-serif;"
463  "}"
464  "h2{ background-color: #F6F6F6;"
465  " color: #8FB171; "
466  " font-size: medium; "
467  " font-weight: normal;"
468  " font-family: luxi serif, georgia, times new roman, times, serif;"
469  " background: none;"
470  " padding: 0.75em 0 0;"
471  " margin: 0;"
472  " line-height: 1.1em;"
473  "}"
474  "h3{ background-color: #F6F6F6;"
475  " color: #729FCF;"
476  " font-family: luxi serif, georgia, times new roman, times, serif;"
477  " font-weight: bold;"
478  " font-size: large;"
479  " text-align: right;"
480  " border-bottom: 5px solid #DCEB5C;"
481  "}"
482  "h4{ background-color: #F6F6F6;"
483  " color: #729FCF;"
484  " font-family: luxi serif, georgia, times new roman, times, serif;"
485  " font-weight: bold;"
486  " font-size: medium;"
487  " text-align: right;"
488  "}"
489  "h5{ background-color: #F6F6F6;"
490  " color: #729FCF;"
491  " font-family: luxi serif, georgia, times new roman, times, serif;"
492  " font-weight: bold;"
493  " font-size: small;"
494  " text-align: right;"
495  "}"
496  "a{ color: #729FCF;"
497  " font-family: arial,sans-serif;"
498  " font-size: small;"
499  "}"
500  "label{ background-color: #FFFFCC;"
501  " border: 1px solid black;"
502  " margin: 1px;"
503  " padding: 0px 3px; "
504  " font-size: small;"
505  "}";
506  return myStyle;
507 }
508 
510 {
511  if ( 0 >= OGRGetDriverCount() )
512  {
513  OGRRegisterAll();
514  }
515 }
516 
517 QString QgsApplication::absolutePathToRelativePath( QString aPath, QString targetPath )
518 {
519 #if defined( Q_OS_WIN )
520  const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
521 
522  aPath.replace( "\\", "/" );
523  if ( aPath.startsWith( "//" ) )
524  {
525  // keep UNC prefix
526  aPath = "\\\\" + aPath.mid( 2 );
527  }
528 
529  targetPath.replace( "\\", "/" );
530  if ( targetPath.startsWith( "//" ) )
531  {
532  // keep UNC prefix
533  targetPath = "\\\\" + targetPath.mid( 2 );
534  }
535 #else
536  const Qt::CaseSensitivity cs = Qt::CaseSensitive;
537 #endif
538 
539  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
540  QStringList aPathElems = aPath.split( "/", QString::SkipEmptyParts );
541 
542  targetElems.removeAll( "." );
543  aPathElems.removeAll( "." );
544 
545  // remove common part
546  int n = 0;
547  while ( aPathElems.size() > 0 &&
548  targetElems.size() > 0 &&
549  aPathElems[0].compare( targetElems[0], cs ) == 0 )
550  {
551  aPathElems.removeFirst();
552  targetElems.removeFirst();
553  n++;
554  }
555 
556  if ( n == 0 )
557  {
558  // no common parts; might not even be a file
559  return aPath;
560  }
561 
562  if ( targetElems.size() > 0 )
563  {
564  // go up to the common directory
565  for ( int i = 0; i < targetElems.size(); i++ )
566  {
567  aPathElems.insert( 0, ".." );
568  }
569  }
570  else
571  {
572  // let it start with . nevertheless,
573  // so relative path always start with either ./ or ../
574  aPathElems.insert( 0, "." );
575  }
576 
577  return aPathElems.join( "/" );
578 }
579 
580 QString QgsApplication::relativePathToAbsolutePath( QString rpath, QString targetPath )
581 {
582  // relative path should always start with ./ or ../
583  if ( !rpath.startsWith( "./" ) && !rpath.startsWith( "../" ) )
584  {
585  return rpath;
586  }
587 
588 #if defined(Q_OS_WIN)
589  rpath.replace( "\\", "/" );
590  targetPath.replace( "\\", "/" );
591 
592  bool uncPath = targetPath.startsWith( "//" );
593 #endif
594 
595  QStringList srcElems = rpath.split( "/", QString::SkipEmptyParts );
596  QStringList targetElems = targetPath.split( "/", QString::SkipEmptyParts );
597 
598 #if defined(Q_OS_WIN)
599  if ( uncPath )
600  {
601  targetElems.insert( 0, "" );
602  targetElems.insert( 0, "" );
603  }
604 #endif
605 
606  // append source path elements
607  targetElems << srcElems;
608  targetElems.removeAll( "." );
609 
610  // resolve ..
611  int pos;
612  while (( pos = targetElems.indexOf( ".." ) ) > 0 )
613  {
614  // remove preceding element and ..
615  targetElems.removeAt( pos - 1 );
616  targetElems.removeAt( pos - 1 );
617  }
618 
619 #if !defined(Q_OS_WIN)
620  // make path absolute
621  targetElems.prepend( "" );
622 #endif
623 
624  return targetElems.join( "/" );
625 }