Index: src/app/qgsframewidget.cpp =================================================================== --- src/app/qgsframewidget.cpp (revision 0) +++ src/app/qgsframewidget.cpp (revision 0) @@ -0,0 +1,704 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qgisapp.h" +#include "qgsapplication.h" +#include "qgscursors.h" +#include "qgslegend.h" +#include "qgsmapcanvas.h" +#include "qgsmaplayerregistry.h" +#include "qgsmapoverviewcanvas.h" +#include "qgsmaptip.h" +#include "qgsproject.h" + +// map tools +#include "qgsmaptooladdfeature.h" +#include "qgsmaptooladdisland.h" +#include "qgsmaptooladdring.h" +#include "qgsmaptooladdvertex.h" +#include "qgsmaptooldeletering.h" +#include "qgsmaptooldeletepart.h" +#include "qgsmaptooldeletevertex.h" +#include "qgsmaptoolidentify.h" +#include "qgsmaptoolmovefeature.h" +#include "qgsmaptoolmovevertex.h" +#include "qgsmaptoolnodetool.h" +#include "qgsmaptoolpan.h" +#include "qgsmaptoolselect.h" +#include "qgsmaptoolsplitfeatures.h" +#include "qgsmaptoolvertexedit.h" +#include "qgsmaptoolzoom.h" +#include "qgsmaptoolsimplify.h" +#include "qgsmeasuretool.h" + +#include "tabs/qgsdesktabwidget.h" + +#include "qgsframewidget.h" + +QgsFrameWidget::QgsFrameWidget( QgisApp *qgis ) + : mQgis(qgis) +{ + setObjectName( "theFrameWidget" ); + + createStatusBar(); + createCanvas(); + createLegend(); + createOverview(); + createMapTips(); + + mMapTipsVisible = false; + mQgisMenuBar = qgis->menuBar(); +} + +QgsFrameWidget::~QgsFrameWidget() +{ + delete mMapOverviewCanvas; + delete mLegend; + delete mTools; + delete mMapCanvas; +} + +// ------------------------------- public ---------------------------------- // +void QgsFrameWidget::setupConnections() +{ + // connect map layer registry signals to legend + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), + mLegend, SLOT( removeLayer( QString ) ) ); + connect( QgsMapLayerRegistry::instance(), SIGNAL( removedAll() ), + mLegend, SLOT( removeAll() ) ); + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), + mLegend, SLOT( addLayer( QgsMapLayer * ) ) ); + connect( mLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), + mQgis, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer* ) ) ); + + connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), + this, SLOT( layerWasAdded( QgsMapLayer * ) ) ); + + //signal when mouse moved over window ( coords display in status bar ) + connect( mMapCanvas, SIGNAL( xyCoordinates( const QgsPoint & ) ), this, SLOT( showMouseCoordinate( const QgsPoint & ) ) ); + connect( mMapCanvas->mapRenderer(), SIGNAL( drawingProgress( int, int ) ), this, SLOT( showProgress( int, int ) ) ); + connect( mMapCanvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( hasCrsTransformEnabled( bool ) ) ); + connect( mMapCanvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( destinationSrsChanged() ) ); + connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( showExtents() ) ); + connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( showScale( double ) ) ); + connect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( updateMouseCoordinatePrecision() ) ); + connect( mMapCanvas, SIGNAL( mapToolSet( QgsMapTool * ) ), this, SLOT( mapToolChanged( QgsMapTool * ) ) ); + connect( mMapCanvas, SIGNAL( selectionChanged( QgsMapLayer * ) ), + mQgis, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer * ) ) ); + + connect( mRenderSuppressionCBox, SIGNAL( toggled( bool ) ), mMapCanvas, SLOT( setRenderFlag( bool ) ) ); + connect( mStopRenderButton, SIGNAL( clicked() ), mQgis, SLOT( stopRendering() ) ); + + connect( QgsProject::instance(), SIGNAL( layerLoaded( int, int ) ), this, SLOT( showProgress( int, int ) ) ); +} // setupConnections + +void QgsFrameWidget::removeConnections() +{ + // disconnect map layer registry signals to legend + disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), + mLegend, SLOT( removeLayer( QString ) ) ); + disconnect( QgsMapLayerRegistry::instance(), SIGNAL( removedAll() ), + mLegend, SLOT( removeAll() ) ); + disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), + mLegend, SLOT( addLayer( QgsMapLayer * ) ) ); + disconnect( mLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), + mQgis, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer* ) ) ); + + disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), + this, SLOT( layerWasAdded( QgsMapLayer * ) ) ); + + //signal when mouse moved over window ( coords display in status bar ) + disconnect( mMapCanvas, SIGNAL( xyCoordinates( const QgsPoint & ) ), this, SLOT( showMouseCoordinate( const QgsPoint & ) ) ); + disconnect( mMapCanvas->mapRenderer(), SIGNAL( drawingProgress( int, int ) ), this, SLOT( showProgress( int, int ) ) ); + disconnect( mMapCanvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( hasCrsTransformEnabled( bool ) ) ); + disconnect( mMapCanvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( destinationSrsChanged() ) ); + disconnect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( showExtents() ) ); + disconnect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( showScale( double ) ) ); + disconnect( mMapCanvas, SIGNAL( scaleChanged( double ) ), this, SLOT( updateMouseCoordinatePrecision() ) ); + disconnect( mMapCanvas, SIGNAL( mapToolSet( QgsMapTool * ) ), this, SLOT( mapToolChanged( QgsMapTool * ) ) ); + disconnect( mMapCanvas, SIGNAL( selectionChanged( QgsMapLayer * ) ), + mQgis, SLOT( activateDeactivateLayerRelatedActions( QgsMapLayer * ) ) ); + + disconnect( mRenderSuppressionCBox, SIGNAL( toggled( bool ) ), mMapCanvas, SLOT( setRenderFlag( bool ) ) ); + disconnect( mStopRenderButton, SIGNAL( clicked() ), mQgis, SLOT( stopRendering() ) ); + + disconnect( QgsProject::instance(), SIGNAL( layerLoaded( int, int ) ), this, SLOT( showProgress( int, int ) ) ); +} // removeConnections + +void QgsFrameWidget::saveState() +{ + mQgisState = mQgis->saveState(); + if (mQgisMenuBar->isVisible()) + { + mQgisMenuBar->close(); + mQgisMenuBar->setParent(0); + } +} + +void QgsFrameWidget::restoreState() +{ + QList< QToolBar * > tbs = mQgis->findChildren< QToolBar * >(); + foreach( QToolBar *tb, tbs) + tb->hide(); + + if (mQgisMenuBar->isHidden()) + { + mQgis->menuBar()->close(); + mQgis->menuBar()->setParent(0); + mQgis->setMenuBar(mQgisMenuBar); + mQgis->menuBar()->show(); + } + + mQgis->restoreState(mQgisState); +} + +// ----------------------------- private slots ----------------------------- // +void QgsFrameWidget::destinationSrsChanged() +{ + // save this information to project + long srsid = mMapCanvas->mapRenderer()->destinationSrs().srsid(); + QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int )srsid ); +} + +// slot to update the progress bar in the status bar +void QgsFrameWidget::hasCrsTransformEnabled( bool theFlag ) +{ + // save this information to project + QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectionsEnabled", ( theFlag ? 1 : 0 ) ); + + // update icon + if ( theFlag ) + { + mOnTheFlyProjectionStatusButton->setIcon( + mQgis->getThemeIcon( "mIconProjectionEnabled.png" ) ); + } + else + { + mOnTheFlyProjectionStatusButton->setIcon( + mQgis->getThemeIcon( "mIconProjectionDisabled.png" ) ); + } +} + +void QgsFrameWidget::mapToolChanged( QgsMapTool *tool ) +{ + if ( tool ) + { + if ( !tool->isEditTool() ) + { + mQgis->mNonEditMapTool = tool; + } + mTools->mCurrentTool = tool; + } +} + +void QgsFrameWidget::projectPropertiesProjections() +{ + // Driver to display the project props dialog and switch to the + // projections tab + mQgis->mShowProjectionTab = true; + mQgis->projectProperties(); +} + +void QgsFrameWidget::showProgress( int theProgress, int theTotalSteps ) +{ + if ( theProgress == theTotalSteps ) + { + mProgressBar->reset(); + mProgressBar->hide(); + } + else + { + //only call show if not already hidden to reduce flicker + if ( !mProgressBar->isVisible() ) + { + mProgressBar->show(); + } + mProgressBar->setMaximum( theTotalSteps ); + mProgressBar->setValue( theProgress ); + } +} + +void QgsFrameWidget::showMouseCoordinate( const QgsPoint & p ) +{ + if ( mMapTipsVisible ) + { + // store the point, we need it for when the maptips timer fires + mLastMapPosition = p; + + // we use this slot to control the timer for maptips since it is fired each time + // the mouse moves. + if ( mMapCanvas->underMouse() ) + { + // Clear the maptip (this is done conditionally) + mpMaptip->clear( mMapCanvas ); + // don't start the timer if the mouse is not over the map canvas + mpMapTipsTimer->start(); + //QgsDebugMsg("Started maptips timer"); + } + } + if ( mToggleExtentsViewButton->isChecked() ) + { + //we are in show extents mode so no need to do anything + return; + } + else + { + mCoordsLabel->setText( p.toString( mMousePrecisionDecimalPlaces ) ); + // Set minimum necessary width + if ( mCoordsLabel->width() > mCoordsLabel->minimumWidth() ) + { + mCoordsLabel->setMinimumWidth( mCoordsLabel->width() ); + } + } +} + +void QgsFrameWidget::showScale( double theScale ) +{ + if ( theScale >= 1.0 ) + mScaleEdit->setText( "1:" + QString::number( theScale, 'f', 0 ) ); + else if ( theScale > 0.0 ) + mScaleEdit->setText( QString::number( 1.0 / theScale, 'f', 0 ) + ":1" ); + else + mScaleEdit->setText( tr( "Invalid scale" ) ); + + // Set minimum necessary width + if ( mScaleEdit->width() > mScaleEdit->minimumWidth() ) + { + mScaleEdit->setMinimumWidth( mScaleEdit->width() ); + } +} + +void QgsFrameWidget::showExtents() +{ + if ( !mToggleExtentsViewButton->isChecked() ) + { + //we are in show coords mode so no need to do anything + return; + } + // update the statusbar with the current extents. + QgsRectangle myExtents = mMapCanvas->extent(); + mCoordsLabel->setText( tr( "Extents: %1" ).arg( myExtents.toString( true ) ) ); + //ensure the label is big enough + if ( mCoordsLabel->width() > mCoordsLabel->minimumWidth() ) + { + mCoordsLabel->setMinimumWidth( mCoordsLabel->width() ); + } +} + +void QgsFrameWidget::showMapTip() +{ + /* Show the maptip using tooltip */ + // Stop the timer while we look for a maptip + mpMapTipsTimer->stop(); + + // Only show tooltip if the mouse is over the canvas + if ( mMapCanvas->underMouse() ) + { + QPoint myPointerPos = mMapCanvas->mouseLastXY(); + + // Make sure there is an active layer before proceeding + + QgsMapLayer* mypLayer = mMapCanvas->currentLayer(); + if ( mypLayer ) + { + //QgsDebugMsg("Current layer for maptip display is: " + mypLayer->source()); + // only process vector layers + if ( mypLayer->type() == QgsMapLayer::VectorLayer ) + { + // Show the maptip if the maptips button is depressed + if ( mMapTipsVisible ) + { + mpMaptip->showMapTip( mypLayer, mLastMapPosition, myPointerPos, mMapCanvas ); + } + } + } + else + { + mStatusBar->showMessage( tr( "Maptips require an active layer" ) ); + } + } +} + +void QgsFrameWidget::extentsViewToggled( bool theFlag ) +{ + if ( theFlag ) + { + //extents view mode! + mToggleExtentsViewButton->setIcon( mQgis->getThemeIcon( "extents.png" ) ); + mCoordsLabel->setToolTip( tr( "Map coordinates for the current view extents" ) ); + showExtents(); + } + else + { + //mouse cursor pos view mode! + mToggleExtentsViewButton->setIcon( mQgis->getThemeIcon( "tracking.png" ) ); + mCoordsLabel->setToolTip( tr( "Map coordinates at mouse cursor position" ) ); + } +} + +void QgsFrameWidget::updateMouseCoordinatePrecision() +{ + // Work out what mouse display precision to use. This only needs to + // be when the settings change or the zoom level changes. This + // function needs to be called every time one of the above happens. + + // Get the display precision from the project settings + bool automatic = QgsProject::instance()->readBoolEntry( "PositionPrecision", "/Automatic" ); + int dp = 0; + + if ( automatic ) + { + // Work out a suitable number of decimal places for the mouse + // coordinates with the aim of always having enough decimal places + // to show the difference in position between adjacent pixels. + // Also avoid taking the log of 0. + if ( mMapCanvas->mapUnitsPerPixel() != 0.0 ) + dp = static_cast( ceil( -1.0 * log10( mMapCanvas->mapUnitsPerPixel() ) ) ); + } + else + dp = QgsProject::instance()->readNumEntry( "PositionPrecision", "/DecimalPlaces" ); + + // Keep dp sensible + if ( dp < 0 ) dp = 0; + + mMousePrecisionDecimalPlaces = dp; +} + +void QgsFrameWidget::userScale() +{ + double currentScale = mMapCanvas->scale(); + + QStringList parts = mScaleEdit->text().split( ':' ); + if ( parts.size() == 2 ) + { + bool leftOk, rightOk; + double leftSide = parts.at( 0 ).toDouble( &leftOk ); + double rightSide = parts.at( 1 ).toDouble( &rightOk ); + if ( leftSide > 0.0 && leftOk && rightOk ) + { + double wantedScale = rightSide / leftSide; + mMapCanvas->zoomByFactor( wantedScale / currentScale ); + } + } +} + +void QgsFrameWidget::userCenter() +{ + QStringList parts = mCoordsEdit->text().split( ',' ); + if ( parts.size() != 2 ) + return; + + bool xOk; + double x = parts.at( 0 ).toDouble( &xOk ); + if ( !xOk ) + return; + + bool yOk; + double y = parts.at( 1 ).toDouble( &yOk ); + if ( !yOk ) + return; + + QgsRectangle r = mMapCanvas->extent(); + + mMapCanvas->setExtent( + QgsRectangle( + x - r.width() / 2.0, y - r.height() / 2.0, + x + r.width() / 2.0, y + r.height() / 2.0 + ) + ); + mMapCanvas->refresh(); +} + +void QgsFrameWidget::layerWasAdded( QgsMapLayer *layer ) +{ + if ( layer->type() == QgsMapLayer::RasterLayer ) + { + QObject::connect( layer, + SIGNAL( drawingProgress( int, int ) ), + this, + SLOT( showProgress( int, int ) ) ); + // connect up any request the raster may make to update the statusbar message + QObject::connect( layer, + SIGNAL( statusChanged( QString ) ), + mStatusBar, + SLOT( showMessage( QString ) ) ); + } +} + +// ------------------------------- private --------------------------------- // +void QgsFrameWidget::createCanvas() +{ + // create map canvas and tools + mMapCanvas = new QgsMapCanvas( this ); + mTools = new QgisApp::Tools(); + + setToolsForMapCanvas( mMapCanvas, mTools ); + mMapCanvas->setObjectName( "theMapCanvas" ); + + // set canvas color in map canvas + int redInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorRedPart", 255 ); + int greenInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorGreenPart", 255 ); + int blueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 ); + QColor color = QColor( redInt, greenInt, blueInt ); + mMapCanvas->setCanvasColor( color ); // this is fill colour before rendering onto canvas + + // set initial extent for map canvas + QRect tabRect = mQgis->deskTabWidget()->rect(); + QgsRectangle initExtent(tabRect.x(), tabRect.y(), tabRect.width(), tabRect.height()); + mMapCanvas->setExtent(initExtent); +} + +void QgsFrameWidget::createLegend() +{ + // create map legend for map canvas + mLegend = new QgsLegend( NULL, "theMapLegend" ); + mLegend->setObjectName( "theMapLegend" ); + mLegend->setMapCanvas( mMapCanvas ); + + // add the toggle editing action also to legend such that right click menu and button show the same state + mLegend->setToggleEditingAction( mQgis->actionToggleEditing() ); + mLegend->setWhatsThis( 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." ) ); +} + +void QgsFrameWidget::createOverview() +{ + // create overview canvas + mMapOverviewCanvas = new QgsMapOverviewCanvas( NULL, mMapCanvas ); + mMapOverviewCanvas->setWhatsThis( 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." ) ); + + QBitmap overviewPanBmp = QBitmap::fromData( QSize( 16, 16 ), pan_bits ); + QBitmap overviewPanBmpMask = QBitmap::fromData( QSize( 16, 16 ), pan_mask_bits ); + //set upper left corner as hot spot - this is better when extent marker is small; hand won't cover the marker + mQgis->mOverviewMapCursor = new QCursor( overviewPanBmp, overviewPanBmpMask, 0, 0 ); + mMapOverviewCanvas->setCursor( *mQgis->mOverviewMapCursor ); + + mMapCanvas->enableOverviewMode( mMapOverviewCanvas ); + + // moved here to set anti aliasing to both map canvas and overview + QSettings mySettings; + mMapCanvas->enableAntiAliasing( mySettings.value( "/qgis/enable_anti_aliasing", false ).toBool() ); + mMapCanvas->useImageToRender( mySettings.value( "/qgis/use_qimage_to_render", false ).toBool() ); + + int action = mySettings.value( "/qgis/wheel_action", 0 ).toInt(); + double zoomFactor = mySettings.value( "/qgis/zoom_factor", 2 ).toDouble(); + mMapCanvas->setWheelAction(( QgsMapCanvas::WheelAction ) action, zoomFactor ); +} + +void QgsFrameWidget::createMapTips() +{ + // Set up the timer for maptips. The timer is reset everytime the mouse is moved + mpMapTipsTimer = new QTimer( mMapCanvas ); + // connect the timer to the maptips slot + connect( mpMapTipsTimer, SIGNAL( timeout() ), this, SLOT( showMapTip() ) ); + // set the interval to 0.850 seconds - timer will be started next time the mouse moves + mpMapTipsTimer->setInterval( 850 ); + // Create the maptips object + mpMaptip = new QgsMapTip(); +} + +void QgsFrameWidget::createStatusBar() +{ + mStatusBar = new QStatusBar; + // + // Add a panel to the status bar for the scale, coords and progress + // And also rendering suppression checkbox + // + mProgressBar = new QProgressBar( mStatusBar ); + mProgressBar->setMaximumWidth( 100 ); + mProgressBar->hide(); + mProgressBar->setWhatsThis( tr( "Progress bar that displays the status " + "of rendering layers and other time-intensive operations" ) ); + mStatusBar->addPermanentWidget( mProgressBar, 1 ); + // Bumped the font up one point size since 8 was too + // small on some platforms. A point size of 9 still provides + // plenty of display space on 1024x768 resolutions + QFont myFont( "Arial", 9 ); + + mStatusBar->setFont( myFont ); + //toggle to switch between mouse pos and extents display in status bar widget + mToggleExtentsViewButton = new QToolButton( mStatusBar ); + mToggleExtentsViewButton->setMaximumWidth( 20 ); + mToggleExtentsViewButton->setMaximumHeight( 20 ); + mToggleExtentsViewButton->setIcon( mQgis->getThemeIcon( "tracking.png" ) ); + mToggleExtentsViewButton->setToolTip( tr( "Toggle extents and mouse position display" ) ); + mToggleExtentsViewButton->setCheckable( true ); + connect( mToggleExtentsViewButton, SIGNAL( toggled( bool ) ), this, SLOT( extentsViewToggled( bool ) ) ); + mStatusBar->addPermanentWidget( mToggleExtentsViewButton, 0 ); + + // add a label to show current scale + mCoordsLabel = new QLabel( QString(), mStatusBar ); + mCoordsLabel->setFont( myFont ); + mCoordsLabel->setMinimumWidth( 10 ); + mCoordsLabel->setMaximumHeight( 20 ); + mCoordsLabel->setMargin( 3 ); + mCoordsLabel->setAlignment( Qt::AlignCenter ); + mCoordsLabel->setFrameStyle( QFrame::NoFrame ); + mCoordsLabel->setText( tr( "Coordinate:" ) ); + mCoordsLabel->setToolTip( tr( "Current map coordinate" ) ); + mStatusBar->addPermanentWidget( mCoordsLabel, 0 ); + + //coords status bar widget + mCoordsEdit = new QLineEdit( QString(), mStatusBar ); + mCoordsEdit->setFont( myFont ); + mCoordsEdit->setMinimumWidth( 10 ); + mCoordsEdit->setMaximumWidth( 200 ); + mCoordsEdit->setMaximumHeight( 20 ); + mCoordsEdit->setContentsMargins( 0, 0, 0, 0 ); + mCoordsEdit->setAlignment( Qt::AlignCenter ); + mCoordsEdit->setAlignment( Qt::AlignCenter ); + QRegExp coordValidator( "[+-]?\\d+\\.?\\d*\\s*,\\s*[+-]?\\d+\\.?\\d*" ); + mCoordsEditValidator = new QRegExpValidator( coordValidator, mCoordsEdit ); + mCoordsEdit->setWhatsThis( tr( "Shows the map coordinates at the " + "current cursor position. The display is continuously updated " + "as the mouse is moved. It also allows editing to set the canvas " + "center to a given position." ) ); + mCoordsEdit->setToolTip( tr( "Current map coordinate (formatted as x,y)" ) ); + mStatusBar->addPermanentWidget( mCoordsEdit, 0 ); + connect( mCoordsEdit, SIGNAL( editingFinished() ), this, SLOT( userCenter() ) ); + + // add a label to show current scale + mScaleLabel = new QLabel( QString(), mStatusBar ); + mScaleLabel->setFont( myFont ); + mScaleLabel->setMinimumWidth( 10 ); + mScaleLabel->setMaximumHeight( 20 ); + mScaleLabel->setMargin( 3 ); + mScaleLabel->setAlignment( Qt::AlignCenter ); + mScaleLabel->setFrameStyle( QFrame::NoFrame ); + mScaleLabel->setText( tr( "Scale " ) ); + mScaleLabel->setToolTip( tr( "Current map scale" ) ); + mStatusBar->addPermanentWidget( mScaleLabel, 0 ); + + mScaleEdit = new QLineEdit( QString(), mStatusBar ); + mScaleEdit->setFont( myFont ); + mScaleEdit->setMinimumWidth( 10 ); + mScaleEdit->setMaximumWidth( 100 ); + mScaleEdit->setMaximumHeight( 20 ); + mScaleEdit->setContentsMargins( 0, 0, 0, 0 ); + mScaleEdit->setAlignment( Qt::AlignLeft ); + QRegExp validator( "\\d+\\.?\\d*:\\d+\\.?\\d*" ); + mScaleEditValidator = new QRegExpValidator( validator, mScaleEdit ); + mScaleEdit->setValidator( mScaleEditValidator ); + mScaleEdit->setWhatsThis( tr( "Displays the current map scale" ) ); + mScaleEdit->setToolTip( tr( "Current map scale (formatted as x:y)" ) ); + mStatusBar->addPermanentWidget( mScaleEdit, 0 ); + connect( mScaleEdit, SIGNAL( editingFinished() ), this, SLOT( userScale() ) ); + + //stop rendering status bar widget + mStopRenderButton = new QToolButton( mStatusBar ); + mStopRenderButton->setMaximumWidth( 20 ); + mStopRenderButton->setMaximumHeight( 20 ); + mStopRenderButton->setIcon( mQgis->getThemeIcon( "mIconDelete.png" ) ); + mStopRenderButton->setToolTip( tr( "Stop map rendering" ) ); + mStatusBar->addPermanentWidget( mStopRenderButton, 0 ); + // render suppression status bar widget + mRenderSuppressionCBox = new QCheckBox( tr( "Render" ), mStatusBar ); + mRenderSuppressionCBox->setChecked( true ); + mRenderSuppressionCBox->setFont( myFont ); + mRenderSuppressionCBox->setWhatsThis( 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." ) ); + mRenderSuppressionCBox->setToolTip( tr( "Toggle map rendering" ) ); + mStatusBar->addPermanentWidget( mRenderSuppressionCBox, 0 ); + // On the fly projection status bar icon + // Changed this to a tool button since a QPushButton is + // sculpted on OS X and the icon is never displayed [gsherman] + mOnTheFlyProjectionStatusButton = new QToolButton( mStatusBar ); + mOnTheFlyProjectionStatusButton->setMaximumWidth( 20 ); + // Maintain uniform widget height in status bar by setting button height same as labels + // For Qt/Mac 3.3, the default toolbutton height is 30 and labels were expanding to match + mOnTheFlyProjectionStatusButton->setMaximumHeight( mScaleLabel->height() ); + mOnTheFlyProjectionStatusButton->setIcon( mQgis->getThemeIcon( "mIconProjectionDisabled.png" ) ); + if ( !QFile::exists( QgsApplication::defaultThemePath() + "/mIconProjectionDisabled.png" ) ) + { + QMessageBox::critical( this, tr( "Resource Location Error" ), + tr( "Error reading icon resources from: \n %1\n Quitting..." ).arg( + QgsApplication::defaultThemePath() + "/mIconProjectionDisabled.png" + ) ); + exit( 0 ); + } + mOnTheFlyProjectionStatusButton->setWhatsThis( tr( "This icon shows whether " + "on the fly coordinate reference system transformation is enabled or not. " + "Click the icon to bring up " + "the project properties dialog to alter this behaviour." ) ); + mOnTheFlyProjectionStatusButton->setToolTip( tr( "CRS status - Click " + "to open coordinate reference system dialog" ) ); + connect( mOnTheFlyProjectionStatusButton, SIGNAL( clicked() ), + this, SLOT( projectPropertiesProjections() ) );//bring up the project props dialog when clicked + mStatusBar->addPermanentWidget( mOnTheFlyProjectionStatusButton, 0 ); + mStatusBar->showMessage( tr( "Ready" ) ); +} + +void QgsFrameWidget::setToolsForMapCanvas( QgsMapCanvas *theMapCanvas, QgisApp::Tools *theMapTools ) +{ + // "theMapCanvas" used to find this canonical instance later + theMapCanvas->setWhatsThis( tr( "Map canvas. This is where raster and vector " + "layers are displayed when added to the map" ) ); + + // set the focus to the map canvas + theMapCanvas->setFocus(); + + // create tools + theMapTools->mZoomIn = new QgsMapToolZoom( theMapCanvas, false /* zoomIn */ ); + theMapTools->mZoomIn->setAction( mQgis->actionZoomIn() ); + theMapTools->mZoomOut = new QgsMapToolZoom( theMapCanvas, true /* zoomOut */ ); + theMapTools->mZoomOut->setAction( mQgis->actionZoomOut() ); + theMapTools->mPan = new QgsMapToolPan( theMapCanvas ); + theMapTools->mPan->setAction( mQgis->actionPan() ); + theMapTools->mIdentify = new QgsMapToolIdentify( theMapCanvas ); + theMapTools->mIdentify->setAction( mQgis->actionIdentify() ); + theMapTools->mMeasureDist = new QgsMeasureTool( theMapCanvas, false /* area */ ); + theMapTools->mMeasureDist->setAction( mQgis->actionMeasure() ); + theMapTools->mMeasureArea = new QgsMeasureTool( theMapCanvas, true /* area */ ); + theMapTools->mMeasureArea->setAction( mQgis->actionMeasureArea() ); + theMapTools->mCapturePoint = new QgsMapToolAddFeature( theMapCanvas, QgsMapToolCapture::CapturePoint ); + theMapTools->mCapturePoint->setAction( mQgis->actionCapturePoint() ); + mQgis->actionCapturePoint()->setVisible( false ); + theMapTools->mCaptureLine = new QgsMapToolAddFeature( theMapCanvas, QgsMapToolCapture::CaptureLine ); + theMapTools->mCaptureLine->setAction( mQgis->actionCaptureLine() ); + mQgis->actionCaptureLine()->setVisible( false ); + theMapTools->mCapturePolygon = new QgsMapToolAddFeature( theMapCanvas, QgsMapToolCapture::CapturePolygon ); + theMapTools->mCapturePolygon->setAction( mQgis->actionCapturePolygon() ); + mQgis->actionCapturePolygon()->setVisible( false ); + theMapTools->mMoveFeature = new QgsMapToolMoveFeature( theMapCanvas ); + theMapTools->mMoveFeature->setAction( mQgis->actionMoveFeature() ); + theMapTools->mSplitFeatures = new QgsMapToolSplitFeatures( theMapCanvas ); + theMapTools->mSplitFeatures->setAction( mQgis->actionSplitFeatures() ); + theMapTools->mSelect = new QgsMapToolSelect( theMapCanvas ); + theMapTools->mSelect->setAction( mQgis->actionSelect() ); + theMapTools->mVertexAdd = new QgsMapToolAddVertex( theMapCanvas ); + theMapTools->mVertexAdd->setAction( mQgis->actionAddVertex() ); + theMapTools->mVertexMove = new QgsMapToolMoveVertex( theMapCanvas ); + theMapTools->mVertexMove->setAction( mQgis->actionMoveVertex() ); + theMapTools->mVertexDelete = new QgsMapToolDeleteVertex( theMapCanvas ); + theMapTools->mVertexDelete->setAction( mQgis->actionDeleteVertex() ); + theMapTools->mAddRing = new QgsMapToolAddRing( theMapCanvas ); + theMapTools->mAddRing->setAction( mQgis->actionAddRing() ); + theMapTools->mAddIsland = new QgsMapToolAddIsland( theMapCanvas ); + theMapTools->mSimplifyFeature = new QgsMapToolSimplify( theMapCanvas ); + theMapTools->mSimplifyFeature->setAction( mQgis->actionSimplifyFeature() ); + theMapTools->mDeleteRing = new QgsMapToolDeleteRing( theMapCanvas ); + theMapTools->mDeleteRing->setAction( mQgis->actionDeleteRing() ); + theMapTools->mDeletePart = new QgsMapToolDeletePart( theMapCanvas ); + theMapTools->mDeletePart->setAction( mQgis->actionDeletePart() ); + theMapTools->mNodeTool = new QgsMapToolNodeTool( theMapCanvas ); + theMapTools->mNodeTool->setAction( mQgis->actionNodeTool() ); + + // set a current map tool + theMapTools->mCurrentTool = theMapTools->mPan; + + //ensure that non edit tool is initialised or we will get crashes in some situations + mQgis->mNonEditMapTool = theMapTools->mPan; +} // setToolsForMapCanvas Property changes on: src/app/qgsframewidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/app/qgisappinterface.h =================================================================== --- src/app/qgisappinterface.h (revision 11922) +++ src/app/qgisappinterface.h (working copy) @@ -87,6 +87,10 @@ /** Return a pointer to the map canvas used by qgisapp */ QgsMapCanvas * mapCanvas(); +#ifdef HAVE_TABS + /** Return a pointer to the main tab widget that containing map canvas */ + QgsDeskTabWidgetInterface * deskTabWidget(); +#endif /** Gives access to main QgisApp object Plugins don't need to know about QgisApp, as we pass it as QWidget, Index: src/app/composer/qgscomposer.cpp =================================================================== --- src/app/composer/qgscomposer.cpp (revision 11922) +++ src/app/composer/qgscomposer.cpp (working copy) @@ -38,6 +38,9 @@ #include "qgsmessageviewer.h" #include "qgscontexthelp.h" #include "qgscursors.h" +#ifdef HAVE_TABS +#include "tabs/qgswidgetregistry.h" +#endif #include #include @@ -48,6 +51,11 @@ #include #include +#ifdef HAVE_TABS +#include +#include +#endif + #include #include #include @@ -1396,6 +1404,50 @@ on_mActionSelectMoveItem_triggered(); } +#ifdef HAVE_TABS +void QgsComposer::prepareTabbing() +{ + QList< QToolBar * > tbs = mQgis->findChildren< QToolBar * >(); + foreach ( QToolBar *tb, tbs ) + tb->hide(); + + QSize iconSize = mQgis->mapNavToolToolBar()->iconSize(); + toolBar->setIconSize(iconSize); + + mQgis->addToolBar( toolBar ); + toolBar->show(); + + statusBar()->close(); + statusBar()->setParent(0); + buttonBox->close(); + + mComposerMenuBar = menuBar(); + + mQgisStateByteArray = mQgis->saveState(); +} + +void QgsComposer::restoreState( int tabIndex ) +{ + int i = QgsWidgetRegistry::tabIndexOf(this); + if ( tabIndex == i ) + { + mQgis->menuBar()->close(); + mQgis->menuBar()->setParent(0); + + mQgis->setMenuBar(mComposerMenuBar); + mQgis->menuBar()->show(); + + mQgis->restoreState(mQgisStateByteArray, tabIndex); + mQgis->statusBar()->hide(); + } + else if (mComposerMenuBar->isVisible()) + { + mComposerMenuBar->close(); + mComposerMenuBar->setParent(0); + } +} +#endif + bool QgsComposer::containsWMSLayer() const { QMap::const_iterator item_it = mItemWidgetMap.constBegin(); Index: src/app/composer/qgscomposer.h =================================================================== --- src/app/composer/qgscomposer.h (revision 11922) +++ src/app/composer/qgscomposer.h (working copy) @@ -19,6 +19,7 @@ #define QGSCOMPOSER_H #include "ui_qgscomposerbase.h" #include "qgscomposeritem.h" +#include "qgsconfig.h" class QgisApp; class QgsComposerLabel; @@ -77,6 +78,10 @@ QString id() const {return mId;} +#ifdef HAVE_TABS + void prepareTabbing(); +#endif + protected: //! Move event virtual void moveEvent( QMoveEvent * ); @@ -225,13 +230,16 @@ void setSelectionTool(); +#ifdef HAVE_TABS + void restoreState(int tabIndex); +#endif + private slots: //! Raise, unminimize and activate this window void activate(); private: - /**Establishes the signal slot connection for the class*/ void connectSlots(); @@ -283,6 +291,11 @@ //! Help context id static const int context_id = 985715179; + // window state of composer + QByteArray mQgisStateByteArray; + + // Composer menuBar + QMenuBar *mComposerMenuBar; }; #endif Index: src/app/qgisapp.h =================================================================== --- src/app/qgisapp.h (revision 11922) +++ src/app/qgisapp.h (working copy) @@ -68,6 +68,14 @@ #include "qgsfeature.h" #include "qgspoint.h" +#ifdef HAVE_TABS +class QgsFrameWidget; +class QgsMapOverviewCanvas; +class QgsDeskTabWidget; +class QgsLegendTabWidget; +class QgsAddTabDialog; +#endif + /*! \class QgisApp * \brief Main window for the Qgis application */ @@ -141,8 +149,15 @@ //!Overloaded version of the private function with same name that takes the imagename as a parameter void saveMapAsImage( QString, QPixmap * ); /** Get the mapcanvas object from the app */ - QgsMapCanvas * mapCanvas() { return mMapCanvas; }; - + QgsMapCanvas * mapCanvas() { return mMapCanvas; } +#ifdef HAVE_TABS + /** Get the main (desk) tabwidget object from the app */ + QgsDeskTabWidget *deskTabWidget() { return mDeskTabWidget; } + /** Get the legend tabwidget object from the app */ + QgsLegendTabWidget *legendTabWidget() { return mLegendTabWidget; } + // Create print composer but don't add it in composer map + QgsComposer *createPrintComposer(QString composerId); +#endif //! Set theme (icons) void setTheme( QString themeName = "default" ); //! Setup the toolbar popup menus for a given theme @@ -182,11 +197,12 @@ * After adding the dock widget to the ui (by delegating to the QMainWindow * parent class, it will also add it to the View menu list of docks.*/ void addDockWidget( Qt::DockWidgetArea area, QDockWidget * dockwidget ); +#ifndef HAVE_TABS /** Add a toolbar to the main window. Overloaded from QMainWindow. * After adding the toolbar to the ui (by delegating to the QMainWindow * parent class, it will also add it to the View menu list of toolbars.*/ QToolBar *addToolBar( QString name ); - +#endif /** Add window to Window menu. The action title is the window title * and the action should raise, unminimize and activate the window. */ void addWindow( QAction *action ); @@ -202,6 +218,12 @@ //! Actions to be inserted in menus and toolbars QAction *actionNewProject() { return mActionNewProject; } +#ifdef HAVE_TABS + QAction *actionNewTab() { return mActionAddTabDialog; } + QAction *actionNewCanvasTab() { return mActionCanvasTab; } + QAction *actionCloseTab() { return mActionCloseTab; } + QAction *actionRestoreTab() { return mActionRestoreTab; } +#endif QAction *actionOpenProject() { return mActionOpenProject; } QAction *actionFileSeparator1() { return mActionFileSeparator1; } QAction *actionSaveProject() { return mActionSaveProject; } @@ -398,6 +420,7 @@ //#endif /** toggles whether the current selected layer is in overview or not */ void isInOverview(); +#ifndef HAVE_TABS //! Slot to show the map coordinate position of the mouse cursor void showMouseCoordinate( const QgsPoint & ); //! Slot to show current map scale; @@ -406,6 +429,7 @@ void userScale(); //! Slot to handle user center input; void userCenter(); +#endif //! Remove a layer from the map and legend void removeLayer(); //! zoom to extent of layer @@ -437,6 +461,16 @@ //! Open the project file corresponding to the //! text)= of the given action. void openProject( QAction *action ); +#ifdef HAVE_TABS + void addTabDialog(); + void addCanvasTab(); + void closeTab(); + void restoreTab(); + void nextTab(); + void previousTab(); + + void updateFrame( QgsFrameWidget *frame ); +#endif //! Save the map view as an image - user is prompted for image name using a dialog void saveMapAsImage(); //! Open a project @@ -487,8 +521,10 @@ void socketError( QAbstractSocket::SocketError e ); //! Set project properties, including map untis void projectProperties(); +#ifndef HAVE_TABS //! Open project properties dialog and show the projections tab void projectPropertiesProjections(); +#endif /* void urlData(); */ //! Show the spatial bookmarks dialog void showBookmarks(); @@ -541,20 +577,28 @@ //! starts/stops editing mode of the current layer void toggleEditing(); +#ifndef HAVE_TABS //! map tool changed void mapToolChanged( QgsMapTool *tool ); +#endif /** Activates or deactivates actions depending on the current maplayer type. Is called from the legend when the current legend item has changed*/ void activateDeactivateLayerRelatedActions( QgsMapLayer* layer ); +#ifndef HAVE_TABS void showProgress( int theProgress, int theTotalSteps ); void extentsViewToggled( bool theFlag ); void showExtents(); void showStatusMessage( QString theMessage ); +#endif +#ifdef HAVE_TABS void updateMouseCoordinatePrecision(); +#endif +#ifndef HAVE_TABS void hasCrsTransformEnabled( bool theFlag ); void destinationSrsChanged(); +#endif // void debugHook(); //! Add a vector layer to the map void addVectorLayer(); @@ -596,10 +640,10 @@ //! Toggle map tips on/off void toggleMapTips(); - +#ifndef HAVE_TABS //! Show the map tip void showMapTip(); - +#endif //! Toggle full screen mode void toggleFullScreen(); @@ -663,6 +707,7 @@ bool isValidVectorFileName( QString theFileNameQString ); /** Overloaded version of the above function provided for convenience that takes a qstring pointer */ bool isValidVectorFileName( QString * theFileNameQString ); + /** add this file to the recently opened/saved projects list * pass settings by reference since creating more than one * instance simultaneously results in data loss. @@ -696,13 +741,22 @@ void createActionGroups(); void createMenus(); void createToolBars(); +#ifndef HAVE_TABS void createStatusBar(); +#endif void setupConnections(); +#ifndef HAVE_TABS void createLegend(); +#else void createOverview(); + void createLegendDock(); + void createOverviewDock(); +#endif void createCanvas(); bool createDB(); +#ifndef HAVE_TABS void createMapTips(); +#endif // toolbars --------------------------------------- QToolBar *mFileToolBar; @@ -717,6 +771,14 @@ // actions for menus and toolbars ----------------- QAction *mActionNewProject; +#ifdef HAVE_TABS + QAction *mActionAddTabDialog; + QAction *mActionCanvasTab; + QAction *mActionNextTab; + QAction *mActionPreviousTab; + QAction *mActionCloseTab; + QAction *mActionRestoreTab; +#endif QAction *mActionOpenProject; QAction *mActionFileSeparator1; QAction *mActionSaveProject; @@ -856,6 +918,9 @@ class Tools { public: +#ifdef HAVE_TABS + ~Tools(); +#endif QgsMapTool* mZoomIn; QgsMapTool* mZoomOut; QgsMapTool* mPan; @@ -879,10 +944,15 @@ QgsMapTool* mDeletePart; QgsMapTool* mNodeTool; QgsMapTool* mRotatePointSymbolsTool; +#ifndef HAVE_TABS } mMapTools; +#else + QgsMapTool* mCurrentTool; + } *mMapTools; +#endif QgsMapTool *mNonEditMapTool; - +#ifndef HAVE_TABS //! Widget that will live on the statusbar to display "scale 1:" QLabel * mScaleLabel; //! Widget that will live on the statusbar to display scale value @@ -905,6 +975,7 @@ QToolButton* mStopRenderButton; //! Widget in status bar used to show status of on the fly projection QToolButton * mOnTheFlyProjectionStatusButton; +#endif //! Popup menu QMenu * mPopupMenu; //! Top level plugin menu @@ -917,6 +988,17 @@ QMenu *toolPopupCapture; //! Map canvas QgsMapCanvas *mMapCanvas; +#ifdef HAVE_TABS + friend class QgsFrameWidget; + //! Desk (main) tab widget + QgsDeskTabWidget *mDeskTabWidget; + //! Map overview canvas + QgsMapOverviewCanvas *mMapOverviewCanvas; + //! Legend tab widget + QgsLegendTabWidget *mLegendTabWidget; + //! Dialog for adding tab + QgsAddTabDialog *mAddTabDialog; +#endif //! Table of contents (legend) for the map QgsLegend *mMapLegend; //! Cursor for the overview map @@ -948,8 +1030,10 @@ //! How to determine the number of decimal places used to //! display the mouse position bool mMousePrecisionAutomatic; +#ifdef HAVE_TABS //! The number of decimal places to use if not automatic unsigned int mMousePrecisionDecimalPlaces; +#endif /** QGIS-internal vector feature clipboard */ QgsClipboard* mInternalClipboard; //! Flag to indicate how the project properties dialog was summoned @@ -963,6 +1047,7 @@ */ QString mRasterFileFilter; +#ifndef HAVE_TABS /** Timer for map tips */ QTimer *mpMapTipsTimer; @@ -977,6 +1062,7 @@ // Flag to indicate if maptips are on or off bool mMapTipsVisible; +#endif //!flag to indicate whether we are in fullscreen mode or not bool mFullScreenMode; Index: src/app/qgsframewidget.h =================================================================== --- src/app/qgsframewidget.h (revision 0) +++ src/app/qgsframewidget.h (revision 0) @@ -0,0 +1,113 @@ +#ifndef QGSFRAMEWIDGET_H +#define QGSFRAMEWIDGET_H + +#include + +#include "qgisapp.h" + +// this class holds map canvas, map legend, and map overview canvas, map tools and statusbar +// it is used to communicate with class QgisApp +class QgsFrameWidget : public QWidget +{ + Q_OBJECT + +public: + QgsFrameWidget( QgisApp *qgis ); + ~QgsFrameWidget(); + + QgsMapCanvas *mapCanvas() { return mMapCanvas; } + QgsMapOverviewCanvas *mapOverviewCanvas() { return mMapOverviewCanvas; } + QgsLegend *legend() { return mLegend; } + QgisApp::Tools *tools() { return mTools; } + QStatusBar *statusBar() { return mStatusBar; } + + void setupConnections(); + void removeConnections(); + void saveState(); + void restoreState(); + +private slots: + void destinationSrsChanged(); + void hasCrsTransformEnabled( bool theFlag ); + void mapToolChanged( QgsMapTool *tool ); + void projectPropertiesProjections(); + + void showProgress( int theProgress, int theTotalSteps ); + void showMouseCoordinate( const QgsPoint & p ); + void showScale( double theScale ); + void showExtents(); + void showMapTip(); + + void extentsViewToggled( bool theFlag ); + void updateMouseCoordinatePrecision(); + void userScale(); + void userCenter(); + + void layerWasAdded( QgsMapLayer *layer ); + +private: + void createCanvas(); + void createLegend(); + void createOverview(); + void createMapTips(); + void createStatusBar(); + + void setToolsForMapCanvas( QgsMapCanvas *theMapCanvas, QgisApp::Tools *theMapTools ); + + QgsMapCanvas *mMapCanvas; + QgsLegend *mLegend; + QgsMapOverviewCanvas *mMapOverviewCanvas; + QgisApp::Tools *mTools; + QStatusBar *mStatusBar; + + //! Widget that will live in the statusbar to show progress of operations + QProgressBar * mProgressBar; + //! A toggle to switch between mouse coords and view extents display + QToolButton * mToggleExtentsViewButton; + //! Widget that will live in the statusbar to display coords + QLabel * mCoordsLabel; + //! Widget that will live on the statusbar to display "scale 1:" + QLabel * mScaleLabel; + //! Widget that will live in the statusbar to display and edit coords + QLineEdit * mCoordsEdit; + //! The validator for the mCoordsEdit + QValidator * mCoordsEditValidator; + //! Widget that will live on the statusbar to display scale value + QLineEdit * mScaleEdit; + //! The validator for the mScaleEdit + QValidator * mScaleEditValidator; + //! Button used to stop rendering + QToolButton* mStopRenderButton; + //! Widget used to suppress rendering + QCheckBox * mRenderSuppressionCBox; + //! Widget in status bar used to show status of on the fly projection + QToolButton * mOnTheFlyProjectionStatusButton; + + //! The number of decimal places to use if not automatic + unsigned int mMousePrecisionDecimalPlaces; + + /** Timer for map tips + */ + QTimer *mpMapTipsTimer; + + /** Point of last mouse position in map coordinates (used with MapTips) + */ + QgsPoint mLastMapPosition; + + /* Maptip object + */ + QgsMapTip * mpMaptip; + + // Flag to indicate if maptips are on or off + bool mMapTipsVisible; + + // state of QGis for this frame + QByteArray mQgisState; + + QgisApp *mQgis; + + // QGis menuBar + QMenuBar *mQgisMenuBar; +}; + +#endif // QGSFRAMEWIDGET_H Property changes on: src/app/qgsframewidget.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/app/CMakeLists.txt =================================================================== --- src/app/CMakeLists.txt (revision 11922) +++ src/app/CMakeLists.txt (working copy) @@ -109,6 +109,11 @@ attributetable/qgsattributetabledelegate.cpp ) +IF (HAVE_TABS) + SET (QGIS_APP_SRCS ${QGIS_APP_SRCS} + qgsframewidget.cpp + ) +ENDIF (HAVE_TABS) SET (QGIS_APP_MOC_HDRS qgisapp.h @@ -195,6 +200,12 @@ attributetable/qgsattributetabledelegate.h ) +IF (HAVE_TABS) + SET (QGIS_APP_MOC_HDRS ${QGIS_APP_MOC_HDRS} + qgsframewidget.h + ) +ENDIF (HAVE_TABS) + IF (POSTGRES_FOUND) IF(HAVE_PGCONFIG) ADD_DEFINITIONS(-DHAVE_PGCONFIG=1) Index: src/app/qgisapp.cpp =================================================================== --- src/app/qgisapp.cpp (revision 11922) +++ src/app/qgisapp.cpp (working copy) @@ -138,6 +138,13 @@ #include "qgsvectorlayer.h" #include "ogr/qgsopenvectorlayerdialog.h" #include "qgsattributetabledialog.h" +#ifdef HAVE_TABS +#include "qgsframewidget.h" +#include "tabs/qgsaddtabdialog.h" +#include "tabs/qgsdesktabwidget.h" +#include "tabs/qgslegendtabwidget.h" +#include "tabs/qgswidgetregistry.h" +#endif // // Gdal/Ogr includes // @@ -326,6 +333,10 @@ // constructor starts here QgisApp::QgisApp( QSplashScreen *splash, QWidget * parent, Qt::WFlags fl ) : QMainWindow( parent, fl ), +#ifdef HAVE_TABS + mMapCanvas( 0 ), + mMapLegend( 0 ), +#endif mSplash( splash ), mPythonConsole( NULL ), mPythonUtils( NULL ) @@ -355,22 +366,34 @@ mSplash->showMessage( tr( "Setting up the GUI" ), Qt::AlignHCenter | Qt::AlignBottom ); qApp->processEvents(); - - - +#ifdef HAVE_TABS + setDockOptions(QMainWindow::ForceTabbedDocks); +#endif createActions(); createActionGroups(); createMenus(); createToolBars(); +#ifndef HAVE_TABS createStatusBar(); +#endif +#ifdef HAVE_TABS + createOverview(); + createOverviewDock(); +#endif createCanvas(); mMapCanvas->freeze(); +#ifdef HAVE_TABS + createLegendDock(); +#else createLegend(); createOverview(); createMapTips(); +#endif readSettings(); updateRecentProjectPaths(); - +#ifdef HAVE_TABS + mAddTabDialog = new QgsAddTabDialog(); // Dialog for opening tabs +#endif mInternalClipboard = new QgsClipboard; // create clipboard mQgisInterface = new QgisAppInterface( this ); // create the interfce @@ -450,9 +473,9 @@ restoreWindowState(); mSplash->showMessage( tr( "QGIS Ready!" ), Qt::AlignHCenter | Qt::AlignBottom ); - +#ifndef HAVE_TABS mMapTipsVisible = false; - +#endif // setup drag drop setAcceptDrops( true ); @@ -472,9 +495,7 @@ QgisApp::~QgisApp() { - delete mInternalClipboard; - delete mQgisInterface; - +#ifndef HAVE_TABS delete mMapTools.mZoomIn; delete mMapTools.mZoomOut; delete mMapTools.mPan; @@ -497,7 +518,11 @@ delete mMapTools.mDeletePart; delete mMapTools.mAddIsland; delete mMapTools.mNodeTool; +#endif + delete mInternalClipboard; + delete mQgisInterface; + delete mPythonConsole; delete mPythonUtils; @@ -602,6 +627,44 @@ mActionExit->setMenuRole( QAction::QuitRole ); // put in Application menu on Mac OS X connect( mActionExit, SIGNAL( triggered() ), this, SLOT( fileExit() ) ); +#ifdef HAVE_TABS + mActionAddTabDialog = new QAction( getThemeIcon( "mActionAddTabDialog.png" ), tr( "New &Tab" ), this ); + shortcuts->registerAction( mActionAddTabDialog, tr( "Ctrl+T", "New Tab" ) ); + // mActionNewCanvas->setShortcut( QKeySequence::AddTab ); + mActionAddTabDialog->setStatusTip( tr( "New Tab" ) ); + connect( mActionAddTabDialog, SIGNAL( triggered() ), this, SLOT(addTabDialog()) ); + + mActionCanvasTab = new QAction( getThemeIcon( "mActionCanvasTab.png" ), tr( "New &canvas" ), this ); +// shortcuts->registerAction( mActionCanvasTab, tr( "Ctrl+T", "New Canvas" ) ); + // mActionNewCanvas->setShortcut( QKeySequence::AddTab ); + mActionCanvasTab->setStatusTip( tr( "New canvas" ) ); + connect( mActionCanvasTab, SIGNAL( triggered() ), this, SLOT(addCanvasTab()) ); + + mActionCloseTab = new QAction( getThemeIcon( "mActionCloseTab.png" ), tr( "&Close Tab" ), this ); + shortcuts->registerAction( mActionCloseTab, tr( "Ctrl+W", "Close Tab" ) ); + // mActionCloseTab->setShortcut( QKeySequence::Close ); + mActionCloseTab->setStatusTip( tr( "Close Tab" ) ); + connect( mActionCloseTab, SIGNAL( triggered() ), this, SLOT(closeTab()) ); + + mActionRestoreTab = new QAction( getThemeIcon( "mActionRestoreTab.png" ), tr( "&Restore Tab" ), this ); + shortcuts->registerAction( mActionRestoreTab, tr( "Ctrl+Shift+T", "Restore Tab" ) ); + mActionRestoreTab->setStatusTip( tr( "Restore Tab" ) ); + mActionRestoreTab->setEnabled( false ); + connect( mActionRestoreTab, SIGNAL( triggered() ), this, SLOT(restoreTab()) ); + + // create actions that helps user to navigate in tabs + mActionNextTab = new QAction(this); + shortcuts->registerAction( mActionNextTab, tr( "Ctrl+Tab", "Goto next tab" ) ); + mActionNextTab->setShortcut(QKeySequence::NextChild); + connect(mActionNextTab, SIGNAL(triggered()), this, SLOT(nextTab())); + addAction(mActionNextTab); + + mActionPreviousTab = new QAction(this); + shortcuts->registerAction( mActionPreviousTab, tr( "Ctrl+Shift+Tab", "Goto previous tab" ) ); + // mActionPreviousTab->setShortcut(QKeySequence::PreviousChild); + connect(mActionPreviousTab, SIGNAL(triggered()), this, SLOT(previousTab())); + addAction(mActionPreviousTab); +#endif // Edit Menu Items #if 0 @@ -1149,6 +1212,10 @@ mFileMenu->addAction( mActionNewProject ); mFileMenu->addAction( mActionOpenProject ); +#ifdef HAVE_TABS + mFileMenu->addAction( mActionAddTabDialog ); + mFileMenu->addAction( mActionCanvasTab ); +#endif mRecentProjectsMenu = mFileMenu->addMenu( tr( "&Open Recent Projects" ) ); // Connect once for the entire submenu. connect( mRecentProjectsMenu, SIGNAL( triggered( QAction * ) ), @@ -1170,6 +1237,10 @@ mPrintComposersMenu = mFileMenu->addMenu( tr( "Print Composers" ) ); mActionFileSeparator4 = mFileMenu->addSeparator(); +#ifdef HAVE_TABS + mFileMenu->addAction( mActionRestoreTab ); + mFileMenu->addAction( mActionCloseTab ); +#endif mFileMenu->addAction( mActionExit ); // Edit Menu @@ -1469,6 +1540,7 @@ mToolbarMenu->addAction( mHelpToolBar->toggleViewAction() ); } +#ifndef HAVE_TABS void QgisApp::createStatusBar() { // @@ -1600,6 +1672,7 @@ statusBar()->addPermanentWidget( mOnTheFlyProjectionStatusButton, 0 ); statusBar()->showMessage( tr( "Ready" ) ); } +#endif void QgisApp::setTheme( QString theThemeName ) @@ -1627,11 +1700,17 @@ QgsApplication::setThemeName( theThemeName ); //QgsDebugMsg("Setting theme to \n" + theThemeName); mActionNewProject->setIcon( getThemeIcon( "/mActionFileNew.png" ) ); +#ifdef HAVE_TABS + mActionCanvasTab->setIcon( getThemeIcon( "/mActionCanvasTab.png" ) ); +#endif mActionOpenProject->setIcon( getThemeIcon( "/mActionFileOpen.png" ) ); mActionSaveProject->setIcon( getThemeIcon( "/mActionFileSave.png" ) ); mActionSaveProjectAs->setIcon( getThemeIcon( "/mActionFileSaveAs.png" ) ); mActionNewPrintComposer->setIcon( getThemeIcon( "/mActionNewComposer.png" ) ); mActionSaveMapAsImage->setIcon( getThemeIcon( "/mActionSaveMapAsImage.png" ) ); +#ifdef HAVE_TABS + mActionCloseTab->setIcon( getThemeIcon( "/mActionCloseTab.png" ) ); +#endif mActionExit->setIcon( getThemeIcon( "/mActionFileExit.png" ) ); mActionAddOgrLayer->setIcon( getThemeIcon( "/mActionAddOgrLayer.png" ) ); mActionAddRasterLayer->setIcon( getThemeIcon( "/mActionAddRasterLayer.png" ) ); @@ -1710,6 +1789,7 @@ { // connect the "cleanup" slot connect( qApp, SIGNAL( aboutToQuit() ), this, SLOT( saveWindowState() ) ); +#ifndef HAVE_TABS //connect the legend, mapcanvas and overview canvas to the registry // connect map layer registry signals to legend @@ -1743,21 +1823,69 @@ // Do we really need this ??? - its already connected to the esc key...TS // connect( mStopRenderButton, SIGNAL( clicked() ), this, SLOT( stopRendering() ) ); - +#endif // Connect warning dialog from project reading connect( QgsProject::instance(), SIGNAL( oldProjectVersionWarning( QString ) ), this, SLOT( oldProjectVersionWarning( QString ) ) ); - +#ifndef HAVE_TABS connect( QgsProject::instance(), SIGNAL( layerLoaded( int, int ) ), this, SLOT( showProgress( int, int ) ) ); - +#endif // setup undo/redo actions connect( mActionUndo, SIGNAL( triggered() ), mUndoWidget, SLOT( undo() ) ); connect( mActionRedo, SIGNAL( triggered() ), mUndoWidget, SLOT( redo() ) ); connect( mUndoWidget, SIGNAL( undoStackChanged() ), this, SLOT( updateUndoActions() ) ); } +#ifdef HAVE_TABS +// it needs here to init map canvas, map legend, map overview and tools +void QgisApp::updateFrame( QgsFrameWidget *frame ) +{ + // update main controls of QGis + mMapCanvas = frame->mapCanvas(); + mMapOverviewCanvas = frame->mapOverviewCanvas(); + mMapLegend = frame->legend(); + mMapTools = frame->tools(); + + // update state of controls + mMapCanvas->setMapTool( mMapTools->mCurrentTool ); + mMapLegend->setMapCanvas( mMapCanvas ); + + mMapCanvas->enableOverviewMode( mMapOverviewCanvas ); + mMapOverviewCanvas->setMapCanvas( mMapCanvas ); + mOverviewDock->setWidget(mMapOverviewCanvas); + + // set status bar for tabbed mapCanvas + if (!QgsWidgetRegistry::isDetached(mMapCanvas)) + { + // set parent of current statusBar to NULL if do not do it statusBar will be removed + if (findChild()) + { + statusBar()->close(); + statusBar()->setParent( 0 ); + } + setStatusBar( frame->statusBar() ); + statusBar()->show(); + } +} +#endif + void QgisApp::createCanvas() { +#ifdef HAVE_TABS + // create the main tab widgets + mDeskTabWidget = new QgsDeskTabWidget( this ); + mLegendTabWidget = new QgsLegendTabWidget(this); + + // create frame (map canvas, map legend, map overview and tools) and add map canvas to tab + mDeskTabWidget->addFrameTab( "Canvas 1" ); + mDeskTabWidget->updateFrameAt(0); + + setCentralWidget( mDeskTabWidget ); + + QList< QToolBar * > tbs = findChildren< QToolBar * >(); + foreach( QToolBar *tb, tbs) + tb->show(); +#else // "theMapCanvas" used to find this canonical instance later mMapCanvas = new QgsMapCanvas( this, "theMapCanvas" ); mMapCanvas->setWhatsThis( tr( "Map canvas. This is where raster and vector " @@ -1818,11 +1946,28 @@ mMapTools.mRotatePointSymbolsTool->setAction( mActionRotatePointSymbols ); //ensure that non edit tool is initialised or we will get crashes in some situations mNonEditMapTool = mMapTools.mPan; +#endif } +#ifdef HAVE_TABS void QgisApp::createOverview() { // overview canvas + mMapOverviewCanvas = new QgsMapOverviewCanvas(); + mMapOverviewCanvas->setWhatsThis( 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." ) ); + + QBitmap overviewPanBmp = QBitmap::fromData( QSize( 16, 16 ), pan_bits ); + QBitmap overviewPanBmpMask = QBitmap::fromData( QSize( 16, 16 ), pan_mask_bits ); + mOverviewMapCursor = new QCursor( overviewPanBmp, overviewPanBmpMask, 0, 0 ); //set upper left corner as hot spot - this is better when extent marker is small; hand won't cover the marker + mMapOverviewCanvas->setCursor( *mOverviewMapCursor ); +} + +void QgisApp::createOverviewDock() +{ +#else +void QgisApp::createOverview() +{ + // overview canvas QgsMapOverviewCanvas* overviewCanvas = new QgsMapOverviewCanvas( NULL, mMapCanvas ); overviewCanvas->setWhatsThis( 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." ) ); @@ -1830,14 +1975,21 @@ QBitmap overviewPanBmpMask = QBitmap::fromData( QSize( 16, 16 ), pan_mask_bits ); mOverviewMapCursor = new QCursor( overviewPanBmp, overviewPanBmpMask, 0, 0 ); //set upper left corner as hot spot - this is better when extent marker is small; hand won't cover the marker overviewCanvas->setCursor( *mOverviewMapCursor ); +#endif + // QVBoxLayout *myOverviewLayout = new QVBoxLayout; // myOverviewLayout->addWidget(overviewCanvas); // overviewFrame->setLayout(myOverviewLayout); mOverviewDock = new QDockWidget( tr( "Overview" ), this ); mOverviewDock->setObjectName( "Overview" ); mOverviewDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); +#ifndef HAVE_TABS mOverviewDock->setWidget( overviewCanvas ); +#else + mOverviewDock->setWidget( mMapOverviewCanvas ); +#endif addDockWidget( Qt::LeftDockWidgetArea, mOverviewDock ); +#ifndef HAVE_TABS // add to the Panel submenu mPanelMenu->addAction( mOverviewDock->toggleViewAction() ); @@ -1851,6 +2003,7 @@ int action = mySettings.value( "/qgis/wheel_action", 0 ).toInt(); double zoomFactor = mySettings.value( "/qgis/zoom_factor", 2 ).toDouble(); mMapCanvas->setWheelAction(( QgsMapCanvas::WheelAction ) action, zoomFactor ); +#endif } void QgisApp::addDockWidget( Qt::DockWidgetArea theArea, QDockWidget * thepDockWidget ) @@ -1866,11 +2019,13 @@ mPanelMenu->addAction( thepDockWidget->toggleViewAction() ); thepDockWidget->show(); - +#ifndef HAVE_TABS // refresh the map canvas mMapCanvas->refresh(); +#endif } +#ifndef HAVE_TABS QToolBar *QgisApp::addToolBar( QString name ) { QToolBar *toolBar = QMainWindow::addToolBar( name ); @@ -1878,7 +2033,17 @@ mToolbarMenu->addAction( toolBar->toggleViewAction() ); return toolBar; } +#endif +#ifdef HAVE_TABS +void QgisApp::createLegendDock() +{ + mLegendDock = new QDockWidget( tr( "Layers" ), this ); + mLegendDock->setObjectName( "Legend" ); + mLegendDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); + mLegendDock->setWidget( mLegendTabWidget ); + addDockWidget( Qt::LeftDockWidgetArea, mLegendDock ); +#else void QgisApp::createLegend() { //legend @@ -1898,6 +2063,7 @@ // add to the Panel submenu mPanelMenu->addAction( mLegendDock->toggleViewAction() ); return; +#endif } bool QgisApp::createDB() @@ -1927,6 +2093,7 @@ return TRUE; } +#ifndef HAVE_TABS void QgisApp::createMapTips() { // Set up the timer for maptips. The timer is reset everytime the mouse is moved @@ -1938,6 +2105,7 @@ // Create the maptips object mpMaptip = new QgsMapTip(); } +#endif // Update file menu with the current list of recently accessed projects void QgisApp::updateRecentProjectPaths() @@ -1997,9 +2165,16 @@ { // store window and toolbar positions QSettings settings; +#ifdef HAVE_TABS + QWidget *w = mDeskTabWidget->currentWidget(); + if (QgsWidgetRegistry::isMapCanvas(w)) + { +#endif // store the toolbar/dock widget settings using Qt4 settings API settings.setValue( "/UI/state", saveState() ); - +#ifdef HAVE_TABS + } +#endif // store window geometry settings.setValue( "/UI/geometry", saveGeometry() ); @@ -3143,8 +3318,13 @@ mMapCanvas->mapRenderer()->setProjectionsEnabled( FALSE ); // set the initial map tool +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mPan ); + mNonEditMapTool = mMapTools->mPan; // signals are not yet setup to catch this +#else mMapCanvas->setMapTool( mMapTools.mPan ); mNonEditMapTool = mMapTools.mPan; // signals are not yet setup to catch this +#endif } // QgisApp::fileNew(bool thePromptToSaveFlag) @@ -3625,6 +3805,39 @@ } // QgisApp::openProject +#ifdef HAVE_TABS +void QgisApp::addTabDialog() +{ + mAddTabDialog->show(); +} + +void QgisApp::addCanvasTab() +{ + int index = mDeskTabWidget->addFrameTab( tr("Canvas %1").arg( mDeskTabWidget->count() + 1 ) ); + mDeskTabWidget->setCurrentIndex( index ); +} + +void QgisApp::closeTab() +{ + mDeskTabWidget->removeTab( mDeskTabWidget->currentIndex() ); +} + +void QgisApp::restoreTab() +{ + mDeskTabWidget->restoreTab(); +} + +void QgisApp::nextTab() +{ + mDeskTabWidget->nextTab(); +} + +void QgisApp::previousTab() +{ + mDeskTabWidget->previousTab(); +} +#endif + /** Open the specified project file; prompt to save previous project if necessary. Used to process a commandline argument or OpenDocument AppleEvent. @@ -3680,7 +3893,17 @@ return ok; } +#ifdef HAVE_TABS +QgsComposer *QgisApp::createPrintComposer(QString composerId) +{ + //create new composer object + QgsComposer* newComposerObject = new QgsComposer( this, composerId ); + //and place action into print composers menu + mPrintComposersMenu->addAction( newComposerObject->windowAction() ); + return newComposerObject; +} +#endif void QgisApp::newPrintComposer() { if ( mMapCanvas && mMapCanvas->isDrawing() ) @@ -3708,7 +3931,13 @@ composerExists = false; } } - +#ifdef HAVE_TABS + //create new composer object and action + QgsComposer* newComposerObject = createPrintComposer(composerId); + //add it to the map of existing print composers + mPrintComposers.insert( composerId, newComposerObject ); + newComposerObject->open(); +#else //create new composer object QgsComposer* newComposerObject = new QgsComposer( this, composerId ); //add it to the map of existing print composers @@ -3716,6 +3945,7 @@ //and place action into print composers menu mPrintComposersMenu->addAction( newComposerObject->windowAction() ); newComposerObject->open(); +#endif } void QgisApp::saveMapAsImage() @@ -3863,11 +4093,11 @@ // showMaxmized() is a work-around. Turn off rendering for this as it // would otherwise cause two re-renders of the map, which can take a // long time. - bool renderFlag = mapCanvas()->renderFlag(); - mapCanvas()->setRenderFlag( false ); + bool renderFlag = mMapCanvas->renderFlag(); + mMapCanvas->setRenderFlag( false ); showNormal(); showMaximized(); - mapCanvas()->setRenderFlag( renderFlag ); + mMapCanvas->setRenderFlag( renderFlag ); mPrevScreenModeMaximized = false; } else @@ -3962,7 +4192,7 @@ { QgsDebugMsg( "hiding all layers!" ); - legend()->selectAll( false ); + mMapLegend->selectAll( false ); } @@ -3971,7 +4201,7 @@ { QgsDebugMsg( "Showing all layers!" ); - legend()->selectAll( true ); + mMapLegend->selectAll( true ); } @@ -3979,7 +4209,11 @@ { QgsDebugMsg( "Setting map tool to zoomIn" ); +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mZoomIn ); +#else mMapCanvas->setMapTool( mMapTools.mZoomIn ); +#endif // notify the project we've made a change QgsProject::instance()->dirty( true ); @@ -3988,8 +4222,11 @@ void QgisApp::zoomOut() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mZoomOut ); +#else mMapCanvas->setMapTool( mMapTools.mZoomOut ); - +#endif // notify the project we've made a change QgsProject::instance()->dirty( true ); } @@ -4004,7 +4241,11 @@ void QgisApp::pan() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mPan ); +#else mMapCanvas->setMapTool( mMapTools.mPan ); +#endif } void QgisApp::zoomFull() @@ -4038,17 +4279,29 @@ void QgisApp::identify() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mIdentify ); +#else mMapCanvas->setMapTool( mMapTools.mIdentify ); +#endif } void QgisApp::measure() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mMeasureDist ); +#else mMapCanvas->setMapTool( mMapTools.mMeasureDist ); +#endif } void QgisApp::measureArea() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mMeasureArea ); +#else mMapCanvas->setMapTool( mMapTools.mMeasureArea ); +#endif } void QgisApp::attributeTable() @@ -4132,22 +4385,38 @@ void QgisApp::moveFeature() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mMoveFeature ); +#else mMapCanvas->setMapTool( mMapTools.mMoveFeature ); +#endif } void QgisApp::simplifyFeature() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mSimplifyFeature ); +#else mMapCanvas->setMapTool( mMapTools.mSimplifyFeature ); +#endif } void QgisApp::deleteRing() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mDeleteRing ); +#else mMapCanvas->setMapTool( mMapTools.mDeleteRing ); +#endif } void QgisApp::deletePart() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mDeletePart ); +#else mMapCanvas->setMapTool( mMapTools.mDeletePart ); +#endif } QgsGeometry* QgisApp::unionGeometries( const QgsVectorLayer* vl, QgsFeatureList& featureList ) @@ -4366,22 +4635,38 @@ void QgisApp::nodeTool() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mNodeTool ); +#else mMapCanvas->setMapTool( mMapTools.mNodeTool ); +#endif } void QgisApp::rotatePointSymbols() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mRotatePointSymbolsTool ); +#else mMapCanvas->setMapTool( mMapTools.mRotatePointSymbolsTool ); +#endif } void QgisApp::splitFeatures() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mSplitFeatures ); +#else mMapCanvas->setMapTool( mMapTools.mSplitFeatures ); +#endif } void QgisApp::reshapeFeatures() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mReshapeFeatures ); +#else mMapCanvas->setMapTool( mMapTools.mReshapeFeatures ); +#endif } void QgisApp::capturePoint() @@ -4392,7 +4677,11 @@ } // set current map tool to select +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mCapturePoint ); +#else mMapCanvas->setMapTool( mMapTools.mCapturePoint ); +#endif } void QgisApp::captureLine() @@ -4402,7 +4691,11 @@ return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mCaptureLine ); +#else mMapCanvas->setMapTool( mMapTools.mCaptureLine ); +#endif } void QgisApp::capturePolygon() @@ -4411,12 +4704,20 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mCapturePolygon ); +#else mMapCanvas->setMapTool( mMapTools.mCapturePolygon ); +#endif } void QgisApp::select() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mSelect ); +#else mMapCanvas->setMapTool( mMapTools.mSelect ); +#endif } @@ -4426,7 +4727,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexAdd ); +#else mMapCanvas->setMapTool( mMapTools.mVertexAdd ); +#endif } @@ -4436,7 +4741,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexMove ); +#else mMapCanvas->setMapTool( mMapTools.mVertexMove ); +#endif } void QgisApp::addRing() @@ -4445,7 +4754,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mAddRing ); +#else mMapCanvas->setMapTool( mMapTools.mAddRing ); +#endif } void QgisApp::addIsland() @@ -4454,7 +4767,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mAddIsland ); +#else mMapCanvas->setMapTool( mMapTools.mAddIsland ); +#endif } @@ -4464,7 +4781,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexDelete ); +#else mMapCanvas->setMapTool( mMapTools.mVertexDelete ); +#endif } @@ -4577,12 +4898,12 @@ void QgisApp::toggleMapTips() { - mMapTipsVisible = !mMapTipsVisible; - // if off, stop the timer - if ( !mMapTipsVisible ) - { - mpMapTipsTimer->stop(); - } +// mMapTipsVisible = !mMapTipsVisible; +// // if off, stop the timer +// if ( !mMapTipsVisible ) +// { +// mpMapTipsTimer->stop(); +// } // TODO !!! } void QgisApp::toggleEditing() @@ -4669,6 +4990,7 @@ vlayer->triggerRepaint(); } +#ifndef HAVE_TABS void QgisApp::showMouseCoordinate( const QgsPoint & p ) { if ( mMapTipsVisible ) @@ -4709,7 +5031,6 @@ } } - void QgisApp::showScale( double theScale ) { if ( theScale >= 1.0 ) @@ -4770,8 +5091,8 @@ ); mMapCanvas->refresh(); } +#endif - // toggle overview status void QgisApp::isInOverview() { @@ -5372,6 +5693,7 @@ mPluginToolBar->removeAction( qAction ); } +#ifndef HAVE_TABS void QgisApp::destinationSrsChanged() { // save this information to project @@ -5462,8 +5784,8 @@ mCoordsEdit->setMinimumWidth( mCoordsEdit->width() ); } } // QgisApp::showExtents - - +#endif +#ifdef HAVE_TABS void QgisApp::updateMouseCoordinatePrecision() { // Work out what mouse display precision to use. This only needs to @@ -5491,7 +5813,8 @@ mMousePrecisionDecimalPlaces = dp; } - +#endif +#ifndef HAVE_TABS void QgisApp::showStatusMessage( QString theMessage ) { statusBar()->showMessage( theMessage ); @@ -5531,6 +5854,7 @@ } } } + void QgisApp::projectPropertiesProjections() { // Driver to display the project props dialog and switch to the @@ -5538,7 +5862,7 @@ mShowProjectionTab = true; projectProperties(); } - +#endif void QgisApp::projectProperties() { if ( mMapCanvas && mMapCanvas->isDrawing() ) @@ -6383,3 +6707,30 @@ mActionUndo->setEnabled( canUndo ); mActionRedo->setEnabled( canRedo ); } + +#ifdef HAVE_TABS +QgisApp::Tools::~Tools() +{ + delete mZoomIn; + delete mZoomOut; + delete mPan; + delete mIdentify; + delete mMeasureDist; + delete mMeasureArea; + delete mCapturePoint; + delete mCaptureLine; + delete mCapturePolygon; + delete mMoveFeature; + delete mSplitFeatures; + delete mSelect; + delete mVertexAdd; + delete mVertexMove; + delete mVertexDelete; + delete mAddRing; + delete mAddIsland; + delete mSimplifyFeature; + delete mDeleteRing; + delete mDeletePart; + delete mNodeTool; +} +#endif Index: src/app/qgisappinterface.cpp =================================================================== --- src/app/qgisappinterface.cpp (revision 11922) +++ src/app/qgisappinterface.cpp (working copy) @@ -30,6 +30,9 @@ #include "qgsmapcanvas.h" #include "qgslegend.h" #include "qgsshortcutsmanager.h" +#ifdef HAVE_TABS +#include "tabs/qgsdesktabwidget.h" +#endif QgisAppInterface::QgisAppInterface( QgisApp * _qgis ) : qgis( _qgis ) @@ -142,6 +145,13 @@ return qgis->mapCanvas(); } +#ifdef HAVE_TABS +QgsDeskTabWidgetInterface * QgisAppInterface::deskTabWidget() +{ + return qgis->deskTabWidget(); +} +#endif + QWidget * QgisAppInterface::mainWindow() { return qgis; Index: src/gui/qgsmapoverviewcanvas.h =================================================================== --- src/gui/qgsmapoverviewcanvas.h (revision 11922) +++ src/gui/qgsmapoverviewcanvas.h (working copy) @@ -62,6 +62,10 @@ void updateFullExtent( const QgsRectangle& rect ); +#ifdef HAVE_TABS + void setMapCanvas( QgsMapCanvas * canvas ) {mMapCanvas = canvas;} +#endif + public slots: void hasCrsTransformEnabled( bool flag ); Index: src/gui/CMakeLists.txt =================================================================== --- src/gui/CMakeLists.txt (revision 11922) +++ src/gui/CMakeLists.txt (working copy) @@ -28,6 +28,20 @@ qgsvertexmarker.cpp ) +IF (HAVE_TABS) + SET (QGIS_GUI_SRCS ${QGIS_GUI_SRCS} + tabs/qgsaddtabdialog.cpp + tabs/qgsdesktabbar.cpp + tabs/qgsdesktabwidget.cpp + tabs/qgsdesktabwidgetinterface.cpp + tabs/qgsfloatcanvaswindow.cpp + tabs/qgslegendtabbar.cpp + tabs/qgslegendtabwidget.cpp + tabs/qgstabbarbase.cpp + tabs/qgswidgetregistry.cpp + ) +ENDIF (HAVE_TABS) + SET(QGIS_GUI_MOC_HDRS qgscomposerview.h qgsdetaileditemdelegate.h @@ -43,6 +57,20 @@ qgsquickprint.h ) +IF (HAVE_TABS) + SET (QGIS_GUI_MOC_HDRS ${QGIS_GUI_MOC_HDRS} + tabs/qgsaddtabdialog.h + tabs/qgsdesktabbar.h + tabs/qgsdesktabwidget.h + tabs/qgsdesktabwidgetinterface.h + tabs/qgsfloatcanvaswindow.h + tabs/qgslegendtabbar.h + tabs/qgslegendtabwidget.h + tabs/qgstabbarbase.h + tabs/qgswidgetregistry.h + ) +ENDIF (HAVE_TABS) + QT4_WRAP_CPP(QGIS_GUI_MOC_SRCS ${QGIS_GUI_MOC_HDRS}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ../core @@ -51,6 +79,9 @@ ${CMAKE_CURRENT_BINARY_DIR}/../ui ${GEOS_INCLUDE_DIR} ) +IF (HAVE_TABS) + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} tabs) +ENDIF (HAVE_TABS) IF (WITH_INTERNAL_SPATIALITE) INCLUDE_DIRECTORIES(../core/spatialite/headers/spatialite) ELSE (WITH_INTERNAL_SPATIALITE) @@ -130,7 +161,6 @@ ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsprojectionselectorbase.h ) - INSTALL(CODE "MESSAGE(\"Installing GUI headers...\")") INSTALL(FILES ${QGIS_GUI_HDRS} ${QGIS_GUI_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR}) Index: src/gui/tabs/qgsdesktabwidget.h =================================================================== --- src/gui/tabs/qgsdesktabwidget.h (revision 0) +++ src/gui/tabs/qgsdesktabwidget.h (revision 0) @@ -0,0 +1,60 @@ +#ifndef QGSDESKTABWIDGET_H +#define QGSDESKTABWIDGET_H + +#include + +#include "qgsdesktabwidgetinterface.h" + +class QgisApp; +class QgsFrameWidget; +class QgsMapCanvas; +class QgsLegend; +class QgsDeskTabBar; + +class GUI_EXPORT QgsDeskTabWidget : public QgsDeskTabWidgetInterface +{ + Q_OBJECT + +public: + QgsDeskTabWidget(QgisApp *qgis); + ~QgsDeskTabWidget(); + + int addFrameTab(QString nameInTab); + int insertFrameTab(int index, QString nameInTab); + int restoreTab(); + + void nextTab(); + void previousTab(); + +public slots: + void updateFrameAt(int index); + +protected: + void tabInserted(int index); + void tabRemoved(int index); + void resizeEvent(QResizeEvent *); + +signals: + void frameUpdated(QgsFrameWidget *); + void canvasDetached(QgsMapCanvas *); + +private slots: + void moveTab(int from, int to); + void changeCurrentTab(int index); + void changeFocus(QWidget *, QWidget *now); + void detachTab(); + void renameTab(); + void closeTab(int index); + +private: + void detachCanvas(int index); + void detachWidget(int index); + + QgisApp *mQgis; + QgsFrameWidget *mCurrentFrame; + QgsFrameWidget *mPreviousFrame; + + QgsDeskTabBar *mTabBar; +}; + +#endif // QGSDESKTABWIDGET_H Property changes on: src/gui/tabs/qgsdesktabwidget.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgstabbarbase.cpp =================================================================== --- src/gui/tabs/qgstabbarbase.cpp (revision 0) +++ src/gui/tabs/qgstabbarbase.cpp (revision 0) @@ -0,0 +1,215 @@ +#include + +#include "../app/qgisapp.h" + +#include "qgsmapcanvas.h" +#include "qgsmaplayer.h" +#include "qgsdesktabwidget.h" + +#include "qgstabbarbase.h" + +QgsTabBarBase::QgsTabBarBase(QWidget *parent, QgisApp *qgis) + : QTabBar(parent), mQgis(qgis), mPreviewPosition(PreviewTop), + mPreviewSize(300, 200), mLegendFont(QFont()), mLegendFontColor(Qt::black), + mPreviewRectColor(Qt::gray), mPrevTabIdx(-1) +{ + setMouseTracking(true); + setDocumentMode(true); + setDrawBase(false); + + connect(this, SIGNAL(tabMoved(int,int)), this, SLOT(movePixmap(int,int))); +} + +// --------------------------------- public -------------------------------- // +void QgsTabBarBase::appendCanvasInPreview(QgsMapCanvas *mapCanvas) +{ + insertCanvasInPreview(mPixmapLabelsVector.size(), mapCanvas); +} + +void QgsTabBarBase::insertCanvasInPreview(int index, QgsMapCanvas *mapCanvas) +{ + // create new preview label + QPixmap preview = drawPreviewCanvas(mapCanvas); + QBitmap lbMask = drawLabelMask(preview.size()); + QLabel *lb = new QLabel(0, Qt::ToolTip | Qt::FramelessWindowHint); + + lb->setPixmap(preview); + lb->setMask(lbMask); + +// int localIndex = QgsWidgetRegistry::localIndexOf(mapCanvas); + mPixmapLabelsVector.insert(index, lb); + + connect(mapCanvas, SIGNAL(renderComplete(QPainter *)), this, SLOT(updateCanvasPixmap())); + connect(this, SIGNAL(currentChanged(int)), lb, SLOT(close())); +} + +void QgsTabBarBase::insertWidgetInPreview(int index, QWidget *widget) +{ + QPixmap preview(widget->size()); + widget->render(&preview); + preview = preview.scaled(mPreviewSize, Qt::KeepAspectRatio); + preview = drawFrame(preview); + + QBitmap lbMask = drawLabelMask(preview.size()); + QLabel *lb = new QLabel(0, Qt::ToolTip | Qt::FramelessWindowHint); + + lb->resize(preview.size()); + lb->setPixmap(preview); + lb->setMask(lbMask); + + mPixmapLabelsVector.insert(index, lb); + + connect(this, SIGNAL(currentChanged(int)), lb, SLOT(close())); +} + +// ------------------------------- protected ------------------------------- // +void QgsTabBarBase::updateCanvasPixmapAt(int index, QgsMapCanvas *mapCanvas) +{ + // use sender() because we need tabIdx of current mapcanvas and it's layers + QPixmap preview = drawPreviewCanvas(mapCanvas); + QBitmap lbMask = drawLabelMask(preview.size()); + + // update preview for current mapcanvas + QLabel *lb = mPixmapLabelsVector.at(index); + lb->resize(preview.size()); + lb->setPixmap(preview); + lb->setMask(lbMask); + mPixmapLabelsVector.replace(index, lb); +} + +void QgsTabBarBase::mouseMoveEvent(QMouseEvent *e) +{ + // show preview + int nowTabIdx = tabAt(e->pos()); + if (nowTabIdx != currentIndex() && + nowTabIdx == mPrevTabIdx && + nowTabIdx != -1) + { + QLabel *lb = mPixmapLabelsVector.at(nowTabIdx); + QPoint mvPt = moveLabelToPoint(lb, nowTabIdx); + lb->move(mvPt); + lb->show(); + } + else if (mPrevTabIdx != -1) + { + QLabel *lb = mPixmapLabelsVector.at(mPrevTabIdx); + lb->close(); + } + + mPrevTabIdx = nowTabIdx; + QTabBar::mouseMoveEvent(e); +} + +void QgsTabBarBase::leaveEvent(QEvent *e) +{ + if (mPrevTabIdx != -1) + { + QLabel *lb = mPixmapLabelsVector.at(mPrevTabIdx); + lb->close(); + } + + QTabBar::leaveEvent(e); +} + +void QgsTabBarBase::tabRemoved(int index) +{ + QLabel *lb = mPixmapLabelsVector.at(index); + lb->close(); + mPrevTabIdx = -1; + + mPixmapLabelsVector.remove(index); +} + +// ----------------------------- private slots ----------------------------- // +void QgsTabBarBase::movePixmap(int from, int to) +{ + QLabel *tLb = mPixmapLabelsVector.at(from); + mPixmapLabelsVector.replace(from, mPixmapLabelsVector.at(to)); + mPixmapLabelsVector.replace(to, tLb); + + mPrevTabIdx = to; +} + +// -------------------------------- private -------------------------------- // +QPixmap QgsTabBarBase::drawFrame(QPixmap in_pixmap) +{ + QPixmap out_pixmap(in_pixmap); + QPainter painter(&out_pixmap); + painter.setRenderHints(QPainter::Antialiasing, true); + QPen pen(mPreviewRectColor, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter.setPen(pen); + painter.drawRoundedRect(in_pixmap.rect(), 10, 10, Qt::RelativeSize); + return out_pixmap; +} + +QPixmap QgsTabBarBase::drawPreviewCanvas(QgsMapCanvas *mapCanvas) +{ + QPixmap preview = mapCanvas->canvasPixmap().scaled(mPreviewSize, Qt::KeepAspectRatio); + preview = drawFrame(preview); + + // draw legend + QPainter painter(&preview); + painter.setFont(mLegendFont); + painter.setPen(Qt::black); + QPoint pt(preview.rect().topLeft().x() + 2 * painter.fontMetrics().width(" "), + preview.rect().topLeft().y()); + for (int i = 0; i < mapCanvas->layerCount(); ++i) + { + pt.setY(pt.y() + painter.fontMetrics().height()); + painter.drawText(pt, mapCanvas->layer(i)->name()); + } + + return preview; +} + +QBitmap QgsTabBarBase::drawLabelMask(QSize size) +{ + // draw mask for preview tab + QBitmap bmMask(size); + QPainter painter(&bmMask); + painter.setPen(Qt::color0); + painter.setBrush(Qt::color0); + painter.drawRect(bmMask.rect()); + + QPen pen(Qt::color1, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter.setPen(pen); + painter.setBrush(Qt::color1); + QRect r(bmMask.rect().topLeft(), bmMask.rect().bottomRight() - QPoint(1, 1)); + painter.drawRoundedRect(r, 10, 10, Qt::RelativeSize); + + return bmMask; +} + +QPoint QgsTabBarBase::moveLabelToPoint(QLabel *label, int nowTabIdx) +{ + QRect r = tabRect(nowTabIdx); + QPoint cPt = mapToGlobal(r.center()); + + // find point in which we should move preview label + QPoint mvPt; + switch (mPreviewPosition) + { + case PreviewBottom: + { + mvPt = mapToGlobal(r.bottomRight()); + // a litle trick if the preview goes around bottom of QGis draw it on top + if (!(mvPt.y() + label->height() > mQgis->geometry().bottom())) + break; + } + case PreviewTop: + { + QPoint tlPt = mapToGlobal(r.topLeft()); + mvPt = QPoint(cPt.x() - label->rect().width() / 2, tlPt.y() - label->rect().height() - 10); + + // if move point goes around left bound of QGis set it to left bound of QGis + if (mvPt.x() < mQgis->geometry().x()) + mvPt.setX(mQgis->geometry().x()); + + // if move point goes around right bound of QGis set it to right bound of QGis + if (mvPt.x() + label->rect().width() > mQgis->geometry().right()) + mvPt.setX(mQgis->geometry().right() - label->rect().width()); + } + } + + return mvPt; +} Property changes on: src/gui/tabs/qgstabbarbase.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsfloatcanvaswindow.cpp =================================================================== --- src/gui/tabs/qgsfloatcanvaswindow.cpp (revision 0) +++ src/gui/tabs/qgsfloatcanvaswindow.cpp (revision 0) @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include + +#include "../app/qgisapp.h" +#include "../app/qgsframewidget.h" + +#include "qgsdesktabwidget.h" +#include "qgslegendtabwidget.h" +#include "qgsmapcanvas.h" +#include "qgswidgetregistry.h" + +#include "qgsfloatcanvaswindow.h" + +QgsFloatCanvasWindow::QgsFloatCanvasWindow(QgisApp *qgis, QgsDeskTabWidget *deskTabWidget, + QgsFrameWidget *frame, int index) + : QMainWindow(), mQgis(qgis), mDeskTabWidget(deskTabWidget), mFrame(frame), + mIndex(index), mLostFocus(true) +{ + setWindowFlags(windowFlags() & ~Qt::WindowCloseButtonHint); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName("theFloatCanvasWindow"); + QString windowTitle = mDeskTabWidget->tabText(mDeskTabWidget->currentIndex()); + setWindowTitle(windowTitle); + setAcceptDrops(true); // TODO: implement drag'n'drop functions for map canvas + setFocusPolicy(Qt::StrongFocus); + setStatusBar(mQgis->statusBar()); + setProperty("detached", true); + + createActions(); + createToolBars(); + + connect(this, SIGNAL(frameUpdated(QgsFrameWidget*)), qgis, SLOT(updateFrame(QgsFrameWidget*))); +} + +// -------------------------------- protected ------------------------------ // +// setup connections only when focus was lost +void QgsFloatCanvasWindow::focusInEvent(QFocusEvent *) +{ + if (mLostFocus) + { + mFrame->setupConnections(); + emit frameUpdated(mFrame); + mQgis->legendTabWidget()->setCurrentIndex(mIndex); + } +} + +// focus lost only when it go in QGis +void QgsFloatCanvasWindow::focusOutEvent(QFocusEvent *) +{ + if (qApp->activeWindow() == mQgis) + { + if (mFrame) + mFrame->removeConnections(); + mLostFocus = true; + } + else + mLostFocus = false; +} + +// ----------------------------- private slots ----------------------------- // +void QgsFloatCanvasWindow::returnInQgis() +{ + // get mapCanvas + QWidget *mapCanvas = mFrame->mapCanvas(); + mapCanvas->setObjectName("theMapCanvas"); + + mFrame->setObjectName("theFrameWidget"); + mFrame->removeConnections(); + + // insert mapCanvas in tabWidget + QString canvasName = windowTitle(); + mDeskTabWidget->insertTab(mIndex, mapCanvas, canvasName); + QgsWidgetRegistry::setDetached(mapCanvas, false); + + if (mIndex > mDeskTabWidget->count()) + mDeskTabWidget->setCurrentIndex(mDeskTabWidget->count()); + else + mDeskTabWidget->setCurrentIndex(mIndex); + + // it is needed to avoid deleting of statusBar + if (findChild()) + statusBar()->setParent(0); + + close(); +} + +void QgsFloatCanvasWindow::stayOnTop() +{ + setWindowFlags(windowFlags() ^ Qt::WindowStaysOnTopHint); + show(); +} + +void QgsFloatCanvasWindow::closeWindow() +{ + // remove mapCanvas from list + int idx = QgsWidgetRegistry::instance()->globalIndexOf(centralWidget()); + QgsWidgetRegistry::instance()->remove(idx); + + QgsFrameWidget *f = mFrame; + mFrame = 0; + delete f; + + close(); +} + +// --------------------------------- private ------------------------------- // +void QgsFloatCanvasWindow::createActions() +{ + // add some QGis actions to detached frame + QList< QAction * > editMenu = mQgis->editMenu()->actions(); + QList< QAction * > viewMenu = mQgis->viewMenu()->actions(); + QList< QAction * > layerMenu = mQgis->layerMenu()->actions(); + + mQgisActions.append(editMenu); + mQgisActions.append(viewMenu); + mQgisActions.append(layerMenu); + + addActions(mQgisActions); + + mActionReturnInQgis = new QAction(mQgis->getThemeIcon("mActionReturnInQGis.png"), + tr("Return in QGis"), mQgis); + mActionReturnInQgis->setShortcut(tr("Alt+R", "Return in QGis")); + mActionReturnInQgis->setStatusTip(tr("Return in QGis")); + connect(mActionReturnInQgis, SIGNAL(triggered()), this, SLOT(returnInQgis())); + + mActionStayOnTop = new QAction(mQgis->getThemeIcon("mActionStayOnTop.png"), + tr("Stay on top"), mQgis); + mActionStayOnTop->setStatusTip(tr("Stay on top")); + mActionStayOnTop->setCheckable(true); + connect(mActionStayOnTop, SIGNAL(triggered()), this, SLOT(stayOnTop())); + + mActionCloseFloatCanvas = new QAction(mQgis->getThemeIcon("mActionCloseFloatCanvas.png"), + tr("Close float canvas window"), mQgis); + mActionCloseFloatCanvas->setShortcut(tr("Alt+Q", "Close float canvas window")); + mActionCloseFloatCanvas->setStatusTip(tr("Close float canvas window")); + connect(mActionCloseFloatCanvas, SIGNAL(triggered()), this, SLOT(closeWindow())); +} + +void QgsFloatCanvasWindow::createToolBars() +{ + mMapNavToolBar = new QToolBar(tr("Map Navigation")); + mAttributesToolBar = new QToolBar(tr("Attributes")); + mControlToolBar = new QToolBar(tr("Control")); + QSize iconSize = mQgis->mapNavToolToolBar()->iconSize(); + + mControlToolBar->addAction(mActionReturnInQgis); + mControlToolBar->addAction(mActionStayOnTop); + mControlToolBar->addAction(mActionCloseFloatCanvas); + mControlToolBar->setIconSize(iconSize); + addToolBar(mControlToolBar); + + QList actions(mQgis->mapNavToolToolBar()->actions()); + mMapNavToolBar->addActions(actions); + mMapNavToolBar->setIconSize(iconSize); + addToolBar(mMapNavToolBar); + + actions = QList(mQgis->attributesToolBar()->actions()); + mAttributesToolBar->addActions(actions); + mAttributesToolBar->setIconSize(iconSize); + addToolBar(mAttributesToolBar); +} Property changes on: src/gui/tabs/qgsfloatcanvaswindow.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgslegendtabwidget.cpp =================================================================== --- src/gui/tabs/qgslegendtabwidget.cpp (revision 0) +++ src/gui/tabs/qgslegendtabwidget.cpp (revision 0) @@ -0,0 +1,204 @@ +#include + +#include "qgsdesktabwidget.h" +#include "qgsfloatcanvaswindow.h" +#include "qgsmapcanvas.h" +#include "qgswidgetregistry.h" + +#include "../app/qgisapp.h" +#include "../app/legend/qgslegend.h" + +#include "qgslegendtabbar.h" +#include "qgslegendtabwidget.h" + +QgsLegendTabWidget::QgsLegendTabWidget(QgisApp *qgis) + : QTabWidget(), mQgis(qgis) +{ + mTabBar = new QgsLegendTabBar(this, qgis); + setTabBar(mTabBar); + setObjectName("theLegendTabWidget"); + setTabPosition(QTabWidget::South); + mTabBar->hide(); + + mSyncWithTWToolButton = new QToolButton(this); + mSyncWithTWToolButton->setIcon(qgis->getThemeIcon("mSyncTabWidgets.png")); + mSyncWithTWToolButton->setStatusTip("Sync legend tabs with desk tabs"); + mSyncWithTWToolButton->setAutoRaise(true); + mSyncWithTWToolButton->setCheckable(true); + setCornerWidget(mSyncWithTWToolButton, Qt::BottomRightCorner); + + mTimer = new QTimer(this); + mTimer->setSingleShot(true); + + connect(mSyncWithTWToolButton, SIGNAL(clicked(bool)), + this, SLOT(syncWithDeskTabWidget(bool))); + connect(qgis->deskTabWidget(), SIGNAL(canvasDetached(QgsMapCanvas *)), + this, SLOT(markTabFloat(QgsMapCanvas *))); + + connect(QgsWidgetRegistry::instance(), SIGNAL(legendInserted(int,QgsLegend *)), + this, SLOT(insertLegend(int,QgsLegend *))); + connect(QgsWidgetRegistry::instance(), SIGNAL(mapCanvasInserted(int,QgsMapCanvas*)), + this, SLOT(insertCanvasInPreview(int,QgsMapCanvas*))); + + connect(qgis->deskTabWidget(), SIGNAL(tabClosed(int)), + this, SLOT(closeTab(int))); + connect(qgis->deskTabWidget(), SIGNAL(tabMoved(int,int)), + this, SLOT(moveTab(int,int))); + +// connect(this, SIGNAL(currentChanged(int)), +// qgis->deskTabWidget(), SLOT(setCurrentTabbedCanvas(int))); +} + +// ---------------------------- public slots ------------------------------- // +void QgsLegendTabWidget::moveTab(int deskFrom, int deskTo) +{ + // desk tabs and legend tabs has different indexes + QWidget *wFrom = QgsWidgetRegistry::instance()->mapCanvasTabAt(deskFrom); + QWidget *wTo = QgsWidgetRegistry::instance()->mapCanvasTabAt(deskTo); + int legendFrom = QgsWidgetRegistry::localIndexOf(wFrom); + int legendTo = QgsWidgetRegistry::localIndexOf(wTo); + + if (abs(legendFrom - legendTo) != 1) + { + // setTabText(legendFrom, QString::number(legendTo)); + // setTabText(legendTo, QString::number(legendFrom)); + + // updateTabText(); + + mTabBar->moveTab(legendFrom, legendTo); + if (legendFrom > legendTo) + { + mTabBar->moveTab(legendTo + 1, legendFrom); + } + else + { + mTabBar->moveTab(legendTo - 1, legendFrom); + } + } + else + { + mTabBar->moveTab(legendFrom, legendTo); + } + mTabBar->setCurrentIndex(legendFrom); +} + +int QgsLegendTabWidget::insertLegend(int index, QgsLegend *legend) +{ + if (QgsWidgetRegistry::instance()->isDetached(legend)) + { + // remove "f" prefix in tab name + setTabText(index, tabText(index).right(tabText(index).size() - 1)); + return indexOf(legend); + } else + return insertTab(index, legend, ""); +} + +void QgsLegendTabWidget::insertCanvasInPreview(int, QgsMapCanvas *mapCanvas) +{ + connect(mapCanvas, SIGNAL(renderComplete(QPainter *)), + mTabBar, SLOT(updateCanvasPixmap())); + + int localIndex = QgsWidgetRegistry::localIndexOf(mapCanvas); + mTabBar->insertCanvasInPreview(localIndex, mapCanvas); +} + +// ------------------------------ protected -------------------------------- // +void QgsLegendTabWidget::tabInserted(int index) +{ + qDebug() << index; + if (count() > 1) + { + mTabBar->show(); + mTimer->start(1500); + connect(mTimer, SIGNAL(timeout()), mTabBar, SLOT(hide())); + } + updateTabText(); +} + +void QgsLegendTabWidget::tabRemoved(int) +{ + if (count() == 1) + mTabBar->hide(); + updateTabText(); +} + +void QgsLegendTabWidget::enterEvent(QEvent *) +{ + mTimer->stop(); + if (mTabBar->isHidden() && count() != 1) + mTabBar->show(); +} + +void QgsLegendTabWidget::leaveEvent(QEvent *) +{ + if (!(mTabBar->isHidden() || mSyncWithTWToolButton->isChecked())) + { + mTimer->start(800); + connect(mTimer, SIGNAL(timeout()), mTabBar, SLOT(hide())); + } +} + +// --------------------------- private slots ------------------------------- // +void QgsLegendTabWidget::setCurrentCanvas(int index) +{ + QgsMapCanvas *mc = QgsWidgetRegistry::instance()->mapCanvasAt(index); + if (QgsWidgetRegistry::instance()->isDetached(mc)) + { + QWidget *w = qobject_cast(mc->parent()); + w->activateWindow(); + w->raise(); + } + else + { + int tabIndex = QgsWidgetRegistry::tabIndexOf(mc); + mQgis->deskTabWidget()->setCurrentIndex(tabIndex); + } +} + +void QgsLegendTabWidget::closeTab(int index) +{ + removeTab(index); +} + +void QgsLegendTabWidget::syncWithDeskTabWidget(bool isSync) +{ + if (isSync) + { + connect(this, SIGNAL(currentChanged(int)), + this, SLOT(setCurrentCanvas(int))); + } + else + { + disconnect(this, SIGNAL(currentChanged(int)), + this, SLOT(setCurrentCanvas(int))); + } +} + +void QgsLegendTabWidget::markTabFloat(QgsMapCanvas *mc) +{ + int localIndex = QgsWidgetRegistry::localIndexOf(mc); + if (!tabText(localIndex).startsWith(tr("f"))) + setTabText(localIndex, tr("f") + tabText(localIndex)); +} + +// ----------------------------- private ----------------------------------- // +void QgsLegendTabWidget::updateTabText() +{ + for (int i = 0; i < QgsWidgetRegistry::instance()->count(); ++i) + { + QWidget *w = QgsWidgetRegistry::instance()->widget(i); + if (QgsWidgetRegistry::isMapCanvas(w)) + { + int localIndex = QgsWidgetRegistry::localIndexOf(w); + if (QgsWidgetRegistry::isDetached(w)) + { + QgsMapCanvas *mc = qobject_cast(w); + markTabFloat(mc); + } + else + { + setTabText(localIndex, QString::number(localIndex)); + } + } + } +} Property changes on: src/gui/tabs/qgslegendtabwidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgstabbarbase.h =================================================================== --- src/gui/tabs/qgstabbarbase.h (revision 0) +++ src/gui/tabs/qgstabbarbase.h (revision 0) @@ -0,0 +1,65 @@ +#ifndef QGSTABBARBASE_H +#define QGSTABBARBASE_H + +#include +#include +#include +#include + +#include "qgswidgetregistry.h" + +class QgisApp; +class QgsMapCanvas; +class QgsDeskTabWidget; + +class QgsTabBarBase : public QTabBar +{ + Q_OBJECT + +public: + enum PreviewPosition { + PreviewTop, + PreviewBottom + }; + + QgsTabBarBase(QWidget *parent = 0, QgisApp *qgis = 0); + + void setPreviewPosition(QgsTabBarBase::PreviewPosition pos) { mPreviewPosition = pos; } + void setPreviewSize(QSize size) { mPreviewSize = size; } + void setLegendFont(QFont font) { mLegendFont = font; } + void setLegendFontColor(QColor color) { mLegendFontColor = color; } + void setPreviewRectColor(QBrush color) { mPreviewRectColor = color; } + + void appendCanvasInPreview(QgsMapCanvas *mapCanvas); + void insertCanvasInPreview(int index, QgsMapCanvas *mapCanvas); + void insertWidgetInPreview(int index, QWidget *widget); + +protected: + void updateCanvasPixmapAt(int index, QgsMapCanvas *mapCanvas); + void mouseMoveEvent(QMouseEvent *e); + void leaveEvent(QEvent *e); + void tabRemoved(int index); + + QgisApp *mQgis; + +private slots: + void movePixmap(int from, int to); + +private: + QPixmap drawFrame(QPixmap in_pixmap); + QPixmap drawPreviewCanvas(QgsMapCanvas *mapCanvas); + QBitmap drawLabelMask(QSize size); + QPoint moveLabelToPoint(QLabel *label, int nowTabIdx); + + QVector mPixmapLabelsVector; + + PreviewPosition mPreviewPosition; + QSize mPreviewSize; + QFont mLegendFont; + QColor mLegendFontColor; + QBrush mPreviewRectColor; + + int mPrevTabIdx; +}; + +#endif // QGSTABBARBASE_H Property changes on: src/gui/tabs/qgstabbarbase.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgslegendtabwidget.h =================================================================== --- src/gui/tabs/qgslegendtabwidget.h (revision 0) +++ src/gui/tabs/qgslegendtabwidget.h (revision 0) @@ -0,0 +1,49 @@ +#ifndef QGSLEGENDTABWIDGET_H +#define QGSLEGENDTABWIDGET_H + +#include +#include +#include + +class QgisApp; +class QgsLegend; +class QgsLegendTabBar; +class QgsMapCanvas; + +class QgsLegendTabWidget : public QTabWidget +{ + Q_OBJECT + +public: + QgsLegendTabWidget(QgisApp *qgis); + +public slots: + void moveTab(int deskFrom, int deskTo); + + int insertLegend(int index, QgsLegend *legend); + void insertCanvasInPreview(int index, QgsMapCanvas *mapCanvas); + +protected: + void tabInserted(int index); + void tabRemoved(int index); + + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + +private slots: + void setCurrentCanvas(int); + void closeTab(int index); + void syncWithDeskTabWidget(bool isSync); + void markTabFloat(QgsMapCanvas *); + +private: + void updateTabText(); + + QgisApp *mQgis; + QgsLegendTabBar *mTabBar; + + QTimer *mTimer; + QToolButton *mSyncWithTWToolButton; +}; + +#endif // QGSLEGENDTABWIDGET_H Property changes on: src/gui/tabs/qgslegendtabwidget.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsfloatcanvaswindow.h =================================================================== --- src/gui/tabs/qgsfloatcanvaswindow.h (revision 0) +++ src/gui/tabs/qgsfloatcanvaswindow.h (revision 0) @@ -0,0 +1,58 @@ +#ifndef QGSFLOATCANVASWINDOW_H +#define QGSFLOATCANVASWINDOW_H + +#include +#include + +class QgisApp; +class QgsFrameWidget; +class QgsDeskTabWidget; + +class QgsFloatCanvasWindow : public QMainWindow +{ + Q_OBJECT + +public: + QgsFloatCanvasWindow(QgisApp *qgis, QgsDeskTabWidget *deskTabWidget, + QgsFrameWidget *frame, int index); + + int index() { return mIndex; } + +protected: + void focusInEvent(QFocusEvent *); + void focusOutEvent(QFocusEvent *); + +signals: + void frameUpdated(QgsFrameWidget *); + +private slots: + void returnInQgis(); + void stayOnTop(); + void closeWindow(); + +private: + void createActions(); + void createToolBars(); + + QList< QAction * > mQgisActions; + + QAction *mActionReturnInQgis; + QAction *mActionStayOnTop; + QAction *mActionCloseFloatCanvas; + + QToolBar *mMapNavToolBar; + QToolBar *mAttributesToolBar; + QToolBar *mControlToolBar; + + QgisApp *mQgis; + QgsDeskTabWidget *mDeskTabWidget; + QgsFrameWidget *mFrame; + + // index of float window + int mIndex; + // Flag that says if window lose focus permanently (if window lose focus when user opened + // new layer window should hold focuse and it shoud hold focus when measure tool was selected) + bool mLostFocus; +}; + +#endif // QGSFLOATCANVASWINDOW_H Property changes on: src/gui/tabs/qgsfloatcanvaswindow.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsaddtabdialog.cpp =================================================================== --- src/gui/tabs/qgsaddtabdialog.cpp (revision 0) +++ src/gui/tabs/qgsaddtabdialog.cpp (revision 0) @@ -0,0 +1,60 @@ +#include "qgsaddtabdialog.h" + +#include +#include +#include + +#include "../app/qgisapp.h" +#include "../app/composer/qgscomposer.h" +#include "qgsdesktabwidget.h" + +QgsAddTabDialog::QgsAddTabDialog(QWidget *parent) : + QWidget(parent) +{ + setupUi(this); + + mQgis = QgisApp::instance(); + mTabWidget = mQgis->deskTabWidget(); +} + +void QgsAddTabDialog::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) + { + case QEvent::LanguageChange: + retranslateUi(this); + break; + default: + break; + } +} + +void QgsAddTabDialog::on_pbnMapCanvasTab_clicked() +{ + int index = mTabWidget->insertFrameTab( mTabWidget->count(), "Canvas " + + QString::number( mTabWidget->count() + 1 ) ); + mTabWidget->setCurrentIndex( index ); + close(); +} + +void QgsAddTabDialog::on_pbnMapComposerTab_clicked() +{ + QString composerId = QString::number(mTabWidget->count()); + QgsComposer *composer = mQgis->createPrintComposer(composerId); + if ( composer ) + { + composer->prepareTabbing(); + int index = mTabWidget->addTab( composer, "Composer " + + QString::number( mTabWidget->count() + 1 ) ); + connect( mTabWidget, SIGNAL(currentChanged(int)), composer, SLOT(restoreState(int))); + mTabWidget->setCurrentIndex( index ); + } + close(); +} + +void QgsAddTabDialog::on_pbnAttributeTableTab_clicked() +{ + +} + Property changes on: src/gui/tabs/qgsaddtabdialog.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsdesktabwidgetinterface.cpp =================================================================== --- src/gui/tabs/qgsdesktabwidgetinterface.cpp (revision 0) +++ src/gui/tabs/qgsdesktabwidgetinterface.cpp (revision 0) @@ -0,0 +1,9 @@ +#include "qgsdesktabwidgetinterface.h" + +QgsDeskTabWidgetInterface::QgsDeskTabWidgetInterface() +{ +} + +QgsDeskTabWidgetInterface::~QgsDeskTabWidgetInterface() +{ +} Property changes on: src/gui/tabs/qgsdesktabwidgetinterface.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsdesktabbar.cpp =================================================================== --- src/gui/tabs/qgsdesktabbar.cpp (revision 0) +++ src/gui/tabs/qgsdesktabbar.cpp (revision 0) @@ -0,0 +1,88 @@ +#include +#include +#include + +#include "qgsmapcanvas.h" +#include "qgsmaplayer.h" + +#include "../app/qgisapp.h" +#include "../app/qgsshortcutsmanager.h" + +#include "qgsdesktabbar.h" + +QgsDeskTabBar::QgsDeskTabBar(QgsDeskTabWidget *tabWidget, QgisApp *qgis) + : QgsTabBarBase(tabWidget, qgis), mTabWidget(tabWidget) +{ + createActions(); + createContextMenu(); + + setObjectName("theDeskTabBar"); + setShape(QTabBar::RoundedSouth); + setLegendFont(QFont(font().family(), 9, QFont::DemiBold, true)); + setContextMenuPolicy(Qt::CustomContextMenu); + setStatusTip(tr("To detach tab press Ctrl+D")); + setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); + + connect(this, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(execContextMenu(QPoint))); +} + +// ------------------------------- protecetd ------------------------------- // +void QgsDeskTabBar::tabInserted(int index) +{ + QToolButton *tbnDetachTab = new QToolButton(); + tbnDetachTab->setIcon(mQgis->getThemeIcon("mActionDetachTab.png")); + tbnDetachTab->setAutoRaise(true); + connect(tbnDetachTab, SIGNAL(clicked()), mActionDetachTab, SLOT(trigger())); + + // in different styles close button may not be located on right side of tab + QTabBar::ButtonPosition closeSide = + (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this); + if (closeSide == QTabBar::RightSide) + setTabButton(index, QTabBar::LeftSide, tbnDetachTab); + else + setTabButton(index, QTabBar::RightSide, tbnDetachTab); +} + +// ----------------------------- private slots ----------------------------- // +void QgsDeskTabBar::execContextMenu( QPoint pt ) +{ + pt = mapToGlobal(pt); + mTabBarContextMenu->exec(pt); +} + +void QgsDeskTabBar::updateCanvasPixmap() +{ + QgsMapCanvas *mapCanvas = qobject_cast(sender()); + int index = mTabWidget->indexOf(mapCanvas); + if (index != -1) + QgsTabBarBase::updateCanvasPixmapAt(index, mapCanvas); +} + +// -------------------------------- private -------------------------------- // +void QgsDeskTabBar::createActions() +{ + QgsShortcutsManager* shortcuts = QgsShortcutsManager::instance(); + + mActionDetachTab = new QAction(mQgis->getThemeIcon("mActionDetachTab.png"), + tr("Detach tab"), this); + shortcuts->registerAction(mActionDetachTab, tr("Alt+D", "Detach tab")); + mActionDetachTab->setStatusTip(tr("Detach tab from QGis")); + mActionDetachTab->setIconVisibleInMenu(true); + connect(mActionDetachTab, SIGNAL(triggered()), mTabWidget, SLOT(detachTab())); + + mActionRenameTab = new QAction(mQgis->getThemeIcon("mActionRenameTab.png"), + tr("Rename tab"), this); + mActionRenameTab->setStatusTip(tr("Rename tab")); + connect(mActionRenameTab, SIGNAL(triggered()), mTabWidget, SLOT(renameTab())); + + mTabWidget->addAction(mActionDetachTab); + mTabWidget->addAction(mActionRenameTab); +} + +void QgsDeskTabBar::createContextMenu() +{ + mTabBarContextMenu = new QMenu("TabBar context menu"); + mTabBarContextMenu->addAction(mActionDetachTab); + mTabBarContextMenu->addAction(mActionRenameTab); +} Property changes on: src/gui/tabs/qgsdesktabbar.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsaddtabdialog.h =================================================================== --- src/gui/tabs/qgsaddtabdialog.h (revision 0) +++ src/gui/tabs/qgsaddtabdialog.h (revision 0) @@ -0,0 +1,29 @@ +#ifndef QGSADDTABDIALOG_H +#define QGSADDTABDIALOG_H + +#include "ui_qgsaddtabdialogbase.h" + +class QgisApp; +class QgsDeskTabWidget; + +class QgsAddTabDialog : public QWidget, private Ui::QgsAddTabDialog +{ + Q_OBJECT + +public: + QgsAddTabDialog(QWidget *parent = 0); + +protected: + void changeEvent(QEvent *e); + +private slots: + void on_pbnMapCanvasTab_clicked(); + void on_pbnMapComposerTab_clicked(); + void on_pbnAttributeTableTab_clicked(); + +private: + QgsDeskTabWidget *mTabWidget; + QgisApp *mQgis; +}; + +#endif // QGSADDTABDIALOG_H Property changes on: src/gui/tabs/qgsaddtabdialog.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsdesktabbar.h =================================================================== --- src/gui/tabs/qgsdesktabbar.h (revision 0) +++ src/gui/tabs/qgsdesktabbar.h (revision 0) @@ -0,0 +1,37 @@ +#ifndef QGSDESKTABBAR_H +#define QGSDESKTABBAR_H + +#include +#include +#include +#include + +#include "qgsdesktabwidget.h" +#include "qgstabbarbase.h" + +class QgsDeskTabBar : public QgsTabBarBase +{ + Q_OBJECT + +public: + QgsDeskTabBar(QgsDeskTabWidget *tabWidget, QgisApp *qgis); + +protected: + void tabInserted(int index); + +private slots: + void execContextMenu( QPoint pt ); + void updateCanvasPixmap(); + +private: + void createActions(); + void createContextMenu(); + + QgsDeskTabWidget *mTabWidget; + + QMenu *mTabBarContextMenu; + QAction *mActionDetachTab; + QAction *mActionRenameTab; +}; + +#endif // QGSDESKTABBAR_H Property changes on: src/gui/tabs/qgsdesktabbar.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsdesktabwidgetinterface.h =================================================================== --- src/gui/tabs/qgsdesktabwidgetinterface.h (revision 0) +++ src/gui/tabs/qgsdesktabwidgetinterface.h (revision 0) @@ -0,0 +1,23 @@ +#ifndef QGSDESKTABWIDGETINTERFACE_H +#define QGSDESKTABWIDGETINTERFACE_H + +#include + +class QgsMapCanvas; +class QgsMapCanvasContainer; + +class QgsDeskTabWidgetInterface : public QTabWidget +{ + Q_OBJECT + +public: + QgsDeskTabWidgetInterface(); + virtual ~QgsDeskTabWidgetInterface(); + +signals: + void tabDetached(); + void tabMoved(int, int); + void tabClosed(int); +}; + +#endif // QGSDESKTABWIDGETINTERFACE_H Property changes on: src/gui/tabs/qgsdesktabwidgetinterface.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgslegendtabbar.cpp =================================================================== --- src/gui/tabs/qgslegendtabbar.cpp (revision 0) +++ src/gui/tabs/qgslegendtabbar.cpp (revision 0) @@ -0,0 +1,39 @@ +#include + +#include "qgsmapcanvas.h" + +#include "../app/qgisapp.h" + +#include "qgslegendtabbar.h" + +QgsLegendTabBar::QgsLegendTabBar(QWidget *parent, QgisApp *qgis) + : QgsTabBarBase(parent, qgis) +{ + setObjectName("theLegendTabBar"); + setFont(QFont(font().family(), 7, QFont::DemiBold, true)); + setLegendFont(font()); + setPreviewPosition(QgsTabBarBase::PreviewBottom); + setPreviewSize(QSize(150, 100)); + setShape(QTabBar::TriangularSouth); +} + +// ----------------------------- protected --------------------------------- // +void QgsLegendTabBar::showEvent(QShowEvent *) +{ + // TODO: implement some nice effects +} + +void QgsLegendTabBar::hideEvent(QHideEvent *) +{ + // TODO: implement some nice effects +} + +// ----------------------------- private slots ----------------------------- // +void QgsLegendTabBar::updateCanvasPixmap() +{ + QgsMapCanvas *mapCanvas = qobject_cast(sender()); + int index = QgsWidgetRegistry::localIndexOf(mapCanvas); + + if (index != -1) + QgsTabBarBase::updateCanvasPixmapAt(index, mapCanvas); +} Property changes on: src/gui/tabs/qgslegendtabbar.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgswidgetregistry.cpp =================================================================== --- src/gui/tabs/qgswidgetregistry.cpp (revision 0) +++ src/gui/tabs/qgswidgetregistry.cpp (revision 0) @@ -0,0 +1,329 @@ +#include "qgsmapcanvas.h" +#include "qgsdesktabwidget.h" + +#include "../app/qgisapp.h" +#include "../app/qgsframewidget.h" +#include "../app/composer/qgscomposer.h" +#include "../app/legend/qgslegend.h" +//#include "../app/attributetable/qgsattributetabledialog.h" +//#include "../app/attributetable/qgsattributetableview.h" + +#include "qgswidgetregistry.h" + +//typedef bool (QgsWidgetRegistry:: + +// initialization static variable +QgsWidgetRegistry *QgsWidgetRegistry::mInstance = 0; + +QgsWidgetRegistry::~QgsWidgetRegistry() +{ +} + +// ------------------------------ public ----------------------------------- // +void QgsWidgetRegistry::append(QWidget *w) +{ + insert(mWidgets.size(), w); +} + +void QgsWidgetRegistry::insert(int index, QWidget *w) +{ + if (isMapCanvas(w)) + { + // get frame from dynamic property of added mapCanvas + QWidget *f = w->property("parentFrame").value(); + QgsFrameWidget *frame = qobject_cast(f); + + bool bDetached = isDetached(w); + setDetached(frame->legend(), bDetached); + + if (!bDetached) + { + mWidgets.insert(index, w); + } + updateLocalIndex(&QgsWidgetRegistry::isMapCanvas); + + // notify all about added mapCanvas and legend + emit legendInserted(index, frame->legend()); + emit mapCanvasInserted(index, frame->mapCanvas()); + } + else if (isComposer(w)) + { + if (!isDetached(w)) + { + mWidgets.insert(index, w); + } + updateLocalIndex(&QgsWidgetRegistry::isComposer); + } /*else if (isAttr)*/ + + updateTabIndex(); +} + +void QgsWidgetRegistry::swap(int from, int to) +{ + mWidgets.swap(from, to); + + if (isMapCanvas(mWidgets.at(from)) || isMapCanvas(mWidgets.at(to))) + updateLocalIndex(&QgsWidgetRegistry::isMapCanvas); + if (isComposer(mWidgets.at(from)) || isComposer(mWidgets.at(to))) + updateLocalIndex(&QgsWidgetRegistry::isComposer); +// if (isAttributeTableAt(from) || isAttributeTableAt(to)) +// updateAttributeTableLocalIndex(); +// if (isPluginAt(from) || isPluginAt(to)) +// updatePluginLocalIndex(); + + updateTabIndex(); +} + +void QgsWidgetRegistry::remove(int index) +{ + QWidget *removed = mWidgets.at(index); + mWidgets.removeAt(index); + if (!isDetached(removed)) + { + setRestoreIndex(removed, index); + mRemovedWidgets.push(removed); + } + + if (isMapCanvas(removed)) + { + updateLocalIndex(&QgsWidgetRegistry::isMapCanvas); + } + else if (isComposer(removed)) + { + updateLocalIndex(&QgsWidgetRegistry::isComposer); + } /*else if (A*/ + + updateTabIndex(); +} + +void QgsWidgetRegistry::removeAll() +{ + for (int i = 0; i < mWidgets.count(); ++i) + remove(i); +} + +QWidget *QgsWidgetRegistry::restore() +{ + return mRemovedWidgets.pop(); +} + +bool QgsWidgetRegistry::isRestoredAll() +{ + return mRemovedWidgets.isEmpty(); +} + +bool QgsWidgetRegistry::isEmpty() +{ + return mWidgets.isEmpty(); +} + +int QgsWidgetRegistry::count() +{ + return mWidgets.count(); +} + +int QgsWidgetRegistry::globalIndexOf(QWidget *w) +{ + return mWidgets.indexOf(w); +} + +int QgsWidgetRegistry::localIndexOf(QWidget *w) +{ + return w->property("localIdx").toInt(); +} + +int QgsWidgetRegistry::tabIndexOf(QWidget *w) +{ + return w->property("tabIdx").toInt(); +} + +bool QgsWidgetRegistry::isDetached(const QWidget *w) +{ + return w->property("detached").toBool(); +} + +bool QgsWidgetRegistry::isMapCanvas(const QWidget *w) +{ + return isType(w, "QgsMapCanvas"); +} + +bool QgsWidgetRegistry::isComposer(const QWidget *w) +{ + return isType(w, "QgsComposer"); +} + +//bool QgsWidgetRegistry::isAttributeTable(const QWidget *w) +//{ +// return isType(w, "QgsAttributeTableDialog"); +//} + +bool QgsWidgetRegistry::isPlugin(const QWidget *w) +{ + if (!(isMapCanvas(w) || isComposer(w) /*|| isAttributeTable(w)*/)) + return true; + else + return false; +} + +QgsFrameWidget *QgsWidgetRegistry::getFrameOf(const QgsMapCanvas *mc) +{ + QWidget *p = mc->property("parentFrame").value(); + QgsFrameWidget *f = qobject_cast(p); + return f; +} + +QString QgsWidgetRegistry::getNameInTabOf(const QWidget *w) +{ + return w->property("nameInTab").toString(); +} + +int QgsWidgetRegistry::getRestoreIdx(const QWidget *w) +{ + return w->property("restoreIdx").toInt(); +} + +void QgsWidgetRegistry::setNameInTab(QWidget *w, QString nameInTab) +{ + w->setProperty("nameInTab", nameInTab); +} + +void QgsWidgetRegistry::setCanvasParentFrame(QgsMapCanvas *mc, QgsFrameWidget *f) +{ + QVariant frameVariant; + frameVariant.setValue( qobject_cast< QWidget *>( f ) ); + mc->setProperty( "parentFrame", frameVariant ); +} + +void QgsWidgetRegistry::setDetached(QWidget *w, bool isDetached) +{ + w->setProperty("detached", isDetached); +} + +QWidget *QgsWidgetRegistry::widget(int index) +{ + return mWidgets.at(index); +} + +QgsMapCanvas *QgsWidgetRegistry::mapCanvasAt(int index) +{ + QWidget *w = getWidget(&QgsWidgetRegistry::isMapCanvas, index); + QgsMapCanvas *mc = qobject_cast(w); + Q_ASSERT(mc != 0); + return mc; +} + +QgsMapCanvas *QgsWidgetRegistry::mapCanvasTabAt(int index) +{ + updateTabIndex(); + + foreach (QWidget *w, mWidgets) + { + if (isMapCanvas(w) && tabIndexOf(w) == index) + { + QgsMapCanvas *mc = qobject_cast(w); + Q_ASSERT(mc != 0); + return mc; + } + } + Q_ASSERT(0); + return 0; +} + +QgsComposer *QgsWidgetRegistry::composerAt(int index) +{ + QWidget *w = getWidget(&QgsWidgetRegistry::isComposer, index); + QgsComposer *c = qobject_cast(w); + Q_ASSERT(c != 0); + return c; +} + +//QgsAttributeTableDialog *QgsWidgetRegistry::attributeTableAt(int index) +//{ +// QWidget *w = getWidget(&QgsWidgetRegistry::isAttributeTable, index); +// QgsAttributeTableDialog *at = qobject_cast(w); +// Q_ASSERT(at != 0); +// return at; +//} + +QWidget *QgsWidgetRegistry::pluginAt(int index) +{ + QWidget *w = getWidget(&QgsWidgetRegistry::isPlugin, index); + Q_ASSERT(w != 0); + return w; +} + +QgsWidgetRegistry *QgsWidgetRegistry::instance() +{ + if (mInstance == 0) + mInstance = new QgsWidgetRegistry(); + return mInstance; +} + +// ---------------------------- proteceted --------------------------------- // +QgsWidgetRegistry::QgsWidgetRegistry() +{ +} + +// ------------------------------ private ---------------------------------- // +void QgsWidgetRegistry::setLocalIndex(QWidget *w, int index) +{ + w->setProperty("localIdx", index); +} + +void QgsWidgetRegistry::setTabIndex(QWidget *w, int index) +{ + w->setProperty("tabIdx", index); +} + +void QgsWidgetRegistry::setRestoreIndex(QWidget *w, int index) +{ + w->setProperty("restoreIdx", index); +} + +bool QgsWidgetRegistry::isType(const QWidget *w, QString type) +{ + if (w) + return QString(w->metaObject()->className()) == type; + else + return false; +} + +QWidget *QgsWidgetRegistry::getWidget(WidgetType widgetType, int index) +{ + foreach (QWidget *w, mWidgets) + { + if ((widgetType)(w) && localIndexOf(w) == index) + return w; + } + return 0; +} + +void QgsWidgetRegistry::updateTabIndex() +{ + int tabIdx = 0; + foreach (QWidget *w, mWidgets) + { + if (!isDetached(w)) + { + setTabIndex(w, tabIdx); + tabIdx++; + } + else + { + setTabIndex(w, -1); + } + } +} + +void QgsWidgetRegistry::updateLocalIndex(WidgetType widgetType) +{ + int localIdx = 0; + foreach (QWidget *w, mWidgets) + { + if ((widgetType)(w)) + { + setLocalIndex(w, localIdx); + localIdx++; + } + } +} Property changes on: src/gui/tabs/qgswidgetregistry.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgslegendtabbar.h =================================================================== --- src/gui/tabs/qgslegendtabbar.h (revision 0) +++ src/gui/tabs/qgslegendtabbar.h (revision 0) @@ -0,0 +1,23 @@ +#ifndef QGSLEGENDTABBAR_H +#define QGSLEGENDTABBAR_H + +#include + +#include "qgstabbarbase.h" + +class QgsLegendTabBar : public QgsTabBarBase +{ + Q_OBJECT + +public: + QgsLegendTabBar(QWidget *parent, QgisApp *qgis); + +protected: + void showEvent(QShowEvent *); + void hideEvent(QHideEvent *); + +private slots: + void updateCanvasPixmap(); +}; + +#endif // QGSLEGENDTABBAR_H Property changes on: src/gui/tabs/qgslegendtabbar.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgsdesktabwidget.cpp =================================================================== --- src/gui/tabs/qgsdesktabwidget.cpp (revision 0) +++ src/gui/tabs/qgsdesktabwidget.cpp (revision 0) @@ -0,0 +1,309 @@ +#include +#include +#include + +#include "../app/qgisapp.h" +#include "../app/qgsframewidget.h" +#include "../app/legend/qgslegend.h" + +#include "qgsdesktabbar.h" +#include "qgsfloatcanvaswindow.h" +#include "qgslegendtabwidget.h" +#include "qgsmapcanvas.h" +//#include "qgswidgetregistry.h" + +#include "qgsdesktabwidget.h" + +QgsDeskTabWidget::QgsDeskTabWidget(QgisApp *qgis) + : QgsDeskTabWidgetInterface(), mQgis(qgis), mCurrentFrame(0), mPreviousFrame(0) +{ + mTabBar = new QgsDeskTabBar(this, qgis); + setTabBar(mTabBar); + setObjectName("theDeskTabWidget"); + setTabPosition(QTabWidget::South); + setTabsClosable(true); + setMovable(true); + mTabBar->hide(); + + connect(this, SIGNAL(currentChanged(int)), this, SLOT(changeCurrentTab(int))); + connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + connect(this, SIGNAL(frameUpdated(QgsFrameWidget*)), mQgis, SLOT(updateFrame(QgsFrameWidget*))); + + connect(mTabBar, SIGNAL(tabMoved(int,int)), this, SLOT(moveTab(int,int))); + connect(mTabBar, SIGNAL(tabMoved(int,int)), this, SIGNAL(tabMoved(int,int))); + + connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), this, SLOT(changeFocus(QWidget *, QWidget *))); +} + +QgsDeskTabWidget::~QgsDeskTabWidget() +{ +} + +// --------------------------------- public -------------------------------- // +int QgsDeskTabWidget::addFrameTab(QString nameInTab) +{ + return insertFrameTab(count(), nameInTab); +} + +int QgsDeskTabWidget::insertFrameTab(int index, QString nameInTab) +{ + QgsFrameWidget *frame = new QgsFrameWidget(mQgis); + + QgsWidgetRegistry::setNameInTab(frame->mapCanvas(), nameInTab); + QgsWidgetRegistry::setCanvasParentFrame(frame->mapCanvas(), frame); + + int res = insertTab(index, frame->mapCanvas(), mQgis->getThemeIcon("mFrameTabIcon.png"), nameInTab); + + frame->saveState(); + return res; +} + +int QgsDeskTabWidget::restoreTab() +{ + QWidget *restored = QgsWidgetRegistry::instance()->restore(); + if (QgsWidgetRegistry::instance()->isRestoredAll()) + mQgis->actionRestoreTab()->setEnabled(false); + + int restoreIdx = QgsWidgetRegistry::getRestoreIdx(restored); + QString nameInTab = QgsWidgetRegistry::getNameInTabOf(restored); + insertTab(restoreIdx, restored, nameInTab); + + setCurrentIndex(restoreIdx); + + return restoreIdx; +} + +void QgsDeskTabWidget::nextTab() +{ + currentIndex() == count() - 1 ? + setCurrentIndex(0) : + setCurrentIndex(currentIndex() + 1); +} + +void QgsDeskTabWidget::previousTab() +{ + currentIndex() == 0 ? + setCurrentIndex(count() - 1) : + setCurrentIndex(currentIndex() - 1); +} + +void QgsDeskTabWidget::updateFrameAt(int index) +{ + if (QgsWidgetRegistry::isMapCanvas(widget(index)) && + !QgsWidgetRegistry::instance()->isEmpty()) + { + QgsMapCanvas *mc = QgsWidgetRegistry::instance()->mapCanvasTabAt(index); + mCurrentFrame = QgsWidgetRegistry::instance()->getFrameOf(mc); + if (mCurrentFrame != mPreviousFrame) + { + if (mPreviousFrame) + { + mPreviousFrame->saveState(); + mPreviousFrame->removeConnections(); + } + + mCurrentFrame->setupConnections(); + emit frameUpdated(mCurrentFrame); + mPreviousFrame = mCurrentFrame; + + mCurrentFrame->restoreState(); + } + } +} + +// ------------------------------- protected ------------------------------- // +void QgsDeskTabWidget::tabInserted(int index) +{ + QWidget *page = widget(index); + QgsWidgetRegistry::instance()->insert(index, page); + + if (QgsWidgetRegistry::isMapCanvas(page)) + { + QgsMapCanvas *mc = qobject_cast(page); + mTabBar->insertCanvasInPreview(index, mc); + } + else + mTabBar->insertWidgetInPreview(index, page); + + if (count() > 1) + { + mTabBar->show(); + mQgis->actionCloseTab()->setEnabled(true); + } +} + +void QgsDeskTabWidget::tabRemoved(int index) +{ + const QWidget *w = QgsWidgetRegistry::instance()->widget(index); + if (!QgsWidgetRegistry::isDetached(w)) + { + if (!mQgis->actionRestoreTab()->isEnabled()) + mQgis->actionRestoreTab()->setEnabled(true); + QgsWidgetRegistry::instance()->remove(index); + + emit tabClosed(index); + } + + if (count() == 1) + { + mTabBar->hide(); + mQgis->actionCloseTab()->setEnabled(false); + } +} + +void QgsDeskTabWidget::resizeEvent(QResizeEvent *e) +{ + qDebug() << e; + qDebug() << e->type(); + qDebug() << e->size(); + if (sender()) + qDebug() << sender()->objectName(); +} + +// ----------------------------- private slots ----------------------------- // +void QgsDeskTabWidget::moveTab(int from, int to) +{ + int globalFrom = QgsWidgetRegistry::instance()->globalIndexOf(widget(from)); + int globalTo = QgsWidgetRegistry::instance()->globalIndexOf(widget(to)); + + QgsWidgetRegistry::instance()->swap(globalFrom, globalTo); + changeCurrentTab(from); +} + +void QgsDeskTabWidget::changeCurrentTab(int index) +{ + if (index == -1) + return; + + if (QgsWidgetRegistry::isMapCanvas(widget(index))) + { + updateFrameAt(index); + + int localIndex = QgsWidgetRegistry::localIndexOf(widget(index)); + mQgis->legendTabWidget()->setCurrentIndex(localIndex); + } + else if (mPreviousFrame) + { + mPreviousFrame->removeConnections(); + mPreviousFrame = 0; + } +} + +void QgsDeskTabWidget::changeFocus(QWidget *, QWidget *now) +{ + if (now && QgsWidgetRegistry::isDetached(now) && mCurrentFrame) + { + mCurrentFrame->removeConnections(); + mCurrentFrame = mPreviousFrame = 0; + } + else if (now && qApp->activeWindow() == mQgis) + { + changeCurrentTab(currentIndex()); + } +} + +void QgsDeskTabWidget::detachTab() +{ + if (count() == 1) + return; + + int index = mTabBar->tabAt(mTabBar->mapFromGlobal(QCursor::pos())); + if (index == -1) + index = currentIndex(); + + if (QgsWidgetRegistry::isMapCanvas(widget(index))) + detachCanvas(index); + else + detachWidget(index); + + emit tabDetached(); +} + +void QgsDeskTabWidget::renameTab() +{ + bool ok; + QString textInTab = QInputDialog::getText(this, tr("Tab text"), tr("Enter new tab text:"), + QLineEdit::Normal, tr("Canvas %1").arg(currentIndex() + 1), &ok); + + if (ok && !textInTab.isEmpty()) + { + setTabText(currentIndex(), textInTab); + QgsWidgetRegistry::setNameInTab(currentWidget(), textInTab); + } +} + +void QgsDeskTabWidget::closeTab(int index) +{ + removeTab(index); + mCurrentFrame->removeConnections(); + mPreviousFrame = 0; +} + +// --------------------------------- private ------------------------------- // +void QgsDeskTabWidget::detachCanvas(int index) +{ + QgsMapCanvas *mc = QgsWidgetRegistry::instance()->mapCanvasTabAt(index); + mc->setObjectName("theMapCanvasFloat"); + QgsWidgetRegistry::setDetached(mc, true); + + QgsFrameWidget *f = QgsWidgetRegistry::getFrameOf(mc); + int localIndex = QgsWidgetRegistry::localIndexOf(mc); + QgsFloatCanvasWindow *floatCanvasWidget = new QgsFloatCanvasWindow(mQgis, this, f, localIndex); + + // tab will be removed when mapCanvas will be added in floatCanvasWidget + floatCanvasWidget->setCentralWidget(mc); + + // adjust the widget and the map canvas size and show them + floatCanvasWidget->resize(mc->size()); + floatCanvasWidget->show(); + + mc->setFocusProxy(floatCanvasWidget); + mc->show(); + mc->setFocus(); + + emit canvasDetached(mc); +} // detachCanvas + +void QgsDeskTabWidget::detachWidget(int index) // TODO +{ +// QWidget *theWidget = mTabbedWidgetsVector.at(index); +// theWidget->setProperty("detached", 1); +// +// int insertIndex = mFloatWidgetsMap.size(); +// // theWidget->setObjectName("theQWidgetFloat"); ??? +// mFloatWidgetsMap.insert(insertIndex, theWidget); +// +// theWidget->setEnabled(true); +// theWidget->setWindowTitle(tabText(index) /*windowTitle*/); +// theWidget->setFocusPolicy(Qt::StrongFocus); +// theWidget->setProperty("fltIdx", insertIndex); +// +// // widget being removed when parent will be set to NULL +// theWidget->setParent(NULL); +// theWidget->show(); +} // detachWidget + +//void QgsDeskTabWidget::returnWidget() // TODO remove +//{ +// QWidget *theWidget = QApplication::activeWindow(); +// Q_ASSERT(theWidget); +// if (theWidget->objectName() == "QgisApp") +// return; +// +// // remove theWidget from float theWidget list +// int fltIdx = theWidget->property("fltIdx").toInt(); +// int insertIndex = theWidget->property("tabIdx").toInt(); +//// mFloatWidgetsMap.remove(fltIdx); +// +// // theWidget->setObjectName("theQWidget"); ??? +// // reset dynamic property +// theWidget->setProperty("fltIdx", -1); +// theWidget->setProperty("detached", QVariant()); +// +// QString canvasName = theWidget->windowTitle(); +// insertTab(insertIndex, theWidget, canvasName); +// setCurrentIndex(insertIndex); +// + // emit tabReturned(); + // disconnect(myWidget, SIGNAL(returnInTabWidget()), this, SLOT(returnWidget())); ??? +//} // returnWidget Property changes on: src/gui/tabs/qgsdesktabwidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/tabs/qgswidgetregistry.h =================================================================== --- src/gui/tabs/qgswidgetregistry.h (revision 0) +++ src/gui/tabs/qgswidgetregistry.h (revision 0) @@ -0,0 +1,89 @@ +#ifndef QGSWIDGETREGISTRY_H +#define QGSWIDGETREGISTRY_H + +#include +#include +#include +#include + +//class QgsAttributeTableDialog; +class QgsComposer; +class QgsFrameWidget; +class QgsLegend; +class QgsMapCanvas; + +typedef bool (*WidgetType)(const QWidget *w); + +class QgsWidgetRegistry : public QObject +{ + Q_OBJECT + +public: + ~QgsWidgetRegistry(); + + void append(QWidget *w); + void insert(int index, QWidget *w); + void swap(int from, int to); + + void remove(int index); + void removeAll(); + QWidget *restore(); + + bool isRestoredAll(); + bool isEmpty(); + + int count(); + int globalIndexOf(QWidget *w); + static int localIndexOf(QWidget *w); + static int tabIndexOf(QWidget *w); + + static bool isDetached(const QWidget *w); + static bool isMapCanvas(const QWidget *w); + static bool isComposer(const QWidget *w); +// static bool isAttributeTable(const QWidget *w); + static bool isPlugin(const QWidget *w); + + static QgsFrameWidget *getFrameOf(const QgsMapCanvas *mc); + static QString getNameInTabOf(const QWidget *w); + static int getRestoreIdx(const QWidget *w); + + static void setNameInTab(QWidget *w, QString nameInTab); + static void setCanvasParentFrame(QgsMapCanvas *mc, QgsFrameWidget *f); + static void setDetached(QWidget *w, bool isDetached); + + QWidget *widget(int index); + QgsMapCanvas *mapCanvasAt(int index); + QgsMapCanvas *mapCanvasTabAt(int index); + QgsComposer *composerAt(int index); +// QgsAttributeTableDialog *attributeTableAt(int index); + QWidget *pluginAt(int index); + + static QgsWidgetRegistry *instance(); + +signals: + void legendInserted(int, QgsLegend *); + void mapCanvasInserted(int, QgsMapCanvas *); + + void mapCanvasRemoved(int); + void removedAll(); + +protected: + QgsWidgetRegistry(); + +private: + static void setLocalIndex(QWidget *w, int index); + static void setTabIndex(QWidget *w, int index); + static void setRestoreIndex(QWidget *w, int index); + static bool isType(const QWidget *w, QString type); + + QWidget *getWidget(WidgetType widgetType, int index); + void updateLocalIndex(WidgetType thisType); + void updateTabIndex(); + + QList mWidgets; + QStack mRemovedWidgets; + + static QgsWidgetRegistry *mInstance; +}; + +#endif // QGSWIDGETREGISTRY_H Property changes on: src/gui/tabs/qgswidgetregistry.h ___________________________________________________________________ Added: svn:eol-style + native Index: src/gui/qgisinterface.h =================================================================== --- src/gui/qgisinterface.h (revision 11922) +++ src/gui/qgisinterface.h (working copy) @@ -19,8 +19,13 @@ #ifndef QGISINTERFACE_H #define QGISINTERFACE_H +#include "qgsconfig.h" + class QAction; class QMenu; +#ifdef HAVE_TABS +class QIcon; +#endif class QToolBar; class QDockWidget; class QMainWindow; @@ -30,6 +35,9 @@ #include +#ifdef HAVE_TABS +#include "tabs/qgsdesktabwidgetinterface.h" +#endif class QgisApp; class QgsComposerView; @@ -107,6 +115,11 @@ /** Return a pointer to the map canvas */ virtual QgsMapCanvas * mapCanvas() = 0; +#ifdef HAVE_TABS + /** Return a pointer to the main tab widget */ +// virtual QgsDeskTabWidgetInterface * deskTabWidget() = 0; +#endif + /** Return a pointer to the main window (instance of QgisApp in case of QGIS) */ virtual QWidget * mainWindow() = 0; Index: src/ui/qgsaddtabdialogbase.ui =================================================================== --- src/ui/qgsaddtabdialogbase.ui (revision 0) +++ src/ui/qgsaddtabdialogbase.ui (revision 0) @@ -0,0 +1,95 @@ + + + QgsAddTabDialog + + + + 0 + 0 + 222 + 184 + + + + Form + + + + + + + + Name of tab + + + + + + + + + + + + Core tools + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + Map c&anvas + + + + + + + Map c&omposer + + + + + + + Attribute &table + + + + + + + + + + Plug-ins + + + true + + + false + + + + 6 + + + 9 + + + 9 + + + + + + + + + Index: images/themes/default/mActionCloseFloatCanvas.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Property changes on: images/themes/default/mActionCloseFloatCanvas.png ___________________________________________________________________ Added: svn:mime-type + image/png Index: images/themes/default/mSyncTabWidgets.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Property changes on: images/themes/default/mSyncTabWidgets.png ___________________________________________________________________ Added: svn:mime-type + image/png Index: images/themes/default/mActionStayOnTop.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Property changes on: images/themes/default/mActionStayOnTop.png ___________________________________________________________________ Added: svn:mime-type + image/png Index: images/themes/default/mActionReturnInQGis.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Property changes on: images/themes/default/mActionReturnInQGis.png ___________________________________________________________________ Added: svn:mime-type + image/png Index: images/themes/default/mActionDetachTab.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Property changes on: images/themes/default/mActionDetachTab.png ___________________________________________________________________ Added: svn:mime-type + image/png Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 11922) +++ CMakeLists.txt (working copy) @@ -64,6 +64,13 @@ ENDIF (WITH_INTERNAL_SPATIALITE) ENDIF (WITH_SPATIALITE) +# whether build gui with tabs +SET (TABBED_GUI TRUE CACHE BOOL "Build QGIS with tabs?") + +IF (TABBED_GUI) + SET(HAVE_TABS TRUE) +ENDIF(TABBED_GUI) + # try to configure and build python bindings by default SET (WITH_BINDINGS TRUE CACHE BOOL "Determines whether python bindings should be built") IF (WITH_BINDINGS) Index: cmake_templates/qgsconfig.h.in =================================================================== --- cmake_templates/qgsconfig.h.in (revision 11922) +++ cmake_templates/qgsconfig.h.in (working copy) @@ -29,5 +29,7 @@ #cmakedefine HAVE_PYTHON +#cmakedefine HAVE_TABS + #endif