1
/***************************************************************************
2
qgisapp.cpp - description
5
begin : Sat Jun 22 2002
6
copyright : (C) 2002 by Gary E.Sherman
7
email : sherman at mrcc.com
8
Romans 3:23=>Romans 6:23=>Romans 10:9,10=>Romans 12
9
***************************************************************************/
11
/***************************************************************************
13
* This program is free software; you can redistribute it and/or modify *
14
* it under the terms of the GNU General Public License as published by *
15
* the Free Software Foundation; either version 2 of the License, or *
16
* (at your option) any later version. *
18
***************************************************************************/
19
/* $Id: qgisapp.cpp 7019 2007-06-11 03:55:32Z timlinux $ */
22
// QT4 includes make sure to use the new <CamelCase> style!
24
#include <Q3ListViewItem>
26
#include <QApplication>
32
#include <QDesktopWidget>
38
#include <QInputDialog>
45
#include <QMessageBox>
52
#include <QProgressBar>
54
#include <QSplashScreen>
56
#include <QStringList>
58
#include <QTextStream>
59
#include <QToolButton>
61
#include <QVBoxLayout>
67
// Must include before GEOS 3 due to unqualified use of 'Point'
70
#include <ApplicationServices/ApplicationServices.h>
74
// QGIS Specific Includes
76
#include "../../images/themes/default/qgis.xpm"
79
#include "qgisplugin.h"
81
#include "qgsapplication.h"
82
#include "qgsbookmarkitem.h"
83
#include "qgsbookmarks.h"
84
#include "qgscomposer.h"
85
#include <qgscursors.h>
86
#include "qgscustomprojectiondialog.h"
87
#include "qgsencodingfiledialog.h"
88
#include "qgsgeomtypedialog.h"
89
#include "qgshelpviewer.h"
90
#include "qgslegend.h"
91
#include "qgslegendlayerfile.h"
92
#include "qgslegendlayer.h"
93
#include "qgslogger.h"
94
#include "qgsmapcanvas.h"
95
#include "qgsmaplayer.h"
96
#include "qgsmaplayerinterface.h"
97
#include "qgsmaplayerregistry.h"
98
#include "qgsmapoverviewcanvas.h"
99
#include "qgsmaprender.h"
100
#include "qgsmessageviewer.h"
101
#include "qgsoptions.h"
102
#include "qgspastetransformations.h"
103
#include "qgspluginitem.h"
104
#include "qgspluginmanager.h"
105
#include "qgspluginregistry.h"
106
#include "qgsproject.h"
107
#include "qgsprojectproperties.h"
108
#include "qgsproviderregistry.h"
109
#include "qgsrasterlayer.h"
110
#include "qgsrasterlayerproperties.h"
112
#include "qgsserversourceselect.h"
113
#include "qgssinglesymbolrenderer.h"
114
#include "qgsvectordataprovider.h"
115
#include "qgsvectorfilewriter.h"
116
#include "qgsvectorlayer.h"
121
#include <ogrsf_frmts.h>
128
#include <functional>
138
#include "qgsmaptoolcapture.h"
139
#include "qgsmaptoolidentify.h"
140
#include "qgsmaptoolpan.h"
141
#include "qgsmaptoolselect.h"
142
#include "qgsmaptoolvertexedit.h"
143
#include "qgsmaptoolzoom.h"
144
#include "qgsmeasure.h"
147
// Conditional Includes
149
#ifdef HAVE_POSTGRESQL
150
#include "qgsdbsourceselect.h"
158
class QTreeWidgetItem;
160
/* typedefs for plugins */
161
typedef QgsMapLayerInterface *create_it();
162
typedef QgisPlugin *create_ui(QgisApp * qgis, QgisIface * qI);
163
typedef QString name_t();
164
typedef QString description_t();
165
typedef int type_t();
167
// IDs for locating particular menu items
168
const int BEFORE_RECENT_PATHS = 123;
169
const int AFTER_RECENT_PATHS = 321;
172
/// build the vector file filter string for a QFileDialog
174
called in ctor for initializing mVectorFileFilter
176
static void buildSupportedVectorFileFilter_(QString & fileFilters);
179
/** set the application title bar text
181
If the current project title is null
182
if the project file is null then
183
set title text to just application name and version
185
set set title text to the the project file name
187
set the title text to project title
189
static void setTitleBarText_( QWidget & qgisApp )
191
QString caption = QgisApp::tr("Quantum GIS - ");
192
caption += QString("%1 ('%2') ").arg(QGis::qgisVersion).arg(QGis::qgisReleaseName) + " ";
194
if ( QgsProject::instance()->title().isEmpty() )
196
if ( QgsProject::instance()->filename().isEmpty() )
198
// no project title nor file name, so just leave caption with
199
// application name and version
203
QFileInfo projectFileInfo( QgsProject::instance()->filename() );
204
caption += projectFileInfo.baseName();
209
caption += QgsProject::instance()->title();
212
qgisApp.setCaption( caption );
213
} // setTitleBarText_( QWidget * qgisApp )
218
// constructor starts here
219
QgisApp::QgisApp(QSplashScreen *splash, QWidget * parent, Qt::WFlags fl)
220
: QMainWindow(parent,fl),
225
mSplash->showMessage(tr("Checking database"), Qt::AlignHCenter | Qt::AlignBottom);
226
qApp->processEvents();
227
// Do this early on before anyone else opens it and prevents us copying it
230
mSplash->showMessage(tr("Reading settings"), Qt::AlignHCenter | Qt::AlignBottom);
231
qApp->processEvents();
233
mSplash->showMessage(tr("Setting up the GUI"), Qt::AlignHCenter | Qt::AlignBottom);
234
qApp->processEvents();
236
createActionGroups();
240
setTheme(mThemeName);
241
updateRecentProjectPaths();
246
fileNew(); // prepare empty project
247
qApp->processEvents();
249
// register all GDAL and OGR plug-ins
250
// Should this be here? isnt it the job of the provider? Tim
254
icon = QPixmap(qgis_xpm);
256
// store startup location
257
QDir *d = new QDir();
258
mStartupPath = d->absPath();
261
// zoomincur = QBitmap(cursorzoomin);
262
QBitmap zoomincurmask;
263
// zoomincurmask = QBitmap(cursorzoomin_mask);
264
QString caption = tr("Quantum GIS - ");
265
caption += QString("%1 ('%2')").arg(QGis::qgisVersion).arg(QGis::qgisReleaseName);
267
// create the interfce
268
mQgisInterface = new QgisIface(this);
272
// Create the plugin registry and load plugins
274
// Get pointer to the provider registry singleton
275
QString plib = QgsApplication::pluginPath();
276
// set the provider plugin path
277
mProviderRegistry = QgsProviderRegistry::instance(plib);
279
std::cout << "Plugins and providers are installed in " << plib.toLocal8Bit().data() << std::endl;
281
// load any plugins that were running in the last session
282
mSplash->showMessage(tr("Restoring loaded plugins"), Qt::AlignHCenter | Qt::AlignBottom);
283
qApp->processEvents();
284
restoreSessionPlugins(plib);
286
/* Delete this I think - Tim - FIXME
288
// Create the map layer registry. Any layers loaded will
289
// register themselves here. Deleting layers shouls ONLY
290
// be done by means of a removeMapLayer call to the regsitry.
291
// This allows a single layer instance to be shared
292
// between more than one canvas. The registry is a singleton
293
// and is constructed using the static instance call.
295
// syntactic sugar shortcut for instance handle
296
//QgsMapLayerRegistry * mapLayerRegistry = QgsMapLayerRegistry::instance();
300
mComposer = new QgsComposer(this);
302
mSplash->showMessage(tr("Initializing file filters"), Qt::AlignHCenter | Qt::AlignBottom);
303
qApp->processEvents();
304
// now build vector file filter
305
buildSupportedVectorFileFilter_( mVectorFileFilter );
307
// now build raster file filter
308
QgsRasterLayer::buildSupportedRasterFileFilter( mRasterFileFilter );
310
// Set the background colour for toolbox and overview as they default to
311
// white instead of the window color
312
QPalette myPalette = toolBox->palette();
313
myPalette.setColor(QPalette::Button, myPalette.window().color());
314
toolBox->setPalette(myPalette);
315
//do the same for legend control
316
myPalette = toolBox->palette();
317
myPalette.setColor(QPalette::Button, myPalette.window().color());
318
mMapLegend->setPalette(myPalette);
319
//and for overview control this is done in createOverView method
321
// Do this last in the ctor to ensure that all members are instantiated properly
324
// Please make sure this is the last thing the ctor does so that we can ensure teh
325
// widgets are all initialised before trying to restore their state.
327
mSplash->showMessage(tr("Restoring window state"), Qt::AlignHCenter | Qt::AlignBottom);
328
qApp->processEvents();
329
restoreWindowState();
331
mSplash->showMessage(tr("QGIS Ready!"), Qt::AlignHCenter | Qt::AlignBottom);
332
qApp->processEvents();
339
delete mMapTools.mZoomIn;
340
delete mMapTools.mZoomOut;
341
delete mMapTools.mPan;
342
delete mMapTools.mIdentify;
343
delete mMapTools.mMeasureDist;
344
delete mMapTools.mMeasureArea;
345
delete mMapTools.mCapturePoint;
346
delete mMapTools.mCaptureLine;
347
delete mMapTools.mCapturePolygon;
348
delete mMapTools.mSelect;
349
delete mMapTools.mVertexAdd;
350
delete mMapTools.mVertexMove;
351
delete mMapTools.mVertexDelete;
354
// restore any application settings stored in QSettings
355
void QgisApp::readSettings()
357
// get the application dir
358
mAppDir = QgsApplication::prefixPath();
361
// get the users theme preference from the settings
362
mThemeName = settings.readEntry("/Themes","default");
365
// Set the initial visibility flag for layers
366
// This user option allows the user to turn off inital drawing of
367
// layers when they are added to the map. This is useful when adding
368
// many layers and the user wants to adjusty symbology, etc prior to
369
// actually viewing the layer.
370
mAddedLayersVisible = settings.readBoolEntry("/qgis/new_layers_visible", 1);
372
// Add the recently accessed project file paths to the File menu
373
mRecentProjectPaths = settings.readListEntry("/UI/recentProjectsList");
375
// Set the behaviour when the map splitters are resized
376
bool splitterRedraw = settings.value("/qgis/splitterRedraw", true).toBool();
377
canvasLegendSplit->setOpaqueResize(splitterRedraw);
378
legendOverviewSplit->setOpaqueResize(splitterRedraw);
382
//////////////////////////////////////////////////////////////////////
383
// Set Up the gui toolbars, menus, statusbar etc
384
//////////////////////////////////////////////////////////////////////
386
void QgisApp::createActions()
388
QString myIconPath = QgsApplication::themePath();
390
// File Menu Related Items
392
mActionFileNew= new QAction(QIcon(myIconPath+"/mActionFileNew.png"), tr("&New Project"), this);
393
mActionFileNew->setShortcut(tr("Ctrl+N","New Project"));
394
mActionFileNew->setStatusTip(tr("New Project"));
395
connect(mActionFileNew, SIGNAL(triggered()), this, SLOT(fileNew()));
397
mActionFileOpen= new QAction(QIcon(myIconPath+"/mActionFileOpen.png"), tr("&Open Project..."), this);
398
mActionFileOpen->setShortcut(tr("Ctrl+O","Open a Project"));
399
mActionFileOpen->setStatusTip(tr("Open a Project"));
400
connect(mActionFileOpen, SIGNAL(triggered()), this, SLOT(fileOpen()));
402
mActionFileSave= new QAction(QIcon(myIconPath+"/mActionFileSave.png"), tr("&Save Project"), this);
403
mActionFileSave->setShortcut(tr("Ctrl+S","Save Project"));
404
mActionFileSave->setStatusTip(tr("Save Project"));
405
connect(mActionFileSave, SIGNAL(triggered()), this, SLOT(fileSave()));
407
mActionFileSaveAs= new QAction(QIcon(myIconPath+"/mActionFileSaveAs.png"), tr("Save Project &As..."), this);
408
mActionFileSaveAs->setShortcut(tr("Ctrl+A","Save Project under a new name"));
409
mActionFileSaveAs->setStatusTip(tr("Save Project under a new name"));
410
connect(mActionFileSaveAs, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
412
mActionFilePrint= new QAction(QIcon(myIconPath+"/mActionFilePrint.png"), tr("&Print..."), this);
413
mActionFilePrint->setShortcut(tr("Ctrl+P","Print"));
414
mActionFilePrint->setStatusTip(tr("Print"));
415
connect(mActionFilePrint, SIGNAL(triggered()), this, SLOT(filePrint()));
417
mActionSaveMapAsImage= new QAction(QIcon(myIconPath+"/mActionSaveMapAsImage.png"), tr("Save as Image..."), this);
418
mActionSaveMapAsImage->setShortcut(tr("Ctrl+I","Save map as image"));
419
mActionSaveMapAsImage->setStatusTip(tr("Save map as image"));
420
connect(mActionSaveMapAsImage, SIGNAL(triggered()), this, SLOT(saveMapAsImage()));
422
mActionExportMapServer= new QAction(QIcon(myIconPath+"/mActionExportMapServer.png"), tr("Export to MapServer Map..."), this);
423
mActionExportMapServer->setShortcut(tr("M","Export as MapServer .map file"));
424
mActionExportMapServer->setStatusTip(tr("Export as MapServer .map file"));
425
connect(mActionExportMapServer, SIGNAL(triggered()), this, SLOT(exportMapServer()));
427
mActionFileExit= new QAction(QIcon(myIconPath+"/mActionFileExit.png"), tr("Exit"), this);
428
mActionFileExit->setShortcut(tr("Ctrl+Q","Exit QGIS"));
429
mActionFileExit->setStatusTip(tr("Exit QGIS"));
430
connect(mActionFileExit, SIGNAL(triggered()), this, SLOT(fileExit()));
432
// Layer Menu Related Items
434
mActionAddNonDbLayer= new QAction(QIcon(myIconPath+"/mActionAddNonDbLayer.png"), tr("Add a Vector Layer..."), this);
435
mActionAddNonDbLayer->setShortcut(tr("V","Add a Vector Layer"));
436
mActionAddNonDbLayer->setStatusTip(tr("Add a Vector Layer"));
437
connect(mActionAddNonDbLayer, SIGNAL(triggered()), this, SLOT(addLayer()));
439
mActionAddRasterLayer= new QAction(QIcon(myIconPath+"/mActionAddRasterLayer.png"), tr("Add a Raster Layer..."), this);
440
mActionAddRasterLayer->setShortcut(tr("R","Add a Raster Layer"));
441
mActionAddRasterLayer->setStatusTip(tr("Add a Raster Layer"));
442
connect(mActionAddRasterLayer, SIGNAL(triggered()), this, SLOT(addRasterLayer()));
444
mActionAddLayer= new QAction(QIcon(myIconPath+"/mActionAddLayer.png"), tr("Add a PostGIS Layer..."), this);
445
mActionAddLayer->setShortcut(tr("D","Add a PostGIS Layer"));
446
mActionAddLayer->setStatusTip(tr("Add a PostGIS Layer"));
447
//#ifdef HAVE_POSTGRESQL
448
// std::cout << "HAVE_POSTGRESQL is defined" << std::endl;
451
// std::cout << "HAVE_POSTGRESQL not defined" << std::endl;
454
connect(mActionAddLayer, SIGNAL(triggered()), this, SLOT(addDatabaseLayer()));
456
mActionNewVectorLayer= new QAction(QIcon(myIconPath+"/mActionNewVectorLayer.png"), tr("New Vector Layer..."), this);
457
mActionNewVectorLayer->setShortcut(tr("N","Create a New Vector Layer"));
458
mActionNewVectorLayer->setStatusTip(tr("Create a New Vector Layer"));
459
connect(mActionNewVectorLayer, SIGNAL(triggered()), this, SLOT(newVectorLayer()));
461
mActionRemoveLayer= new QAction(QIcon(myIconPath+"/mActionRemoveLayer.png"), tr("Remove Layer"), this);
462
mActionRemoveLayer->setShortcut(tr("Ctrl+D","Remove a Layer"));
463
mActionRemoveLayer->setStatusTip(tr("Remove a Layer"));
464
connect(mActionRemoveLayer, SIGNAL(triggered()), this, SLOT(removeLayer()));
466
mActionAddAllToOverview= new QAction(QIcon(myIconPath+"/mActionAddAllToOverview.png"), tr("Add All To Overview"), this);
467
mActionAddAllToOverview->setShortcut(tr("+","Show all layers in the overview map"));
468
mActionAddAllToOverview->setStatusTip(tr("Show all layers in the overview map"));
469
connect(mActionAddAllToOverview, SIGNAL(triggered()), this, SLOT(addAllToOverview()));
471
mActionRemoveAllFromOverview= new QAction(QIcon(myIconPath+"/mActionRemoveAllFromOverview.png"), tr("Remove All From Overview"), this);
472
mActionRemoveAllFromOverview->setShortcut(tr("-","Remove all layers from overview map"));
473
mActionRemoveAllFromOverview->setStatusTip(tr("Remove all layers from overview map"));
474
connect(mActionRemoveAllFromOverview, SIGNAL(triggered()), this, SLOT(removeAllFromOverview()));
476
mActionShowAllLayers= new QAction(QIcon(myIconPath+"/mActionShowAllLayers.png"), tr("Show All Layers"), this);
477
mActionShowAllLayers->setShortcut(tr("S","Show all layers"));
478
mActionShowAllLayers->setStatusTip(tr("Show all layers"));
479
connect(mActionShowAllLayers, SIGNAL(triggered()), this, SLOT(showAllLayers()));
481
mActionHideAllLayers= new QAction(QIcon(myIconPath+"/mActionHideAllLayers.png"), tr("Hide All Layers"), this);
482
mActionHideAllLayers->setShortcut(tr("H","Hide all layers"));
483
mActionHideAllLayers->setStatusTip(tr("Hide all layers"));
484
connect(mActionHideAllLayers, SIGNAL(triggered()), this, SLOT(hideAllLayers()));
486
// Settings Menu Related Items
488
mActionProjectProperties= new QAction(QIcon(myIconPath+"/mActionProjectProperties.png"), tr("Project Properties..."), this);
489
mActionProjectProperties->setShortcut(tr("P","Set project properties"));
490
mActionProjectProperties->setStatusTip(tr("Set project properties"));
491
connect(mActionProjectProperties, SIGNAL(triggered()), this, SLOT(projectProperties()));
493
mActionOptions= new QAction(QIcon(myIconPath+"/mActionOptions.png"), tr("Options..."), this);
494
// mActionOptions->setShortcut(tr("Alt+O","Change various QGIS options"));
495
mActionOptions->setStatusTip(tr("Change various QGIS options"));
496
connect(mActionOptions, SIGNAL(triggered()), this, SLOT(options()));
498
mActionCustomProjection= new QAction(QIcon(myIconPath+"/mActionCustomProjection.png"), tr("Custom Projection..."), this);
499
// mActionCustomProjection->setShortcut(tr("Alt+I","Manage custom projections"));
500
mActionCustomProjection->setStatusTip(tr("Manage custom projections"));
501
connect(mActionCustomProjection, SIGNAL(triggered()), this, SLOT(customProjection()));
503
// Help Menu Related items
505
mActionHelpContents= new QAction(QIcon(myIconPath+"/mActionHelpContents.png"), tr("Help Contents"), this);
507
mActionHelpContents->setShortcut(tr("Ctrl+?","Help Documentation (Mac)"));
509
mActionHelpContents->setShortcut(tr("F1","Help Documentation"));
511
mActionHelpContents->setStatusTip(tr("Help Documentation"));
512
connect(mActionHelpContents, SIGNAL(triggered()), this, SLOT(helpContents()));
514
mActionQgisHomePage= new QAction(QIcon(myIconPath+"/mActionQgisHomePage.png"), tr("Qgis Home Page"), this);
516
mActionQgisHomePage->setShortcut(tr("Ctrl+H","QGIS Home Page"));
518
mActionQgisHomePage->setStatusTip(tr("QGIS Home Page"));
519
connect(mActionQgisHomePage, SIGNAL(triggered()), this, SLOT(helpQgisHomePage()));
521
mActionHelpAbout= new QAction(QIcon(myIconPath+"/mActionHelpAbout.png"), tr("About"), this);
522
mActionHelpAbout->setStatusTip(tr("About QGIS"));
523
connect(mActionHelpAbout, SIGNAL(triggered()), this, SLOT(about()));
525
mActionCheckQgisVersion= new QAction(QIcon(myIconPath+"/mActionCheckQgisVersion.png"), tr("Check Qgis Version"), this);
526
mActionCheckQgisVersion->setStatusTip(tr("Check if your QGIS version is up to date (requires internet access)"));
527
connect(mActionCheckQgisVersion, SIGNAL(triggered()), this, SLOT(checkQgisVersion()));
531
mActionDraw= new QAction(QIcon(myIconPath+"/mActionDraw.png"), tr("Refresh"), this);
532
mActionDraw->setShortcut(tr("Ctrl+R","Refresh Map"));
533
mActionDraw->setStatusTip(tr("Refresh Map"));
534
connect(mActionDraw, SIGNAL(triggered()), this, SLOT(refreshMapCanvas()));
536
mActionZoomIn= new QAction(QIcon(myIconPath+"/mActionZoomIn.png"), tr("Zoom In"), this);
537
mActionZoomIn->setShortcut(tr("Ctrl++","Zoom In"));
538
mActionZoomIn->setStatusTip(tr("Zoom In"));
539
connect(mActionZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
541
mActionZoomOut= new QAction(QIcon(myIconPath+"/mActionZoomOut.png"), tr("Zoom Out"), this);
542
mActionZoomOut->setShortcut(tr("Ctrl+-","Zoom Out"));
543
mActionZoomOut->setStatusTip(tr("Zoom Out"));
544
connect(mActionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
546
mActionZoomFullExtent= new QAction(QIcon(myIconPath+"/mActionZoomFullExtent.png"), tr("Zoom Full"), this);
547
mActionZoomFullExtent->setShortcut(tr("F","Zoom to Full Extents"));
548
mActionZoomFullExtent->setStatusTip(tr("Zoom to Full Extents"));
549
connect(mActionZoomFullExtent, SIGNAL(triggered()), this, SLOT(zoomFull()));
551
mActionZoomToSelected= new QAction(QIcon(myIconPath+"/mActionZoomToSelected.png"), tr("Zoom To Selection"), this);
552
mActionZoomToSelected->setShortcut(tr("Ctrl+F","Zoom to selection"));
553
mActionZoomToSelected->setStatusTip(tr("Zoom to selection"));
554
connect(mActionZoomToSelected, SIGNAL(triggered()), this, SLOT(zoomToSelected()));
556
mActionPan= new QAction(QIcon(myIconPath+"/mActionPan.png"), tr("Pan Map"), this);
557
mActionPan->setStatusTip(tr("Pan the map"));
558
connect(mActionPan, SIGNAL(triggered()), this, SLOT(pan()));
560
mActionZoomLast= new QAction(QIcon(myIconPath+"/mActionZoomLast.png"), tr("Zoom Last"), this);
561
//mActionZoomLast->setShortcut(tr("Ctrl+O","Zoom to Last Extent"));
562
mActionZoomLast->setStatusTip(tr("Zoom to Last Extent"));
563
connect(mActionZoomLast, SIGNAL(triggered()), this, SLOT(zoomPrevious()));
565
mActionZoomToLayer= new QAction(QIcon(myIconPath+"/mActionZoomToLayer.png"), tr("Zoom To Layer"), this);
566
//mActionZoomToLayer->setShortcut(tr("Ctrl+O","Zoom to Layer"));
567
mActionZoomToLayer->setStatusTip(tr("Zoom to Layer"));
568
connect(mActionZoomToLayer, SIGNAL(triggered()), this, SLOT(zoomToLayerExtent()));
570
mActionIdentify= new QAction(QIcon(myIconPath+"/mActionIdentify.png"), tr("Identify Features"), this);
571
mActionIdentify->setShortcut(tr("I","Click on features to identify them"));
572
mActionIdentify->setStatusTip(tr("Click on features to identify them"));
573
connect(mActionIdentify, SIGNAL(triggered()), this, SLOT(identify()));
575
mActionSelect= new QAction(QIcon(myIconPath+"/mActionSelect.png"), tr("Select Features"), this);
576
mActionSelect->setStatusTip(tr("Select Features"));
577
connect(mActionSelect, SIGNAL(triggered()), this, SLOT(select()));
578
mActionSelect->setEnabled(false);
580
mActionOpenTable= new QAction(QIcon(myIconPath+"/mActionOpenTable.png"), tr("Open Table"), this);
581
//mActionOpenTable->setShortcut(tr("Ctrl+O","Open Table"));
582
mActionOpenTable->setStatusTip(tr("Open Table"));
583
connect(mActionOpenTable, SIGNAL(triggered()), this, SLOT(attributeTable()));
584
mActionOpenTable->setEnabled(false);
586
mActionMeasure= new QAction(QIcon(myIconPath+"/mActionMeasure.png"), tr("Measure Line "), this);
587
mActionMeasure->setShortcut(tr("Ctrl+M","Measure a Line"));
588
mActionMeasure->setStatusTip(tr("Measure a Line"));
589
connect(mActionMeasure, SIGNAL(triggered()), this, SLOT(measure()));
591
mActionMeasureArea= new QAction(QIcon(myIconPath+"/mActionMeasureArea.png"), tr("Measure Area"), this);
592
mActionMeasureArea->setShortcut(tr("Ctrl+J","Measure an Area"));
593
mActionMeasureArea->setStatusTip(tr("Measure an Area"));
594
connect(mActionMeasureArea, SIGNAL(triggered()), this, SLOT(measureArea()));
596
mActionShowBookmarks= new QAction(QIcon(myIconPath+"/mActionShowBookmarks.png"), tr("Show Bookmarks"), this);
597
mActionShowBookmarks->setShortcut(tr("B","Show Bookmarks"));
598
mActionShowBookmarks->setStatusTip(tr("Show Bookmarks"));
599
connect(mActionShowBookmarks, SIGNAL(triggered()), this, SLOT(showBookmarks()));
601
mActionShowAllToolbars = new QAction(tr("Show most toolbars"), this);
602
mActionShowAllToolbars->setShortcut(tr("T", "Show most toolbars"));
603
mActionShowAllToolbars->setStatusTip(tr("Show most toolbars"));
604
connect(mActionShowAllToolbars, SIGNAL(triggered()), this,
605
SLOT(showAllToolbars()));
607
mActionHideAllToolbars = new QAction(tr("Hide most toolbars"), this);
608
mActionHideAllToolbars->setShortcut(tr("Ctrl+T", "Hide most toolbars"));
609
mActionHideAllToolbars->setStatusTip(tr("Hide most toolbars"));
610
connect(mActionHideAllToolbars, SIGNAL(triggered()), this,
611
SLOT(hideAllToolbars()));
613
mActionNewBookmark= new QAction(QIcon(myIconPath+"/mActionNewBookmark.png"), tr("New Bookmark..."), this);
614
mActionNewBookmark->setShortcut(tr("Ctrl+B","New Bookmark"));
615
mActionNewBookmark->setStatusTip(tr("New Bookmark"));
616
connect(mActionNewBookmark, SIGNAL(triggered()), this, SLOT(newBookmark()));
618
mActionAddWmsLayer= new QAction(QIcon(myIconPath+"/mActionAddWmsLayer.png"), tr("Add WMS Layer..."), this);
619
mActionAddWmsLayer->setShortcut(tr("W","Add Web Mapping Server Layer"));
620
mActionAddWmsLayer->setStatusTip(tr("Add Web Mapping Server Layer"));
621
connect(mActionAddWmsLayer, SIGNAL(triggered()), this, SLOT(addWmsLayer()));
623
mActionInOverview= new QAction(QIcon(myIconPath+"/mActionInOverview.png"), tr("In Overview"), this);
624
mActionInOverview->setShortcut(tr("O","Add current layer to overview map"));
625
mActionInOverview->setStatusTip(tr("Add current layer to overview map"));
626
connect(mActionInOverview, SIGNAL(triggered()), this, SLOT(inOverview()));
628
// Plugin Menu Related Items
630
mActionShowPluginManager= new QAction(QIcon(myIconPath+"/mActionShowPluginManager.png"), tr("Plugin Manager..."), this);
631
// mActionShowPluginManager->setShortcut(tr("Ctrl+P","Open the plugin manager"));
632
mActionShowPluginManager->setStatusTip(tr("Open the plugin manager"));
633
connect(mActionShowPluginManager, SIGNAL(triggered()), this, SLOT(showPluginManager()));
635
// Add the whats this toolbar button
636
// QWhatsThis::whatsThisButton(mHelpToolBar);
639
// Digitising Toolbar Items
642
mActionStartEditing = new QAction(QIcon(myIconPath+"/mActionStartEditing.png"),
643
tr("Start editing the current layer"), this);
644
mActionStartEditing->setStatusTip(tr("Start editing the current layer"));
645
connect(mActionStartEditing, SIGNAL(triggered()), this, SLOT(startEditing()));
647
mActionStopEditing = new QAction(QIcon(myIconPath+"/mActionStopEditing.png"),
648
tr("Stop editing the current layer"), this);
649
mActionStopEditing->setStatusTip(tr("Stop editing the current layer"));
650
connect(mActionStopEditing, SIGNAL(triggered()), this, SLOT(stopEditing()));
652
mActionCapturePoint= new QAction(QIcon(myIconPath+"/mActionCapturePoint.png"), tr("Capture Point"), this);
653
mActionCapturePoint->setShortcut(tr(".","Capture Points"));
654
mActionCapturePoint->setStatusTip(tr("Capture Points"));
655
connect(mActionCapturePoint, SIGNAL(triggered()), this, SLOT(capturePoint()));
656
mActionCapturePoint->setEnabled(false);
658
mActionCaptureLine= new QAction(QIcon(myIconPath+"/mActionCaptureLine.png"), tr("Capture Line"), this);
659
mActionCaptureLine->setShortcut(tr("/","Capture Lines"));
660
mActionCaptureLine->setStatusTip(tr("Capture Lines"));
661
connect(mActionCaptureLine, SIGNAL(triggered()), this, SLOT(captureLine()));
662
mActionCaptureLine->setEnabled(false);
664
mActionCapturePolygon= new QAction(QIcon(myIconPath+"/mActionCapturePolygon.png"), tr("Capture Polygon"), this);
665
mActionCapturePolygon->setShortcut(tr("Ctrl+/","Capture Polygons"));
666
mActionCapturePolygon->setStatusTip(tr("Capture Polygons"));
667
connect(mActionCapturePolygon, SIGNAL(triggered()), this, SLOT(capturePolygon()));
668
mActionCapturePolygon->setEnabled(false);
670
mActionDeleteSelected = new QAction(QIcon(myIconPath+"/mActionDeleteSelected.png"), tr("Delete Selected"), this);
671
mActionDeleteSelected->setStatusTip(tr("Delete Selected"));
672
connect(mActionDeleteSelected, SIGNAL(triggered()), this, SLOT(deleteSelected()));
673
mActionDeleteSelected->setEnabled(false);
675
mActionAddVertex = new QAction(QIcon(myIconPath+"/mActionAddVertex.png"), tr("Add Vertex"), this);
676
mActionAddVertex->setStatusTip(tr("Add Vertex"));
677
connect(mActionAddVertex, SIGNAL(triggered()), this, SLOT(addVertex()));
678
mActionAddVertex->setEnabled(false);
680
mActionDeleteVertex = new QAction(QIcon(myIconPath+"/mActionDeleteVertex.png"), tr("Delete Vertex"), this);
681
mActionDeleteVertex->setStatusTip(tr("Delete Vertex"));
682
connect(mActionDeleteVertex, SIGNAL(triggered()), this, SLOT(deleteVertex()));
683
mActionDeleteVertex->setEnabled(false);
685
mActionMoveVertex = new QAction(QIcon(myIconPath+"/mActionMoveVertex.png"), tr("Move Vertex"), this);
686
mActionMoveVertex->setStatusTip(tr("Move Vertex"));
687
connect(mActionMoveVertex, SIGNAL(triggered()), this, SLOT(moveVertex()));
688
mActionMoveVertex->setEnabled(false);
690
mActionEditCut = new QAction(QIcon(myIconPath+"/mActionEditCut.png"), tr("Cut Features"), this);
691
mActionEditCut->setStatusTip(tr("Cut selected features"));
692
connect(mActionEditCut, SIGNAL(triggered()), this, SLOT(editCut()));
693
mActionEditCut->setEnabled(false);
695
mActionEditCopy = new QAction(QIcon(myIconPath+"/mActionEditCopy.png"), tr("Copy Features"), this);
696
mActionEditCopy->setStatusTip(tr("Copy selected features"));
697
connect(mActionEditCopy, SIGNAL(triggered()), this, SLOT(editCopy()));
698
mActionEditCopy->setEnabled(false);
700
mActionEditPaste = new QAction(QIcon(myIconPath+"/mActionEditPaste.png"), tr("Paste Features"), this);
701
mActionEditPaste->setStatusTip(tr("Paste selected features"));
702
connect(mActionEditPaste, SIGNAL(triggered()), this, SLOT(editPaste()));
703
mActionEditPaste->setEnabled(false);
706
void QgisApp::createActionGroups()
710
mMapToolGroup = new QActionGroup(this);
711
mActionPan->setCheckable(true);
712
mMapToolGroup->addAction(mActionPan);
713
mActionZoomIn->setCheckable(true);
714
mMapToolGroup->addAction(mActionZoomIn);
715
mActionZoomOut->setCheckable(true);
716
mMapToolGroup->addAction(mActionZoomOut);
717
mActionIdentify->setCheckable(true);
718
mMapToolGroup->addAction(mActionIdentify);
719
mActionSelect->setCheckable(true);
720
mMapToolGroup->addAction(mActionSelect);
721
mActionMeasure->setCheckable(true);
722
mMapToolGroup->addAction(mActionMeasure);
723
mActionMeasureArea->setCheckable(true);
724
mMapToolGroup->addAction(mActionMeasureArea);
725
mActionCaptureLine->setCheckable(true);
726
mMapToolGroup->addAction(mActionCaptureLine);
727
mActionCapturePoint->setCheckable(true);
728
mMapToolGroup->addAction(mActionCapturePoint);
729
mActionCapturePolygon->setCheckable(true);
730
mMapToolGroup->addAction(mActionCapturePolygon);
731
mMapToolGroup->addAction(mActionDeleteSelected);
732
mActionAddVertex->setCheckable(true);
733
mMapToolGroup->addAction(mActionAddVertex);
734
mActionDeleteVertex->setCheckable(true);
735
mMapToolGroup->addAction(mActionDeleteVertex);
736
mActionMoveVertex->setCheckable(true);
737
mMapToolGroup->addAction(mActionMoveVertex);
740
void QgisApp::createMenus()
742
QString myIconPath = QgsApplication::themePath();
745
mFileMenu = menuBar()->addMenu(tr("&File"));
746
mFileMenu->addAction(mActionFileNew);
747
mFileMenu->addAction(mActionFileOpen);
748
mRecentProjectsMenu = mFileMenu->addMenu(tr("&Open Recent Projects"));
749
// Connect once for the entire submenu.
750
connect(mRecentProjectsMenu, SIGNAL(triggered(QAction *)),
751
this, SLOT(openProject(QAction *)));
753
mFileMenu->addSeparator();
754
mFileMenu->addAction(mActionFileSave);
755
mFileMenu->addAction(mActionFileSaveAs);
756
mFileMenu->addAction(mActionSaveMapAsImage);
757
mFileMenu->addSeparator();
758
mFileMenu->addAction(mActionExportMapServer);
759
mFileMenu->addAction(mActionFilePrint);
760
mFileMenu->addSeparator();
761
mFileMenu->addAction(mActionFileExit);
765
mViewMenu = menuBar()->addMenu(tr("&View"));
766
mViewMenu->addAction(mActionZoomFullExtent);
767
mViewMenu->addAction(mActionZoomToSelected);
768
mViewMenu->addAction(mActionZoomToLayer);
769
mViewMenu->addAction(mActionZoomLast);
770
mViewMenu->addAction(mActionDraw);
771
mViewMenu->addSeparator();
772
mViewMenu->addAction(mActionShowBookmarks);
773
mViewMenu->addAction(mActionNewBookmark);
774
mViewMenu->addSeparator();
775
mToolbarMenu = mViewMenu->addMenu(QIcon(myIconPath+"/mActionOptions.png"),
779
// View:toolbars menu
780
mToolbarMenu->addAction(mActionShowAllToolbars);
781
mToolbarMenu->addAction(mActionHideAllToolbars);
785
mLayerMenu = menuBar()->addMenu(tr("&Layer"));
786
mLayerMenu->addAction(mActionAddNonDbLayer);
787
mLayerMenu->addAction(mActionAddRasterLayer);
788
#ifdef HAVE_POSTGRESQL
789
mLayerMenu->addAction(mActionAddLayer);
791
mLayerMenu->addAction(mActionAddWmsLayer);
792
mLayerMenu->addSeparator();
793
mLayerMenu->addAction(mActionRemoveLayer);
794
mLayerMenu->addAction(mActionNewVectorLayer);
795
mLayerMenu->addSeparator();
796
mLayerMenu->addAction(mActionInOverview);
797
mLayerMenu->addAction(mActionAddAllToOverview);
798
mLayerMenu->addAction(mActionRemoveAllFromOverview);
799
mLayerMenu->addSeparator();
800
mLayerMenu->addAction(mActionHideAllLayers);
801
mLayerMenu->addAction(mActionShowAllLayers);
805
mSettingsMenu = menuBar()->addMenu(tr("&Settings"));
806
mSettingsMenu->addAction(mActionProjectProperties);
807
mSettingsMenu->addAction(mActionCustomProjection);
808
mSettingsMenu->addAction(mActionOptions);
812
mPluginMenu = menuBar()->addMenu(tr("&Plugins"));
813
mPluginMenu->addAction(mActionShowPluginManager);
814
mPluginMenu->addSeparator();
816
// Add the plugin manager action to it
817
//actionPluginManager->addTo(mPluginMenu);
818
// Add separator. Plugins will add their menus to this
819
// menu when they are loaded by the plugin manager
820
//mPluginMenu->insertSeparator();
821
// Add to the menubar
822
//menuBar()->insertItem(tr("&Plugins"), mPluginMenu, -1, menuBar()->count() - 1);
824
menuBar()->addSeparator();
825
mHelpMenu = menuBar()->addMenu(tr("&Help"));
826
mHelpMenu->addAction(mActionHelpContents);
827
mHelpMenu->addSeparator();
828
mHelpMenu->addAction(mActionQgisHomePage);
829
mHelpMenu->addAction(mActionCheckQgisVersion);
830
mHelpMenu->addSeparator();
831
mHelpMenu->addAction(mActionHelpAbout);
834
void QgisApp::createToolBars()
836
// Note: we need to set each object name to ensure that
837
// qmainwindow::saveState and qmainwindow::restoreState
842
mFileToolBar = addToolBar(tr("File"));
843
mFileToolBar->setIconSize(QSize(24,24));
844
mFileToolBar->setObjectName("FileToolBar");
845
mFileToolBar->addAction(mActionFileNew);
846
mFileToolBar->addAction(mActionFileNew);
847
mFileToolBar->addAction(mActionFileSave);
848
mFileToolBar->addAction(mActionFileSaveAs);
849
mFileToolBar->addAction(mActionFileOpen);
850
mFileToolBar->addAction(mActionFilePrint);
853
mLayerToolBar = addToolBar(tr("Manage Layers"));
854
mLayerToolBar->setIconSize(QSize(24,24));
855
mLayerToolBar->setObjectName("LayerToolBar");
856
mLayerToolBar->addAction(mActionAddNonDbLayer);
857
mLayerToolBar->addAction(mActionAddRasterLayer);
858
#ifdef HAVE_POSTGRESQL
859
mLayerToolBar->addAction(mActionAddLayer);
861
mLayerToolBar->addAction(mActionAddWmsLayer);
862
mLayerToolBar->addAction(mActionNewVectorLayer);
863
mLayerToolBar->addAction(mActionRemoveLayer);
864
mLayerToolBar->addAction(mActionInOverview);
865
mLayerToolBar->addAction(mActionAddAllToOverview);
866
mLayerToolBar->addAction(mActionRemoveAllFromOverview);
867
mLayerToolBar->addAction(mActionShowAllLayers);
868
mLayerToolBar->addAction(mActionHideAllLayers);
871
mHelpToolBar = addToolBar(tr("Help"));
872
mHelpToolBar->setIconSize(QSize(24,24));
873
mHelpToolBar->setObjectName("Help");
874
mHelpToolBar->addAction(mActionHelpContents);
876
// Digitizing Toolbar
877
mDigitizeToolBar = addToolBar(tr("Digitizing"));
878
mDigitizeToolBar->setIconSize(QSize(24,24));
879
mDigitizeToolBar->setObjectName("Digitizing");
880
mDigitizeToolBar->addAction(mActionStartEditing);
881
mDigitizeToolBar->addAction(mActionStopEditing);
882
mDigitizeToolBar->addAction(mActionCapturePoint);
883
mDigitizeToolBar->addAction(mActionCaptureLine);
884
mDigitizeToolBar->addAction(mActionCapturePolygon);
885
mDigitizeToolBar->addAction(mActionDeleteSelected);
886
mDigitizeToolBar->addAction(mActionAddVertex);
887
mDigitizeToolBar->addAction(mActionDeleteVertex);
888
mDigitizeToolBar->addAction(mActionMoveVertex);
889
mDigitizeToolBar->addAction(mActionEditCut);
890
mDigitizeToolBar->addAction(mActionEditCopy);
891
mDigitizeToolBar->addAction(mActionEditPaste);
893
// Map Navigation Toolbar
894
mMapNavToolBar = addToolBar(tr("Map Navigation"));
895
mMapNavToolBar->setIconSize(QSize(24,24));
896
mMapNavToolBar->setObjectName("Map Navigation");
897
mMapNavToolBar->addAction(mActionPan);
898
mMapNavToolBar->addAction(mActionZoomIn);
899
mMapNavToolBar->addAction(mActionZoomOut);
900
mMapNavToolBar->addAction(mActionZoomFullExtent);
901
mMapNavToolBar->addAction(mActionZoomToSelected);
902
mMapNavToolBar->addAction(mActionZoomToLayer);
903
mMapNavToolBar->addAction(mActionZoomLast);
904
mMapNavToolBar->addAction(mActionDraw);
906
// Attributes Toolbar
907
mAttributesToolBar = addToolBar(tr("Attributes"));
908
mAttributesToolBar->setIconSize(QSize(24,24));
909
mAttributesToolBar->setObjectName("Attributes");
910
mAttributesToolBar->addAction(mActionIdentify);
911
mAttributesToolBar->addAction(mActionSelect);
912
mAttributesToolBar->addAction(mActionOpenTable);
913
mAttributesToolBar->addAction(mActionMeasure);
914
mAttributesToolBar->addAction(mActionMeasureArea);
915
mAttributesToolBar->addAction(mActionShowBookmarks);
916
mAttributesToolBar->addAction(mActionNewBookmark);
919
mPluginToolBar = addToolBar(tr("Plugins"));
920
mPluginToolBar->setIconSize(QSize(24,24));
921
mPluginToolBar->setObjectName("Plugins");
924
void QgisApp::createStatusBar()
927
// Add a panel to the status bar for the scale, coords and progress
928
// And also rendering suppression checkbox
930
mProgressBar = new QProgressBar(statusBar());
931
mProgressBar->setMaximumWidth(100);
932
mProgressBar->hide();
933
QWhatsThis::add(mProgressBar, tr("Progress bar that displays the status of rendering layers and other time-intensive operations"));
934
statusBar()->addWidget(mProgressBar, 1,true);
935
// Bumped the font up one point size since 8 was too
936
// small on some platforms. A point size of 9 still provides
937
// plenty of display space on 1024x768 resolutions
938
QFont myFont( "Arial", 9 );
939
statusBar()->setFont(myFont);
940
mScaleLabel = new QLabel(QString(),statusBar());
941
mScaleLabel->setFont(myFont);
942
mScaleLabel->setMinimumWidth(10);
943
mScaleLabel->setMargin(3);
944
mScaleLabel->setAlignment(Qt::AlignCenter);
945
QWhatsThis::add(mScaleLabel, tr("Displays the current map scale"));
946
QToolTip::add (mScaleLabel, tr("Current map scale"));
947
statusBar()->addWidget(mScaleLabel, 0,true);
948
//coords status bar widget
949
mCoordsLabel = new QLabel(QString(), statusBar());
950
mCoordsLabel->setMinimumWidth(10);
951
mCoordsLabel->setFont(myFont);
952
mCoordsLabel->setMargin(3);
953
mCoordsLabel->setAlignment(Qt::AlignCenter);
954
QWhatsThis::add(mCoordsLabel, tr("Shows the map coordinates at the current cursor postion. The display is continuously updated as the mouse is moved."));
955
QToolTip::add (mCoordsLabel, tr("Map coordinates at mouse cursor position"));
956
statusBar()->addWidget(mCoordsLabel, 0, true);
957
// render suppression status bar widget
958
mRenderSuppressionCBox = new QCheckBox(tr("Render"),statusBar());
959
mRenderSuppressionCBox->setChecked(true);
960
mRenderSuppressionCBox->setFont(myFont);
961
QWhatsThis::add(mRenderSuppressionCBox, tr("When checked, the map layers are rendered in response to map navigation commands and other events. When not checked, no rendering is done. This allows you to add a large number of layers and symbolize them before rendering."));
962
QToolTip::add( mRenderSuppressionCBox, tr("Toggle map rendering") );
963
statusBar()->addWidget(mRenderSuppressionCBox,0,true);
964
// On the fly projection status bar icon
965
// Changed this to a tool button since a QPushButton is
966
// sculpted on OS X and the icon is never displayed [gsherman]
967
mOnTheFlyProjectionStatusButton = new QToolButton(statusBar());
968
mOnTheFlyProjectionStatusButton->setMaximumWidth(20);
969
// Maintain uniform widget height in status bar by setting button height same as labels
970
// For Qt/Mac 3.3, the default toolbutton height is 30 and labels were expanding to match
971
mOnTheFlyProjectionStatusButton->setMaximumHeight(mScaleLabel->height());
972
QPixmap myProjPixmap;
973
QString myIconPath = QgsApplication::themePath();
974
myProjPixmap.load(myIconPath+"/mIconProjectionDisabled.png");
975
mOnTheFlyProjectionStatusButton->setPixmap(myProjPixmap);
976
assert(!myProjPixmap.isNull());
977
QWhatsThis::add(mOnTheFlyProjectionStatusButton, tr("This icon shows whether on the fly projection is enabled or not. Click the icon to bring up the project properties dialog to alter this behaviour."));
978
QToolTip::add( mOnTheFlyProjectionStatusButton, tr("Projection status - Click to open projection dialog"));
979
connect(mOnTheFlyProjectionStatusButton, SIGNAL(clicked()),
980
this, SLOT(projectPropertiesProjections()));//bring up the project props dialog when clicked
981
statusBar()->addWidget(mOnTheFlyProjectionStatusButton,0,true);
982
statusBar()->showMessage(tr("Ready"));
985
QString QgisApp::themePath()
987
return mAppDir +"/share/qgis/themes/" + mThemeName + "/";
991
void QgisApp::setTheme(QString theThemeName)
993
/*****************************************************************
994
// Init the toolbar icons by setting the icon for each action.
995
// All toolbar/menu items must be a QAction in order for this
998
// When new toolbar/menu QAction objects are added to the interface,
999
// add an entry below to set the icon
1001
// PNG names must match those defined for the default theme. The
1002
// default theme is installed in <prefix>/share/qgis/themes/default.
1004
// New core themes can be added by creating a subdirectory under src/themes
1005
// and modifying the appropriate Makefile.am files. User contributed themes
1006
// will be installed directly into <prefix>/share/qgis/themes/<themedir>.
1008
// Themes can be selected from the preferences dialog. The dialog parses
1009
// the themes directory and builds a list of themes (ie subdirectories)
1010
// for the user to choose from.
1012
// TODO: Check as each icon is grabbed and if it doesn't exist, use the
1013
// one from the default theme (which is installed with qgis and should
1016
QgsApplication::selectTheme(theThemeName);
1017
QString myIconPath = QgsApplication::themePath();
1018
mActionFileNew->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFileNew.png")));
1019
mActionFileSave->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFileSave.png")));
1020
mActionFileSaveAs->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFileSaveAs.png")));
1021
mActionFileOpen->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFileOpen.png")));
1022
mActionFilePrint->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFilePrint.png")));
1023
mActionSaveMapAsImage->setIconSet(QIcon(QPixmap(myIconPath + "/mActionSaveMapAsImage.png")));
1024
mActionExportMapServer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionExportMapServer.png")));
1025
mActionFileExit->setIconSet(QIcon(QPixmap(myIconPath + "/mActionFileExit.png")));
1026
mActionAddNonDbLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionAddNonDbLayer.png")));
1027
mActionAddRasterLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionAddRasterLayer.png")));
1028
mActionAddLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionAddLayer.png")));
1029
mActionRemoveLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionRemoveLayer.png")));
1030
mActionNewVectorLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionNewVectorLayer.png")));
1031
mActionAddAllToOverview->setIconSet(QIcon(QPixmap(myIconPath + "/mActionAddAllToOverview.png")));
1032
mActionHideAllLayers->setIconSet(QIcon(QPixmap(myIconPath + "/mActionHideAllLayers.png")));
1033
mActionShowAllLayers->setIconSet(QIcon(QPixmap(myIconPath + "/mActionShowAllLayers.png")));
1034
mActionRemoveAllFromOverview->setIconSet(QIcon(QPixmap(myIconPath + "/mActionRemoveAllFromOverview.png")));
1035
mActionProjectProperties->setIconSet(QIcon(QPixmap(myIconPath + "/mActionProjectProperties.png")));
1036
mActionShowPluginManager->setIconSet(QIcon(QPixmap(myIconPath + "/mActionShowPluginManager.png")));
1037
mActionCheckQgisVersion->setIconSet(QIcon(QPixmap(myIconPath + "/mActionCheckQgisVersion.png")));
1038
mActionOptions->setIconSet(QIcon(QPixmap(myIconPath + "/mActionOptions.png")));
1039
mActionHelpContents->setIconSet(QIcon(QPixmap(myIconPath + "/mActionHelpContents.png")));
1040
mActionQgisHomePage->setIconSet(QIcon(QPixmap(myIconPath + "/mActionQgisHomePage.png")));
1041
mActionHelpAbout->setIconSet(QIcon(QPixmap(myIconPath + "/mActionHelpAbout.png")));
1042
mActionDraw->setIconSet(QIcon(QPixmap(myIconPath + "/mActionDraw.png")));
1043
mActionCapturePoint->setIconSet(QIcon(QPixmap(myIconPath + "/mActionCapturePoint.png")));
1044
mActionCaptureLine->setIconSet(QIcon(QPixmap(myIconPath + "/mActionCaptureLine.png")));
1045
mActionCapturePolygon->setIconSet(QIcon(QPixmap(myIconPath + "/mActionCapturePolygon.png")));
1046
mActionZoomIn->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomIn.png")));
1047
mActionZoomOut->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomOut.png")));
1048
mActionZoomFullExtent->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomFullExtent.png")));
1049
mActionZoomToSelected->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomToSelected.png")));
1050
mActionPan->setIconSet(QIcon(QPixmap(myIconPath + "/mActionPan.png")));
1051
mActionZoomLast->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomLast.png")));
1052
mActionZoomToLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionZoomToLayer.png")));
1053
mActionIdentify->setIconSet(QIcon(QPixmap(myIconPath + "/mActionIdentify.png")));
1054
mActionSelect->setIconSet(QIcon(QPixmap(myIconPath + "/mActionSelect.png")));
1055
mActionOpenTable->setIconSet(QIcon(QPixmap(myIconPath + "/mActionOpenTable.png")));
1056
mActionMeasure->setIconSet(QIcon(QPixmap(myIconPath + "/mActionMeasure.png")));
1057
mActionMeasureArea->setIconSet(QIcon(QPixmap(myIconPath + "/mActionMeasureArea.png")));
1058
mActionShowBookmarks->setIconSet(QIcon(QPixmap(myIconPath + "/mActionShowBookmarks.png")));
1059
mActionNewBookmark->setIconSet(QIcon(QPixmap(myIconPath + "/mActionNewBookmark.png")));
1060
mActionCustomProjection->setIconSet(QIcon(QPixmap(myIconPath + "/mActionCustomProjection.png")));
1061
mActionAddWmsLayer->setIconSet(QIcon(QPixmap(myIconPath + "/mActionAddWmsLayer.png")));
1062
mActionInOverview->setIconSet(QIcon(QPixmap(myIconPath + "/mActionInOverview.png")));
1065
void QgisApp::setupConnections()
1067
// connect the "cleanup" slot
1068
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(saveWindowState()));
1069
//connect the legend, mapcanvas and overview canvas to the registry
1071
// connect map layer registry signals to legend
1072
connect(QgsMapLayerRegistry::instance(), SIGNAL(layerWillBeRemoved(QString)),
1073
mMapLegend, SLOT(removeLayer(QString)));
1074
connect(QgsMapLayerRegistry::instance(), SIGNAL(removedAll()),
1075
mMapLegend, SLOT(removeAll()));
1076
connect(QgsMapLayerRegistry::instance(), SIGNAL(layerWasAdded(QgsMapLayer*)),
1077
mMapLegend, SLOT(addLayer(QgsMapLayer *)));
1079
//signal when mouse moved over window (coords display in status bar)
1080
connect(mMapCanvas, SIGNAL(xyCoordinates(QgsPoint &)), this, SLOT(showMouseCoordinate(QgsPoint &)));
1081
//signal when mouse in capturePoint mode and mouse clicked on canvas
1082
connect(mMapCanvas->mapRender(), SIGNAL(drawingProgress(int,int)), this, SLOT(showProgress(int,int)));
1083
connect(mMapCanvas, SIGNAL(extentsChanged(QgsRect )),this,SLOT(showExtents(QgsRect )));
1084
connect(mMapCanvas, SIGNAL(scaleChanged(QString)), this, SLOT(showScale(QString)));
1085
connect(mMapCanvas, SIGNAL(scaleChanged(QString)), this, SLOT(updateMouseCoordinatePrecision()));
1087
connect(mRenderSuppressionCBox, SIGNAL(toggled(bool )), mMapCanvas, SLOT(setRenderFlag(bool)));
1089
void QgisApp::createCanvas()
1091
// "theMapCanvas" used to find this canonical instance later
1092
mMapCanvas = new QgsMapCanvas(NULL, "theMapCanvas" );
1093
QWhatsThis::add(mMapCanvas, tr("Map canvas. This is where raster and vector layers are displayed when added to the map"));
1095
mMapCanvas->setMinimumWidth(10);
1096
QVBoxLayout *myCanvasLayout = new QVBoxLayout;
1097
myCanvasLayout->addWidget(mMapCanvas);
1098
tabWidget->widget(0)->setLayout(myCanvasLayout);
1099
// set the focus to the map canvas
1100
mMapCanvas->setFocus();
1103
mMapTools.mZoomIn = new QgsMapToolZoom(mMapCanvas, FALSE /* zoomIn */);
1104
mMapTools.mZoomIn->setAction(mActionZoomIn);
1105
mMapTools.mZoomOut = new QgsMapToolZoom(mMapCanvas, TRUE /* zoomOut */);
1106
mMapTools.mZoomOut->setAction(mActionZoomOut);
1107
mMapTools.mPan = new QgsMapToolPan(mMapCanvas);
1108
mMapTools.mPan->setAction(mActionPan);
1109
mMapTools.mIdentify = new QgsMapToolIdentify(mMapCanvas);
1110
mMapTools.mIdentify->setAction(mActionIdentify);
1111
mMapTools.mMeasureDist = new QgsMeasure(FALSE /* area */, mMapCanvas);
1112
mMapTools.mMeasureDist->setAction(mActionMeasure);
1113
mMapTools.mMeasureArea = new QgsMeasure(TRUE /* area */, mMapCanvas);
1114
mMapTools.mMeasureArea->setAction(mActionMeasureArea);
1115
mMapTools.mCapturePoint = new QgsMapToolCapture(mMapCanvas, QgsMapToolCapture::CapturePoint);
1116
mMapTools.mCapturePoint->setAction(mActionCapturePoint);
1117
mMapTools.mCaptureLine = new QgsMapToolCapture(mMapCanvas, QgsMapToolCapture::CaptureLine);
1118
mMapTools.mCaptureLine->setAction(mActionCaptureLine);
1119
mMapTools.mCapturePolygon = new QgsMapToolCapture(mMapCanvas, QgsMapToolCapture::CapturePolygon);
1120
mMapTools.mCapturePolygon->setAction(mActionCapturePolygon);
1121
mMapTools.mSelect = new QgsMapToolSelect(mMapCanvas);
1122
mMapTools.mSelect->setAction(mActionSelect);
1123
mMapTools.mVertexAdd = new QgsMapToolVertexEdit(mMapCanvas, QgsMapToolVertexEdit::AddVertex);
1124
mMapTools.mVertexAdd->setAction(mActionAddVertex);
1125
mMapTools.mVertexMove = new QgsMapToolVertexEdit(mMapCanvas, QgsMapToolVertexEdit::MoveVertex);
1126
mMapTools.mVertexMove->setAction(mActionMoveVertex);
1127
mMapTools.mVertexDelete = new QgsMapToolVertexEdit(mMapCanvas, QgsMapToolVertexEdit::DeleteVertex);
1128
mMapTools.mVertexDelete->setAction(mActionDeleteVertex);
1131
void QgisApp::createOverview()
1134
QgsMapOverviewCanvas* overviewCanvas = new QgsMapOverviewCanvas(NULL, mMapCanvas);
1135
QWhatsThis::add(overviewCanvas, tr("Map overview canvas. This canvas can be used to display a locator map that shows the current extent of the map canvas. The current extent is shown as a red rectangle. Any layer on the map can be added to the overview canvas."));
1137
QBitmap overviewPanBmp(16, 16, pan_bits, true);
1138
QBitmap overviewPanBmpMask(16, 16, pan_mask_bits, true);
1139
mOverviewMapCursor = new QCursor(overviewPanBmp, overviewPanBmpMask, 5, 5);
1140
overviewCanvas->setCursor(*mOverviewMapCursor);
1141
QVBoxLayout *myOverviewLayout = new QVBoxLayout;
1142
myOverviewLayout->addWidget(overviewCanvas);
1143
overviewFrame->setLayout(myOverviewLayout);
1145
mMapCanvas->setOverview(overviewCanvas);
1147
// moved here to set anti aliasing to both map canvas and overview
1148
QSettings mySettings;
1149
mMapCanvas->enableAntiAliasing(mySettings.value("/qgis/enable_anti_aliasing",false).toBool());
1150
mMapCanvas->useQImageToRender(mySettings.value("/qgis/use_qimage_to_render",false).toBool());
1152
int action = mySettings.value("/qgis/wheel_action", 0).toInt();
1153
double zoomFactor = mySettings.value("/qgis/zoom_factor", 2).toDouble();
1154
mMapCanvas->setWheelAction((QgsMapCanvas::WheelAction) action, zoomFactor);
1158
void QgisApp::createLegend()
1161
mMapLegend = new QgsLegend(this,NULL, "theMapLegend");
1162
mMapLegend->setObjectName("theMapLegend");
1163
mMapLegend->setMapCanvas(mMapCanvas);
1164
QWhatsThis::add(mMapLegend, tr("Map legend that displays all the layers currently on the map canvas. Click on the check box to turn a layer on or off. Double click on a layer in the legend to customize its appearance and set other properties."));
1165
QVBoxLayout *myLegendLayout = new QVBoxLayout;
1166
myLegendLayout->addWidget(mMapLegend);
1167
toolBox->widget(0)->setLayout(myLegendLayout);
1171
bool QgisApp::createDB()
1173
// Check qgis.db and make private copy if necessary
1174
QFile qgisPrivateDbFile(QgsApplication::qgisUserDbFilePath());
1176
// first we look for ~/.qgis/qgis.db
1177
if (!qgisPrivateDbFile.exists())
1179
// if it doesnt exist we copy it in from the global resources dir
1180
QString qgisMasterDbFileName = QgsApplication::qgisMasterDbFilePath();
1181
QFile masterFile(qgisMasterDbFileName);
1183
// Must be sure there is destination directory ~/.qgis
1184
QDir().mkpath(QgsApplication::qgisSettingsDirPath());
1186
//now copy the master file into the users .qgis dir
1187
bool isDbFileCopied = masterFile.copy(qgisPrivateDbFile.name());
1190
if (!isDbFileCopied)
1192
std::cout << "[ERROR] Can not make qgis.db private copy" << std::endl;
1200
// Update file menu with the current list of recently accessed projects
1201
void QgisApp::updateRecentProjectPaths()
1203
// Remove existing paths from the recent projects menu
1206
int menusize = mRecentProjectsMenu->actions().size();
1208
for(i = menusize; i < mRecentProjectPaths.size(); i++)
1210
mRecentProjectsMenu->addAction("Dummy text");
1213
QList<QAction *> menulist = mRecentProjectsMenu->actions();
1215
assert(menulist.size() == mRecentProjectPaths.size());
1217
for (i = 0; i < mRecentProjectPaths.size(); i++)
1219
menulist.at(i)->setText(mRecentProjectPaths.at(i));
1221
// Disable this menu item if the file has been removed, if not enable it
1222
menulist.at(i)->setEnabled(QFile::exists((mRecentProjectPaths.at(i))));
1225
} // QgisApp::updateRecentProjectPaths
1227
// add this file to the recently opened/saved projects list
1228
void QgisApp::saveRecentProjectPath(QString projectPath, QSettings & settings)
1230
// Get canonical absolute path
1231
QFileInfo myFileInfo(projectPath);
1232
projectPath = myFileInfo.absFilePath();
1234
// If this file is already in the list, remove it
1235
mRecentProjectPaths.removeAll(projectPath);
1237
// Prepend this file to the list
1238
mRecentProjectPaths.prepend(projectPath);
1240
// Keep the list to 8 items by trimming excess off the bottom
1241
while (mRecentProjectPaths.count() > 8)
1243
mRecentProjectPaths.pop_back();
1247
settings.writeEntry("/UI/recentProjectsList", mRecentProjectPaths);
1249
// Update menu list of paths
1250
updateRecentProjectPaths();
1252
} // QgisApp::saveRecentProjectPath
1254
void QgisApp::saveWindowState()
1256
// store window and toolbar positions
1258
// store the toolbar/dock widget settings using Qt4 settings API
1259
settings.setValue("/Geometry/state", this->saveState());
1261
// store window geometry
1262
QPoint p = this->pos();
1263
QSize s = this->size();
1264
settings.writeEntry("/Geometry/maximized", this->isMaximized());
1265
settings.writeEntry("/Geometry/x", p.x());
1266
settings.writeEntry("/Geometry/y", p.y());
1267
settings.writeEntry("/Geometry/w", s.width());
1268
settings.writeEntry("/Geometry/h", s.height());
1269
settings.setValue("/Geometry/canvasSplitterState", canvasLegendSplit->saveState());
1270
settings.setValue("/Geometry/legendSplitterState", legendOverviewSplit->saveState());
1273
void QgisApp::restoreWindowState()
1275
// restore the toolbar and dock widgets postions using Qt4 settings API
1277
QVariant vstate = settings.value("/Geometry/state");
1278
this->restoreState(vstate.toByteArray());
1280
// restore window geometry
1281
QDesktopWidget *d = QApplication::desktop();
1282
int dw = d->width(); // returns desktop width
1283
int dh = d->height(); // returns desktop height
1284
int w = settings.readNumEntry("/Geometry/w", 600);
1285
int h = settings.readNumEntry("/Geometry/h", 400);
1286
int x = settings.readNumEntry("/Geometry/x", (dw - 600) / 2);
1287
int y = settings.readNumEntry("/Geometry/y", (dh - 400) / 2);
1291
canvasLegendSplit->restoreState(settings.value("/Geometry/canvasSplitterState").toByteArray());
1292
legendOverviewSplit->restoreState(settings.value("/Geometry/legendSplitterState").toByteArray());
1294
///////////// END OF GUI SETUP ROUTINES ///////////////
1296
void QgisApp::about()
1298
static QgsAbout *abt = NULL;
1300
QApplication::setOverrideCursor(Qt::WaitCursor);
1301
abt = new QgsAbout();
1302
QString versionString = tr("Version ");
1303
versionString += QGis::qgisVersion;
1304
versionString += " (";
1305
versionString += QGis::qgisSvnVersion;
1306
versionString += ")";
1307
#ifdef HAVE_POSTGRESQL
1309
versionString += tr(" with PostgreSQL support");
1312
versionString += tr(" (no PostgreSQL support)");
1314
versionString += tr("\nCompiled against Qt ") + QT_VERSION_STR
1315
+ tr(", running against Qt ") + qVersion();
1318
// special version stuff for windows (if required)
1319
// versionString += "\nThis is a Windows preview release - not for production use";
1322
abt->setVersion(versionString);
1323
QString urls = "<p align=\"center\">" +
1324
tr("Quantum GIS is licensed under the GNU General Public License") +
1325
"</p><p align=\"center\">" +
1326
tr("http://www.gnu.org/licenses") +
1329
QString watsNew = "<html><body>" + tr("Version") + " ";
1330
watsNew += QGis::qgisVersion;
1331
watsNew += "<h3>" + tr("New features") + "</h3>";
1332
watsNew += "<ul><li>"
1333
+ tr("Numerous bug fixes")
1335
+ tr("Improvements in how segment lengths appear in the measure tool. The current segment length is shown/updated in the list of segments")
1337
+ tr("Improvement to zoom-in speed for rasters")
1339
+ tr("Improve line/area measuring behaviour when the user has been informed that they are probably using the wrong projection for the map canvas")
1341
+ tr("Added tooltips to the scale and coordinate position displays in the status bar")
1343
+ tr("Removed ugly console on WIN32 when not debugging")
1345
+ tr("Added icons to all GRASS tools. All GRASS tools are now on the toolbar")
1347
+ tr("New GRASS modules added to the GRASS toolbox")
1349
+ tr("The GRASS plugin is now fully internationalized")
1351
+ tr("Launcher plugin added to core plugins ")
1352
+ "</ul></body></html>";
1355
abt->setWhatsNew(watsNew);
1357
// add the available plugins to the list
1358
QString providerInfo = "<b>" + tr("Available Data Provider Plugins") + "</b><br>";
1359
abt->setPluginInfo(providerInfo + mProviderRegistry->pluginList(true));
1360
QApplication::restoreOverrideCursor();
1364
abt->setActiveWindow();
1367
/** Load up any plugins used in the last session
1370
void QgisApp::restoreSessionPlugins(QString thePluginDirString)
1373
QSettings mySettings;
1376
std::cerr << " -------------------- Restoring plugins from last session " << thePluginDirString.toLocal8Bit().data() << std::endl;
1378
// check all libs in the current plugin directory and get name and descriptions
1381
QDir myPluginDir(thePluginDirString, "*.dll", QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks);
1384
QDir myPluginDir(thePluginDirString, "*.so*", QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks);
1387
if (myPluginDir.count() == 0)
1394
for (unsigned i = 0; i < myPluginDir.count(); i++)
1396
QString myFullPath = thePluginDirString + "/" + myPluginDir[i];
1399
std::cerr << "Examining " << myFullPath.toLocal8Bit().data() << std::endl;
1402
QLibrary *myLib = new QLibrary(myFullPath);
1403
myLib->setLoadHints(QLibrary::ExportExternalSymbolsHint | QLibrary::ResolveAllSymbolsHint);
1404
bool loaded = myLib->load();
1408
//purposely leaving this one to stdout!
1409
std::cout << "Loaded " << myLib->library().toLocal8Bit().data() << std::endl;
1411
name_t * myName =(name_t *) myLib->resolve("name");
1412
description_t * myDescription = (description_t *) myLib->resolve("description");
1413
version_t * myVersion = (version_t *) myLib->resolve("version");
1414
if (myName && myDescription && myVersion )
1416
//check if the plugin was active on last session
1417
QString myEntryName = myName();
1418
// Windows stores a "true" value as a 1 in the registry so we
1419
// have to use readBoolEntry in this function
1421
if (mySettings.readBoolEntry("/Plugins/" + myEntryName))
1424
std::cerr << " -------------------- loading " << myEntryName.toLocal8Bit().data() << std::endl;
1427
loadPlugin(myName(), myDescription(), myFullPath);
1433
std::cerr << "Failed to get name, description, or type for " << myLib->library().toLocal8Bit().data() << std::endl;
1440
std::cerr << "Failed to load " << myLib->library().toLocal8Bit().data() << std::endl;
1441
std::cerr << "Reason: " << myLib->errorString().toLocal8Bit().data() << std::endl;
1452
Convenience function for readily creating file filters.
1454
Given a long name for a file filter and a regular expression, return
1455
a file filter string suitable for use in a QFileDialog::OpenFiles()
1456
call. The regular express, glob, will have both all lower and upper
1457
case versions added.
1460
static QString createFileFilter_(QString const &longName, QString const &glob)
1462
return longName + " (" + glob.lower() + " " + glob.upper() + ");;";
1463
} // createFileFilter_
1468
Builds the list of file filter strings to later be used by
1471
We query OGR for a list of supported vector formats; we then build a list
1472
of file filter strings from that list. We return a string that contains
1473
this list that is suitable for use in a a QFileDialog::getOpenFileNames()
1476
XXX Most of the file name filters need to be filled in; however we
1477
XXX may want to wait until we've tested each format before committing
1478
XXX them permanently instead of blindly relying on OGR to properly
1479
XXX supply all needed spatial data.
1482
static void buildSupportedVectorFileFilter_(QString & fileFilters)
1486
static QString myFileFilters;
1488
// if we've already built the supported vector string, just return what
1489
// we've already built
1490
if ( ! ( myFileFilters.isEmpty() || myFileFilters.isNull() ) )
1492
fileFilters = myFileFilters;
1497
// first get the GDAL driver manager
1499
OGRSFDriverRegistrar *driverRegistrar = OGRSFDriverRegistrar::GetRegistrar();
1501
if (!driverRegistrar)
1503
QMessageBox::warning(0,tr("OGR Driver Manager"),tr("unable to get OGRDriverManager"));
1504
return; // XXX good place to throw exception if we
1505
} // XXX decide to do exceptions
1507
// then iterate through all of the supported drivers, adding the
1508
// corresponding file filter
1510
OGRSFDriver *driver; // current driver
1512
QString driverName; // current driver name
1514
// Grind through all the drivers and their respective metadata.
1515
// We'll add a file filter for those drivers that have a file
1516
// extension defined for them; the others, welll, even though
1517
// theoreticaly we can open those files because there exists a
1518
// driver for them, the user will have to use the "All Files" to
1519
// open datasets with no explicitly defined file name extension.
1522
std::cerr << "Driver count: " << driverRegistrar->GetDriverCount() << std::endl;
1525
for (int i = 0; i < driverRegistrar->GetDriverCount(); ++i)
1527
driver = driverRegistrar->GetDriver(i);
1529
Q_CHECK_PTR(driver);
1533
qWarning("unable to get driver %d", i);
1537
driverName = driver->GetName();
1541
if (driverName.startsWith("ESRI"))
1543
myFileFilters += createFileFilter_("ESRI Shapefiles", "*.shp");
1545
else if (driverName.startsWith("UK"))
1547
// XXX needs file filter extension
1549
else if (driverName.startsWith("SDTS"))
1551
myFileFilters += createFileFilter_( "Spatial Data Transfer Standard",
1554
else if (driverName.startsWith("TIGER"))
1556
// XXX needs file filter extension
1558
else if (driverName.startsWith("S57"))
1560
// XXX needs file filter extension
1562
else if (driverName.startsWith("MapInfo"))
1564
myFileFilters += createFileFilter_("MapInfo", "*.mif *.tab");
1565
// XXX needs file filter extension
1567
else if (driverName.startsWith("DGN"))
1569
// XXX needs file filter extension
1571
else if (driverName.startsWith("VRT"))
1573
// XXX needs file filter extension
1575
else if (driverName.startsWith("AVCBin"))
1577
// XXX needs file filter extension
1579
else if (driverName.startsWith("REC"))
1581
// XXX needs file filter extension
1583
else if (driverName.startsWith("Memory"))
1585
// XXX needs file filter extension
1587
else if (driverName.startsWith("Jis"))
1589
// XXX needs file filter extension
1591
else if (driverName.startsWith("GML"))
1593
// XXX not yet supported; post 0.1 release task
1594
myFileFilters += createFileFilter_( "Geography Markup Language",
1599
// NOP, we don't know anything about the current driver
1600
// with regards to a proper file filter string
1601
qDebug( "%s:%d unknown driver %s", __FILE__, __LINE__, (const char *)driverName.toLocal8Bit().data() );
1604
} // each loaded GDAL driver
1606
std::cout << myFileFilters.toLocal8Bit().data() << std::endl;
1608
// can't forget the default case
1610
myFileFilters += "All files (*.*)";
1611
fileFilters = myFileFilters;
1613
#endif // DEPRECATED
1615
fileFilters = QgsProviderRegistry::instance()->fileVectorFilters();
1617
} // buildSupportedVectorFileFilter_()
1623
Open files, preferring to have the default file selector be the
1624
last one used, if any; also, prefer to start in the last directory
1625
associated with filterName.
1627
@param filterName the name of the filter; used for persistent store
1629
@param filters the file filters used for QFileDialog
1631
@param selectedFiles string list of selected files; will be empty
1633
@param enc encoding?
1634
@param title the title for the dialog
1637
Stores persistent settings under /UI/. The sub-keys will be
1638
filterName and filterName + "Dir".
1640
Opens dialog on last directory associated with the filter name, or
1641
the current working directory if this is the first time invoked
1642
with the current filter name.
1645
static void openFilesRememberingFilter_(QString const &filterName,
1646
QString const &filters, QStringList & selectedFiles, QString& enc, QString &title)
1649
bool haveLastUsedFilter = false; // by default, there is no last
1652
QSettings settings; // where we keep last used filter in
1655
QString lastUsedFilter = settings.readEntry("/UI/" + filterName,
1657
&haveLastUsedFilter);
1659
QString lastUsedDir = settings.readEntry("/UI/" + filterName + "Dir",".");
1661
QString lastUsedEncoding = settings.readEntry("/UI/encoding");
1664
std::cerr << "Opening file dialog with filters: " << filters.toLocal8Bit().data() << std::endl;
1667
QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog(0,
1668
title, lastUsedDir, filters, lastUsedEncoding);
1670
// allow for selection of more than one file
1671
openFileDialog->setMode(QFileDialog::ExistingFiles);
1673
if (haveLastUsedFilter) // set the filter to the last one used
1675
openFileDialog->selectFilter(lastUsedFilter);
1678
if (openFileDialog->exec() == QDialog::Accepted)
1680
selectedFiles = openFileDialog->selectedFiles();
1681
enc = openFileDialog->encoding();
1682
// Fix by Tim - getting the dirPath from the dialog
1683
// directly truncates the last node in the dir path.
1684
// This is a workaround for that
1685
QString myFirstFileName = selectedFiles.first();
1686
QFileInfo myFI(myFirstFileName);
1687
QString myPath = myFI.dirPath();
1689
qDebug("Writing last used dir: " + myPath);
1692
settings.writeEntry("/UI/" + filterName, openFileDialog->selectedFilter());
1693
settings.writeEntry("/UI/" + filterName + "Dir", myPath);
1694
settings.writeEntry("/UI/encoding", openFileDialog->encoding());
1697
delete openFileDialog;
1698
} // openFilesRememberingFilter_
1702
This method prompts the user for a list of vector filenames with a dialog.
1704
@todo XXX I'd really like to return false, but can't because this
1705
XXX is for a slot that was defined void; need to fix.
1707
void QgisApp::addLayer()
1709
mMapCanvas->freeze();
1711
QStringList selectedFiles;
1713
std::cerr << "Vector file filters: " << mVectorFileFilter.toLocal8Bit().data() << std::endl;
1717
QString title = tr("Open an OGR Supported Vector Layer");
1718
openFilesRememberingFilter_("lastVectorFileFilter", mVectorFileFilter, selectedFiles, enc,
1720
if (selectedFiles.isEmpty())
1722
// no files were selected, so just bail
1723
mMapCanvas->freeze(false);
1728
addLayer(selectedFiles, enc);
1729
} // QgisApp::addLayer()
1734
bool QgisApp::addLayer(QFileInfo const & vectorFile)
1736
// let the user know we're going to possibly be taking a while
1737
// Let render() do its own cursor management
1738
// QApplication::setOverrideCursor(Qt::WaitCursor);
1740
mMapCanvas->freeze(); // XXX why do we do this?
1743
QgsDebugMsg("completeBaseName is: " + vectorFile.completeBaseName());
1745
QgsVectorLayer *layer = new QgsVectorLayer(vectorFile.filePath(),
1746
vectorFile.completeBaseName(),
1748
Q_CHECK_PTR( layer );
1752
mMapCanvas->freeze(false);
1753
QApplication::restoreOverrideCursor();
1755
// XXX insert meaningful whine to the user here
1759
if (layer->isValid())
1761
// init the context menu so it can connect to slots
1763
// XXX move to legend::addLayer() layer->initContextMenu(this);
1765
// XXX What about the rest of these? Where should they be moved, if at
1766
// XXX all? Some of this functionality is taken care of in the
1767
// XXX QgsProject::read() (If layers added via that.)
1769
//add single symbol renderer as default
1770
QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer(layer->vectorType());
1772
Q_CHECK_PTR( renderer );
1776
mMapCanvas->freeze(false);
1777
// Let render() do its own cursor management
1778
// QApplication::restoreOverrideCursor();
1780
// XXX should we also delete the layer?
1782
// XXX insert meaningful whine to the user here
1786
layer->setRenderer(renderer);
1788
// Register this layer with the layers registry
1789
QgsMapLayerRegistry::instance()->addMapLayer(layer);
1790
layer->refreshLegend();
1792
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
1794
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
1796
QObject::connect(this,
1797
SIGNAL(keyPressed(QKeyEvent *)),
1799
SLOT(keyPressed(QKeyEvent* )));
1804
QString msg = vectorFile.completeBaseName() + " ";
1805
msg += tr("is not a valid or recognized data source");
1806
QMessageBox::critical(this, tr("Invalid Data Source"), msg);
1808
// since the layer is bad, stomp on it
1811
mMapCanvas->freeze(false);
1813
// Let render() do its own cursor management
1814
// QApplication::restoreOverrideCursor();
1819
mMapCanvas->freeze(false);
1820
// mMapLegend->update(); NOW UPDATED VIA SIGNAL/SLOT
1821
qApp->processEvents(); // XXX why does this need to be called manually?
1823
mMapCanvas->refresh();
1825
// Let render() do its own cursor management
1826
// QApplication::restoreOverrideCursor();
1828
statusBar()->message(mMapCanvas->extent().stringRep(2));
1832
} // QgisApp::addLayer()
1838
/** \brief overloaded vesion of the above method that takes a list of
1839
* filenames instead of prompting user with a dialog.
1841
XXX yah know, this could be changed to just iteratively call the above
1844
bool QgisApp::addLayer(QStringList const &theLayerQStringList, const QString& enc)
1846
mMapCanvas->freeze();
1848
// Let render() do its own cursor management
1849
// QApplication::setOverrideCursor(Qt::WaitCursor);
1851
for ( QStringList::ConstIterator it = theLayerQStringList.begin();
1852
it != theLayerQStringList.end();
1856
QString base = fi.completeBaseName();
1858
QgsDebugMsg("completeBaseName: "+base);
1862
QgsVectorLayer *layer = new QgsVectorLayer(*it, base, "ogr");
1863
Q_CHECK_PTR( layer );
1864
// set the visibility based on user preference for newly added
1866
layer->setVisible(mAddedLayersVisible);
1870
mMapCanvas->freeze(false);
1872
// Let render() do its own cursor management
1873
// QApplication::restoreOverrideCursor();
1875
// XXX insert meaningful whine to the user here
1879
if (layer->isValid())
1881
layer->setProviderEncoding(enc);
1882
// init the context menu so it can connect to slots
1885
// XXX now taken care of in legend layer->initContextMenu(this);
1887
//add single symbol renderer as default
1888
QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer(layer->vectorType());
1890
Q_CHECK_PTR( renderer );
1894
mMapCanvas->freeze(false);
1896
// Let render() do its own cursor management
1897
// QApplication::restoreOverrideCursor();
1899
// XXX insert meaningful whine to the user here
1903
layer->setRenderer(renderer);
1905
// Register this layer with the layers registry
1906
QgsMapLayerRegistry::instance()->addMapLayer(layer);
1908
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
1910
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
1912
QObject::connect(this,
1913
SIGNAL(keyPressed(QKeyEvent *)),
1915
SLOT(keyPressed(QKeyEvent* )));
1919
QString msg = *it + " ";
1920
msg += tr("is not a valid or recognized data source");
1921
QMessageBox::critical(this, tr("Invalid Data Source"), msg);
1923
// since the layer is bad, stomp on it
1926
// XXX should we return false here, or just grind through
1927
// XXX the remaining arguments?
1932
//qApp->processEvents();
1934
/*! \todo Need legend scrollview and legenditem classes */
1937
// mMapLegend->update(); NOW UPDATED VIA SIGNAL/SLOTS
1938
qApp->processEvents(); // XXX why does this need to be called manually?
1939
mMapCanvas->freeze(false);
1940
mMapCanvas->refresh();
1942
// Let render() do its own cursor management
1943
// QApplication::restoreOverrideCursor();
1945
statusBar()->message(mMapCanvas->extent().stringRep(2));
1950
} // QgisApp::addLayer()
1954
/** This helper checks to see whether the filename appears to be a valid vector file name */
1955
bool QgisApp::isValidVectorFileName(QString theFileNameQString)
1957
return (theFileNameQString.lower().endsWith(".shp"));
1960
/** Overloaded of the above function provided for convenience that takes a qstring pointer */
1961
bool QgisApp::isValidVectorFileName(QString * theFileNameQString)
1963
//dereference and delegate
1964
return isValidVectorFileName(*theFileNameQString);
1967
#ifndef HAVE_POSTGRESQL
1968
void QgisApp::addDatabaseLayer(){}
1970
void QgisApp::addDatabaseLayer()
1972
// only supports postgis layers at present
1974
// show the postgis dialog
1976
QgsDbSourceSelect *dbs = new QgsDbSourceSelect(this);
1978
mMapCanvas->freeze();
1982
// Let render() do its own cursor management
1983
// QApplication::setOverrideCursor(Qt::WaitCursor);
1986
// repaint the canvas if it was covered by the dialog
1988
// add files to the map canvas
1989
QStringList tables = dbs->selectedTables();
1991
QString connInfo = dbs->connInfo();
1992
// for each selected table, connect to the database, parse the WKT geometry,
1993
// and build a cavnasitem for it
1994
// readWKB(connInfo,tables);
1995
QStringList::Iterator it = tables.begin();
1996
while (it != tables.end())
2000
//qWarning("creating layer");
2001
QgsVectorLayer *layer = new QgsVectorLayer(connInfo + " table=" + *it, *it, "postgres");
2002
if (layer->isValid())
2004
// set initial visibility based on user preference
2005
layer->setVisible(mAddedLayersVisible);
2007
// give it a random color
2008
QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer(layer->vectorType()); // add single symbol renderer as default
2009
layer->setRenderer(renderer);
2011
// register this layer with the central layers registry
2012
QgsMapLayerRegistry::instance()->addMapLayer(layer);
2013
layer->refreshLegend();
2015
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
2017
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
2019
QObject::connect(this,
2020
SIGNAL(keyPressed(QKeyEvent *)),
2022
SLOT(keyPressed(QKeyEvent* )));
2026
std::cerr << (*it).toLocal8Bit().data() << " is an invalid layer - not loaded" << std::endl;
2027
QMessageBox::critical(this, tr("Invalid Layer"), tr("%1 is an invalid layer and cannot be loaded.").arg(*it));
2030
//qWarning("incrementing iterator");
2033
statusBar()->message(mMapCanvas->extent().stringRep(2));
2037
qApp->processEvents();
2038
mMapCanvas->freeze(false);
2039
mMapCanvas->refresh();
2041
// Let render() do its own cursor management
2042
// QApplication::restoreOverrideCursor();
2044
} // QgisApp::addDatabaseLayer()
2047
void QgisApp::addWmsLayer()
2052
std::cout << "QgisApp::addWmsLayer: about to addRasterLayer" << std::endl;
2056
QgsServerSourceSelect *wmss = new QgsServerSourceSelect(this);
2058
mMapCanvas->freeze();
2063
addRasterLayer(wmss->connInfo(),
2066
wmss->selectedLayers(),
2067
wmss->selectedStylesForSelectedLayers(),
2068
wmss->selectedImageEncoding(),
2069
wmss->selectedCrs(),
2070
wmss->connProxyHost(),
2071
wmss->connProxyPort(),
2072
wmss->connProxyUser(),
2073
wmss->connProxyPass()
2081
/// file data representation
2082
enum dataType { IS_VECTOR, IS_RASTER, IS_BOGUS };
2086
/** returns data type associated with the given QgsProject file DOM node
2088
The DOM node should represent the state associated with a specific layer.
2092
dataType_( QDomNode & layerNode )
2094
QString type = layerNode.toElement().attribute( "type" );
2096
if ( QString::null == type )
2098
qDebug( "%s:%d cannot find ``type'' attribute", __FILE__, __LINE__ );
2103
if ( "raster" == type )
2105
qDebug( "%s:%d is a raster", __FILE__, __LINE__ );
2109
else if ( "vector" == type )
2111
qDebug( "%s:%d is a vector", __FILE__, __LINE__ );
2116
qDebug( "%s:%d is unknown type %s", __FILE__, __LINE__, (const char *)type.toLocal8Bit().data() );
2119
} // dataType_( QDomNode & layerNode )
2122
/** return the data source for the given layer
2124
The QDomNode is a QgsProject DOM node corresponding to a map layer state.
2126
Essentially dumps <datasource> tag.
2131
dataSource_( QDomNode & layerNode )
2133
QDomNode dataSourceNode = layerNode.namedItem( "datasource" );
2135
if ( dataSourceNode.isNull() )
2137
qDebug( "%s:%d cannot find datasource node", __FILE__, __LINE__ );
2139
return QString::null;
2142
return dataSourceNode.toElement().text();
2144
} // dataSource_( QDomNode & layerNode )
2148
/// the three flavors for data
2149
typedef enum { IS_FILE, IS_DATABASE, IS_URL, IS_UNKNOWN } providerType;
2152
/** return the physical storage type associated with the given layer
2154
The QDomNode is a QgsProject DOM node corresponding to a map layer state.
2156
If the <provider> is "ogr", then it's a file type.
2158
However, if the layer is a raster, then there won't be a <provider> tag. It
2159
will always have an associated file.
2161
If the layer doesn't fall into either of the previous two categories, then
2162
it's either a database or URL. If the <datasource> tag has "url=", then
2163
it's URL based. If the <datasource> tag has "dbname=">, then the layer data
2169
providerType_( QDomNode & layerNode )
2171
// XXX but what about rasters that can be URLs? _Can_ they be URLs?
2173
switch( dataType_( layerNode ) )
2177
QString dataSource = dataSource_( layerNode );
2180
qDebug( "%s:%d datasource is %s", __FILE__, __LINE__, (const char *)dataSource.toLocal8Bit().data() );
2182
if ( dataSource.contains("host=") )
2186
#ifdef HAVE_POSTGRESQL
2187
else if ( dataSource.contains("dbname=") )
2192
// be default, then, this should be a file based layer data source
2193
// XXX is this a reasonable assumption?
2198
case IS_RASTER: // rasters are currently only accessed as
2203
qDebug( "%s:%d unknown ``type'' attribute", __FILE__, __LINE__ );
2212
/** set the <datasource> to the new value
2216
setDataSource_( QDomNode & layerNode, QString const & dataSource )
2218
QDomNode dataSourceNode = layerNode.namedItem("datasource");
2219
QDomElement dataSourceElement = dataSourceNode.toElement();
2220
QDomText dataSourceText = dataSourceElement.firstChild().toText();
2224
QString originalDataSource = dataSourceText.data();
2226
qDebug( "%s:%d datasource changed from %s", __FILE__, __LINE__, (const char *)originalDataSource.toLocal8Bit().data() );
2229
dataSourceText.setData( dataSource );
2232
QString newDataSource = dataSourceText.data();
2234
qDebug( "%s:%d to %s", __FILE__, __LINE__, (const char *)newDataSource.toLocal8Bit().data() );
2241
/** this is used to locate files that have moved or otherwise are missing
2246
findMissingFile_( QString const & fileFilters, QDomNode & layerNode )
2248
// Prepend that file name to the valid file format filter list since it
2249
// makes it easier for the user to not only find the original file, but to
2250
// perhaps find a similar file.
2252
QFileInfo originalDataSource( dataSource_(layerNode) );
2254
QString memoryQualifier; // to differentiate between last raster and
2255
// vector directories
2257
switch( dataType_( layerNode ) )
2261
memoryQualifier = "lastVectorFileFilter";
2267
memoryQualifier = "lastRasterFileFilter";
2272
qDebug( "%s:%d unable to determine data type", __FILE__, __LINE__ );
2276
// Prepend the original data source base name to make it easier to pick it
2277
// out from a list of other files; however the appropriate filter strings
2278
// for the file type will also be added in case the file name itself has
2281
QString myFileFilters = originalDataSource.fileName() + ";;" + fileFilters;
2283
QStringList selectedFiles;
2285
QString title( QObject::trUtf8("Open an OGR Supported Layer") );
2287
openFilesRememberingFilter_(memoryQualifier,
2293
if (selectedFiles.isEmpty())
2299
setDataSource_( layerNode, selectedFiles.first() );
2300
if ( ! QgsProject::instance()->read( layerNode ) )
2302
qDebug( "%s:%d unable to re-read layer", __FILE__, __LINE__ );
2306
} // findMissingFile_
2311
/** find relocated data source for the given layer
2313
This QDom object represents a QgsProject node that maps to a specific layer.
2315
@param layerNode QDom node containing layer project information
2319
XXX Only implemented for file based layers. It will need to be extended for
2320
XXX other data source types such as databases.
2325
findLayer_( QString const & fileFilters, QDomNode const & constLayerNode )
2327
// XXX actually we could possibly get away with a copy of the node
2328
QDomNode & layerNode = const_cast<QDomNode&>(constLayerNode);
2330
switch ( providerType_(layerNode) )
2333
qDebug( "%s:%d layer is file based", __FILE__, __LINE__ );
2334
findMissingFile_( fileFilters, layerNode );
2338
qDebug( "%s:%d layer is database based", __FILE__, __LINE__ );
2342
qDebug( "%s:%d layer is URL based", __FILE__, __LINE__ );
2346
qDebug( "%s:%d layer has an unkown type", __FILE__, __LINE__ );
2355
/** find relocated data sources for given layers
2357
These QDom objects represent QgsProject nodes that map to specific layers.
2362
findLayers_( QString const & fileFilters, list<QDomNode> const & layerNodes )
2365
const char * fileFiltersC = fileFilters.ascii(); // debugger probe
2368
for( list<QDomNode>::const_iterator i = layerNodes.begin();
2369
i != layerNodes.end();
2372
findLayer_( fileFilters, *i );
2383
void QgisApp::fileExit()
2385
if (saveDirty() != QMessageBox::Cancel)
2394
void QgisApp::fileNew()
2396
fileNew(TRUE); // prompts whether to save project
2400
//as file new but accepts flags to indicate whether we should prompt to save
2401
void QgisApp::fileNew(bool thePromptToSaveFlag)
2403
if (thePromptToSaveFlag)
2405
int answer = saveDirty();
2407
if (answer == QMessageBox::Cancel)
2414
std::cout << "erasing project" << std::endl;
2417
mMapCanvas->freeze(true);
2418
QgsMapLayerRegistry::instance()->removeAllMapLayers();
2419
mMapCanvas->clear();
2421
QgsProject* prj = QgsProject::instance();
2422
prj->title( QString::null );
2423
prj->filename( QString::null );
2424
prj->clearProperties(); // why carry over properties from previous projects?
2428
//set the colour for selections
2429
//the default can be set in qgisoptions
2430
//use project properties to override the colour on a per project basis
2431
int myRed = settings.value("/qgis/default_selection_color_red",255).toInt();
2432
int myGreen = settings.value("/qgis/default_selection_color_green",255).toInt();
2433
int myBlue = settings.value("/qgis/default_selection_color_blue",0).toInt();
2434
prj->writeEntry("Gui","/SelectionColorRedPart",myRed);
2435
prj->writeEntry("Gui","/SelectionColorGreenPart",myGreen);
2436
prj->writeEntry("Gui","/SelectionColorBluePart",myBlue);
2437
QgsRenderer::mSelectionColor=QColor(myRed,myGreen,myBlue);
2439
//set the canvas to the default background colour
2440
//the default can be set in qgisoptions
2441
//use project properties to override the colour on a per project basis
2442
myRed = settings.value("/qgis/default_canvas_color_red",255).toInt();
2443
myGreen = settings.value("/qgis/default_canvas_color_green",255).toInt();
2444
myBlue = settings.value("/qgis/default_canvas_color_blue",255).toInt();
2445
prj->writeEntry("Gui","/CanvasColorRedPart",myRed);
2446
prj->writeEntry("Gui","/CanvasColorGreenPart",myGreen);
2447
prj->writeEntry("Gui","/CanvasColorBluePart",myBlue);
2448
mMapCanvas->setCanvasColor(QColor(myRed,myGreen,myBlue));
2452
setTitleBarText_( *this );
2455
std::cout << "emiting new project signal" << std::endl ;
2458
//note by Tim: I did some casual egrepping and this signal doesnt actually
2459
//seem to be connected to anything....why is it here? Just for future needs?
2460
//note by Martin: actually QgsComposer does use it
2463
mMapCanvas->freeze(false);
2464
mMapCanvas->refresh();
2466
//set the projections enabled icon in the status bar
2467
int myProjectionEnabledFlag = prj->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0);
2468
projectionsEnabled(myProjectionEnabledFlag);
2470
pan(); // set map tool - panning
2472
} // QgisApp::fileNew(bool thePromptToSaveFlag)
2475
void QgisApp::newVectorLayer()
2478
QGis::WKBTYPE geometrytype;
2481
QgsGeomTypeDialog geomDialog(this);
2482
if(geomDialog.exec()==QDialog::Rejected)
2486
geometrytype = geomDialog.selectedType();
2487
fileformat = geomDialog.selectedFileFormat();
2489
std::list<std::pair<QString, QString> > attributes;
2490
geomDialog.attributes(attributes);
2492
bool haveLastUsedFilter = false; // by default, there is no last
2497
QSettings settings; // where we keep last used filter in
2500
QString lastUsedFilter = settings.readEntry("/UI/lastVectorFileFilter",
2502
&haveLastUsedFilter);
2504
QString lastUsedDir = settings.readEntry("/UI/lastVectorFileFilterDir",
2507
QString lastUsedEncoding = settings.readEntry("/UI/encoding");
2511
std::cerr << "Saving vector file dialog without filters: " << std::endl;
2514
QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog(this,
2515
tr("Save As"), lastUsedDir, "", lastUsedEncoding);
2517
// allow for selection of more than one file
2518
openFileDialog->setMode(QFileDialog::AnyFile);
2519
openFileDialog->setAcceptMode(QFileDialog::AcceptSave);
2520
openFileDialog->setConfirmOverwrite( true );
2522
if (haveLastUsedFilter) // set the filter to the last one used
2524
openFileDialog->selectFilter(lastUsedFilter);
2527
if (openFileDialog->exec() != QDialog::Accepted)
2529
delete openFileDialog;
2533
filename = openFileDialog->selectedFile();
2534
enc = openFileDialog->encoding();
2536
// If the file exists, delete it otherwise we'll end up loading that
2537
// file, which can cause problems (e.g., if the file contains
2538
// linestrings, but we're wanting to create points, we'll end up
2539
// with a linestring file).
2540
QFile::remove(filename);
2542
settings.writeEntry("/UI/lastVectorFileFilter", openFileDialog->selectedFilter());
2544
settings.writeEntry("/UI/lastVectorFileFilterDir", openFileDialog->directory().absolutePath());
2545
settings.writeEntry("/UI/encoding", openFileDialog->encoding());
2547
delete openFileDialog;
2549
//try to create the new layer with OGRProvider instead of QgsVectorFileWriter
2550
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
2551
QString ogrlib = pReg->library("ogr");
2552
// This var is not used...remove? TS FIXME
2553
const char *cOgrLib = (const char *) ogrlib;
2554
// load the data provider
2555
QLibrary* myLib = new QLibrary((const char *) ogrlib);
2556
bool loaded = myLib->load();
2560
qWarning("ogr provider loaded");
2562
typedef bool (*createEmptyDataSourceProc)(const QString&, const QString&, const QString&, QGis::WKBTYPE, \
2563
const std::list<std::pair<QString, QString> >&);
2564
createEmptyDataSourceProc createEmptyDataSource=(createEmptyDataSourceProc)myLib->resolve("createEmptyDataSource");
2565
if(createEmptyDataSource)
2567
if(geometrytype == QGis::WKBPoint)
2569
createEmptyDataSource(filename,fileformat, enc, QGis::WKBPoint, attributes);
2571
else if (geometrytype == QGis::WKBLineString)
2573
createEmptyDataSource(filename,fileformat, enc, QGis::WKBLineString, attributes);
2575
else if(geometrytype == QGis::WKBPolygon)
2577
createEmptyDataSource(filename,fileformat, enc, QGis::WKBPolygon, attributes);
2582
qWarning("QgisApp.cpp: geometry type not recognised");
2590
qWarning("Resolving newEmptyDataSource(...) failed");;
2595
//then add the layer to the view
2596
QStringList filelist;
2597
filelist.append(filename);
2598
addLayer(filelist, enc);
2602
void QgisApp::fileOpen()
2604
// possibly save any pending work before opening a new project
2605
int answer = saveDirty();
2607
if (answer != QMessageBox::Cancel)
2609
// Retrieve last used project dir from persistent settings
2611
QString lastUsedDir = settings.readEntry("/UI/lastProjectDir", ".");
2613
QFileDialog * openFileDialog = new QFileDialog(this,
2614
tr("Choose a QGIS project file to open"),
2615
lastUsedDir, QObject::tr("QGis files (*.qgs)"));
2616
openFileDialog->setMode(QFileDialog::ExistingFile);
2620
if (openFileDialog->exec() == QDialog::Accepted)
2622
// Fix by Tim - getting the dirPath from the dialog
2623
// directly truncates the last node in the dir path.
2624
// This is a workaround for that
2625
fullPath = openFileDialog->selectedFile();
2626
QFileInfo myFI(fullPath);
2627
QString myPath = myFI.dirPath();
2628
// Persist last used project dir
2629
settings.writeEntry("/UI/lastProjectDir", myPath);
2633
// if they didn't select anything, just return
2634
delete openFileDialog;
2638
delete openFileDialog;
2640
// clear out any stuff from previous project
2643
QgsProject::instance()->filename( fullPath );
2647
if ( QgsProject::instance()->read() )
2649
setTitleBarText_( *this );
2650
mMapCanvas->setMapUnits(QgsProject::instance()->mapUnits());
2651
emit projectRead(); // let plug-ins know that we've read in a new
2652
// project so that they can check any project
2653
// specific plug-in state
2655
// add this to the list of recently used project files
2656
saveRecentProjectPath(fullPath, settings);
2659
catch ( QgsProjectBadLayerException & e )
2661
QMessageBox::critical(this,
2662
tr("QGIS Project Read Error"),
2663
tr("") + "\n" + QString::fromLocal8Bit( e.what() ) );
2664
qDebug( "%s:%d %d bad layers found", __FILE__, __LINE__, e.layers().size() );
2666
// attempt to find the new locations for missing layers
2667
// XXX vector file hard-coded -- but what if it's raster?
2668
findLayers_( mVectorFileFilter, e.layers() );
2670
catch ( std::exception & e )
2672
QMessageBox::critical(this,
2673
tr("QGIS Project Read Error"),
2674
tr("") + "\n" + QString::fromLocal8Bit( e.what() ) );
2675
qDebug( "%s:%d BAD LAYERS FOUND", __FILE__, __LINE__ );
2678
//loop through all layers in the layers registry and connect up
2679
// keybindings for the escape key
2680
std::map<QString, QgsMapLayer *> myMapLayers
2681
= QgsMapLayerRegistry::instance()->mapLayers();
2682
std::map<QString, QgsMapLayer *>::iterator myMapIterator;
2683
for ( myMapIterator = myMapLayers.begin(); myMapIterator != myMapLayers.end(); ++myMapIterator )
2686
QgsMapLayer * myMapLayer = myMapIterator->second;
2687
QObject::connect(this,
2688
SIGNAL(keyPressed(QKeyEvent *)),
2690
SLOT(keyPressed(QKeyEvent* )));
2693
//set the projections enabled icon in the status bar
2694
int myProjectionEnabledFlag =
2695
QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0);
2696
projectionsEnabled(myProjectionEnabledFlag);
2697
} // QgisApp::fileOpen
2702
adds a saved project to qgis, usually called on startup by specifying a
2703
project file on the command line
2705
bool QgisApp::addProject(QString projectFile)
2707
mMapCanvas->freeze(true);
2709
// clear the map canvas
2714
if ( QgsProject::instance()->read( projectFile ) )
2716
setTitleBarText_( *this );
2717
int myRedInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorRedPart",255);
2718
int myGreenInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorGreenPart",255);
2719
int myBlueInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorBluePart",255);
2720
QColor myColor = QColor(myRedInt,myGreenInt,myBlueInt);
2721
mMapCanvas->setCanvasColor(myColor); //this is fill colour before rendering starts
2722
qDebug("Canvas background color restored...");
2724
emit projectRead(); // let plug-ins know that we've read in a new
2725
// project so that they can check any project
2726
// specific plug-in state
2728
// add this to the list of recently used project files
2730
saveRecentProjectPath(projectFile, settings);
2734
mMapCanvas->freeze(false);
2735
mMapCanvas->refresh();
2739
catch ( QgsProjectBadLayerException & e )
2741
qDebug( "%s:%d %d bad layers found", __FILE__, __LINE__, e.layers().size() );
2743
if ( QMessageBox::Yes == QMessageBox::critical( this,
2744
tr("QGIS Project Read Error"),
2745
tr("") + "\n" + QString::fromLocal8Bit( e.what() ) + "\n" +
2746
tr("Try to find missing layers?"),
2747
QMessageBox::Yes | QMessageBox::Default,
2748
QMessageBox::No | QMessageBox::Escape ) )
2750
qDebug( "%s:%d want to find missing layers is true", __FILE__, __LINE__ );
2752
// attempt to find the new locations for missing layers
2753
// XXX vector file hard-coded -- but what if it's raster?
2754
findLayers_( mVectorFileFilter, e.layers() );
2758
catch ( std::exception & e )
2760
qDebug( "%s:%d BAD LAYERS FOUND", __FILE__, __LINE__ );
2762
QMessageBox::critical( 0x0,
2763
tr("Unable to open project"), QString::fromLocal8Bit( e.what() ), QMessageBox::Ok,
2766
mMapCanvas->freeze(false);
2767
mMapCanvas->refresh();
2771
mMapCanvas->freeze(false);
2772
mMapCanvas->refresh();
2774
} // QgisApp::addProject(QString projectFile)
2778
bool QgisApp::fileSave()
2780
// if we don't have a filename, then obviously we need to get one; note
2781
// that the project file name is reset to null in fileNew()
2784
// we need to remember if this is a new project so that we know to later
2785
// update the "last project dir" settings; we know it's a new project if
2786
// the current project file name is empty
2787
bool isNewProject = false;
2789
if ( QgsProject::instance()->filename().isNull() )
2791
isNewProject = true;
2793
// Retrieve last used project dir from persistent settings
2795
QString lastUsedDir = settings.readEntry("/UI/lastProjectDir", ".");
2797
std::auto_ptr<QFileDialog> saveFileDialog( new QFileDialog(this,
2798
tr("Choose a QGIS project file"),
2799
lastUsedDir, QObject::tr("QGis files (*.qgs)")) );
2801
saveFileDialog->setMode(QFileDialog::AnyFile);
2802
saveFileDialog->setAcceptMode(QFileDialog::AcceptSave);
2803
saveFileDialog->setConfirmOverwrite( true );
2805
if (saveFileDialog->exec() == QDialog::Accepted)
2807
fullPath.setFile( saveFileDialog->selectedFile() );
2811
// if they didn't select anything, just return
2812
// delete saveFileDialog; auto_ptr auto destroys
2816
// make sure we have the .qgs extension in the file name
2817
if( "qgs" != fullPath.extension( false ) )
2819
QString newFilePath = fullPath.filePath() + ".qgs";
2821
const char* filePathStr = newFilePath.ascii(); // debugger probe
2823
fullPath.setFile( newFilePath );
2828
const char* filePathStr = fullPath.filePath().ascii(); // debugger probe
2830
QgsProject::instance()->filename( fullPath.filePath() );
2835
if ( QgsProject::instance()->write() )
2837
setTitleBarText_(*this); // update title bar
2838
statusBar()->message(tr("Saved project to:") + " " + QgsProject::instance()->filename() );
2842
// add this to the list of recently used project files
2844
saveRecentProjectPath(fullPath.filePath(), settings);
2849
QMessageBox::critical(this,
2850
tr("Unable to save project"),
2851
tr("Unable to save project to ") + QgsProject::instance()->filename() );
2854
catch ( std::exception & e )
2856
QMessageBox::critical( 0x0,
2857
tr("Unable to save project ") + QgsProject::instance()->filename(),
2858
QString::fromLocal8Bit( e.what() ),
2864
} // QgisApp::fileSave
2868
void QgisApp::fileSaveAs()
2870
// Retrieve last used project dir from persistent settings
2872
QString lastUsedDir = settings.readEntry("/UI/lastProjectDir", ".");
2874
auto_ptr<QFileDialog> saveFileDialog( new QFileDialog(this,
2875
tr("Choose a filename to save the QGIS project file as"),
2876
lastUsedDir, QObject::tr("QGis files (*.qgs)")) );
2878
saveFileDialog->setMode(QFileDialog::AnyFile);
2880
saveFileDialog->setAcceptMode(QFileDialog::AcceptSave);
2882
saveFileDialog->setConfirmOverwrite( true );
2884
// if we don't have a filename, then obviously we need to get one; note
2885
// that the project file name is reset to null in fileNew()
2888
if (saveFileDialog->exec() == QDialog::Accepted)
2890
// Fix by Tim - getting the dirPath from the dialog
2891
// directly truncates the last node in the dir path.
2892
// This is a workaround for that
2893
fullPath.setFile(saveFileDialog->selectedFile());
2894
QString myPath = fullPath.dirPath();
2895
// Persist last used project dir
2896
settings.writeEntry("/UI/lastProjectDir", myPath);
2900
// if they didn't select anything, just return
2901
// delete saveFileDialog; auto_ptr auto deletes
2905
// make sure the .qgs extension is included in the path name. if not, add it...
2906
if( "qgs" != fullPath.extension( false ) )
2908
QString newFilePath = fullPath.filePath() + ".qgs";
2910
const char* filePathStr = newFilePath.ascii(); // debugger probe
2912
fullPath.setFile( newFilePath );
2917
QgsProject::instance()->filename( fullPath.filePath() );
2919
if ( QgsProject::instance()->write() )
2921
setTitleBarText_(*this); // update title bar
2922
statusBar()->message(tr("Saved project to:") + " " + QgsProject::instance()->filename() );
2923
// add this to the list of recently used project files
2924
saveRecentProjectPath(fullPath.filePath(), settings);
2928
QMessageBox::critical(this,
2929
tr("Unable to save project"),
2930
tr("Unable to save project to ") + QgsProject::instance()->filename() );
2933
catch ( std::exception & e )
2935
QMessageBox::critical( 0x0,
2936
tr("Unable to save project ") + QgsProject::instance()->filename(),
2937
QString::fromLocal8Bit( e.what() ),
2941
} // QgisApp::fileSaveAs
2948
// Open the project file corresponding to the
2949
// path at the given index in mRecentProjectPaths
2950
void QgisApp::openProject(QAction *action)
2953
// possibly save any pending work before opening a different project
2955
assert(action != NULL);
2957
debugme = action->text();
2959
int answer = saveDirty();
2960
if (answer != QMessageBox::Cancel)
2962
addProject(debugme);
2965
//set the projections enabled icon in the status bar
2966
int myProjectionEnabledFlag =
2967
QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0);
2968
projectionsEnabled(myProjectionEnabledFlag);
2970
} // QgisApp::openProject
2973
Open the specified project file; prompt to save previous project if necessary.
2974
Used to process a commandline argument or OpenDocument AppleEvent.
2976
void QgisApp::openProject(const QString & fileName)
2978
// possibly save any pending work before opening a different project
2979
int answer = saveDirty();
2981
if (answer != QMessageBox::Cancel)
2985
if ( ! addProject(fileName) )
2988
std::cerr << "unable to load project " << fileName.toLocal8Bit().data() << "\n";
2995
catch ( QgsIOException & io_exception )
2997
QMessageBox::critical( 0x0,
2998
tr("QGIS: Unable to load project"),
2999
tr("Unable to load project ") + fileName );
3007
Open a raster or vector file; ignore other files.
3008
Used to process a commandline argument or OpenDocument AppleEvent.
3009
@returns true if the file is successfully opened
3011
bool QgisApp::openLayer(const QString & fileName)
3013
QFileInfo fileInfo(fileName);
3014
// try to load it as raster
3016
CPLPushErrorHandler(CPLQuietErrorHandler);
3017
if (QgsRasterLayer::isValidRasterFileName(fileName))
3018
ok = addRasterLayer(fileInfo, false);
3019
else // nope - try to load it as a shape/ogr
3020
ok = addLayer(fileInfo);
3021
CPLPopErrorHandler();
3025
// we have no idea what this file is...
3026
std::cout << "Unable to load " << fileName.toLocal8Bit().data() << std::endl;
3034
void QgisApp::filePrint()
3037
// Warn the user first that priting is experimental still
3039
QString myHeading = "QGIS Printing Support is Experimental";
3040
QString myMessage = "Please note that printing only works on A4 landscape at the moment.\n";
3041
myMessage += "For other page sizes your mileage may vary.\n";
3042
QMessageBox::information( this, tr(myHeading),tr(myMessage) );
3044
QPrinter myQPrinter;
3045
if(myQPrinter.setup(this))
3048
std::cout << ".............................." << std::endl;
3049
std::cout << "...........Printing..........." << std::endl;
3050
std::cout << ".............................." << std::endl;
3052
// Ithought we could just do this:
3053
//mMapCanvas->render(&myQPrinter);
3054
//but it doesnt work so now we try this....
3055
QPaintDeviceMetrics myMetrics( &myQPrinter ); // need width/height of printer surface
3056
std::cout << "Print device width: " << myMetrics.width() << std::endl;
3057
std::cout << "Print device height: " << myMetrics.height() << std::endl;
3058
QPainter myQPainter;
3059
myQPainter.begin( &myQPrinter );
3060
QPixmap myQPixmap(myMetrics.width(),myMetrics.height());
3062
mMapCanvas->freeze(false);
3063
mMapCanvas->setDirty(true);
3064
mMapCanvas->render(&myQPixmap);
3065
myQPainter.drawPixmap(0,0, myQPixmap);
3071
void QgisApp::filePrint()
3074
mComposer->zoomFull();
3077
void QgisApp::saveMapAsImage()
3079
//create a map to hold the QImageIO names and the filter names
3080
//the QImageIO name must be passed to the mapcanvas saveas image function
3081
typedef QMap<QString, QString> FilterMap;
3082
FilterMap myFilterMap;
3084
//find out the last used filter
3085
QSettings myQSettings; // where we keep last used filter in persistant state
3086
QString myLastUsedFilter = myQSettings.readEntry("/UI/saveAsImageFilter");
3087
QString myLastUsedDir = myQSettings.readEntry("/UI/lastSaveAsImageDir",".");
3090
// get a list of supported output image types
3093
QList<QByteArray> formats = QPictureIO::outputFormats();
3094
// Workaround for a problem with Qt4 - calls to outputFormats tend
3095
// to return nothing :(
3096
if (formats.count() == 0)
3098
formats.append("png");
3099
formats.append("jpg");
3102
for ( ; myCounterInt < formats.count(); myCounterInt++ )
3104
QString myFormat=QString(formats.at( myCounterInt ));
3105
QString myFilter = createFileFilter_(myFormat + " format", "*."+myFormat);
3106
myFilters += myFilter;
3107
myFilterMap[myFilter] = myFormat;
3110
std::cout << "Available Filters Map: " << std::endl;
3111
FilterMap::Iterator myIterator;
3112
for ( myIterator = myFilterMap.begin(); myIterator != myFilterMap.end(); ++myIterator )
3114
std::cout << myIterator.key().toLocal8Bit().data() << " : " << myIterator.data().toLocal8Bit().data() << std::endl;
3119
//create a file dialog using the the filter list generated above
3120
std::auto_ptr < QFileDialog > myQFileDialog( new QFileDialog(this,
3121
tr("Choose a filename to save the map image as"),
3122
myLastUsedDir, myFilters) );
3124
// allow for selection of more than one file
3125
myQFileDialog->setMode(QFileDialog::AnyFile);
3127
myQFileDialog->setAcceptMode(QFileDialog::AcceptSave);
3129
myQFileDialog->setConfirmOverwrite( true );
3132
if (!myLastUsedFilter.isEmpty()) // set the filter to the last one used
3134
myQFileDialog->selectFilter(myLastUsedFilter);
3138
//prompt the user for a filename
3139
QString myOutputFileNameQString; // = myQFileDialog->getSaveFileName(); //delete this
3140
if (myQFileDialog->exec() == QDialog::Accepted)
3142
myOutputFileNameQString = myQFileDialog->selectedFile();
3145
QString myFilterString = myQFileDialog->selectedFilter()+";;";
3148
std::cout << "Selected filter: " << myFilterString.toLocal8Bit().data() << std::endl;
3149
std::cout << "Image type to be passed to mapcanvas: " << (myFilterMap[myFilterString]).toLocal8Bit().data() << std::endl;
3152
// Add the file type suffix to the filename if required
3153
if (!myOutputFileNameQString.endsWith(myFilterMap[myFilterString]))
3155
myOutputFileNameQString += "." + myFilterMap[myFilterString];
3158
myQSettings.writeEntry("/UI/lastSaveAsImageFilter" , myFilterString);
3159
myQSettings.writeEntry("/UI/lastSaveAsImageDir", myQFileDialog->directory().absolutePath());
3161
if ( myOutputFileNameQString !="")
3164
//save the mapview to the selected file
3165
mMapCanvas->saveAsImage(myOutputFileNameQString,NULL,myFilterMap[myFilterString]);
3166
statusBar()->message(tr("Saved map image to") + " " + myOutputFileNameQString);
3173
//overloaded version of the above function
3174
void QgisApp::saveMapAsImage(QString theImageFileNameQString, QPixmap * theQPixmap)
3176
if ( theImageFileNameQString=="")
3178
//no filename chosen
3183
//force the size of the canvase
3184
mMapCanvas->resize(theQPixmap->width(), theQPixmap->height());
3185
//save the mapview to the selected file
3186
mMapCanvas->saveAsImage(theImageFileNameQString,theQPixmap);
3191
//reimplements method from base (gui) class
3192
void QgisApp::addAllToOverview()
3194
std::map<QString, QgsMapLayer *> myMapLayers = QgsMapLayerRegistry::instance()->mapLayers();
3195
std::map<QString, QgsMapLayer *>::iterator myMapIterator;
3196
for ( myMapIterator = myMapLayers.begin(); myMapIterator != myMapLayers.end(); ++myMapIterator )
3198
QgsMapLayer * myMapLayer = myMapIterator->second;
3199
myMapLayer->inOverview(true); // won't do anything if already in overview
3201
mMapCanvas->updateOverview();
3203
// notify the project we've made a change
3204
QgsProject::instance()->dirty(true);
3207
//reimplements method from base (gui) class
3208
void QgisApp::removeAllFromOverview()
3210
std::map<QString, QgsMapLayer *> myMapLayers = QgsMapLayerRegistry::instance()->mapLayers();
3211
std::map<QString, QgsMapLayer *>::iterator myMapIterator;
3212
for ( myMapIterator = myMapLayers.begin(); myMapIterator != myMapLayers.end(); ++myMapIterator )
3214
QgsMapLayer * myMapLayer = myMapIterator->second;
3215
myMapLayer->inOverview(false);
3217
mMapCanvas->updateOverview();
3219
// notify the project we've made a change
3220
QgsProject::instance()->dirty(true);
3221
} // QgisApp::removeAllFromOverview()
3224
//reimplements method from base (gui) class
3225
void QgisApp::hideAllLayers()
3228
std::cout << "hiding all layers!" << std::endl;
3231
legend()->selectAll(false);
3233
// notify the project we've made a change
3234
QgsProject::instance()->dirty(true);
3238
// reimplements method from base (gui) class
3239
void QgisApp::showAllLayers()
3242
std::cout << "Showing all layers!" << std::endl;
3245
legend()->selectAll(true);
3247
// notify the project we've made a change
3248
QgsProject::instance()->dirty(true);
3251
void QgisApp::exportMapServer()
3253
// check to see if there are any layers to export
3254
// Possibly we may reinstate this in the future if we provide 'active project' export again
3255
//if (mMapCanvas->layerCount() > 0)
3257
QString myMSExportPath = QgsApplication::msexportAppPath();
3258
QProcess *process = new QProcess;
3260
// quote the application path on windows
3261
myMSExportPath = QString("\"") + myMSExportPath + QString("\"");
3263
process->start(myMSExportPath);
3265
// Delete this object if the process terminates
3266
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
3267
SLOT(processExited()));
3269
// Delete the process if the application quits
3270
connect(qApp, SIGNAL(aboutToQuit()), process, SLOT(terminate()));
3275
// QMessageBox::warning(this, tr("No Map Layers"),
3276
// tr("No layers to export. You must add at least one layer to the map in order to export the view."));
3282
void QgisApp::zoomIn()
3284
QgsDebugMsg ("Setting map tool to zoomIn");
3286
mMapCanvas->setMapTool(mMapTools.mZoomIn);
3288
// notify the project we've made a change
3289
QgsProject::instance()->dirty(true);
3293
void QgisApp::zoomOut()
3295
mMapCanvas->setMapTool(mMapTools.mZoomOut);
3297
// notify the project we've made a change
3298
QgsProject::instance()->dirty(true);
3301
void QgisApp::zoomToSelected()
3303
mMapCanvas->zoomToSelected();
3305
// notify the project we've made a change
3306
QgsProject::instance()->dirty(true);
3311
mMapCanvas->setMapTool(mMapTools.mPan);
3314
void QgisApp::zoomFull()
3316
mMapCanvas->zoomFullExtent();
3317
// notify the project we've made a change
3318
QgsProject::instance()->dirty(true);
3322
void QgisApp::zoomPrevious()
3324
mMapCanvas->zoomPreviousExtent();
3325
// notify the project we've made a change
3326
QgsProject::instance()->dirty(true);
3330
void QgisApp::identify()
3332
mMapCanvas->setMapTool(mMapTools.mIdentify);
3335
void QgisApp::measure()
3337
mMapCanvas->setMapTool(mMapTools.mMeasureDist);
3340
void QgisApp::measureArea()
3342
mMapCanvas->setMapTool(mMapTools.mMeasureArea);
3347
void QgisApp::attributeTable()
3349
QgsMapLayer *layer = mMapLegend->currentLayer();
3356
QMessageBox::information(this, tr("No Layer Selected"),
3357
tr("To open an attribute table, you must select a layer in the legend"));
3361
void QgisApp::deleteSelected()
3363
QgsMapLayer *layer = mMapLegend->currentLayer();
3366
QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>(layer);
3369
if(!vlayer->deleteSelectedFeatures())
3371
QMessageBox::information(this, tr("Problem deleting features"),
3372
tr("A problem occured during deletion of features"));
3377
QMessageBox::information(this, tr("No Vector Layer Selected"),
3378
tr("Deleting features only works on vector layers"));
3383
QMessageBox::information(this, tr("No Layer Selected"),
3384
tr("To delete features, you must select a vector layer in the legend"));
3387
// notify the project we've made a change
3388
QgsProject::instance()->dirty(true);
3391
void QgisApp::capturePoint()
3393
// set current map tool to select
3394
mMapCanvas->setMapTool(mMapTools.mCapturePoint);
3396
// FIXME: is this still actual or something old that's not used anymore?
3397
//connect(t, SIGNAL(xyClickCoordinates(QgsPoint &)), this, SLOT(showCapturePointCoordinate(QgsPoint &)));
3400
void QgisApp::captureLine()
3402
mMapCanvas->setMapTool(mMapTools.mCaptureLine);
3405
void QgisApp::capturePolygon()
3407
mMapCanvas->setMapTool(mMapTools.mCapturePolygon);
3410
void QgisApp::select()
3412
mMapCanvas->setMapTool(mMapTools.mSelect);
3416
void QgisApp::addVertex()
3418
mMapCanvas->setMapTool(mMapTools.mVertexAdd);
3422
void QgisApp::moveVertex()
3424
mMapCanvas->setMapTool(mMapTools.mVertexMove);
3428
void QgisApp::deleteVertex()
3430
mMapCanvas->setMapTool(mMapTools.mVertexDelete);
3434
void QgisApp::editCut(QgsMapLayer * layerContainingSelection)
3436
QgsMapLayer * selectionLayer = (layerContainingSelection != 0) ?
3437
(layerContainingSelection) :
3442
// Test for feature support in this layer
3443
QgsVectorLayer* selectionVectorLayer = dynamic_cast<QgsVectorLayer*>(selectionLayer);
3445
if (selectionVectorLayer != 0)
3447
clipboard()->replaceWithCopyOf( *(selectionVectorLayer->selectedFeatures()) );
3448
selectionVectorLayer->deleteSelectedFeatures();
3454
void QgisApp::editCopy(QgsMapLayer * layerContainingSelection)
3456
QgsMapLayer * selectionLayer = (layerContainingSelection != 0) ?
3457
(layerContainingSelection) :
3462
// Test for feature support in this layer
3463
QgsVectorLayer* selectionVectorLayer = dynamic_cast<QgsVectorLayer*>(selectionLayer);
3465
if (selectionVectorLayer != 0)
3467
clipboard()->replaceWithCopyOf( *(selectionVectorLayer->selectedFeatures()) );
3473
void QgisApp::editPaste(QgsMapLayer * destinationLayer)
3475
QgsMapLayer * pasteLayer = (destinationLayer != 0) ?
3476
(destinationLayer) :
3481
// Test for feature support in this layer
3482
QgsVectorLayer* pasteVectorLayer = dynamic_cast<QgsVectorLayer*>(pasteLayer);
3484
if (pasteVectorLayer != 0)
3486
pasteVectorLayer->addFeatures( clipboard()->copyOf() );
3487
mMapCanvas->refresh();
3493
void QgisApp::pasteTransformations()
3495
QgsPasteTransformations *pt = new QgsPasteTransformations();
3497
mMapCanvas->freeze();
3503
void QgisApp::refreshMapCanvas()
3506
std::cout << "QgisApp:refreshMapCanvas" << std::endl;
3509
mMapCanvas->refresh();
3512
void QgisApp::startEditing()
3514
QgsMapLayer* theLayer = mMapLegend->currentLayer();
3519
//only vectorlayers can be edited
3520
QgsVectorLayer* theVectorLayer = dynamic_cast<QgsVectorLayer*>(theLayer);
3525
theVectorLayer->startEditing();
3528
void QgisApp::stopEditing()
3530
QgsMapLayer* theLayer = mMapLegend->currentLayer();
3535
//only vectorlayers can be edited
3536
QgsVectorLayer* theVectorLayer = dynamic_cast<QgsVectorLayer*>(theLayer);
3541
theVectorLayer->stopEditing();
3544
void QgisApp::showMouseCoordinate(QgsPoint & p)
3546
mCoordsLabel->setText(p.stringRep(mMousePrecisionDecimalPlaces));
3547
// Set minimum necessary width
3548
if ( mCoordsLabel->width() > mCoordsLabel->minimumWidth() )
3550
mCoordsLabel->setMinimumWidth(mCoordsLabel->width());
3554
void QgisApp::showScale(QString theScale)
3556
mScaleLabel->setText(theScale);
3557
// Set minimum necessary width
3558
if ( mScaleLabel->width() > mScaleLabel->minimumWidth() )
3560
mScaleLabel->setMinimumWidth(mScaleLabel->width());
3564
void QgisApp::testButton()
3566
/* QgsShapeFileLayer *sfl = new QgsShapeFileLayer("foo");
3567
mMapCanvas->addLayer(sfl); */
3572
void QgisApp::menubar_highlighted( int i )
3574
// used to save us from re-enabling layer menu items every single time the
3575
// user tweaks the layers drop down menu
3576
static bool enabled;
3578
if ( 6 == i ) // XXX I hate magic numbers; where is '6' defined
3579
// XXX for Layers menu?
3581
// first, if there are NO layers, disable everything that assumes we
3582
// have at least one layer loaded
3583
if ( QgsMapLayerRegistry::instance()->mapLayers().empty() )
3585
mActionRemoveLayer->setEnabled(false);
3586
mActionRemoveAllFromOverview->setEnabled(false);
3587
mActionInOverview->setEnabled(false);
3588
mActionShowAllLayers->setEnabled(false);
3589
mActionHideAllLayers->setEnabled(false);
3590
mActionOpenTable->setEnabled(false);
3591
mActionLayerProperties->setEnabled(false);
3599
mActionRemoveLayer->setEnabled(true);
3600
mActionRemoveAllFromOverview->setEnabled(true);
3601
mActionInOverview->setEnabled(true);
3602
mActionShowAllLayers->setEnabled(true);
3603
mActionHideAllLayers->setEnabled(true);
3604
mActionOpenTable->setEnabled(true);
3605
mActionLayerProperties->setEnabled(true);
3609
} // QgisApp::menubar_highlighted( int i )
3614
// toggle overview status
3615
void QgisApp::inOverview()
3618
std::cout << "QGisApp::inOverview" << std::endl;
3621
QgsMapLayer* layer = mMapLegend->currentLayer();
3624
layer->inOverview( ! layer->showInOverviewStatus() );
3625
mMapCanvas->updateOverview();
3627
} // QgisApp::inOverview(bool)
3631
void QgisApp::removeLayer()
3633
mMapLegend->legendLayerRemove();
3637
void QgisApp::removeAllLayers()
3639
QgsMapLayerRegistry::instance()->removeAllMapLayers();
3640
mMapCanvas->refresh();
3641
} //remove all layers
3644
void QgisApp::zoomToLayerExtent()
3646
// zoom only if one or more layers loaded
3647
if(QgsMapLayerRegistry::instance()->count() > 0)
3649
QgsMapLayer *layer = mMapLegend->currentLayer();
3652
// Check if the layer extent has to be transformed to the map canvas
3653
// coordinate system
3655
std::cout << "Layer extent is : " << layer->extent() << std::endl;
3657
if (QgsProject::instance()->readNumEntry("SpatialRefSys",
3658
"/ProjectionsEnabled",0)!=0)
3660
QgsCoordinateTransform *ct = layer->coordinateTransform();
3663
QgsRect transformedExtent = ct->transform(layer->extent());
3664
mMapCanvas->setExtent(transformedExtent);
3666
std::cout << "Canvas extent is : " << transformedExtent
3670
catch(QgsCsException &cse)
3673
std::cout << "Caught transform error in zoomToLayerExtent(). "
3674
<< "Setting untransformed extents." << std::endl;
3676
mMapCanvas->setExtent(layer->extent());
3681
mMapCanvas->setExtent(layer->extent());
3683
mMapCanvas->refresh();
3685
// notify the project we've made a change
3686
QgsProject::instance()->dirty(true);
3689
} // QgisApp::zoomToLayerExtent()
3692
QgisIface *QgisApp::getInterface()
3694
return mQgisInterface;
3697
void QgisApp::showPluginManager()
3699
QgsPluginManager *pm = new QgsPluginManager(this);
3702
// load selected plugins
3703
std::vector < QgsPluginItem > pi = pm->getSelectedPlugins();
3704
std::vector < QgsPluginItem >::iterator it = pi.begin();
3705
while (it != pi.end())
3707
QgsPluginItem plugin = *it;
3708
loadPlugin(plugin.name(), plugin.description(), plugin.fullPath());
3714
void QgisApp::loadPlugin(QString name, QString description, QString theFullPathName)
3717
// first check to see if its already loaded
3718
QgsPluginRegistry *pRegistry = QgsPluginRegistry::instance();
3719
QString lib = pRegistry->library(name);
3720
if (lib.length() > 0)
3723
// QMessageBox::warning(this, "Already Loaded", description + " is already loaded");
3727
QLibrary *myLib = new QLibrary(theFullPathName);
3730
std::cerr << "Library name is " << myLib->library().toLocal8Bit().data() << std::endl;
3733
bool loaded = myLib->load();
3737
std::cerr << "Loaded test plugin library" << std::endl;
3738
std::cerr << "Attempting to resolve the classFactory function" << std::endl;
3741
type_t *pType = (type_t *) myLib->resolve("type");
3746
case QgisPlugin::RENDERER:
3747
case QgisPlugin::UI:
3749
// UI only -- doesn't use mapcanvas
3750
create_ui *cf = (create_ui *) myLib->resolve("classFactory");
3753
QgisPlugin *pl = cf(this, mQgisInterface);
3757
// add it to the plugin registry
3758
pRegistry->addPlugin(myLib->library(), name, pl);
3759
//add it to the qsettings file [ts]
3760
settings.writeEntry("/Plugins/" + name, true);
3764
// something went wrong
3765
QMessageBox::warning(this, tr("Error Loading Plugin"), tr("There was an error loading %1."));
3766
//disable it to the qsettings file [ts]
3767
settings.writeEntry("/Plugins/" + name, false);
3773
std::cerr << "Unable to find the class factory for " << theFullPathName.toLocal8Bit().data() << std::endl;
3779
case QgisPlugin::MAPLAYER:
3781
// Map layer - requires interaction with the canvas
3782
create_it *cf = (create_it *) myLib->resolve("classFactory");
3785
QgsMapLayerInterface *pl = cf();
3788
// set the main window pointer for the plugin
3789
pl->setQgisMainWindow(this);
3791
//add it to the qsettings file [ts]
3792
settings.writeEntry("/Plugins/" + name, true);
3797
// something went wrong
3798
QMessageBox::warning(this, tr("Error Loading Plugin"), tr("There was an error loading %1."));
3799
//add it to the qsettings file [ts]
3800
settings.writeEntry("/Plugins/" + name, false);
3806
std::cerr << "Unable to find the class factory for " << theFullPathName.toLocal8Bit().data() << std::endl;
3814
std::cerr << "Plugin " << theFullPathName.toLocal8Bit().data() << " did not return a valid type and cannot be loaded" << std::endl;
3820
std::cout << "Unable to find the class factory for " << mFullPathName << std::endl;
3827
std::cerr << "Failed to load " << theFullPathName.toLocal8Bit().data() << "\n";
3833
void QgisApp::testMapLayerPlugins()
3836
// map layer plugins live in their own directory (somewhere to be determined)
3837
QDir mlpDir("../plugins/maplayer", "*.so.1.0.0", QDir::Name | QDir::IgnoreCase, QDir::Files);
3838
if (mlpDir.count() == 0)
3840
QMessageBox::information(this, tr("No MapLayer Plugins"), tr("No MapLayer plugins in ../plugins/maplayer"));
3844
for (unsigned i = 0; i < mlpDir.count(); i++)
3847
std::cout << "Getting information for plugin: " << mlpDir[i].toLocal8Bit().data() << std::endl;
3848
std::cout << "Attempting to load the plugin using dlopen\n";
3850
// void *handle = dlopen("../plugins/maplayer/" + mlpDir[i], RTLD_LAZY);
3851
void *handle = dlopen(("../plugins/maplayer/" + mlpDir[i]).toLocal8Bit().data(), RTLD_LAZY | RTLD_GLOBAL );
3855
std::cout << "Error in dlopen: " << dlerror() << std::endl;
3862
std::cout << "dlopen suceeded" << std::endl;
3868
QLibrary *myLib = new QLibrary("../plugins/maplayer/" + mlpDir[i]);
3871
std::cout << "Library name is " << myLib->library().toLocal8Bit().data() << std::endl;
3874
bool loaded = myLib->load();
3878
std::cout << "Loaded test plugin library" << std::endl;
3879
std::cout << "Attempting to resolve the classFactory function" << std::endl;
3882
create_it *cf = (create_it *) myLib->resolve("classFactory");
3887
std::cout << "Getting pointer to a MapLayerInterface object from the library\n";
3890
QgsMapLayerInterface *pl = cf();
3894
std::cout << "Instantiated the maplayer test plugin\n";
3896
// set the main window pointer for the plugin
3897
pl->setQgisMainWindow(this);
3899
//the call to getInt is deprecated and this line should be removed
3900
//std::cout << "getInt returned " << pl->getInt() << " from map layer plugin\n";
3908
std::cout << "Unable to instantiate the maplayer test plugin\n";
3917
std::cout << "Failed to load " << mlpDir[i].toLocal8Bit().data() << "\n";
3923
#endif //#ifndef WIN32
3925
void QgisApp::testPluginFunctions()
3927
// test maplayer plugins first
3928
testMapLayerPlugins();
3931
// try to load plugins from the plugin directory and test each one
3933
QDir pluginDir("../plugins", "*.so*", QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks);
3934
//pluginDir.setFilter(QDir::Files || QDir::NoSymLinks);
3935
//pluginDir.setNameFilter("*.so*");
3936
if (pluginDir.count() == 0)
3938
QMessageBox::information(this, tr("No Plugins"),
3939
tr("No plugins found in ../plugins. To test plugins, start qgis from the src directory"));
3944
for (unsigned i = 0; i < pluginDir.count(); i++)
3947
std::cout << "Getting information for plugin: " << pluginDir[i].toLocal8Bit().data() << std::endl;
3950
QLibrary *myLib = new QLibrary("../plugins/" + pluginDir[i]); //"/home/gsherman/development/qgis/plugins/" + pluginDir[i]);
3953
std::cout << "Library name is " << myLib->library().toLocal8Bit().data() << std::endl;
3955
//QLibrary myLib("../plugins/" + pluginDir[i]);
3958
std::cout << "Attempting to load ../plugins/" << pluginDir[i].toLocal8Bit().data() << std::endl;
3960
/* void *handle = dlopen("/home/gsherman/development/qgis/plugins/" + pluginDir[i], RTLD_LAZY);
3962
std::cout << "Error in dlopen: " << dlerror() << std::endl;
3965
std::cout << "dlopen suceeded" << std::endl;
3970
bool loaded = myLib->load();
3974
std::cout << "Loaded test plugin library" << std::endl;
3975
std::cout << "Getting the name of the plugin" << std::endl;
3978
name_t *pName = (name_t *) myLib->resolve("name");
3981
QMessageBox::information(this, tr("Name"), tr("Plugin %1 is named %2").arg(pluginDir[i]).arg(pName()));
3984
std::cout << "Attempting to resolve the classFactory function" << std::endl;
3987
create_t *cf = (create_t *) myLib->resolve("classFactory");
3992
std::cout << "Getting pointer to a QgisPlugin object from the library\n";
3995
QgisPlugin *pl = cf(this, mQgisInterface);
3998
std::cout << "Displaying name, version, and description\n";
3999
std::cout << "Plugin name: " << pl->name().toLocal8Bit().data() << std::endl;
4000
std::cout << "Plugin version: " << pl->version().toLocal8Bit().data() << std::endl;
4001
std::cout << "Plugin description: " << pl->description().toLocal8Bit().data() << std::endl;
4004
QMessageBox::information(this, tr("Plugin Information"), tr("QGis loaded the following plugin:") +
4005
tr("Name: %1").arg(pl->name()) + "\n" + tr("Version: %1").arg(pl->version()) + "\n" +
4006
tr("Description: %1").arg(pl->description()));
4007
// unload the plugin (delete it)
4010
std::cout << "Attempting to resolve the unload function" << std::endl;
4013
unload_t *ul = (unload_t *) myLib.resolve("unload");
4016
std::cout << "Unloaded the plugin\n";
4018
std::cout << "Unable to resolve unload function. Plugin was not unloaded\n";
4025
QMessageBox::warning(this, tr("Unable to Load Plugin"),
4026
tr("QGIS was unable to load the plugin from: %1").arg(pluginDir[i]));
4029
std::cout << "Unable to load library" << std::endl;
4039
void QgisApp::checkQgisVersion()
4041
QApplication::setOverrideCursor(Qt::WaitCursor);
4042
/* QUrlOperator op = new QUrlOperator( "http://mrcc.com/qgis/version.txt" );
4043
connect(op, SIGNAL(data()), SLOT(urlData()));
4044
connect(op, SIGNAL(finished(QNetworkOperation)), SLOT(urlFinished(QNetworkOperation)));
4047
mSocket = new QTcpSocket(this);
4048
connect(mSocket, SIGNAL(connected()), SLOT(socketConnected()));
4049
connect(mSocket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()));
4050
connect(mSocket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
4051
connect(mSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4052
SLOT(socketError(QAbstractSocket::SocketError)));
4053
mSocket->connectToHost("mrcc.com", 80);
4056
void QgisApp::socketConnected()
4058
QTextStream os(mSocket);
4059
mVersionMessage = "";
4060
// send the qgis version string
4061
// os << qgisVersion << "\r\n";
4062
os << "GET /qgis/version.txt HTTP/1.0\n\n";
4067
void QgisApp::socketConnectionClosed()
4069
QApplication::restoreOverrideCursor();
4071
QString contentFlag = "#QGIS Version";
4072
int pos = mVersionMessage.find(contentFlag);
4075
pos += contentFlag.length();
4076
/* std::cout << mVersionMessage << "\n ";
4077
std::cout << "Pos is " << pos <<"\n"; */
4078
mVersionMessage = mVersionMessage.mid(pos);
4079
QStringList parts = QStringList::split("|", mVersionMessage);
4080
// check the version from the server against our version
4081
QString versionInfo;
4082
int currentVersion = parts[0].toInt();
4083
if (currentVersion > QGis::qgisVersionInt)
4085
// show version message from server
4086
versionInfo = tr("There is a new version of QGIS available") + "\n";
4090
if (QGis::qgisVersionInt > currentVersion)
4092
versionInfo = tr("You are running a development version of QGIS") + "\n";
4096
versionInfo = tr("You are running the current version of QGIS") + "\n";
4099
if (parts.count() > 1)
4101
versionInfo += parts[1] + "\n\n" + tr("Would you like more information?");
4103
int result = QMessageBox::information(this, tr("QGIS Version Information"), versionInfo, tr("Yes"), tr("No"));
4107
QgsMessageViewer *mv = new QgsMessageViewer(this);
4108
mv->setCaption(tr("QGIS - Changes in SVN Since Last Release"));
4109
mv->setMessageAsHtml(parts[2]);
4115
QMessageBox::information(this, tr("QGIS Version Information"), versionInfo);
4120
QMessageBox::warning(this, tr("QGIS Version Information"), tr("Unable to get current version information from server"));
4123
void QgisApp::socketError(QAbstractSocket::SocketError e)
4125
if (e == QAbstractSocket::RemoteHostClosedError)
4128
QApplication::restoreOverrideCursor();
4133
case QAbstractSocket::ConnectionRefusedError:
4134
detail = tr("Connection refused - server may be down");
4136
case QAbstractSocket::HostNotFoundError:
4137
detail = tr("QGIS server was not found");
4139
case QAbstractSocket::NetworkError:
4140
detail = tr("Network error while communicating with server");
4143
detail = tr("Unknown network socket error");
4147
// show version message from server
4148
QMessageBox::critical(this, tr("QGIS Version Information"), tr("Unable to communicate with QGIS Version server") + "\n" + detail);
4151
void QgisApp::socketReadyRead()
4153
while (mSocket->bytesAvailable() > 0)
4155
char *data = new char[mSocket->bytesAvailable() + 1];
4156
memset(data, '\0', mSocket->bytesAvailable() + 1);
4157
mSocket->readBlock(data, mSocket->bytesAvailable());
4158
mVersionMessage += data;
4163
void QgisApp::options()
4165
QgsOptions *optionsDialog = new QgsOptions(this);
4166
if(optionsDialog->exec())
4168
// set the theme if it changed
4169
setTheme(optionsDialog->theme());
4170
// set the visible flag for new layers
4171
mAddedLayersVisible = optionsDialog->newVisible();
4172
QSettings mySettings;
4173
mMapCanvas->enableAntiAliasing(mySettings.value("/qgis/enable_anti_aliasing").toBool());
4174
mMapCanvas->useQImageToRender(mySettings.value("/qgis/use_qimage_to_render").toBool());
4176
int action = mySettings.value("/qgis/wheel_action", 0).toInt();
4177
double zoomFactor = mySettings.value("/qgis/zoom_factor", 2).toDouble();
4178
mMapCanvas->setWheelAction((QgsMapCanvas::WheelAction) action, zoomFactor);
4180
bool splitterRedraw = mySettings.value("/qgis/splitterRedraw", true).toBool();
4181
canvasLegendSplit->setOpaqueResize(splitterRedraw);
4182
legendOverviewSplit->setOpaqueResize(splitterRedraw);
4186
void QgisApp::helpContents()
4188
openURL("index.html");
4191
void QgisApp::helpQgisHomePage()
4193
openURL("http://qgis.org", false);
4196
void QgisApp::openURL(QString url, bool useQgisDocDirectory)
4198
// open help in user browser
4199
if (useQgisDocDirectory)
4201
url = "file://" +QgsApplication::pkgDataPath() + "/doc/" + url;
4204
/* Use Mac OS X Launch Services which uses the user's default browser
4205
* and will just open a new window if that browser is already running.
4206
* QProcess creates a new browser process for each invocation and expects a
4207
* commandline application rather than a bundled application.
4209
CFURLRef urlRef = CFURLCreateWithBytes(kCFAllocatorDefault,
4210
reinterpret_cast<const UInt8*>(url.utf8().data()), url.length(),
4211
kCFStringEncodingUTF8, NULL);
4212
OSStatus status = LSOpenCFURLRef(urlRef, NULL);
4217
QString browser = settings.readEntry("/qgis/browser");
4218
if (browser.length() == 0)
4220
// ask user for browser and use it
4222
QString myHeading = tr("QGIS Browser Selection");
4223
QString myMessage = tr("Enter the name of a web browser to use (eg. konqueror).\n");
4224
myMessage += tr("Enter the full path if the browser is not in your PATH.\n");
4225
myMessage += tr("You can change this option later by selecting Options from the Settings menu (Help Browser tab).");
4226
QString text = QInputDialog::getText(myHeading,
4229
QString::null, &ok, this);
4230
if (ok && !text.isEmpty())
4232
// user entered something and pressed OK
4235
settings.writeEntry("/qgis/browser", browser);
4243
if (browser.length() > 0)
4245
// find the installed location of the help files
4246
// open index.html using browser
4247
//XXX for debug on win32 QMessageBox::information(this,"Help opening...", browser + " - " + url);
4248
QProcess *helpProcess = new QProcess(this);
4251
helpProcess->start(browser,myArgs);
4253
/* mHelpViewer = new QgsHelpViewer(this,"helpviewer",false);
4254
mHelpViewer->showContent(mAppDir +"/share/doc","index.html");
4255
mHelpViewer->show(); */
4259
/** Get a pointer to the currently selected map layer */
4260
QgsMapLayer *QgisApp::activeLayer()
4262
return (mMapLegend->currentLayer());
4265
QString QgisApp::activeLayerSource()
4268
QgsMapLayer* layer = mMapLegend->currentLayer();
4271
return (layer->source());
4276
/** Add a vector layer directly without prompting user for location
4277
The caller must provide information compatible with the provider plugin
4278
using the vectorLayerPath and baseName. The provider can use these
4279
parameters in any way necessary to initialize the layer. The baseName
4280
parameter is used in the Map Legend so it should be formed in a meaningful
4283
void QgisApp::addVectorLayer(QString vectorLayerPath, QString baseName, QString providerKey)
4285
mMapCanvas->freeze();
4287
// Let render() do its own cursor management
4288
// QApplication::setOverrideCursor(Qt::WaitCursor);
4291
QgsVectorLayer *layer;
4292
/* Eliminate the need to instantiate the layer based on provider type.
4293
The caller is responsible for cobbling together the needed information to
4298
std::cout << "Creating new vector layer using " <<
4299
vectorLayerPath.toLocal8Bit().data() << " with baseName of " << baseName.toLocal8Bit().data() <<
4300
" and providerKey of " << providerKey.toLocal8Bit().data() << std::endl;
4303
layer = new QgsVectorLayer(vectorLayerPath, baseName, providerKey);
4305
if( layer && layer->isValid() )
4307
// Register this layer with the layers registry
4308
QgsMapLayerRegistry::instance()->addMapLayer(layer);
4309
// init the context menu so it can connect to slots in main app
4310
// now taken care of in legend layer->initContextMenu(this);
4312
// give it a random color
4313
QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer(layer->vectorType()); //add single symbol renderer as default
4314
layer->setRenderer(renderer);
4315
layer->refreshLegend();
4316
// add it to the mapcanvas collection
4317
// mMapCanvas->addLayer(layer); No longer necessary since adding to registry will add to canvas
4319
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
4321
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
4323
QObject::connect(this,
4324
SIGNAL(keyPressed(QKeyEvent * )),
4326
SLOT(keyPressed(QKeyEvent* )));
4328
QgsProject::instance()->dirty(false); // XXX this might be redundant
4330
statusBar()->message(mMapCanvas->extent().stringRep(2));
4335
QMessageBox::critical(this,tr("Layer is not valid"),
4336
tr("The layer is not a valid layer and can not be added to the map"));
4338
qApp->processEvents();
4339
mMapCanvas->freeze(false);
4340
mMapCanvas->refresh();
4342
// Let render() do its own cursor management
4343
// QApplication::restoreOverrideCursor();
4345
} // QgisApp::addVectorLayer
4349
void QgisApp::addMapLayer(QgsMapLayer *theMapLayer)
4351
mMapCanvas->freeze();
4353
// Let render() do its own cursor management
4354
// QApplication::setOverrideCursor(Qt::WaitCursor);
4356
if(theMapLayer->isValid())
4358
// Register this layer with the layers registry
4359
QgsMapLayerRegistry::instance()->addMapLayer(theMapLayer);
4360
// init the context menu so it can connect to slots in main app
4361
// XXX now taken care of in legend theMapLayer->initContextMenu(this);
4362
// add it to the mapcanvas collection
4363
// not necessary since adding to registry adds to canvas mMapCanvas->addLayer(theMapLayer);
4365
statusBar()->message(mMapCanvas->extent().stringRep(2));
4370
QMessageBox::critical(this,tr("Layer is not valid"),
4371
tr("The layer is not a valid layer and can not be added to the map"));
4373
qApp->processEvents();
4374
mMapCanvas->freeze(false);
4375
mMapCanvas->refresh();
4377
// Let render() do its own cursor management
4378
// QApplication::restoreOverrideCursor();
4382
void QgisApp::setExtent(QgsRect theRect)
4384
mMapCanvas->setExtent(theRect);
4390
int QgisApp::saveDirty()
4393
mMapCanvas->freeze(true);
4397
std::cout << "Layer count is " << mMapCanvas->layerCount() << std::endl;
4398
std::cout << "Project is ";
4399
if ( QgsProject::instance()->dirty() )
4401
std::cout << "dirty" << std::endl;
4405
std::cout << "not dirty" << std::endl;
4408
std::cout << "Map canvas is ";
4409
if (mMapCanvas->isDirty())
4411
std::cout << "dirty" << std::endl;
4415
std::cout << "not dirty" << std::endl;
4419
if ((QgsProject::instance()->dirty() || (mMapCanvas->isDirty()) && mMapCanvas->layerCount() > 0))
4421
// flag project as dirty since dirty state of canvas is reset if "dirty"
4422
// is based on a zoom or pan
4423
QgsProject::instance()->dirty( true );
4424
// old code: mProjectIsDirtyFlag = true;
4426
// prompt user to save
4427
answer = QMessageBox::information(this, tr("Save?"),
4428
tr("<p>Do you want to save the current project?</p>"),
4429
QMessageBox::Yes | QMessageBox::Default,
4431
QMessageBox::Cancel | QMessageBox::Escape);
4432
if (QMessageBox::Yes == answer )
4435
answer = QMessageBox::Cancel;
4439
mMapCanvas->freeze(false);
4443
} // QgisApp::saveDirty()
4446
void QgisApp::closeEvent(QCloseEvent* event)
4448
// We'll close in our own good time, thank you very much
4450
// Do the usual checks and ask if they want to save, etc
4455
void QgisApp::whatsThis()
4457
QWhatsThis::enterWhatsThisMode();
4458
} // QgisApp::whatsThis()
4461
std::map<QString, int> QgisApp::menuMapByName()
4463
// Must populate the maps with each call since menus might have been
4466
// Return the menu items mapped by name (key is name, value is menu id)
4467
return mMenuMapByName;
4469
std::map<int, QString> QgisApp::menuMapById()
4471
// Must populate the maps with each call since menus might have been
4474
// Return the menu items mapped by menu id (key is menu id, value is name)
4475
return mMenuMapById;
4477
void QgisApp::populateMenuMaps()
4479
// Populate the two menu maps by iterating through the menu bar
4480
mMenuMapByName.clear();
4481
mMenuMapById.clear();
4484
// Loop until we get an id of -1, which indicates there are no more
4488
menuId = menuBar()->idAt(idx++);
4489
std::cout << "Menu id " << menuId << " is " << menuBar()->text(menuId).toLocal8Bit().data() << std::endl;
4490
mMenuMapByName[menuBar()->text(menuId)] = menuId;
4491
mMenuMapById[menuId] = menuBar()->text(menuId);
4493
while(menuId != -1);
4496
QMenu* QgisApp::getPluginMenu(QString menuName)
4498
// This is going to record the menu item that the potentially new
4499
// menu item is going to be inserted before. A value of 0 will a new
4500
// menu item to be appended.
4501
QAction* before = 0;
4503
QList<QAction*> actions = mPluginMenu->actions();
4504
// Avoid 1 because the first item (number 0) is 'Plugin Manager',
4505
// which we want to stay first. Search in reverse order as that
4506
// makes it easier to find out where which item a new menu item
4507
// should go before (since the insertMenu() function requires a
4508
// 'before' argument).
4509
for (unsigned int i = actions.count()-1; i > 0; --i)
4511
if (actions.at(i)->text() == menuName)
4513
return actions.at(i)->menu();
4515
// Find out where to put the menu item, assuming that it is a new one
4517
// This bit of code assumes that the menu items are already in
4518
// alphabetical order, which they will be if the menus are all
4519
// created using this function.
4520
if (menuName.localeAwareCompare(actions.at(i)->text()) <= 0)
4521
before = actions.at(i);
4524
// It doesn't exist, so create
4525
QMenu* menu = new QMenu(menuName, this);
4526
// Where to put it? - we worked that out above...
4527
mPluginMenu->insertMenu(before, menu);
4532
void QgisApp::addPluginMenu(QString name, QAction* action)
4534
QMenu* menu = getPluginMenu(name);
4535
menu->addAction(action);
4538
void QgisApp::removePluginMenu(QString name, QAction* action)
4540
QMenu* menu = getPluginMenu(name);
4541
menu->removeAction(action);
4542
if (menu->actions().count() == 0)
4544
mPluginMenu->removeAction(menu->menuAction());
4548
int QgisApp::addPluginToolBarIcon (QAction * qAction)
4550
qAction->addTo(mPluginToolBar);
4553
void QgisApp::removePluginToolBarIcon(QAction *qAction)
4555
qAction->removeFrom(mPluginToolBar);
4558
void QgisApp::projectionsEnabled(bool theFlag)
4560
QString myIconPath = QgsApplication::themePath();
4563
QPixmap myProjPixmap;
4564
myProjPixmap.load(myIconPath+"/mIconProjectionEnabled.png");
4565
//assert(!myProjPixmap.isNull());
4566
mOnTheFlyProjectionStatusButton->setPixmap(myProjPixmap);
4570
QPixmap myProjPixmap;
4571
myProjPixmap.load(myIconPath+"/mIconProjectionDisabled.png");
4572
//assert(!myProjPixmap.isNull());
4573
mOnTheFlyProjectionStatusButton->setPixmap(myProjPixmap);
4576
// slot to update the progress bar in the status bar
4577
void QgisApp::showProgress(int theProgress, int theTotalSteps)
4580
std::cout << "showProgress called with " << theProgress << "/" << theTotalSteps << std::endl;
4583
if (theProgress==theTotalSteps)
4585
mProgressBar->reset();
4586
mProgressBar->hide();
4590
//only call show if not already hidden to reduce flicker
4591
if (!mProgressBar->isVisible())
4593
mProgressBar->show();
4595
mProgressBar->setMaximum(theTotalSteps);
4596
mProgressBar->setValue(theProgress);
4602
void QgisApp::showExtents(QgsRect theExtents)
4604
// update the statusbar with the current extents.
4605
statusBar()->message(QString(tr("Extents: ")) + theExtents.stringRep(true));
4607
} // QgisApp::showExtents
4610
void QgisApp::updateMouseCoordinatePrecision()
4612
// Work out what mouse display precision to use. This only needs to
4613
// be when the settings change or the zoom level changes. This
4614
// function needs to be called every time one of the above happens.
4616
// Get the display precision from the project settings
4617
bool automatic = QgsProject::instance()->readBoolEntry("PositionPrecision","/Automatic");
4622
// Work out a suitable number of decimal places for the mouse
4623
// coordinates with the aim of always having enough decimal places
4624
// to show the difference in position between adjacent pixels.
4625
// Also avoid taking the log of 0.
4626
if (getMapCanvas()->mupp() != 0.0)
4627
dp = static_cast<int> (ceil(-1.0*log10(getMapCanvas()->mupp())));
4630
dp = QgsProject::instance()->readNumEntry("PositionPrecision","/DecimalPlaces");
4635
mMousePrecisionDecimalPlaces = dp;
4638
void QgisApp::showStatusMessage(QString theMessage)
4641
// std::cout << "QgisApp::showStatusMessage: entered with '" << theMessage << "'." << std::endl;
4644
statusBar()->message(theMessage);
4647
void QgisApp::projectPropertiesProjections()
4649
// Driver to display the project props dialog and switch to the
4651
mShowProjectionTab = true;
4652
projectProperties();
4655
void QgisApp::projectProperties()
4657
/* Display the property sheet for the Project */
4658
// set wait cursor since construction of the project properties
4659
// dialog results in the construction of the spatial reference
4661
QApplication::setOverrideCursor(Qt::WaitCursor);
4662
QgsProjectProperties *pp = new QgsProjectProperties(this);
4663
// if called from the status bar, show the projection tab
4664
if(mShowProjectionTab)
4666
pp->showProjectionsTab();
4667
mShowProjectionTab = false;
4669
qApp->processEvents();
4670
// Be told if the mouse display precision may have changed by the user
4671
// changing things in the project properties dialog box
4672
connect(pp, SIGNAL(displayPrecisionChanged()), this,
4673
SLOT(updateMouseCoordinatePrecision()));
4674
//listen to changes in on the fly projection state
4675
connect(pp, SIGNAL(projectionEnabled(bool)), this,
4676
SLOT(projectionsEnabled(bool)));
4677
QApplication::restoreOverrideCursor();
4678
//pass any refresg signals off to canvases
4679
//connect (pp,SIGNAL(refresh()), mMapCanvas, SLOT(refresh()));
4680
connect (pp,SIGNAL(mapUnitsChanged()), mMapCanvas, SLOT(mapUnitsChanged()));
4682
bool wasProjected = pp->isProjected();
4683
long oldSRSID = QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectSRSID",GEOSRS_ID);
4685
// Display the modal dialog box.
4688
long newSRSID = QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectSRSID",GEOSRS_ID);
4690
// projections have been turned on/off or dest SRS has changed while projections are on
4691
if (wasProjected != pp->isProjected() || (pp->isProjected() && oldSRSID != newSRSID))
4693
mMapCanvas->updateFullExtent();
4696
int myRedInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorRedPart",255);
4697
int myGreenInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorGreenPart",255);
4698
int myBlueInt = QgsProject::instance()->readNumEntry("Gui","/CanvasColorBluePart",255);
4699
QColor myColor = QColor(myRedInt,myGreenInt,myBlueInt);
4700
mMapCanvas->setCanvasColor(myColor); // this is fill colour before rendering onto canvas
4702
// Set the window title.
4703
setTitleBarText_( *this );
4705
// delete the property sheet object
4707
} // QgisApp::projectProperties
4710
QgsMapLayerRegistry * QgisApp::getLayerRegistry()
4712
return QgsMapLayerRegistry::instance();
4718
QgsClipboard * QgisApp::clipboard()
4720
return &mInternalClipboard;
4723
void QgisApp::activateDeactivateLayerRelatedActions(const QgsMapLayer* layer)
4730
/***********Vector layers****************/
4731
if(layer->type() == QgsMapLayer::VECTOR || layer->type() == QgsMapLayer::DATABASE)
4733
mActionSelect->setEnabled(true);
4734
mActionOpenTable->setEnabled(true);
4735
mActionIdentify->setEnabled(true);
4736
mActionEditCopy->setEnabled(true);
4738
const QgsVectorLayer* vlayer = dynamic_cast<const QgsVectorLayer*>(layer);
4739
const QgsVectorDataProvider* dprovider = vlayer->getDataProvider();
4743
//start editing/stop editing
4744
if(dprovider->capabilities() & QgsVectorDataProvider::AddFeatures)
4746
mActionStartEditing->setEnabled(true);
4747
mActionStopEditing->setEnabled(true);
4748
mActionEditPaste->setEnabled(true);
4752
mActionStartEditing->setEnabled(false);
4753
mActionStopEditing->setEnabled(false);
4754
mActionEditPaste->setEnabled(false);
4757
//does provider allow deleting of features?
4758
if(dprovider->capabilities() & QgsVectorDataProvider::DeleteFeatures)
4760
mActionDeleteSelected->setEnabled(true);
4761
mActionEditCut->setEnabled(true);
4765
mActionDeleteSelected->setEnabled(false);
4766
mActionEditCut->setEnabled(false);
4770
if(vlayer->vectorType() == QGis::Point)
4772
if(dprovider->capabilities() & QgsVectorDataProvider::AddFeatures)
4774
mActionCapturePoint->setEnabled(true);
4778
mActionCapturePoint->setEnabled(false);
4780
mActionCaptureLine->setEnabled(false);
4781
mActionCapturePolygon->setEnabled(false);
4782
mActionAddVertex->setEnabled(false);
4783
mActionDeleteVertex->setEnabled(false);
4784
if(dprovider->capabilities() & QgsVectorDataProvider::ChangeGeometries)
4786
mActionMoveVertex->setEnabled(true);
4790
else if(vlayer->vectorType() == QGis::Line)
4792
if(dprovider->capabilities() & QgsVectorDataProvider::AddFeatures)
4794
mActionCaptureLine->setEnabled(true);
4798
mActionCaptureLine->setEnabled(false);
4800
mActionCapturePoint->setEnabled(false);
4801
mActionCapturePolygon->setEnabled(false);
4803
else if(vlayer->vectorType() == QGis::Polygon)
4805
if(dprovider->capabilities() & QgsVectorDataProvider::AddFeatures)
4807
mActionCapturePolygon->setEnabled(true);
4811
mActionCapturePolygon->setEnabled(false);
4813
mActionCapturePoint->setEnabled(false);
4814
mActionCaptureLine->setEnabled(false);
4817
//are add/delete/move vertex supported?
4818
if(dprovider->capabilities() & QgsVectorDataProvider::ChangeGeometries)
4820
mActionAddVertex->setEnabled(true);
4821
mActionMoveVertex->setEnabled(true);
4822
mActionDeleteVertex->setEnabled(true);
4826
mActionAddVertex->setEnabled(false);
4827
mActionMoveVertex->setEnabled(false);
4828
mActionDeleteVertex->setEnabled(false);
4833
/*************Raster layers*************/
4834
else if(layer->type() == QgsMapLayer::RASTER)
4836
mActionSelect->setEnabled(false);
4837
mActionOpenTable->setEnabled(false);
4838
mActionStartEditing->setEnabled(false);
4839
mActionStopEditing->setEnabled(false);
4840
mActionCapturePoint->setEnabled(false);
4841
mActionCaptureLine->setEnabled(false);
4842
mActionCapturePolygon->setEnabled(false);
4843
mActionDeleteSelected->setEnabled(false);
4844
mActionAddVertex->setEnabled(false);
4845
mActionDeleteVertex->setEnabled(false);
4846
mActionMoveVertex->setEnabled(false);
4847
mActionEditCopy->setEnabled(false);
4848
mActionEditCut->setEnabled(false);
4849
mActionEditPaste->setEnabled(false);
4851
const QgsRasterLayer* vlayer = dynamic_cast<const QgsRasterLayer*> (layer);
4852
const QgsRasterDataProvider* dprovider = vlayer->getDataProvider();
4855
// does provider allow the identify map tool?
4856
if (dprovider->capabilities() & QgsRasterDataProvider::Identify)
4858
mActionIdentify->setEnabled(TRUE);
4862
mActionIdentify->setEnabled(FALSE);
4869
//copy the click coord to clipboard and let the user know its there
4870
void QgisApp::showCapturePointCoordinate(QgsPoint & theQgsPoint)
4873
std::cout << "Capture point (clicked on map) at position " << theQgsPoint.stringRep(2).toLocal8Bit().data() << std::endl;
4876
QClipboard *myClipboard = QApplication::clipboard();
4877
//if we are on x11 system put text into selection ready for middle button pasting
4878
if (myClipboard->supportsSelection())
4880
myClipboard->setText(theQgsPoint.stringRep(2),QClipboard::Selection);
4881
QString myMessage = tr("Clipboard contents set to: ");
4882
statusBar()->message(myMessage + myClipboard->text(QClipboard::Selection));
4886
//user has an inferior operating system....
4887
myClipboard->setText(theQgsPoint.stringRep(2),QClipboard::Clipboard );
4888
QString myMessage = tr("Clipboard contents set to: ");
4889
statusBar()->message(myMessage + myClipboard->text(QClipboard::Clipboard));
4892
/* Well use this in ver 0.5 when we do digitising! */
4894
QgsVectorFileWriter myFileWriter("/tmp/test.shp", wkbPoint);
4895
if (myFileWriter.initialise())
4897
myFileWriter.createField("TestInt",OFTInteger,8,0);
4898
myFileWriter.createField("TestRead",OFTReal,8,3);
4899
myFileWriter.createField("TestStr",OFTString,255,0);
4900
myFileWriter.writePoint(&theQgsPoint);
4908
/////////////////////////////////////////////////////////////////
4911
// Only functions relating to raster layer management in this
4912
// section (look for a similar comment block to this to find
4913
// the end of this section).
4918
/////////////////////////////////////////////////////////////////
4921
/** @todo XXX I'd *really* like to return, ya know, _false_.
4923
//create a raster layer object and delegate to addRasterLayer(QgsRasterLayer *)
4924
void QgisApp::addRasterLayer()
4926
//mMapCanvas->freeze(true);
4928
QString fileFilters;
4931
QStringList selectedFiles;
4932
QString e;//only for parameter correctness
4933
QString title = tr("Open a GDAL Supported Raster Data Source");
4934
openFilesRememberingFilter_("lastRasterFileFilter", mRasterFileFilter, selectedFiles,e,
4937
if (selectedFiles.isEmpty())
4939
// no files were selected, so just bail
4943
addRasterLayer(selectedFiles);
4944
mMapCanvas->freeze(false);
4945
mMapCanvas->refresh();
4946
}// QgisApp::addRasterLayer()
4949
// This is the method that does the actual work of adding a raster layer - the others
4950
// here simply create a raster layer object and delegate here. It is the responsibility
4951
// of the calling method to manage things such as the frozen state of the mapcanvas and
4952
// using waitcursors etc. - this method wont and SHOULDNT do it
4954
bool QgisApp::addRasterLayer(QgsRasterLayer * theRasterLayer, bool theForceRedrawFlag)
4957
Q_CHECK_PTR( theRasterLayer );
4959
if ( ! theRasterLayer )
4961
// XXX insert meaningful whine to the user here; although be
4962
// XXX mindful that a null layer may mean exhausted memory resources
4966
if (theRasterLayer->isValid())
4968
// register this layer with the central layers registry
4969
QgsMapLayerRegistry::instance()->addMapLayer(theRasterLayer);
4970
theRasterLayer->refreshLegend();
4971
// XXX doesn't the mMapCanvas->addLayer() do this?
4973
// QObject::connect(theRasterLayer,
4974
// SIGNAL(repaintRequested()),
4976
// SLOT(refresh()));
4978
// connect up any request the raster may make to update the app progress
4979
QObject::connect(theRasterLayer,
4980
SIGNAL(drawingProgress(int,int)),
4982
SLOT(showProgress(int,int)));
4983
// connect up any request the raster may make to update the statusbar message
4984
QObject::connect(theRasterLayer,
4985
SIGNAL(setStatus(QString)),
4987
SLOT(showStatusMessage(QString)));
4988
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
4990
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
4992
QObject::connect(this ,
4993
SIGNAL(keyPressed(QKeyEvent * )),
4995
SLOT(keyPressed(QKeyEvent* )));
4997
// init the context menu so it can connect to slots in main app
4998
// XXX now taken care of in legend theRasterLayer->initContextMenu(this);
5000
// add it to the mapcanvas collection
5001
// no longer necessary since adding to registry automatically adds to canvas
5002
// mMapCanvas->addLayer(theRasterLayer);
5007
delete theRasterLayer;
5011
if (theForceRedrawFlag)
5013
qApp->processEvents();
5014
mMapCanvas->freeze(false);
5015
mMapCanvas->refresh();
5022
//create a raster layer object and delegate to addRasterLayer(QgsRasterLayer *)
5024
bool QgisApp::addRasterLayer(QFileInfo const & rasterFile, bool guiWarning)
5026
// let the user know we're going to possibly be taking a while
5027
QApplication::setOverrideCursor(Qt::WaitCursor);
5029
mMapCanvas->freeze(true);
5031
// XXX ya know QgsRasterLayer can snip out the basename on its own;
5032
// XXX why do we have to pass it in for it?
5033
QgsRasterLayer *layer =
5034
new QgsRasterLayer(rasterFile.filePath(), rasterFile.completeBaseName());
5036
if (!addRasterLayer(layer))
5038
mMapCanvas->freeze(false);
5039
QApplication::restoreOverrideCursor();
5041
// Let render() do its own cursor management
5042
// QApplication::restoreOverrideCursor();
5046
// don't show the gui warning (probably because we are loading from command line)
5047
QString msg(rasterFile.completeBaseName()
5048
+ tr(" is not a valid or recognized raster data source"));
5049
QMessageBox::critical(this, tr("Invalid Data Source"), msg);
5056
statusBar()->message(mMapCanvas->extent().stringRep(2));
5057
layer->refreshLegend();
5058
mMapCanvas->freeze(false);
5059
QApplication::restoreOverrideCursor();
5061
// Let render() do its own cursor management
5062
// QApplication::restoreOverrideCursor();
5067
} // QgisApp::addRasterLayer
5071
/** Add a raster layer directly without prompting user for location
5072
The caller must provide information compatible with the provider plugin
5073
using the rasterLayerPath and baseName. The provider can use these
5074
parameters in any way necessary to initialize the layer. The baseName
5075
parameter is used in the Map Legend so it should be formed in a meaningful
5078
\note Copied from the equivalent addVectorLayer function in this file
5079
TODO Make it work for rasters specifically.
5081
void QgisApp::addRasterLayer(QString const & rasterLayerPath,
5082
QString const & baseName,
5083
QString const & providerKey,
5084
QStringList const & layers,
5085
QStringList const & styles,
5086
QString const & format,
5087
QString const & crs,
5088
QString const & proxyHost,
5090
QString const & proxyUser,
5091
QString const & proxyPassword)
5095
std::cout << "QgisApp::addRasterLayer: about to get library for " << providerKey.toLocal8Bit().data() << std::endl;
5098
mMapCanvas->freeze();
5100
// Let render() do its own cursor management
5101
// QApplication::setOverrideCursor(Qt::WaitCursor);
5104
QgsRasterLayer *layer;
5105
/* Eliminate the need to instantiate the layer based on provider type.
5106
The caller is responsible for cobbling together the needed information to
5111
std::cout << "QgisApp::addRasterLayer: Creating new raster layer using " <<
5112
rasterLayerPath.toLocal8Bit().data() << " with baseName of " << baseName.toLocal8Bit().data() <<
5113
" and layer list of " << layers.join(", ").toLocal8Bit().data() <<
5114
" and style list of " << styles.join(", ").toLocal8Bit().data() <<
5115
" and format of " << format.toLocal8Bit().data() <<
5116
" and providerKey of " << providerKey.toLocal8Bit().data() <<
5117
" and CRS of " << crs.toLocal8Bit().data() << std::endl;
5120
// TODO: Remove the 0 when the raster layer becomes a full provider gateway.
5121
layer = new QgsRasterLayer(0, rasterLayerPath, baseName, providerKey, layers, styles, format, crs,
5122
proxyHost, proxyPort, proxyUser, proxyPassword);
5125
std::cout << "QgisApp::addRasterLayer: Constructed new layer." << std::endl;
5128
if( layer && layer->isValid() )
5130
// Register this layer with the layers registry
5131
QgsMapLayerRegistry::instance()->addMapLayer(layer);
5132
// init the context menu so it can connect to slots in main app
5133
// now taken care of in legend layer->initContextMenu(this);
5135
// connect up any request the raster may make to update the app progress
5136
QObject::connect(layer,
5137
SIGNAL(drawingProgress(int,int)),
5139
SLOT(showProgress(int,int)));
5140
// connect up any request the raster may make to update the statusbar message
5141
QObject::connect(layer,
5142
SIGNAL(setStatus(QString)),
5144
SLOT(showStatusMessage(QString)));
5146
// connect up any keypresses to be passed tot he layer (e.g. so esc can stop rendering)
5148
std::cout << " Connecting up maplayers keyPressed event to the QgisApp keyPress signal" << std::endl;
5150
QObject::connect(this,
5151
SIGNAL(keyPressed(QKeyEvent * )),
5153
SLOT(keyPressed(QKeyEvent* )));
5155
QgsProject::instance()->dirty(false); // XXX this might be redundant
5157
statusBar()->message(mMapCanvas->extent().stringRep(2));
5162
QMessageBox::critical(this,tr("Layer is not valid"),
5163
tr("The layer is not a valid layer and can not be added to the map"));
5166
qApp->processEvents();
5167
mMapCanvas->freeze(false);
5168
mMapCanvas->refresh();
5170
// Let render() do its own cursor management
5171
// QApplication::restoreOverrideCursor();
5173
} // QgisApp::addRasterLayer
5177
//create a raster layer object and delegate to addRasterLayer(QgsRasterLayer *)
5178
bool QgisApp::addRasterLayer(QStringList const &theFileNameQStringList, bool guiWarning)
5180
if (theFileNameQStringList.empty())
5182
// no files selected so bail out, but
5183
// allow mMapCanvas to handle events
5185
mMapCanvas->freeze(false);
5189
mMapCanvas->freeze(true);
5191
// Let render() do its own cursor management
5192
// QApplication::setOverrideCursor(Qt::WaitCursor);
5194
// this is messy since some files in the list may be rasters and others may
5195
// be ogr layers. We'll set returnValue to false if one or more layers fail
5197
bool returnValue = true;
5198
for (QStringList::ConstIterator myIterator = theFileNameQStringList.begin();
5199
myIterator != theFileNameQStringList.end();
5202
if (QgsRasterLayer::isValidRasterFileName(*myIterator))
5204
QFileInfo myFileInfo(*myIterator);
5205
// get the directory the .adf file was in
5206
QString myDirNameQString = myFileInfo.dirPath();
5207
QString myBaseNameQString = myFileInfo.completeBaseName();
5208
//only allow one copy of a ai grid file to be loaded at a
5209
//time to prevent the user selecting all adfs in 1 dir which
5210
//actually represent 1 coverage,
5213
QgsRasterLayer *layer = new QgsRasterLayer(*myIterator, myBaseNameQString);
5215
// set initial visibility based on user preference
5216
layer->setVisible(mAddedLayersVisible);
5218
addRasterLayer(layer);
5220
//only allow one copy of a ai grid file to be loaded at a
5221
//time to prevent the user selecting all adfs in 1 dir which
5222
//actually represent 1 coverate,
5224
if (myBaseNameQString.lower().endsWith(".adf"))
5231
// Issue message box warning unless we are loading from cmd line since
5232
// non-rasters are passed to this function first and then sucessfully
5233
// loaded afterwards (see main.cpp)
5237
QString msg(*myIterator + tr(" is not a supported raster data source"));
5238
QMessageBox::critical(this, tr("Unsupported Data Source"), msg);
5240
returnValue = false;
5244
statusBar()->message(mMapCanvas->extent().stringRep(2));
5245
mMapCanvas->freeze(false);
5247
// Let render() do its own cursor management
5248
// QApplication::restoreOverrideCursor();
5252
}// QgisApp::addRasterLayer()
5257
///////////////////////////////////////////////////////////////////
5262
// RASTER ONLY RELATED FUNCTIONS BLOCK ENDS....
5267
///////////////////////////////////////////////////////////////////
5270
void QgisApp::keyPressEvent ( QKeyEvent * e )
5272
// The following statment causes a crash on WIN32 and should be
5273
// enclosed in an #ifdef QGISDEBUG if its really necessary. Its
5274
// commented out for now. [gsherman]
5275
// std::cout << e->text().toLocal8Bit().data() << " (keypress recevied)" << std::endl;
5276
emit keyPressed (e);
5280
// Debug hook - used to output diagnostic messages when evoked (usually from the menu)
5281
/* Temporarily disabled...
5282
void QgisApp::debugHook()
5284
std::cout << "Hello from debug hook" << std::endl;
5285
// show the map canvas extent
5286
std::cout << mMapCanvas->extent() << std::endl;
5289
void QgisApp::customProjection()
5291
// Create an instance of the Custom Projection Designer modeless dialog.
5292
// Autodelete the dialog when closing since a pointer is not retained.
5293
QgsCustomProjectionDialog * myDialog = new QgsCustomProjectionDialog(this,
5294
Qt::WDestructiveClose);
5297
void QgisApp::showBookmarks()
5299
// Create or show the single instance of the Bookmarks modeless dialog.
5300
// Closing a QWidget only hides it so it can be shown again later.
5301
static QgsBookmarks *bookmarks = NULL;
5302
if (bookmarks == NULL)
5304
bookmarks = new QgsBookmarks(this, Qt::WindowMinMaxButtonsHint);
5308
bookmarks->setActiveWindow();
5311
void QgisApp::newBookmark()
5313
// Get the name for the bookmark. Everything else we fetch from
5317
QString bookmarkName = QInputDialog::getText(tr("New Bookmark"),
5318
tr("Enter a name for the new bookmark:"), QLineEdit::Normal,
5319
QString::null, &ok, this);
5320
if( ok && !bookmarkName.isEmpty())
5324
// create the bookmark
5325
QgsBookmarkItem *bmi = new QgsBookmarkItem(bookmarkName,
5326
QgsProject::instance()->title(), mMapCanvas->extent(), -1,
5327
QgsApplication::qgisUserDbFilePath());
5330
// emit a signal to indicate that the bookmark was added
5331
emit bookmarkAdded();
5335
QMessageBox::warning(this,tr("Error"), tr("Unable to create the bookmark. Your user database may be missing or corrupted"));
5340
void QgisApp::showAllToolbars()
5342
setToolbarVisibility(true);
5345
void QgisApp::hideAllToolbars()
5347
setToolbarVisibility(false);
5350
void QgisApp::setToolbarVisibility(bool visibility)
5352
mFileToolBar->setVisible(visibility);
5353
mLayerToolBar->setVisible(visibility);
5354
mMapNavToolBar->setVisible(visibility);
5355
mDigitizeToolBar->setVisible(visibility);
5356
mAttributesToolBar->setVisible(visibility);
5357
mPluginToolBar->setVisible(visibility);
5358
mHelpToolBar->setVisible(visibility);