Index: src/app/qgisappinterface.h =================================================================== --- src/app/qgisappinterface.h (revision 11821) +++ 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 11821) +++ src/app/composer/qgscomposer.cpp (working copy) @@ -48,6 +48,11 @@ #include #include +#ifdef HAVE_TABS +#include +#include +#endif + #include #include #include @@ -1264,6 +1269,36 @@ on_mActionSelectMoveItem_triggered(); } +#ifdef HAVE_TABS +void QgsComposer::prepareTabbing() +{ + QList< QToolBar * > tbs = mQgis->findChildren< QToolBar * >(); + foreach( QToolBar *tb, tbs) + tb->hide(); + +// mQgis->legendDock()->hide(); +// mQgis->overviewDock()->hide(); + mQgis->statusBar()->hide(); + + mQgis->addToolBar( toolBar ); + toolBar->show(); +} + +void QgsComposer::restoreState( int index ) +{ + int tabIdx = property( "tabIdx" ).toInt(); + if ( tabIdx == index ) + { + QByteArray ba = property( "state" ).toByteArray(); + qDebug() << mQgis->restoreState( ba, index ); + } + else + { + toolBar->hide(); + } +} +#endif + bool QgsComposer::containsWMSLayer() const { QMap::const_iterator item_it = mItemWidgetMap.constBegin(); Index: src/app/composer/qgscomposer.h =================================================================== --- src/app/composer/qgscomposer.h (revision 11821) +++ 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; @@ -221,6 +222,11 @@ void setSelectionTool(); +#ifdef HAVE_TABS + void prepareTabbing(); + void restoreState( int index ); +#endif + protected: void paintEvent( QPaintEvent* event ); @@ -231,7 +237,6 @@ void activate(); private: - /**Establishes the signal slot connection for the class*/ void connectSlots(); Index: src/app/qgisapp.h =================================================================== --- src/app/qgisapp.h (revision 11821) +++ 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,13 @@ //!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; } +#endif QgsComposer* printComposer() {return mComposer;} //! Set theme (icons) @@ -184,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 ); @@ -198,6 +212,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; } @@ -393,6 +413,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; @@ -401,6 +422,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 @@ -432,6 +454,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 @@ -482,8 +514,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(); @@ -536,20 +570,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(); @@ -591,10 +633,10 @@ //! Toggle map tips on/off void toggleMapTips(); - +#ifndef HAVE_TABS //! Show the map tip void showMapTip(); - +#endif //! Toggle full screen mode void toggleFullScreen(); @@ -658,6 +700,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. @@ -686,13 +729,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; @@ -707,6 +759,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; @@ -845,6 +905,9 @@ class Tools { public: +#ifdef HAVE_TABS + ~Tools(); +#endif QgsMapTool* mZoomIn; QgsMapTool* mZoomOut; QgsMapTool* mPan; @@ -868,10 +931,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 @@ -894,6 +962,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 @@ -906,6 +975,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 @@ -937,8 +1017,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 @@ -952,6 +1034,7 @@ */ QString mRasterFileFilter; +#ifndef HAVE_TABS /** Timer for map tips */ QTimer *mpMapTipsTimer; @@ -966,6 +1049,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/CMakeLists.txt =================================================================== --- src/app/CMakeLists.txt (revision 11821) +++ src/app/CMakeLists.txt (working copy) @@ -108,6 +108,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 @@ -193,6 +198,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 11821) +++ src/app/qgisapp.cpp (working copy) @@ -138,6 +138,12 @@ #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" +#endif // // Gdal/Ogr includes // @@ -326,6 +332,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 ), mComposer( 0 ), mPythonConsole( NULL ), @@ -356,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 mComposer = new QgsComposer( this ); // Map composer mInternalClipboard = new QgsClipboard; // create clipboard mQgisInterface = new QgisAppInterface( this ); // create the interfce @@ -452,9 +474,9 @@ restoreWindowState(); mSplash->showMessage( tr( "QGIS Ready!" ), Qt::AlignHCenter | Qt::AlignBottom ); - +#ifndef HAVE_TABS mMapTipsVisible = false; - +#endif // setup drag drop setAcceptDrops( true ); @@ -471,9 +493,7 @@ QgisApp::~QgisApp() { - delete mInternalClipboard; - delete mQgisInterface; - +#ifndef HAVE_TABS delete mMapTools.mZoomIn; delete mMapTools.mZoomOut; delete mMapTools.mPan; @@ -496,7 +516,11 @@ delete mMapTools.mDeletePart; delete mMapTools.mAddIsland; delete mMapTools.mNodeTool; +#endif + delete mInternalClipboard; + delete mQgisInterface; + delete mPythonConsole; delete mPythonUtils; @@ -599,6 +623,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 @@ -1146,6 +1208,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 * ) ), @@ -1166,6 +1232,10 @@ mFileMenu->addAction( mActionPrintComposer ); mActionFileSeparator4 = mFileMenu->addSeparator(); +#ifdef HAVE_TABS + mFileMenu->addAction( mActionRestoreTab ); + mFileMenu->addAction( mActionCloseTab ); +#endif mFileMenu->addAction( mActionExit ); // Edit Menu @@ -1465,6 +1535,7 @@ mToolbarMenu->addAction( mHelpToolBar->toggleViewAction() ); } +#ifndef HAVE_TABS void QgisApp::createStatusBar() { // @@ -1596,6 +1667,7 @@ statusBar()->addPermanentWidget( mOnTheFlyProjectionStatusButton, 0 ); statusBar()->showMessage( tr( "Ready" ) ); } +#endif void QgisApp::setTheme( QString theThemeName ) @@ -1623,11 +1695,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" ) ); mActionPrintComposer->setIcon( getThemeIcon( "/mActionFilePrint.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" ) ); @@ -1703,6 +1781,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 @@ -1736,21 +1815,66 @@ // 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(); + mMapLegend = frame->mapLegend(); + mMapTools = frame->mapTools(); + mMapOverviewCanvas = frame->mapOverviewCanvas(); + + // update state of controls + mMapCanvas->setMapTool( mMapTools->mCurrentTool ); + mMapLegend->setMapCanvas( mMapCanvas ); + + mMapCanvas->enableOverviewMode( mMapOverviewCanvas ); + mMapOverviewCanvas->setMapCanvas( mMapCanvas ); + mOverviewDock->setWidget(mMapOverviewCanvas); + + int idx = frame->mapCanvas()->property("idx").toInt(); + mLegendTabWidget->setCurrentIndex(idx); + + // set status bar for tabbed mapCanvas + if (frame->objectName() != "theFrameWidgetFloat") + { + // set parent of current statusBar to NULL if do not do it statusBar will be removed + if (findChild()) + statusBar()->setParent( 0 ); + setStatusBar( frame->statusBar() ); + } +// mMapCanvas->refresh(); // TODO is it needed ??? +// mMapCanvas->setExtent(mMapCanvas->extent()); +} +#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 ); +#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 " @@ -1811,11 +1935,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." ) ); @@ -1823,14 +1964,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() ); @@ -1844,6 +1992,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 ) @@ -1859,11 +2008,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 ); @@ -1871,7 +2022,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 @@ -1891,6 +2052,7 @@ // add to the Panel submenu mPanelMenu->addAction( mLegendDock->toggleViewAction() ); return; +#endif } bool QgisApp::createDB() @@ -1920,6 +2082,7 @@ return TRUE; } +#ifndef HAVE_TABS void QgisApp::createMapTips() { // Set up the timer for maptips. The timer is reset everytime the mouse is moved @@ -1931,6 +2094,7 @@ // Create the maptips object mpMaptip = new QgsMapTip(); } +#endif // Update file menu with the current list of recently accessed projects void QgisApp::updateRecentProjectPaths() @@ -3139,8 +3303,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) @@ -3621,6 +3790,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. @@ -3831,11 +4033,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 @@ -3930,7 +4132,7 @@ { QgsDebugMsg( "hiding all layers!" ); - legend()->selectAll( false ); + mMapLegend->selectAll( false ); } @@ -3939,7 +4141,7 @@ { QgsDebugMsg( "Showing all layers!" ); - legend()->selectAll( true ); + mMapLegend->selectAll( true ); } @@ -3947,7 +4149,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 ); @@ -3956,8 +4162,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 ); } @@ -3972,7 +4181,11 @@ void QgisApp::pan() { +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mPan ); +#else mMapCanvas->setMapTool( mMapTools.mPan ); +#endif } void QgisApp::zoomFull() @@ -4006,17 +4219,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() @@ -4100,22 +4325,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 ) @@ -4273,22 +4514,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() @@ -4299,7 +4556,11 @@ } // set current map tool to select +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mCapturePoint ); +#else mMapCanvas->setMapTool( mMapTools.mCapturePoint ); +#endif } void QgisApp::captureLine() @@ -4309,7 +4570,11 @@ return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mCaptureLine ); +#else mMapCanvas->setMapTool( mMapTools.mCaptureLine ); +#endif } void QgisApp::capturePolygon() @@ -4318,12 +4583,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 } @@ -4333,7 +4606,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexAdd ); +#else mMapCanvas->setMapTool( mMapTools.mVertexAdd ); +#endif } @@ -4343,7 +4620,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexMove ); +#else mMapCanvas->setMapTool( mMapTools.mVertexMove ); +#endif } void QgisApp::addRing() @@ -4352,7 +4633,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mAddRing ); +#else mMapCanvas->setMapTool( mMapTools.mAddRing ); +#endif } void QgisApp::addIsland() @@ -4361,7 +4646,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mAddIsland ); +#else mMapCanvas->setMapTool( mMapTools.mAddIsland ); +#endif } @@ -4371,7 +4660,11 @@ { return; } +#ifdef HAVE_TABS + mMapCanvas->setMapTool( mMapTools->mVertexDelete ); +#else mMapCanvas->setMapTool( mMapTools.mVertexDelete ); +#endif } @@ -4481,12 +4774,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() @@ -4568,6 +4861,7 @@ vlayer->triggerRepaint(); } +#ifndef HAVE_TABS void QgisApp::showMouseCoordinate( const QgsPoint & p ) { if ( mMapTipsVisible ) @@ -4601,7 +4895,6 @@ } } - void QgisApp::showScale( double theScale ) { if ( theScale >= 1.0 ) @@ -4662,8 +4955,8 @@ ); mMapCanvas->refresh(); } +#endif - // toggle overview status void QgisApp::isInOverview() { @@ -5264,6 +5557,7 @@ mPluginToolBar->removeAction( qAction ); } +#ifndef HAVE_TABS void QgisApp::destinationSrsChanged() { // save this information to project @@ -5354,8 +5648,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 @@ -5383,7 +5677,8 @@ mMousePrecisionDecimalPlaces = dp; } - +#endif +#ifndef HAVE_TABS void QgisApp::showStatusMessage( QString theMessage ) { statusBar()->showMessage( theMessage ); @@ -5423,6 +5718,7 @@ } } } + void QgisApp::projectPropertiesProjections() { // Driver to display the project props dialog and switch to the @@ -5430,7 +5726,7 @@ mShowProjectionTab = true; projectProperties(); } - +#endif void QgisApp::projectProperties() { if ( mMapCanvas && mMapCanvas->isDrawing() ) @@ -6273,3 +6569,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 11821) +++ 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 11821) +++ 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 11821) +++ 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/qgisinterface.h =================================================================== --- src/gui/qgisinterface.h (revision 11821) +++ 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: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 11821) +++ 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 11821) +++ cmake_templates/qgsconfig.h.in (working copy) @@ -29,5 +29,7 @@ #cmakedefine HAVE_PYTHON +#cmakedefine HAVE_TABS + #endif