Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] Merge of legend refactoring work
This replaces the existing tree widget implementation with more modular approach. In summary:
- tree hierarchy in CORE library: QgsLayerTreeNode, QgsLayerTreeLayer, QgsLayerTreeGroup
- model/view based tree view: QgsLayerTreeModel, QgsLayerTreeView
- tree synchronization with map layer registry: QgsLayerTreeRegistryBridge
- controlling of map canvas: QgsLayerTreeCanvasBridge

Conflicts:
	src/ui/qgisapp.ui
  • Loading branch information
wonder-sk committed May 21, 2014
2 parents 7f218c7 + 0b072e6 commit b2a4c76
Show file tree
Hide file tree
Showing 75 changed files with 5,093 additions and 6,085 deletions.
1 change: 1 addition & 0 deletions python/CMakeLists.txt
Expand Up @@ -86,6 +86,7 @@ INCLUDE_DIRECTORIES(
../src/gui/attributetable
../src/gui/editorwidgets
../src/gui/editorwidgets/core
../src/gui/layertree

${CMAKE_BINARY_DIR} # qgsconfig.h, qgsversion.h
)
Expand Down
3 changes: 3 additions & 0 deletions python/gui/gui.sip
Expand Up @@ -76,6 +76,7 @@
%Include qgsrubberband.sip
%Include qgsscalecombobox.sip
%Include qgsscalerangewidget.sip
%Include qgsscalevisibilitydialog.sip
%Include qgssearchquerybuilder.sip
%Include qgstextannotationitem.sip
%Include qgsvertexmarker.sip
Expand Down Expand Up @@ -146,3 +147,5 @@
%Include editorwidgets/core/qgseditorwidgetfactory.sip
%Include editorwidgets/core/qgseditorwidgetregistry.sip
%Include editorwidgets/core/qgseditorwidgetwrapper.sip

%Include layertree/qgslayertreeview.sip
2 changes: 2 additions & 0 deletions python/gui/qgisinterface.sip
Expand Up @@ -32,6 +32,8 @@ class QgisInterface : QObject

virtual QgsPluginManagerInterface* pluginManagerInterface() = 0;

virtual QgsLayerTreeView* layerTreeView() = 0;

public slots: // TODO: do these functions really need to be slots?

