void GlobePlugin::syncExtent() { QgsMapCanvas* mapCanvas = mQGisIface->mapCanvas(); QgsMapRenderer* mapRenderer = mapCanvas->mapRenderer(); QgsRectangle extent = mapCanvas->extent(); osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>( mOsgViewer->getCameraManipulator() ); //rotate earth to north and perpendicular to camera manip->setRotation( osg::Quat() ); QgsDistanceArea dist; dist.setSourceCrs( mapRenderer->destinationCrs().srsid() ); dist.setEllipsoidalMode( mapRenderer->hasCrsTransformEnabled() ); dist.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); QgsPoint ll = QgsPoint( extent.xMinimum(), extent.yMinimum() ); QgsPoint ul = QgsPoint( extent.xMinimum(), extent.yMaximum() ); double height = dist.measureLine( ll, ul ); //camera viewing angle double viewAngle = 30; //camera distance double distance = height / tan( viewAngle * osg::PI / 180 ); //c = b*cotan(B(rad)) OE_NOTICE << "map extent: " << height << " camera distance: " << distance << std::endl; osgEarth::Util::Viewpoint viewpoint( osg::Vec3d( extent.center().x(), extent.center().y(), 0.0 ), 0.0, -90.0, distance ); manip->setViewpoint( viewpoint, 4.0 ); }
void QgsOsgEarthTileSource::initialize( const std::string& referenceURI, const Profile* overrideProfile ) { Q_UNUSED( referenceURI ); Q_UNUSED( overrideProfile ); setProfile( osgEarth::Registry::instance()->getGlobalGeodeticProfile() ); QgsCoordinateReferenceSystem destCRS; destCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ); QgsMapCanvas *c = mQGisIface->mapCanvas(); if ( c->mapSettings().destinationCrs().authid().compare( GEO_EPSG_CRS_AUTHID, Qt::CaseInsensitive ) != 0 ) { // FIXME: crs from canvas or first layer? QgsCoordinateReferenceSystem srcCRS( c->mapSettings().destinationCrs() ); QgsDebugMsg( QString( "transforming from %1 to %2" ).arg( srcCRS.authid() ).arg( destCRS.authid() ) ); mCoordTransform = new QgsCoordinateTransform( srcCRS, destCRS ); } else { mCoordTransform = 0; } #ifdef USE_RENDERER mMapRenderer = new QgsMapRenderer(); mMapRenderer->setDestinationCrs( destCRS ); mMapRenderer->setProjectionsEnabled( true ); mMapRenderer->setOutputUnits( c->mapRenderer()->outputUnits() ); mMapRenderer->setMapUnits( QGis::Degrees ); #else mMapSettings.setDestinationCrs( destCRS ); mMapSettings.setCrsTransformEnabled( true ); mMapSettings.setMapUnits( QGis::Degrees ); #endif }
void QgsComposerLegendWidget::updateLegend() { if ( mLegend ) { mLegend->beginCommand( tr( "Legend updated" ) ); QgisApp* app = QgisApp::instance(); if ( !app ) { return; } //get layer id list QStringList layerIdList; QgsMapCanvas* canvas = app->mapCanvas(); if ( canvas ) { QgsMapRenderer* renderer = canvas->mapRenderer(); if ( renderer ) { layerIdList = renderer->layerSet(); } } //and also group info QgsAppLegendInterface legendIface( app->legend() ); QList< GroupLayerInfo > groupInfo = legendIface.groupLayerRelationship(); mLegend->model()->setLayerSetAndGroups( layerIdList, groupInfo ); mLegend->endCommand(); } }
void QgsDualView::flashButtonClicked( bool clicked ) { QgsSettings().setValue( QStringLiteral( "/qgis/attributeTable/featureListHighlightFeature" ), clicked ); if ( !clicked ) return; QgsMapCanvas *canvas = mFilterModel->mapCanvas(); if ( canvas ) canvas->flashFeatureIds( mLayer, mFeatureListView->currentEditSelection() ); }
void QgsBookmarks::addClicked() { Q_ASSERT( mModel ); Q_ASSERT( mQgisModel ); QgsMapCanvas *canvas = QgisApp::instance()->mapCanvas(); Q_ASSERT( canvas ); QSqlQuery query( "INSERT INTO tbl_bookmarks(bookmark_id,name,project_name,xmin,ymin,xmax,ymax,projection_srid)" " VALUES (NULL,:name,:project_name,:xmin,:xmax,:ymin,:ymax,:projection_srid)", mQgisModel->database() ); QString projStr( QLatin1String( "" ) ); if ( QgsProject::instance() ) { if ( !QgsProject::instance()->title().isEmpty() ) { projStr = QgsProject::instance()->title(); } else if ( !QgsProject::instance()->fileName().isEmpty() ) { QFileInfo fi( QgsProject::instance()->fileName() ); projStr = fi.exists() ? fi.fileName() : QLatin1String( "" ); } } query.bindValue( QStringLiteral( ":name" ), tr( "New bookmark" ) ); query.bindValue( QStringLiteral( ":project_name" ), projStr ); query.bindValue( QStringLiteral( ":xmin" ), canvas->extent().xMinimum() ); query.bindValue( QStringLiteral( ":ymin" ), canvas->extent().yMinimum() ); query.bindValue( QStringLiteral( ":xmax" ), canvas->extent().xMaximum() ); query.bindValue( QStringLiteral( ":ymax" ), canvas->extent().yMaximum() ); query.bindValue( QStringLiteral( ":projection_srid" ), QVariant::fromValue( canvas->mapSettings().destinationCrs().srsid() ) ); if ( query.exec() ) { mQgisModel->setSort( 0, Qt::AscendingOrder ); mQgisModel->select(); lstBookmarks->scrollTo( mModel->index( mQgisModel->rowCount() - 1, 1 ) ); lstBookmarks->setCurrentIndex( mModel->index( mQgisModel->rowCount() - 1, 1 ) ); lstBookmarks->edit( mModel->index( mQgisModel->rowCount() - 1, 1 ) ); } else { QMessageBox::warning( this, tr( "Error" ), tr( "Unable to create the bookmark.\nDriver:%1\nDatabase:%2" ) .arg( query.lastError().driverText(), query.lastError().databaseText() ) ); } }
void QgsDualView::flashCurrentFeature() { QModelIndex currentIndex = mTableView->currentIndex(); if ( !currentIndex.isValid() ) { return; } QgsFeatureIds ids; ids.insert( mFilterModel->rowToId( currentIndex ) ); QgsMapCanvas *canvas = mFilterModel->mapCanvas(); if ( canvas ) { canvas->flashFeatureIds( mLayer, ids ); } }
void QgsInterpolationDialog::on_mBBoxToCurrentExtent_clicked() { if ( mIface ) { QgsMapCanvas* canvas = mIface->mapCanvas(); if ( canvas ) { QgsRectangle extent = canvas->extent(); mXMinLineEdit->setText( QString::number( extent.xMinimum() ) ); mXMaxLineEdit->setText( QString::number( extent.xMaximum() ) ); mYMinLineEdit->setText( QString::number( extent.yMinimum() ) ); mYMaxLineEdit->setText( QString::number( extent.yMaximum() ) ); setNewCellsizeOnBoundingBoxChange(); } } }
void QgsTileScaleWidget::showTileScale( QMainWindow *mainWindow ) { QgsDockWidget *dock = mainWindow->findChild<QgsDockWidget *>( QStringLiteral( "theTileScaleDock" ) ); if ( dock ) { dock->setVisible( dock->isHidden() ); return; } QgsMapCanvas *canvas = mainWindow->findChild<QgsMapCanvas *>( QStringLiteral( "theMapCanvas" ) ); QgsDebugMsg( QString( "canvas:%1 [%2]" ).arg( ( quint64 ) canvas, 0, 16 ).arg( canvas ? canvas->objectName() : "" ) ); if ( !canvas ) { QgsDebugMsg( "map canvas mapCanvas not found" ); return; } QgsTileScaleWidget *tws = new QgsTileScaleWidget( canvas ); tws->setObjectName( QStringLiteral( "theTileScaleWidget" ) ); QgsLayerTreeView *legend = mainWindow->findChild<QgsLayerTreeView *>( QStringLiteral( "theLayerTreeView" ) ); if ( legend ) { connect( legend, &QgsLayerTreeView::currentLayerChanged, tws, &QgsTileScaleWidget::layerChanged ); } else { QgsDebugMsg( "legend not found" ); } //create the dock widget dock = new QgsDockWidget( tr( "Tile Scale" ), mainWindow ); dock->setObjectName( QStringLiteral( "theTileScaleDock" ) ); connect( dock, &QDockWidget::dockLocationChanged, tws, &QgsTileScaleWidget::locationChanged ); mainWindow->addDockWidget( Qt::RightDockWidgetArea, dock ); // add to the Panel submenu QMenu *panelMenu = mainWindow->findChild<QMenu *>( QStringLiteral( "mPanelMenu" ) ); if ( panelMenu ) { // add to the Panel submenu panelMenu->addAction( dock->toggleViewAction() ); } else { QgsDebugMsg( "panel menu not found" ); } dock->setWidget( tws ); connect( dock, &QDockWidget::visibilityChanged, tws, &QgsTileScaleWidget::scaleEnabled ); QgsSettings settings; dock->setVisible( settings.value( QStringLiteral( "UI/tileScaleEnabled" ), false ).toBool() ); }
void QgsTileScaleWidget::showTileScale( QMainWindow *mainWindow ) { QgsDockWidget *dock = mainWindow->findChild<QgsDockWidget *>( QStringLiteral( "theTileScaleDock" ) ); if ( dock ) { dock->setVisible( dock->isHidden() ); return; } QgsMapCanvas *canvas = mainWindow->findChild<QgsMapCanvas *>( QStringLiteral( "theMapCanvas" ) ); QgsDebugMsg( QString( "canvas:%1 [%2]" ).arg(( ulong ) canvas, 0, 16 ).arg( canvas ? canvas->objectName() : "" ) ); if ( !canvas ) { QgsDebugMsg( "map canvas theMapCanvas not found" ); return; } QgsTileScaleWidget *tws = new QgsTileScaleWidget( canvas ); tws->setObjectName( QStringLiteral( "theTileScaleWidget" ) ); QObject *legend = mainWindow->findChild<QObject*>( QStringLiteral( "theLayerTreeView" ) ); if ( legend ) { connect( legend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), tws, SLOT( layerChanged( QgsMapLayer* ) ) ); } else { QgsDebugMsg( "legend not found" ); } //create the dock widget dock = new QgsDockWidget( tr( "Tile Scale Panel" ), mainWindow ); dock->setObjectName( QStringLiteral( "theTileScaleDock" ) ); dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); mainWindow->addDockWidget( Qt::RightDockWidgetArea, dock ); // add to the Panel submenu QMenu *panelMenu = mainWindow->findChild<QMenu *>( QStringLiteral( "mPanelMenu" ) ); if ( panelMenu ) { // add to the Panel submenu panelMenu->addAction( dock->toggleViewAction() ); } else { QgsDebugMsg( "panel menu not found" ); } dock->setWidget( tws ); connect( dock, SIGNAL( visibilityChanged( bool ) ), tws, SLOT( scaleEnabled( bool ) ) ); QSettings settings; dock->setVisible( settings.value( QStringLiteral( "/UI/tileScaleEnabled" ), false ).toBool() ); }
void GlobePlugin::syncExtent() { QgsMapCanvas* mapCanvas = mQGisIface->mapCanvas(); const QgsMapSettings &mapSettings = mapCanvas->mapSettings(); QgsRectangle extent = mapCanvas->extent(); long epsgGlobe = 4326; QgsCoordinateReferenceSystem globeCrs; globeCrs.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsgGlobe ) ); // transform extent to WGS84 if ( mapSettings.destinationCrs().authid().compare( QString( "EPSG:%1" ).arg( epsgGlobe ), Qt::CaseInsensitive ) != 0 ) { QgsCoordinateReferenceSystem srcCRS( mapSettings.destinationCrs() ); QgsCoordinateTransform* coordTransform = new QgsCoordinateTransform( srcCRS, globeCrs ); extent = coordTransform->transformBoundingBox( extent ); delete coordTransform; } osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>( mOsgViewer->getCameraManipulator() ); //rotate earth to north and perpendicular to camera manip->setRotation( osg::Quat() ); QgsDistanceArea dist; dist.setSourceCrs( globeCrs ); dist.setEllipsoidalMode( true ); dist.setEllipsoid( "WGS84" ); QgsPoint ll = QgsPoint( extent.xMinimum(), extent.yMinimum() ); QgsPoint ul = QgsPoint( extent.xMinimum(), extent.yMaximum() ); double height = dist.measureLine( ll, ul ); //camera viewing angle double viewAngle = 30; //camera distance double distance = height / tan( viewAngle * osg::PI / 180 ); //c = b*cotan(B(rad)) OE_NOTICE << "map extent: " << height << " camera distance: " << distance << std::endl; osgEarth::Util::Viewpoint viewpoint( osg::Vec3d( extent.center().x(), extent.center().y(), 0.0 ), 0.0, -90.0, distance ); manip->setViewpoint( viewpoint, 4.0 ); }
void QgsMapCanvasDockWidget::syncViewCenter( QgsMapCanvas *sourceCanvas ) { // avoid infinite recursion mBlockExtentSync = true; QgsMapCanvas *destCanvas = sourceCanvas == mMapCanvas ? mMainCanvas : mMapCanvas; // reproject extent QgsCoordinateTransform ct( sourceCanvas->mapSettings().destinationCrs(), destCanvas->mapSettings().destinationCrs(), QgsProject::instance() ); try { destCanvas->setCenter( ct.transform( sourceCanvas->center() ) ); } catch ( QgsCsException & ) { destCanvas->setCenter( sourceCanvas->center() ); } destCanvas->refresh(); mBlockExtentSync = false; }
void QgsDualView::panOrZoomToFeature( const QgsFeatureIds &featureset ) { QgsMapCanvas *canvas = mFilterModel->mapCanvas(); if ( canvas ) { if ( mAutoPanButton->isChecked() ) QTimer::singleShot( 0, this, [ = ]() { canvas->panToFeatureIds( mLayer, featureset, false ); } ); else if ( mAutoZoomButton->isChecked() ) QTimer::singleShot( 0, this, [ = ]() { canvas->zoomToFeatureIds( mLayer, featureset ); } ); if ( mFlashButton->isChecked() ) QTimer::singleShot( 0, this, [ = ]() { canvas->flashFeatureIds( mLayer, featureset ); } ); } }
void QgsComposerLegendWidget::on_mAddToolButton_clicked() { if ( !mLegend ) { return; } QStandardItemModel* itemModel = qobject_cast<QStandardItemModel *>( mItemTreeView->model() ); if ( !itemModel ) { return; } QgisApp* app = QgisApp::instance(); if ( !app ) { return; } QgsMapCanvas* canvas = app->mapCanvas(); if ( canvas ) { QList<QgsMapLayer*> layers = canvas->layers(); QgsComposerLegendLayersDialog addDialog( layers ); if ( addDialog.exec() == QDialog::Accepted ) { QgsMapLayer* layer = addDialog.selectedLayer(); if ( layer ) { mLegend->beginCommand( "Legend item added" ); mLegend->model()->addLayer( layer ); mLegend->endCommand(); } } } }
int main(int argc, char ** argv) { // Start the Application QgsApplication app(argc, argv, true); QString myPluginsDir = "/home/timlinux/apps/lib/qgis"; QString myLayerPath = "/home/timlinux/gisdata/brazil/BR_Cidades/"; QString myLayerBaseName = "Brasil_Cap"; QString myProviderName = "ogr"; // Instantiate Provider Registry QgsProviderRegistry::instance(myPluginsDir); // create a maplayer instance QgsVectorLayer * mypLayer = new QgsVectorLayer(myLayerPath, myLayerBaseName, myProviderName); QgsSingleSymbolRenderer *mypRenderer = new QgsSingleSymbolRenderer(mypLayer->geometryType()); QList <QgsMapCanvasLayer> myLayerSet; mypLayer->setRenderer(mypRenderer); if (mypLayer->isValid()) { qDebug("Layer is valid"); } else { qDebug("Layer is NOT valid"); } // Add the Vector Layer to the Layer Registry QgsMapLayerRegistry::instance()->addMapLayer(mypLayer, TRUE); // Add the Layer to the Layer Set myLayerSet.append(QgsMapCanvasLayer(mypLayer, TRUE)); // Create the Map Canvas QgsMapCanvas * mypMapCanvas = new QgsMapCanvas(0, 0); mypMapCanvas->setExtent(mypLayer->extent()); mypMapCanvas->enableAntiAliasing(true); mypMapCanvas->setCanvasColor(QColor(255, 255, 255)); mypMapCanvas->freeze(false); // Set the Map Canvas Layer Set mypMapCanvas->setLayerSet(myLayerSet); mypMapCanvas->setVisible(true); mypMapCanvas->refresh(); // Start the Application Event Loop return app.exec(); }
void QgsDecorationScaleBar::render( QPainter * theQPainter ) { QgsMapCanvas* canvas = QgisApp::instance()->mapCanvas(); int myBufferSize = 1; //softcode this later //Get canvas dimensions int myCanvasHeight = theQPainter->device()->height(); int myCanvasWidth = theQPainter->device()->width(); //Get map units per pixel. This can be negative at times (to do with //projections) and that just confuses the rest of the code in this //function, so force to a positive number. double myMapUnitsPerPixelDouble = qAbs( canvas->mapUnitsPerPixel() ); double myActualSize = mPreferredSize; // Exit if the canvas width is 0 or layercount is 0 or QGIS will freeze int myLayerCount = canvas->layerCount(); if ( !myLayerCount || !myCanvasWidth || !myMapUnitsPerPixelDouble ) return; //Large if statement which determines whether to render the scale bar if ( enabled() ) { // Hard coded sizes int myMajorTickSize = 8; int myTextOffsetX = 3; int myMargin = 20; QSettings settings; QGis::UnitType myPreferredUnits = QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() ); QGis::UnitType myMapUnits = canvas->mapUnits(); // Adjust units meter/feet/... or vice versa myMapUnitsPerPixelDouble *= QGis::fromUnitToUnitFactor( myMapUnits, myPreferredUnits ); myMapUnits = myPreferredUnits; //Calculate size of scale bar for preferred number of map units double myScaleBarWidth = mPreferredSize / myMapUnitsPerPixelDouble; //If scale bar is very small reset to 1/4 of the canvas wide if ( myScaleBarWidth < 30 ) { myScaleBarWidth = myCanvasWidth / 4; // pixels myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble; // map units }; //if scale bar is more than half the canvas wide keep halving until not while ( myScaleBarWidth > myCanvasWidth / 3 ) { myScaleBarWidth = myScaleBarWidth / 3; }; myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble; // Work out the exponent for the number - e.g, 1234 will give 3, // and .001234 will give -3 double myPowerOf10 = floor( log10( myActualSize ) ); // snap to integer < 10 times power of 10 if ( mSnapping ) { double scaler = pow( 10.0, myPowerOf10 ); myActualSize = qRound( myActualSize / scaler ) * scaler; myScaleBarWidth = myActualSize / myMapUnitsPerPixelDouble; } //Get type of map units and set scale bar unit label text QString myScaleBarUnitLabel; switch ( myMapUnits ) { case QGis::Meters: if ( myActualSize > 1000.0 ) { myScaleBarUnitLabel = tr( " km" ); myActualSize = myActualSize / 1000; } else if ( myActualSize < 0.01 ) { myScaleBarUnitLabel = tr( " mm" ); myActualSize = myActualSize * 1000; } else if ( myActualSize < 0.1 ) { myScaleBarUnitLabel = tr( " cm" ); myActualSize = myActualSize * 100; } else myScaleBarUnitLabel = tr( " m" ); break; case QGis::Feet: if ( myActualSize > 5280.0 ) //5280 feet to the mile { myScaleBarUnitLabel = tr( " miles" ); // Adjust scale bar width to get even numbers myActualSize = myActualSize / 5000; myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000; } else if ( myActualSize == 5280.0 ) //5280 feet to the mile { myScaleBarUnitLabel = tr( " mile" ); // Adjust scale bar width to get even numbers myActualSize = myActualSize / 5000; myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000; } else if ( myActualSize < 1 ) { myScaleBarUnitLabel = tr( " inches" ); myActualSize = myActualSize * 10; myScaleBarWidth = ( myScaleBarWidth * 10 ) / 12; } else if ( myActualSize == 1.0 ) { myScaleBarUnitLabel = tr( " foot" ); } else { myScaleBarUnitLabel = tr( " feet" ); } break; case QGis::Degrees: if ( myActualSize == 1.0 ) myScaleBarUnitLabel = tr( " degree" ); else myScaleBarUnitLabel = tr( " degrees" ); break; case QGis::UnknownUnit: myScaleBarUnitLabel = tr( " unknown" ); default: QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( myMapUnits ) ); }; //Set font and calculate width of unit label int myFontSize = 10; //we use this later for buffering QFont myFont( "helvetica", myFontSize ); theQPainter->setFont( myFont ); QFontMetrics myFontMetrics( myFont ); double myFontWidth = myFontMetrics.width( myScaleBarUnitLabel ); double myFontHeight = myFontMetrics.height(); //Set the maximum label QString myScaleBarMaxLabel = QLocale::system().toString( myActualSize ); //Calculate total width of scale bar and label double myTotalScaleBarWidth = myScaleBarWidth + myFontWidth; //determine the origin of scale bar depending on placement selected int myOriginX = myMargin; int myOriginY = myMargin; switch ( mPlacementIndex ) { case 0: // Bottom Left myOriginX = myMargin; myOriginY = myCanvasHeight - myMargin; break; case 1: // Top Left myOriginX = myMargin; myOriginY = myMargin; break; case 2: // Top Right myOriginX = myCanvasWidth - (( int ) myTotalScaleBarWidth ) - myMargin; myOriginY = myMargin; break; case 3: // Bottom Right myOriginX = myCanvasWidth - (( int ) myTotalScaleBarWidth ) - myMargin; myOriginY = myCanvasHeight - myMargin; break; default: QgsDebugMsg( "Unable to determine where to put scale bar so defaulting to top left" ); } //Set pen to draw with QPen myForegroundPen( mColor, 2 ); QPen myBackgroundPen( Qt::white, 4 ); //Cast myScaleBarWidth to int for drawing int myScaleBarWidthInt = ( int ) myScaleBarWidth; //Create array of vertices for scale bar depending on style switch ( mStyleIndex ) { case 0: // Tick Down { QPolygon myTickDownArray( 4 ); //draw a buffer first so bar shows up on dark images theQPainter->setPen( myBackgroundPen ); myTickDownArray.putPoints( 0, 4, myOriginX , ( myOriginY + myMajorTickSize ) , myOriginX , myOriginY , ( myScaleBarWidthInt + myOriginX ), myOriginY , ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ) ); theQPainter->drawPolyline( myTickDownArray ); //now draw the bar itself in user selected color theQPainter->setPen( myForegroundPen ); myTickDownArray.putPoints( 0, 4, myOriginX , ( myOriginY + myMajorTickSize ) , myOriginX , myOriginY , ( myScaleBarWidthInt + myOriginX ), myOriginY , ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ) ); theQPainter->drawPolyline( myTickDownArray ); break; } case 1: // tick up { QPolygon myTickUpArray( 4 ); //draw a buffer first so bar shows up on dark images theQPainter->setPen( myBackgroundPen ); myTickUpArray.putPoints( 0, 4, myOriginX , myOriginY , myOriginX , myOriginY + myMajorTickSize , ( myScaleBarWidthInt + myOriginX ), myOriginY + myMajorTickSize , ( myScaleBarWidthInt + myOriginX ), myOriginY ); theQPainter->drawPolyline( myTickUpArray ); //now draw the bar itself in user selected color theQPainter->setPen( myForegroundPen ); myTickUpArray.putPoints( 0, 4, myOriginX , myOriginY , myOriginX , myOriginY + myMajorTickSize , ( myScaleBarWidthInt + myOriginX ), myOriginY + myMajorTickSize , ( myScaleBarWidthInt + myOriginX ), myOriginY ); theQPainter->drawPolyline( myTickUpArray ); break; } case 2: // Bar { QPolygon myBarArray( 2 ); //draw a buffer first so bar shows up on dark images theQPainter->setPen( myBackgroundPen ); myBarArray.putPoints( 0, 2, myOriginX , ( myOriginY + ( myMajorTickSize / 2 ) ), ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) ) ); theQPainter->drawPolyline( myBarArray ); //now draw the bar itself in user selected color theQPainter->setPen( myForegroundPen ); myBarArray.putPoints( 0, 2, myOriginX , ( myOriginY + ( myMajorTickSize / 2 ) ), ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) ) ); theQPainter->drawPolyline( myBarArray ); break; } case 3: // box { // Want square corners for a box myBackgroundPen.setJoinStyle( Qt::MiterJoin ); myForegroundPen.setJoinStyle( Qt::MiterJoin ); QPolygon myBoxArray( 5 ); //draw a buffer first so bar shows up on dark images theQPainter->setPen( myBackgroundPen ); myBoxArray.putPoints( 0, 5, myOriginX , myOriginY, ( myScaleBarWidthInt + myOriginX ), myOriginY, ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ), myOriginX , ( myOriginY + myMajorTickSize ), myOriginX , myOriginY ); theQPainter->drawPolyline( myBoxArray ); //now draw the bar itself in user selected color theQPainter->setPen( myForegroundPen ); theQPainter->setBrush( QBrush( mColor, Qt::SolidPattern ) ); int midPointX = myScaleBarWidthInt / 2 + myOriginX; myBoxArray.putPoints( 0, 5, myOriginX , myOriginY, midPointX, myOriginY, midPointX, ( myOriginY + myMajorTickSize ), myOriginX , ( myOriginY + myMajorTickSize ), myOriginX , myOriginY ); theQPainter->drawPolygon( myBoxArray ); theQPainter->setBrush( Qt::NoBrush ); myBoxArray.putPoints( 0, 5, midPointX , myOriginY, ( myScaleBarWidthInt + myOriginX ), myOriginY, ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ), midPointX , ( myOriginY + myMajorTickSize ), midPointX , myOriginY ); theQPainter->drawPolygon( myBoxArray ); break; } default: QgsDebugMsg( "Unknown style" ); } //Do actual drawing of scale bar // //Do drawing of scale bar text // QColor myBackColor = Qt::white; QColor myForeColor = Qt::black; //Draw the minimum label buffer theQPainter->setPen( myBackColor ); myFontWidth = myFontMetrics.width( "0" ); myFontHeight = myFontMetrics.height(); for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) { for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) { theQPainter->drawText( int( i + ( myOriginX - ( myFontWidth / 2 ) ) ), int( j + ( myOriginY - ( myFontHeight / 4 ) ) ), "0" ); } } //Draw minimum label theQPainter->setPen( myForeColor ); theQPainter->drawText( int( myOriginX - ( myFontWidth / 2 ) ), int( myOriginY - ( myFontHeight / 4 ) ), "0" ); // //Draw maximum label // theQPainter->setPen( myBackColor ); myFontWidth = myFontMetrics.width( myScaleBarMaxLabel ); myFontHeight = myFontMetrics.height(); //first the buffer for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) { for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) { theQPainter->drawText( int( i + ( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ) ), int( j + ( myOriginY - ( myFontHeight / 4 ) ) ), myScaleBarMaxLabel ); } } //then the text itself theQPainter->setPen( myForeColor ); theQPainter->drawText( int( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ), int( myOriginY - ( myFontHeight / 4 ) ), myScaleBarMaxLabel ); // //Draw unit label // theQPainter->setPen( myBackColor ); //first the buffer for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) { for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) { theQPainter->drawText( i + ( myOriginX + myScaleBarWidthInt + myTextOffsetX ), j + ( myOriginY + myMajorTickSize ), myScaleBarUnitLabel ); } } //then the text itself theQPainter->setPen( myForeColor ); theQPainter->drawText( ( myOriginX + myScaleBarWidthInt + myTextOffsetX ), ( myOriginY + myMajorTickSize ), myScaleBarUnitLabel ); } }
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags ) : QDialog( parent, flags ) , mDock( nullptr ) , mLayer( theLayer ) , mRubberBand( nullptr ) , mCurrentSearchWidgetWrapper( nullptr ) { setupUi( this ); // Fix selection color on loosing focus (Windows) setStyleSheet( QgisApp::instance()->styleSheet() ); setAttribute( Qt::WA_DeleteOnClose ); QSettings settings; // Initialize the window geometry restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() ); QgsAttributeEditorContext context; myDa = new QgsDistanceArea(); myDa->setSourceCrs( mLayer->crs() ); myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); context.setDistanceArea( *myDa ); context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); QgsFeatureRequest r; if ( mLayer->geometryType() != QGis::NoGeometry && settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible ) { QgsMapCanvas *mc = QgisApp::instance()->mapCanvas(); QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) ); r.setFilterRect( extent ); QgsGeometry *g = QgsGeometry::fromRect( extent ); mRubberBand = new QgsRubberBand( mc, QGis::Polygon ); mRubberBand->setToGeometry( g, theLayer ); delete g; mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) ); } // Initialize dual view mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context ); // Initialize filter gui elements mFilterActionMapper = new QSignalMapper( this ); mFilterColumnsMenu = new QMenu( this ); mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu ); mApplyFilterButton->setDefaultAction( mActionApplyFilter ); // Set filter icon in a couple of places QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter.svg" ); mActionShowAllFilter->setIcon( filterIcon ); mActionAdvancedFilter->setIcon( filterIcon ); mActionSelectedFilter->setIcon( filterIcon ); mActionVisibleFilter->setIcon( filterIcon ); mActionEditedFilter->setIcon( filterIcon ); // Connect filter signals connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) ); connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) ); connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) ); connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) ); connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) ); connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) ); connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) ); connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) ); connect( mSetStyles, SIGNAL( pressed() ), SLOT( openConditionalStyles() ) ); // info from layer to table connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) ); connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) ); connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) ); // connect table info to window connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) ); // info from table to application connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) ); bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool(); if ( myDockFlag ) { mDock = new QgsAttributeTableDock( tr( "Attribute table - %1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() ); mDock->setAllowedAreas( Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea ); mDock->setWidget( this ); connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) ); QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock ); } columnBoxInit(); updateTitle(); mRemoveSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnselectAttributes.png" ) ); mSelectedToTopButton->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.png" ) ); mCopySelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) ); mZoomMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) ); mPanMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.svg" ) ); mInvertSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.png" ) ); mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) ); mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) ); mDeleteSelectedButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) ); mOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.png" ) ); mAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) ); mRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) ); mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) ); mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) ); mExpressionSelectButton->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) ); mAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionNewTableRow.png" ) ); // toggle editing bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues; bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures; bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes; bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes; bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures; mToggleEditingButton->blockSignals( true ); mToggleEditingButton->setCheckable( true ); mToggleEditingButton->setChecked( mLayer->isEditable() ); mToggleEditingButton->setEnabled(( canChangeAttributes || canDeleteFeatures || canAddAttributes || canDeleteAttributes || canAddFeatures ) && !mLayer->isReadOnly() ); mToggleEditingButton->blockSignals( false ); mSaveEditsButton->setEnabled( mToggleEditingButton->isEnabled() && mLayer->isEditable() ); mReloadButton->setEnabled( ! mLayer->isEditable() ); mAddAttribute->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() ); mDeleteSelectedButton->setEnabled( canDeleteFeatures && mLayer->isEditable() ); mAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() ); mAddFeature->setHidden( !canAddFeatures ); mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable ); mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor ); // Load default attribute table filter QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt(); switch ( defaultFilterMode ) { case QgsAttributeTableFilterModel::ShowVisible: filterVisible(); break; case QgsAttributeTableFilterModel::ShowSelected: filterSelected(); break; case QgsAttributeTableFilterModel::ShowAll: default: filterShowAll(); break; } mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer ); mFieldModel = new QgsFieldModel( this ); mFieldModel->setLayer( mLayer ); mFieldCombo->setModel( mFieldModel ); connect( mRunFieldCalc, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpression() ) ); connect( mRunFieldCalcSelected, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpressionSelected() ) ); // NW TODO Fix in 2.6 - Doesn't work with field model for some reason. // connect( mUpdateExpressionText, SIGNAL( returnPressed() ), this, SLOT( updateFieldFromExpression() ) ); connect( mUpdateExpressionText, SIGNAL( fieldChanged( QString, bool ) ), this, SLOT( updateButtonStatus( QString, bool ) ) ); mUpdateExpressionText->setLayer( mLayer ); mUpdateExpressionText->setLeftHandButtonStyle( true ); mMainView->setView( QgsDualView::AttributeTable ); editingToggled(); }
bool QgsDecorationNorthArrow::calculateNorthDirection() { QgsMapCanvas* mapCanvas = QgisApp::instance()->mapCanvas(); bool goodDirn = false; if ( mapCanvas->layerCount() > 0 ) { QgsCoordinateReferenceSystem outputCRS = mapCanvas->mapRenderer()->destinationCrs(); if ( outputCRS.isValid() && !outputCRS.geographicFlag() ) { // Use a geographic CRS to get lat/long to work out direction QgsCoordinateReferenceSystem ourCRS; ourCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ); assert( ourCRS.isValid() ); QgsCoordinateTransform transform( outputCRS, ourCRS ); QgsRectangle extent = mapCanvas->extent(); QgsPoint p1( extent.center() ); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2( p1.x(), p1.y() + extent.height() * 0.25 ); // project p1 and p2 to geographic coords try { p1 = transform.transform( p1 ); p2 = transform.transform( p2 ); } catch ( QgsCsException &e ) { Q_UNUSED( e ); // just give up QgsDebugMsg( "North Arrow: Transformation error, quitting" ); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply( PI / 180.0 ); p2.multiply( PI / 180.0 ); double y = sin( p2.x() - p1.x() ) * cos( p2.y() ); double x = cos( p1.y() ) * sin( p2.y() ) - sin( p1.y() ) * cos( p2.y() ) * cos( p2.x() - p1.x() ); if ( y > 0.0 ) { if ( x > TOL ) angle = atan( y / x ); else if ( x < -TOL ) angle = PI - atan( -y / x ); else angle = 0.5 * PI; } else if ( y < 0.0 ) { if ( x > TOL ) angle = -atan( -y / x ); else if ( x < -TOL ) angle = atan( y / x ) - PI; else angle = 1.5 * PI; } else { if ( x > TOL ) angle = 0.0; else if ( x < -TOL ) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = static_cast<int>( round( fmod( 360.0 - angle * 180.0 / PI, 360.0 ) ) ); } else { // For geographic CRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } return goodDirn; }
// Slot called when the menu item is triggered void SqlAnywhere::addSqlAnywhereLayer() { QgsMapCanvas *mMapCanvas = mQGisIface->mapCanvas(); if ( mMapCanvas && mMapCanvas->isDrawing() ) { return; } // show the data source dialog SaSourceSelect *dbs = new SaSourceSelect( mQGisIface->mainWindow() ); mMapCanvas->freeze(); if ( dbs->exec() ) { // add files to the map canvas QStringList tables = dbs->selectedTables(); SaDebugMsg( "Selected tables:\n" + tables.join( "\n" ) + "\n\n" ); QApplication::setOverrideCursor( Qt::WaitCursor ); // retrieve database connection string QString connectionInfo = dbs->connectionInfo(); // create a new map layer for each selected table and register it for ( QStringList::Iterator it = tables.begin() ; it != tables.end() ; it++ ) { // create the layer SaDebugMsg( "Creating layer " + *it ); SaLayer *layer = new SaLayer( connectionInfo + " " + *it, *it ); if ( layer->isValid() ) { // set initial layer name to table name SaDebugMsg( "Beautifying layer name. old: " + layer->name() ); QgsDataSourceURI layerUri = QgsDataSourceURI( *it ); QString newName = QString( "%1 (%2)" ) .arg( layerUri.table() ) .arg( layerUri.geometryColumn() ); if ( QgsMapLayerRegistry::instance()->mapLayers().contains( newName ) ) { newName = QString( "%1.%2 (%3)" ) .arg( layerUri.schema() ) .arg( layerUri.table() ) .arg( layerUri.geometryColumn() ); if ( QgsMapLayerRegistry::instance()->mapLayers().contains( newName ) ) { // give up and revert to original name newName = layer->name(); } } layer->setLayerName( newName ); SaDebugMsg( "Beautifying layer name. new: " + layer->name() ); // register this layer with the central layers registry QgsMapLayerRegistry::instance()->addMapLayer(( QgsVectorLayer* )layer ); } else { SaDebugMsg(( *it ) + " is an invalid layer - not loaded" ); QMessageBox::critical( mQGisIface->mainWindow(), tr( "Invalid Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( *it ) ); delete layer; } } QApplication::restoreOverrideCursor(); (( QMainWindow * ) mQGisIface->mainWindow() )->statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) ); } delete dbs; // update UI qApp->processEvents(); // draw the map mMapCanvas->freeze( false ); mMapCanvas->refresh(); } // SqlAnywhere::addSqlAnywhereLayer()
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags ) : QDialog( parent, flags ) , mDock( nullptr ) , mLayer( theLayer ) , mRubberBand( nullptr ) , mCurrentSearchWidgetWrapper( nullptr ) { setupUi( this ); Q_FOREACH ( const QgsField& field, mLayer->fields() ) { mVisibleFields.append( field.name() ); } // Fix selection color on loosing focus (Windows) setStyleSheet( QgisApp::instance()->styleSheet() ); setAttribute( Qt::WA_DeleteOnClose ); layout()->setMargin( 0 ); layout()->setContentsMargins( 0, 0, 0, 0 ); static_cast< QGridLayout* >( layout() )->setVerticalSpacing( 0 ); QSettings settings; int size = settings.value( "/IconSize", 16 ).toInt(); if ( size > 32 ) { size -= 16; } else if ( size == 32 ) { size = 24; } else { size = 16; } mToolbar->setIconSize( QSize( size, size ) ); // Initialize the window geometry restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() ); myDa = new QgsDistanceArea(); myDa->setSourceCrs( mLayer->crs() ); myDa->setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa->setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); mEditorContext.setDistanceArea( *myDa ); mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); QgsFeatureRequest r; if ( mLayer->geometryType() != QGis::NoGeometry && settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible ) { QgsMapCanvas *mc = QgisApp::instance()->mapCanvas(); QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) ); r.setFilterRect( extent ); QgsGeometry *g = QgsGeometry::fromRect( extent ); mRubberBand = new QgsRubberBand( mc, QGis::Polygon ); mRubberBand->setToGeometry( g, theLayer ); delete g; mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) ); } // Initialize dual view mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext ); QgsAttributeTableConfig config = mLayer->attributeTableConfig(); mMainView->setAttributeTableConfig( config ); // Initialize filter gui elements mFilterActionMapper = new QSignalMapper( this ); mFilterColumnsMenu = new QMenu( this ); mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu ); mApplyFilterButton->setDefaultAction( mActionApplyFilter ); // Set filter icon in a couple of places QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter2.svg" ); mActionShowAllFilter->setIcon( filterIcon ); mActionAdvancedFilter->setIcon( filterIcon ); mActionSelectedFilter->setIcon( filterIcon ); mActionVisibleFilter->setIcon( filterIcon ); mActionEditedFilter->setIcon( filterIcon ); // Connect filter signals connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) ); connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) ); connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) ); connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) ); connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) ); connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) ); connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) ); connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) ); connect( mActionSetStyles, SIGNAL( triggered() ), SLOT( openConditionalStyles() ) ); // info from layer to table connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) ); connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) ); connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) ); // connect table info to window connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) ); connect( mMainView, SIGNAL( filterExpressionSet( QString, QgsAttributeForm::FilterType ) ), this, SLOT( formFilterSet( QString, QgsAttributeForm::FilterType ) ) ); connect( mMainView, SIGNAL( formModeChanged( QgsAttributeForm::Mode ) ), this, SLOT( viewModeChanged( QgsAttributeForm::Mode ) ) ); // info from table to application connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) ); bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool(); if ( myDockFlag ) { mDock = new QgsAttributeTableDock( tr( "%1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() ); mDock->setWidget( this ); connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) ); QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock ); } columnBoxInit(); updateTitle(); mActionRemoveSelection->setIcon( QgsApplication::getThemeIcon( "/mActionDeselectAll.svg" ) ); mActionSelectAll->setIcon( QgsApplication::getThemeIcon( "/mActionSelectAll.svg" ) ); mActionSelectedToTop->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.svg" ) ); mActionCopySelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionEditCopy.svg" ) ); mActionPasteFeatures->setIcon( QgsApplication::getThemeIcon( "/mActionEditPaste.svg" ) ); mActionZoomMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) ); mActionPanMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.svg" ) ); mActionInvertSelection->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.svg" ) ); mActionToggleEditing->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) ); mActionSaveEdits->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) ); mActionDeleteSelected->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) ); mActionOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.svg" ) ); mActionAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.svg" ) ); mActionRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.svg" ) ); mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.svg" ) ); mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionFormView.svg" ) ); mActionExpressionSelect->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) ); mActionAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionNewTableRow.svg" ) ); // toggle editing bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues; bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures; bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes; bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes; bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures; mActionToggleEditing->blockSignals( true ); mActionToggleEditing->setCheckable( true ); mActionToggleEditing->setChecked( mLayer->isEditable() ); mActionToggleEditing->setEnabled(( canChangeAttributes || canDeleteFeatures || canAddAttributes || canDeleteAttributes || canAddFeatures ) && !mLayer->readOnly() ); mActionToggleEditing->blockSignals( false ); mActionSaveEdits->setEnabled( mActionToggleEditing->isEnabled() && mLayer->isEditable() ); mActionReload->setEnabled( ! mLayer->isEditable() ); mActionAddAttribute->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() ); mActionRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() ); mActionDeleteSelected->setEnabled( canDeleteFeatures && mLayer->isEditable() ); if ( !canDeleteFeatures ) mToolbar->removeAction( mActionDeleteSelected ); mActionAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() ); if ( !canAddFeatures ) mToolbar->removeAction( mActionAddFeature ); if ( canDeleteFeatures || canAddFeatures ) mToolbar->insertSeparator( mActionExpressionSelect ); mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable ); mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor ); // Load default attribute table filter QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt(); switch ( defaultFilterMode ) { case QgsAttributeTableFilterModel::ShowVisible: filterVisible(); break; case QgsAttributeTableFilterModel::ShowSelected: filterSelected(); break; case QgsAttributeTableFilterModel::ShowAll: default: filterShowAll(); break; } mUpdateExpressionText->registerGetExpressionContextCallback( &_getExpressionContext, mLayer ); mFieldCombo->setFilters( QgsFieldProxyModel::All | QgsFieldProxyModel::HideReadOnly ); mFieldCombo->setLayer( mLayer ); connect( mRunFieldCalc, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpression() ) ); connect( mRunFieldCalcSelected, SIGNAL( clicked() ), this, SLOT( updateFieldFromExpressionSelected() ) ); // NW TODO Fix in 2.6 - Doesn't work with field model for some reason. // connect( mUpdateExpressionText, SIGNAL( returnPressed() ), this, SLOT( updateFieldFromExpression() ) ); connect( mUpdateExpressionText, SIGNAL( fieldChanged( QString, bool ) ), this, SLOT( updateButtonStatus( QString, bool ) ) ); mUpdateExpressionText->setLayer( mLayer ); mUpdateExpressionText->setLeftHandButtonStyle( true ); int initialView = settings.value( "/qgis/attributeTableView", -1 ).toInt(); if ( initialView < 0 ) { initialView = settings.value( "/qgis/attributeTableLastView", QgsDualView::AttributeTable ).toInt(); } mMainView->setView( static_cast< QgsDualView::ViewMode >( initialView ) ); mMainViewButtonGroup->button( initialView )->setChecked( true ); connect( mActionToggleMultiEdit, SIGNAL( toggled( bool ) ), mMainView, SLOT( setMultiEditEnabled( bool ) ) ); connect( mActionSearchForm, SIGNAL( toggled( bool ) ), mMainView, SLOT( toggleSearchMode( bool ) ) ); updateMultiEditButtonState(); if ( mLayer->editFormConfig()->layout() == QgsEditFormConfig::UiFileLayout ) { //not supported with custom UI mActionToggleMultiEdit->setEnabled( false ); mActionToggleMultiEdit->setToolTip( tr( "Multiedit is not supported when using custom UI forms" ) ); mActionSearchForm->setEnabled( false ); mActionSearchForm->setToolTip( tr( "Search is not supported when using custom UI forms" ) ); } editingToggled(); }
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttributeTableFilterModel::FilterMode initialMode, QWidget *parent, Qt::WindowFlags flags ) : QDialog( parent, flags ) , mLayer( layer ) { setObjectName( QStringLiteral( "QgsAttributeTableDialog/" ) + layer->id() ); setupUi( this ); connect( mActionCutSelectedRows, &QAction::triggered, this, &QgsAttributeTableDialog::mActionCutSelectedRows_triggered ); connect( mActionCopySelectedRows, &QAction::triggered, this, &QgsAttributeTableDialog::mActionCopySelectedRows_triggered ); connect( mActionPasteFeatures, &QAction::triggered, this, &QgsAttributeTableDialog::mActionPasteFeatures_triggered ); connect( mActionToggleEditing, &QAction::toggled, this, &QgsAttributeTableDialog::mActionToggleEditing_toggled ); connect( mActionSaveEdits, &QAction::triggered, this, &QgsAttributeTableDialog::mActionSaveEdits_triggered ); connect( mActionReload, &QAction::triggered, this, &QgsAttributeTableDialog::mActionReload_triggered ); connect( mActionInvertSelection, &QAction::triggered, this, &QgsAttributeTableDialog::mActionInvertSelection_triggered ); connect( mActionRemoveSelection, &QAction::triggered, this, &QgsAttributeTableDialog::mActionRemoveSelection_triggered ); connect( mActionSelectAll, &QAction::triggered, this, &QgsAttributeTableDialog::mActionSelectAll_triggered ); connect( mActionZoomMapToSelectedRows, &QAction::triggered, this, &QgsAttributeTableDialog::mActionZoomMapToSelectedRows_triggered ); connect( mActionPanMapToSelectedRows, &QAction::triggered, this, &QgsAttributeTableDialog::mActionPanMapToSelectedRows_triggered ); connect( mActionSelectedToTop, &QAction::toggled, this, &QgsAttributeTableDialog::mActionSelectedToTop_toggled ); connect( mActionAddAttribute, &QAction::triggered, this, &QgsAttributeTableDialog::mActionAddAttribute_triggered ); connect( mActionRemoveAttribute, &QAction::triggered, this, &QgsAttributeTableDialog::mActionRemoveAttribute_triggered ); connect( mActionOpenFieldCalculator, &QAction::triggered, this, &QgsAttributeTableDialog::mActionOpenFieldCalculator_triggered ); connect( mActionDeleteSelected, &QAction::triggered, this, &QgsAttributeTableDialog::mActionDeleteSelected_triggered ); connect( mMainView, &QgsDualView::currentChanged, this, &QgsAttributeTableDialog::mMainView_currentChanged ); connect( mActionAddFeature, &QAction::triggered, this, &QgsAttributeTableDialog::mActionAddFeature_triggered ); connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered ); connect( mMainView, &QgsDualView::showContextMenuExternally, this, &QgsAttributeTableDialog::showContextMenu ); const QgsFields fields = mLayer->fields(); for ( const QgsField &field : fields ) { mVisibleFields.append( field.name() ); } // Fix selection color on losing focus (Windows) setStyleSheet( QgisApp::instance()->styleSheet() ); setAttribute( Qt::WA_DeleteOnClose ); layout()->setMargin( 0 ); layout()->setContentsMargins( 0, 0, 0, 0 ); static_cast< QGridLayout * >( layout() )->setVerticalSpacing( 0 ); QgsSettings settings; int size = settings.value( QStringLiteral( "/qgis/iconSize" ), 16 ).toInt(); if ( size > 32 ) { size -= 16; } else if ( size == 32 ) { size = 24; } else { size = 16; } mToolbar->setIconSize( QSize( size, size ) ); // Initialize the window geometry restoreGeometry( settings.value( QStringLiteral( "Windows/BetterAttributeTable/geometry" ) ).toByteArray() ); myDa = new QgsDistanceArea(); myDa->setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() ); myDa->setEllipsoid( QgsProject::instance()->ellipsoid() ); mEditorContext.setDistanceArea( *myDa ); mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); mEditorContext.setMapCanvas( QgisApp::instance()->mapCanvas() ); QgsFeatureRequest r; bool needsGeom = false; if ( mLayer->geometryType() != QgsWkbTypes::NullGeometry && initialMode == QgsAttributeTableFilterModel::ShowVisible ) { QgsMapCanvas *mc = QgisApp::instance()->mapCanvas(); QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( layer, mc->extent() ) ); r.setFilterRect( extent ); needsGeom = true; } else if ( initialMode == QgsAttributeTableFilterModel::ShowSelected ) { r.setFilterFids( layer->selectedFeatureIds() ); } if ( !needsGeom ) r.setFlags( QgsFeatureRequest::NoGeometry ); // Initialize dual view mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext, false ); QgsAttributeTableConfig config = mLayer->attributeTableConfig(); mMainView->setAttributeTableConfig( config ); // Initialize filter gui elements mFilterActionMapper = new QSignalMapper( this ); mFilterColumnsMenu = new QMenu( this ); mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu ); mApplyFilterButton->setDefaultAction( mActionApplyFilter ); // Set filter icon in a couple of places QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter2.svg" ); mActionShowAllFilter->setIcon( filterIcon ); mActionAdvancedFilter->setIcon( filterIcon ); mActionSelectedFilter->setIcon( filterIcon ); mActionVisibleFilter->setIcon( filterIcon ); mActionEditedFilter->setIcon( filterIcon ); mActionFeatureActions = new QToolButton(); mActionFeatureActions->setAutoRaise( false ); mActionFeatureActions->setPopupMode( QToolButton::InstantPopup ); mActionFeatureActions->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mAction.svg" ) ) ); mActionFeatureActions->setText( tr( "Actions" ) ); mActionFeatureActions->setToolTip( tr( "Actions" ) ); mToolbar->addWidget( mActionFeatureActions ); // Connect filter signals connect( mActionAdvancedFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterExpressionBuilder ); connect( mActionShowAllFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterShowAll ); connect( mActionSelectedFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterSelected ); connect( mActionVisibleFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterVisible ); connect( mActionEditedFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterEdited ); connect( mFilterActionMapper, SIGNAL( mapped( QObject * ) ), SLOT( filterColumnChanged( QObject * ) ) ); connect( mFilterQuery, &QLineEdit::returnPressed, this, &QgsAttributeTableDialog::filterQueryAccepted ); connect( mActionApplyFilter, &QAction::triggered, this, &QgsAttributeTableDialog::filterQueryAccepted ); connect( mActionSetStyles, &QAction::triggered, this, &QgsAttributeTableDialog::openConditionalStyles ); // info from layer to table connect( mLayer, &QgsVectorLayer::editingStarted, this, &QgsAttributeTableDialog::editingToggled ); connect( mLayer, &QgsVectorLayer::editingStopped, this, &QgsAttributeTableDialog::editingToggled ); connect( mLayer, &QObject::destroyed, mMainView, &QgsDualView::cancelProgress ); connect( mLayer, &QgsVectorLayer::selectionChanged, this, &QgsAttributeTableDialog::updateTitle ); connect( mLayer, &QgsVectorLayer::featureAdded, this, &QgsAttributeTableDialog::updateTitle ); connect( mLayer, &QgsVectorLayer::featuresDeleted, this, &QgsAttributeTableDialog::updateTitle ); connect( mLayer, &QgsVectorLayer::editingStopped, this, &QgsAttributeTableDialog::updateTitle ); connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsAttributeTableDialog::columnBoxInit ); connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsAttributeTableDialog::columnBoxInit ); connect( mLayer, &QgsVectorLayer::readOnlyChanged, this, &QgsAttributeTableDialog::editingToggled ); // connect table info to window connect( mMainView, &QgsDualView::filterChanged, this, &QgsAttributeTableDialog::updateTitle ); connect( mMainView, &QgsDualView::filterExpressionSet, this, &QgsAttributeTableDialog::formFilterSet ); connect( mMainView, &QgsDualView::formModeChanged, this, &QgsAttributeTableDialog::viewModeChanged ); // info from table to application connect( this, &QgsAttributeTableDialog::saveEdits, this, [ = ] { QgisApp::instance()->saveEdits(); } ); const bool dockTable = settings.value( QStringLiteral( "qgis/dockAttributeTable" ), false ).toBool(); if ( dockTable ) { mDock = new QgsAttributeTableDock( QString(), QgisApp::instance() ); mDock->setWidget( this ); connect( this, &QObject::destroyed, mDock, &QWidget::close ); QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock ); } mActionDockUndock->setChecked( dockTable ); connect( mActionDockUndock, &QAction::toggled, this, &QgsAttributeTableDialog::toggleDockMode ); installEventFilter( this ); columnBoxInit(); updateTitle(); mActionRemoveSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeselectAll.svg" ) ) ); mActionSelectAll->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSelectAll.svg" ) ) ); mActionSelectedToTop->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSelectedToTop.svg" ) ) ); mActionCopySelectedRows->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionEditCopy.svg" ) ) ); mActionPasteFeatures->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionEditPaste.svg" ) ) ); mActionZoomMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionZoomToSelected.svg" ) ) ); mActionPanMapToSelectedRows->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionPanToSelected.svg" ) ) ); mActionInvertSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionInvertSelection.svg" ) ) ); mActionToggleEditing->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionToggleEditing.svg" ) ) ); mActionSaveEdits->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSaveEdits.svg" ) ) ); mActionDeleteSelected->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteSelected.svg" ) ) ); mActionOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionCalculateField.svg" ) ) ); mActionAddAttribute->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionNewAttribute.svg" ) ) ); mActionRemoveAttribute->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteAttribute.svg" ) ) ); mTableViewButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionOpenTable.svg" ) ) ); mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFormView.svg" ) ) ); mActionExpressionSelect->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpressionSelect.svg" ) ) ); mActionAddFeature->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionNewTableRow.svg" ) ) ); mActionFeatureActions->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mAction.svg" ) ) ); // toggle editing bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues; bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures; bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes; bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes; bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures; mActionToggleEditing->blockSignals( true ); mActionToggleEditing->setCheckable( true ); mActionToggleEditing->setChecked( mLayer->isEditable() ); mActionToggleEditing->blockSignals( false ); mActionSaveEdits->setEnabled( mActionToggleEditing->isEnabled() && mLayer->isEditable() ); mActionReload->setEnabled( ! mLayer->isEditable() ); mActionAddAttribute->setEnabled( ( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() ); mActionRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() ); if ( !canDeleteFeatures ) { mToolbar->removeAction( mActionDeleteSelected ); mToolbar->removeAction( mActionCutSelectedRows ); } mActionAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() ); mActionPasteFeatures->setEnabled( canAddFeatures && mLayer->isEditable() ); if ( !canAddFeatures ) { mToolbar->removeAction( mActionAddFeature ); mToolbar->removeAction( mActionPasteFeatures ); } mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable ); mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor ); switch ( initialMode ) { case QgsAttributeTableFilterModel::ShowVisible: filterVisible(); break; case QgsAttributeTableFilterModel::ShowSelected: filterSelected(); break; case QgsAttributeTableFilterModel::ShowAll: default: filterShowAll(); break; } // Layer might have been destroyed while loading! if ( mLayer ) { mUpdateExpressionText->registerExpressionContextGenerator( this ); mFieldCombo->setFilters( QgsFieldProxyModel::AllTypes | QgsFieldProxyModel::HideReadOnly ); mFieldCombo->setLayer( mLayer ); connect( mRunFieldCalc, &QAbstractButton::clicked, this, &QgsAttributeTableDialog::updateFieldFromExpression ); connect( mRunFieldCalcSelected, &QAbstractButton::clicked, this, &QgsAttributeTableDialog::updateFieldFromExpressionSelected ); // NW TODO Fix in 2.6 - Doesn't work with field model for some reason. // connect( mUpdateExpressionText, SIGNAL( returnPressed() ), this, SLOT( updateFieldFromExpression() ) ); connect( mUpdateExpressionText, static_cast < void ( QgsFieldExpressionWidget::* )( const QString &, bool ) > ( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsAttributeTableDialog::updateButtonStatus ); mUpdateExpressionText->setLayer( mLayer ); mUpdateExpressionText->setLeftHandButtonStyle( true ); int initialView = settings.value( QStringLiteral( "qgis/attributeTableView" ), -1 ).toInt(); if ( initialView < 0 ) { initialView = settings.value( QStringLiteral( "qgis/attributeTableLastView" ), QgsDualView::AttributeTable ).toInt(); } mMainView->setView( static_cast< QgsDualView::ViewMode >( initialView ) ); mMainViewButtonGroup->button( initialView )->setChecked( true ); connect( mActionToggleMultiEdit, &QAction::toggled, mMainView, &QgsDualView::setMultiEditEnabled ); connect( mActionSearchForm, &QAction::toggled, mMainView, &QgsDualView::toggleSearchMode ); updateMultiEditButtonState(); if ( mLayer->editFormConfig().layout() == QgsEditFormConfig::UiFileLayout ) { //not supported with custom UI mActionToggleMultiEdit->setEnabled( false ); mActionToggleMultiEdit->setToolTip( tr( "Multiedit is not supported when using custom UI forms" ) ); mActionSearchForm->setEnabled( false ); mActionSearchForm->setToolTip( tr( "Search is not supported when using custom UI forms" ) ); } editingToggled(); // Close and delete if the layer has been destroyed connect( mLayer, &QObject::destroyed, this, &QWidget::close ); } else { QWidget::close(); } }
void checkDock::errorListClicked( const QModelIndex& index ) { int row = index.row(); QgsRectangle r = mErrorList[row]->boundingBox(); r.scale( 1.5 ); QgsMapCanvas* canvas = qgsInterface->mapCanvas(); canvas->setExtent( r ); canvas->refresh(); mFixBox->clear(); mFixBox->addItems( mErrorList[row]->fixNames() ); mFixBox->setCurrentIndex( mFixBox->findText( tr( "Select automatic fix" ) ) ); QgsFeature f; QgsGeometry* g; FeatureLayer fl = mErrorList[row]->featurePairs().first(); if ( !fl.layer ) { QgsMessageLog::logMessage( tr( "Invalid first layer" ), tr( "Topology plugin" ) ); return; } //fl1.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl1.feature.id() ) ).nextFeature( f1 ); fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f ); g = f.geometry(); if ( !g ) { QgsMessageLog::logMessage( tr( "Invalid first geometry" ), tr( "Topology plugin" ) ); QMessageBox::information( this, tr( "Topology test" ), tr( "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again." ) ); return; } clearVertexMarkers(); // use vertex marker when highlighting a point // and rubber band otherwise if ( g->type() == QGis::Point ) { mVMFeature1 = new QgsVertexMarker( canvas ); mVMFeature1->setIconType( QgsVertexMarker::ICON_X ); mVMFeature1->setPenWidth( 5 ); mVMFeature1->setIconSize( 5 ); mVMFeature1->setColor( "blue" ); mVMFeature1->setCenter( g->asPoint() ); } else mRBFeature1->setToGeometry( g, fl.layer ); fl = mErrorList[row]->featurePairs()[1]; if ( !fl.layer ) { QgsMessageLog::logMessage( tr( "Invalid second layer" ), tr( "Topology plugin" ) ); return; } fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f ); g = f.geometry(); if ( !g ) { QgsMessageLog::logMessage( tr( "Invalid second geometry" ), tr( "Topology plugin" ) ); QMessageBox::information( this, tr( "Topology test" ), tr( "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again." ) ); return; } if ( g->type() == QGis::Point ) { mVMFeature2 = new QgsVertexMarker( canvas ); mVMFeature2->setIconType( QgsVertexMarker::ICON_BOX ); mVMFeature2->setPenWidth( 5 ); mVMFeature2->setIconSize( 5 ); mVMFeature2->setColor( "green" ); mVMFeature2->setCenter( g->asPoint() ); } else mRBFeature2->setToGeometry( g, fl.layer ); if ( !mErrorList[row]->conflict() ) { QgsMessageLog::logMessage( tr( "Invalid conflict" ), tr( "Topology plugin" ) ); return; } if ( mErrorList[row]->conflict()->type() == QGis::Point ) { mVMConflict = new QgsVertexMarker( canvas ); mVMConflict->setIconType( QgsVertexMarker::ICON_BOX ); mVMConflict->setPenWidth( 5 ); mVMConflict->setIconSize( 5 ); mVMConflict->setColor( "red" ); mVMConflict->setCenter( mErrorList[row]->conflict()->asPoint() ); } else mRBConflict->setToGeometry( mErrorList[row]->conflict(), fl.layer ); }
bool QgsDecorationNorthArrow::calculateNorthDirection() { QgsMapCanvas* mapCanvas = QgisApp::instance()->mapCanvas(); bool goodDirn = false; // Get the shown extent... QgsRectangle canvasExtent = mapCanvas->extent(); // ... and all layers extent, ... QgsRectangle fullExtent = mapCanvas->fullExtent(); // ... and combine QgsRectangle extent = canvasExtent.intersect( & fullExtent ); // If no layers are added or shown, we can't get any direction if ( mapCanvas->layerCount() > 0 && ! extent.isEmpty() ) { QgsCoordinateReferenceSystem outputCRS = mapCanvas->mapSettings().destinationCrs(); if ( outputCRS.isValid() && !outputCRS.geographicFlag() ) { // Use a geographic CRS to get lat/long to work out direction QgsCoordinateReferenceSystem ourCRS = QgsCrsCache::instance()->crsByOgcWmsCrs( GEO_EPSG_CRS_AUTHID ); assert( ourCRS.isValid() ); QgsCoordinateTransform transform( outputCRS, ourCRS ); QgsPoint p1( extent.center() ); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2( p1.x(), p1.y() + extent.height() * 0.25 ); // project p1 and p2 to geographic coords try { p1 = transform.transform( p1 ); p2 = transform.transform( p2 ); } catch ( QgsCsException &e ) { Q_UNUSED( e ); // just give up QgsDebugMsg( "North Arrow: Transformation error, quitting" ); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply( PI / 180.0 ); p2.multiply( PI / 180.0 ); double y = sin( p2.x() - p1.x() ) * cos( p2.y() ); double x = cos( p1.y() ) * sin( p2.y() ) - sin( p1.y() ) * cos( p2.y() ) * cos( p2.x() - p1.x() ); // Use TOL to decide if the quotient is big enough. // Both x and y can be very small, if heavily zoomed // For small y/x, we set directly angle 0. Not sure // if this is needed. if ( y > 0.0 ) { if ( x > 0.0 && ( y / x ) > TOL ) angle = atan( y / x ); else if ( x < 0.0 && ( y / x ) < -TOL ) angle = PI - atan( -y / x ); else angle = 0.5 * PI; } else if ( y < 0.0 ) { if ( x > 0.0 && ( y / x ) < -TOL ) angle = -atan( -y / x ); else if ( x < 0.0 && ( y / x ) > TOL ) angle = atan( y / x ) - PI; else angle = 1.5 * PI; } else { if ( x > TOL ) angle = 0.0; else if ( x < -TOL ) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = qRound( fmod( 360.0 - angle * 180.0 / PI, 360.0 ) ); } else { // For geographic CRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } mRotationInt += mapCanvas->mapSettings().rotation(); return goodDirn; }