/* Exposed functions */
Expand Down
30 changes: 30 additions & 0 deletions python/gui/qgsscalevisibilitydialog.sip
@@ -0,0 +1,30 @@
class QgsScaleVisibilityDialog : QObject
{
%TypeHeaderCode
#include <qgsscalevisibilitydialog.h>
%End

public:
explicit QgsScaleVisibilityDialog( QWidget *parent = 0, QString title = QString(), QgsMapCanvas* mapCanvas = 0 );

//! return if scale visibilty is enabled
bool hasScaleVisibility();

//! return minimum scale (true scale, not scale denominator)
double minimumScale();

//! return maximum scale (true scale, not scale denominator)
double maximumScale();


public slots:
//! set if scale visibility is enabled
void setScaleVisiblity( bool hasScaleVisibility );

//! set minimum scale (true scale, not scale denominator)
void setMinimumScale( double minScale );

//! set maximum scale (true scale, not scale denominator)
void setMaximumScale( double maxScale );

};
27 changes: 15 additions & 12 deletions src/app/CMakeLists.txt
Expand Up @@ -3,6 +3,7 @@ SET(QGIS_APP_SRCS
qgisappinterface.cpp
qgisappstylesheet.cpp
qgsabout.cpp
qgsapplayertreeviewmenuprovider.cpp
qgssponsors.cpp
qgsaddattrdialog.cpp
qgsaddtaborgroup.cpp
Expand Down Expand Up @@ -129,13 +130,7 @@ SET(QGIS_APP_SRCS
composer/qgscompositionwidget.cpp
composer/qgsatlascompositionwidget.cpp

legend/qgslegendgroup.cpp
legend/qgslegend.cpp
legend/qgsapplegendinterface.cpp
legend/qgslegenditem.cpp
legend/qgslegendlayer.cpp
legend/qgslegendsymbologyitem.cpp
legend/qgslayerorder.cpp

ogr/qgsogrhelperfunctions.cpp
ogr/qgsopenvectorlayerdialog.cpp
Expand Down Expand Up @@ -272,10 +267,7 @@ SET (QGIS_APP_MOC_HDRS
composer/qgscompositionwidget.h
composer/qgsatlascompositionwidget.h

legend/qgslegend.h
legend/qgsapplegendinterface.h
legend/qgslegendlayer.h
legend/qgslayerorder.h

ogr/qgsopenvectorlayerdialog.h
ogr/qgsnewogrconnection.h
Expand Down Expand Up @@ -428,11 +420,22 @@ INCLUDE_DIRECTORIES(
${QWT_INCLUDE_DIR}
${QT_QTUITOOLS_INCLUDE_DIR}
${QEXTSERIALPORT_INCLUDE_DIR}
../analysis/raster ../analysis/openstreetmap
../analysis/raster
../analysis/openstreetmap
../core
../core/gps
../core/composer ../core/dxf ../core/raster ../core/symbology-ng
../gui ../gui/symbology-ng ../gui/attributetable ../gui/raster ../gui/editorwidgets ../gui/editorwidgets/core
../core/composer
../core/dxf
../core/layertree
../core/raster
../core/symbology-ng
../gui
../gui/symbology-ng
../gui/attributetable
../gui/raster
../gui/editorwidgets
../gui/editorwidgets/core
../gui/layertree
../plugins
../python
gps
Expand Down
2 changes: 1 addition & 1 deletion src/app/composer/qgscomposerlegendwidget.cpp
Expand Up @@ -922,7 +922,7 @@ void QgsComposerLegendWidget::updateLegend()


//and also group info
QgsAppLegendInterface legendIface( app->legend() );
QgsAppLegendInterface legendIface( app->layerTreeView() );
QList< GroupLayerInfo > groupInfo = legendIface.groupLayerRelationship();
mLegend->model()->setLayerSetAndGroups( layerIdList, groupInfo );
mLegend->endCommand();
Expand Down
30 changes: 15 additions & 15 deletions src/app/gps/qgsgpsinformationwidget.cpp
Expand Up @@ -15,25 +15,27 @@
* *
***************************************************************************/
#include "qgsgpsinformationwidget.h"
#include "qgsnmeaconnection.h"
#include "qgsgpsconnectionregistry.h"
#include "qgsgpsdetector.h"

#include "info.h"

#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgscoordinatetransform.h"
#include "qgsfeatureaction.h"
#include "qgsgeometry.h"
#include "qgsgpsconnectionregistry.h"
#include "qgsgpsdetector.h"
#include "qgslayertreeview.h"
#include "qgslogger.h"
#include "qgsmaprenderer.h"
#include "qgsmaptooladdfeature.h"
#include "qgsnmeaconnection.h"
#include "qgspoint.h"
#include "qgsproject.h"
#include "qgsrubberband.h"
#include "qgsmaprenderer.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
#include "qgsproject.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgsfeatureaction.h"
#include "qgsgeometry.h"
#include "qgisapp.h"

//for avoid intersections static method
#include "qgsmaptooladdfeature.h"

// QWT Charting widget
#include <qwt_global.h>
Expand Down Expand Up @@ -66,8 +68,6 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
{
setupUi( this );

// to connect signals that layers have changed (which layer, edit state)
mpLegend = QgisApp::instance()->legend();
mpLastLayer = 0;

mLastGpsPosition = QgsPoint( 0.0, 0.0 );
Expand Down Expand Up @@ -232,7 +232,7 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
//SLM - added functionality
mLogFile = 0;

connect( mpLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
this, SLOT( updateCloseFeatureButton( QgsMapLayer* ) ) );

mStackedWidget->setCurrentIndex( 3 ); // force to Options
Expand Down
2 changes: 0 additions & 2 deletions src/app/gps/qgsgpsinformationwidget.h
Expand Up @@ -31,7 +31,6 @@ class QgsGPSConnection;
class QgsGPSTrackerThread;
struct QgsGPSInformation;

class QgsLegend;
class QFile;
class QColor;

Expand Down Expand Up @@ -96,7 +95,6 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
QList<QgsPoint> mCaptureList;
FixStatus mLastFixStatus;
QString mDateTimeFormat; // user specified format string in registry (no UI presented)
QgsLegend * mpLegend;
QgsVectorLayer * mpLastLayer;
QFile * mLogFile;
QTextStream mLogFileTextStream;
Expand Down

7 comments on commit b2a4c76

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @wonder-sk, thanks for this new awesome stuff!

Just tested but I get a crash when loading some project:

Program received signal SIGABRT, Aborted.
0x00007ffff0290475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff0290475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff02936f0 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x000000000057795b in qgisCrash (signal=-1) at /home/sam/pacchetti_gis/QGIS/src/app/main.cpp:303
#3  0x0000000000577b32 in myMessageOutput (type=QtFatalMsg, msg=
    0x5d6ecf8 "ASSERT: \"symbol\" in file /home/sam/pacchetti_gis/QGIS/src/core/symbology-ng/qgssymbollayerv2utils.cpp, line 509") at /home/sam/pacchetti_gis/QGIS/src/app/main.cpp:356
#4  0x00007ffff3210630 in qt_message_output(QtMsgType, char const*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#5  0x00007ffff3210a98 in ?? () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#6  0x00007ffff3210c24 in qFatal(char const*, ...) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#7  0x00007ffff47dc2a8 in QgsSymbolLayerV2Utils::symbolPreviewPixmap (symbol=0x0, size=...)
    at /home/sam/pacchetti_gis/QGIS/src/core/symbology-ng/qgssymbollayerv2utils.cpp:509
#8  0x00007ffff40964c1 in QgsLayerTreeModel::addSymbologyToVectorLayer (this=0x1308490, nodeL=0x584ecb0)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:519
#9  0x00007ffff40961ae in QgsLayerTreeModel::addSymbologyToLayer (this=0x1308490, nodeL=0x584ecb0)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:480
#10 0x00007ffff4095e52 in QgsLayerTreeModel::nodeLayerLoaded (this=0x1308490)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:430
#11 0x00007ffff41ab656 in QgsLayerTreeModel::qt_static_metacall (_o=0x1308490, _c=QMetaObject::InvokeMetaMethod, _id=5, _a=
    0x7fffffffabb0) at /home/sam/pacchetti_gis/QGIS/build-master/src/gui/layertree/moc_qgslayertreemodel.cxx:127
#12 0x00007ffff332b54f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#13 0x00007ffff4bc72b1 in QgsLayerTreeLayer::layerLoaded (this=0x584ecb0)
    at /home/sam/pacchetti_gis/QGIS/build-master/src/core/layertree/moc_qgslayertreelayer.cxx:102

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another crash happens when using the Zoom to Layer action:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff26b8ad1 in QAction::data() const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
(gdb) bt
#0  0x00007ffff26b8ad1 in QAction::data() const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#1  0x00007ffff409cf12 in QgsLayerTreeViewDefaultActions::zoomToLayer (this=0x1608440)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreeviewdefaultactions.cpp:159
#2  0x00000000005b3399 in QgisApp::zoomToLayerExtent (this=0x1156670) at /home/sam/pacchetti_gis/QGIS/src/app/qgisapp.cpp:6967
#3  0x000000000090c56a in QgisApp::qt_static_metacall (_o=0x1156670, _c=QMetaObject::InvokeMetaMethod, _id=108, _a=
    0x7fffffffc230) at /home/sam/pacchetti_gis/QGIS/build-master/src/app/moc_qgisapp.cxx:694
#4  0x00007ffff332b54f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#5  0x00007ffff26b9502 in QAction::triggered(bool) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#6  0x00007ffff26b96f0 in QAction::activate(QAction::ActionEvent) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#7  0x00007ffff2a7985f in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#8  0x00007ffff2a79b0c in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007ffff2b33a8a in QToolButton::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff270ee10 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#11 0x00007ffff26bf70c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#12 0x00007ffff26c43eb in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#13 0x00007ffff48b33ae in QgsApplication::notify (this=0x7fffffffd8e0, receiver=0x115e0a0, event=0x7fffffffcb90)
    at /home/sam/pacchetti_gis/QGIS/src/core/qgsapplication.cpp:232
#14 0x00007ffff3315b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#15 0x00007ffff26c054b in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#16 0x00007ffff273afc4 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#17 0x00007ffff2739d51 in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4

@wonder-sk
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slarosa thanks for reporting that - both crashes are fixed now.

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @wonder-sk for the quick fix. Some other thin difference with the old interface which I summarize in the next picture:

  • group icon
  • context menu

senzanome
Also the message box when removing some entry from legend is gone, although I would like see an undo action for that! :-)

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and sometime dragging an entry over a group element I get segfault:

Program received signal SIGSEGV, Segmentation fault.
0x00000000005dd7e0 in QgsLayerTreeNode::parent (this=0x1000000001)
    at /home/sam/pacchetti_gis/QGIS/src/app/../core/layertree/qgslayertreenode.h:73
73      QgsLayerTreeNode* parent() { return mParent; }
(gdb) bt
#0  0x00000000005dd7e0 in QgsLayerTreeNode::parent (this=0x1000000001)
    at /home/sam/pacchetti_gis/QGIS/src/app/../core/layertree/qgslayertreenode.h:73
#1  0x00007ffff4092bf9 in QgsLayerTreeModel::node2index (this=0x1305fb0, node=0x1000000001)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:333
#2  0x00007ffff4092c36 in QgsLayerTreeModel::node2index (this=0x1305fb0, node=0x572be50)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:335
#3  0x00007ffff4093329 in QgsLayerTreeModel::setCurrentNode (this=0x1305fb0, currentNode=0x704de60)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreemodel.cpp:409
#4  0x00007ffff409905a in QgsLayerTreeView::onCurrentChanged (this=0x126ed70, current=..., previous=...)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreeview.cpp:146
#5  0x00007ffff41a9e6f in QgsLayerTreeView::qt_static_metacall (_o=0x126ed70, _c=QMetaObject::InvokeMetaMethod, _id=4, _a=
    0x7fffffffb290) at /home/sam/pacchetti_gis/QGIS/build-master/src/gui/layertree/moc_qgslayertreeview.cxx:65
#6  0x00007ffff332854f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#7  0x00007ffff2c16c5a in QItemSelectionModel::currentChanged(QModelIndex const&, QModelIndex const&) ()
   from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#8  0x00007ffff2c1a36f in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007ffff2c1dba9 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff332854f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#11 0x00007ffff33721f4 in QAbstractItemModel::rowsAboutToBeRemoved(QModelIndex const&, int, int) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#12 0x00007ffff330a316 in QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) ()

@slarosa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @wonder-sk I have one more issue here:

  • when opening a project with 2.2, previously saved with master version, the legend group is broken;
  • when opening a project which has some layer with the datasource broken I can see the one in legend tree (and IMHO that's the correct behavior) but QGIS crashes with the following stacktrace when I try to open the layer context menu:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff496dbb8 in QgsMapLayer::type (this=0x0) at /home/sam/pacchetti_gis/QGIS/src/core/qgsmaplayer.cpp:88
88    return mLayerType;
(gdb) bt
#0  0x00007ffff496dbb8 in QgsMapLayer::type (this=0x0) at /home/sam/pacchetti_gis/QGIS/src/core/qgsmaplayer.cpp:88
#1  0x00000000005fbaa6 in QgsAppLayerTreeViewMenuProvider::createContextMenu (this=0x13f3380)
    at /home/sam/pacchetti_gis/QGIS/src/app/qgsapplayertreeviewmenuprovider.cpp:146
#2  0x00007ffff406f638 in QgsLayerTreeView::contextMenuEvent (this=0x135f700, event=0x7fffffffcb80)
    at /home/sam/pacchetti_gis/QGIS/src/gui/layertree/qgslayertreeview.cpp:106
#3  0x00007ffff269db5a in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#4  0x00007ffff2a48d36 in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#5  0x00007ffff2b56223 in QAbstractItemView::viewportEvent(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#6  0x00007ffff2b99971 in QTreeView::viewportEvent(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#7  0x00007ffff32a4cc6 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) ()
   from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#8  0x00007ffff264e6dc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007ffff26530f5 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff48b06aa in QgsApplication::notify (this=0x7fffffffd8a0, receiver=0x14bb2f0, event=0x7fffffffcb80)
    at /home/sam/pacchetti_gis/QGIS/src/core/qgsapplication.cpp:239
#11 0x00007ffff32a4b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#12 0x00007ffff26ca021 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#13 0x00007ffff26c8d51 in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#14 0x00007ffff26efbc2 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#15 0x00007fffeeb2c355 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#16 0x00007fffeeb2c688 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007fffeeb2c744 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#18 0x00007ffff32d3276 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()

@wonder-sk
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both crashes are fixed now.
Project saved with master version will not keep the grouping because the project format has changed.

Please sign in to comment.