Skip to content

Commit 248a341

Browse files
committed
Improvements to embed dialogs and stability
1 parent a9252db commit 248a341

File tree

6 files changed

+150
-65
lines changed

6 files changed

+150
-65
lines changed

src/app/legend/qgslegend.cpp

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
295295
// record which items were selected and hide them
296296
foreach( QTreeWidgetItem * item, selectedItems() )
297297
{
298+
//prevent to drag out content under groups that are embedded from other
299+
//project files.
300+
if( parentGroupEmbedded( item ) )
301+
{
302+
continue;
303+
}
298304
item->setHidden( true );
299305
mItemsBeingMoved << item;
300306
}
@@ -324,6 +330,7 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
324330
if ( mItemsBeingMoved.isEmpty() )
325331
{
326332
QgsDebugMsg( "nothing to move" );
333+
setCursor( QCursor( Qt::ArrowCursor ) );
327334
return;
328335
}
329336

@@ -364,36 +371,47 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e )
364371

365372
mDropTarget = layer;
366373

367-
if ( e->y() < ( y0 + y1 ) / 2 )
374+
//prevent inserting content into embedded groups
375+
if( !parentGroupEmbedded( litem ) )
368376
{
369-
QgsDebugMsg( "insert before layer" );
370-
mDropAction = BEFORE;
371-
line_y = y0;
372-
}
373-
else
374-
{
375-
QgsDebugMsg( "insert after layer" );
376-
mDropAction = AFTER;
377-
line_y = y1;
377+
if ( e->y() < ( y0 + y1 ) / 2 )
378+
{
379+
QgsDebugMsg( "insert before layer" );
380+
mDropAction = BEFORE;
381+
line_y = y0;
382+
}
383+
else
384+
{
385+
QgsDebugMsg( "insert after layer" );
386+
mDropAction = AFTER;
387+
line_y = y1;
388+
}
378389
}
379390
}
380-
else if ( group )
381-
{
391+
else if ( group )
392+
{
382393
if ( yCoordAboveCenter( litem, e->y() ) ) //over center of item
383394
{
384395
QgsDebugMsg( "insert before group" );
385396

386-
line_y = visualItemRect( item ).top() + 1;
387-
mDropTarget = item;
388-
mDropAction = BEFORE;
397+
//prevent inserting content into embedded groups
398+
if( !parentGroupEmbedded( item ) )
399+
{
400+
line_y = visualItemRect( item ).top() + 1;
401+
mDropTarget = item;
402+
mDropAction = BEFORE;
403+
}
389404
}
390405
else // below center of item
391406
{
392-
QgsDebugMsg( "insert into group" );
407+
if( !groupEmbedded( item ) )
408+
{
409+
QgsDebugMsg( "insert into group" );
393410

394-
line_y = visualItemRect( item ).bottom() - 2;
395-
mDropTarget = item;
396-
mDropAction = INSERT;
411+
line_y = visualItemRect( item ).bottom() - 2;
412+
mDropTarget = item;
413+
mDropAction = INSERT;
414+
}
397415
}
398416
}
399417
else
@@ -566,7 +584,7 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
566584
{
567585
qobject_cast<QgsLegendLayer*>( li )->addToPopupMenu( theMenu );
568586

569-
if ( li->parent() )
587+
if ( li->parent() && !parentGroupEmbedded( li ) )
570588
{
571589
theMenu.addAction( tr( "&Make to toplevel item" ), this, SLOT( makeToTopLevelItem() ) );
572590
}
@@ -583,7 +601,7 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi
583601
tr( "&Set group CRS" ), this, SLOT( legendGroupSetCRS() ) );
584602
}
585603

586-
if ( li->type() == QgsLegendItem::LEGEND_LAYER || li->type() == QgsLegendItem::LEGEND_GROUP )
604+
if ( ( li->type() == QgsLegendItem::LEGEND_LAYER || li->type() == QgsLegendItem::LEGEND_GROUP ) && !groupEmbedded( li ) && !parentGroupEmbedded( li ) )
587605
{
588606
theMenu.addAction( tr( "Re&name" ), this, SLOT( openEditor() ) );
589607
}
@@ -644,6 +662,13 @@ QgsLegendGroup* QgsLegend::addEmbeddedGroup( const QString& groupName, const QSt
644662
QDomElement legendElem = legendGroupList.at(i).toElement();
645663
if( legendElem.attribute("name") == groupName )
646664
{
665+
//embedded groups cannot be embedded again
666+
if( legendElem.attribute("embedded") == "1" )
667+
{
668+
mEmbeddedGroups.remove( groupName );
669+
return 0;
670+
}
671+
647672
QgsLegendGroup* group = 0;
648673
if( parent )
649674
{
@@ -678,6 +703,7 @@ QgsLegendGroup* QgsLegend::addEmbeddedGroup( const QString& groupName, const QSt
678703
addEmbeddedGroup( childElem.attribute("name"), projectFilePath, group );
679704
}
680705
}
706+
checkLayerOrderUpdate();
681707
return group;
682708
}
683709
}
@@ -1092,6 +1118,12 @@ bool QgsLegend::writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDo
10921118
legendlayerfilenode.setAttribute( "layerid", layer->id() );
10931119
layerfilegroupnode.appendChild( legendlayerfilenode );
10941120

1121+
//embedded layer?
1122+
if( !QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
1123+
{
1124+
legendlayerfilenode.setAttribute( "embedded", "1" );
1125+
}
1126+
10951127
// visible flag
10961128
legendlayerfilenode.setAttribute( "visible", ll->isVisible() );
10971129

@@ -1814,7 +1846,10 @@ void QgsLegend::openEditor()
18141846
QTreeWidgetItem* theItem = currentItem();
18151847
if ( theItem )
18161848
{
1817-
editItem( theItem, 0 );
1849+
if( !groupEmbedded( theItem ) && !parentGroupEmbedded( theItem ) )
1850+
{
1851+
editItem( theItem, 0 );
1852+
}
18181853
}
18191854
}
18201855

@@ -1823,10 +1858,13 @@ void QgsLegend::makeToTopLevelItem()
18231858
QgsLegendItem* theItem = dynamic_cast<QgsLegendItem *>( currentItem() );
18241859
if ( theItem )
18251860
{
1826-
theItem->storeAppearanceSettings();
1827-
removeItem( theItem );
1828-
addTopLevelItem( theItem );
1829-
theItem->restoreAppearanceSettings();
1861+
if( !parentGroupEmbedded( theItem ) )
1862+
{
1863+
theItem->storeAppearanceSettings();
1864+
removeItem( theItem );
1865+
addTopLevelItem( theItem );
1866+
theItem->restoreAppearanceSettings();
1867+
}
18301868
}
18311869
}
18321870

@@ -2130,3 +2168,39 @@ void QgsLegend::setCRSForSelectedLayers( const QgsCoordinateReferenceSystem &crs
21302168
if ( renderFlagState )
21312169
mMapCanvas->setRenderFlag( true );
21322170
}
2171+
2172+
bool QgsLegend::parentGroupEmbedded( QTreeWidgetItem* item ) const
2173+
{
2174+
if( !item )
2175+
{
2176+
return false;
2177+
}
2178+
2179+
QgsLegendItem* lItem = dynamic_cast<QgsLegendItem*>(item);
2180+
if( lItem && lItem->parent() )
2181+
{
2182+
QgsLegendGroup* parentGroup = dynamic_cast<QgsLegendGroup*>( lItem->parent() );
2183+
if( parentGroup && parentGroup->type() == QgsLegendItem::LEGEND_GROUP
2184+
&& mEmbeddedGroups.contains( parentGroup->text( 0 ) ) )
2185+
{
2186+
return true;
2187+
}
2188+
}
2189+
return false;
2190+
}
2191+
2192+
bool QgsLegend::groupEmbedded( QTreeWidgetItem* item ) const
2193+
{
2194+
if( !item )
2195+
{
2196+
return false;
2197+
}
2198+
2199+
QgsLegendGroup* gItem = dynamic_cast<QgsLegendGroup*>(item);
2200+
if( !gItem )
2201+
{
2202+
return false;
2203+
}
2204+
2205+
return mEmbeddedGroups.contains( gItem->text( 0 ) );
2206+
}

src/app/legend/qgslegend.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ class QgsLegend : public QTreeWidget
437437
*/
438438
int getItemPos( QTreeWidgetItem* item );
439439

440+
/**Returns true if the item is a group embedde from another project*/
441+
bool groupEmbedded( QTreeWidgetItem* item ) const;
442+
443+
/**Returns true if the parent group is embedded from another project*/
444+
bool parentGroupEmbedded( QTreeWidgetItem* item ) const;
445+
440446
/**Pointer to the main canvas. Used for requiring repaints in case of legend changes*/
441447
QgsMapCanvas* mMapCanvas;
442448

src/app/qgsembedlayerdialog.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#include "qgsembedlayerdialog.h"
2+
#include "qgisapp.h"
23
#include <QDomDocument>
34
#include <QFileDialog>
5+
#include <QFileInfo>
6+
#include <QSettings>
47

58
QgsEmbedLayerDialog::QgsEmbedLayerDialog( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
69
{
710
setupUi( this );
11+
QObject::connect( mButtonBox, SIGNAL(rejected() ), this, SLOT(reject() ) );
812
}
913

1014
QgsEmbedLayerDialog::~QgsEmbedLayerDialog()
@@ -21,7 +25,7 @@ QList< QPair < QString, QString > > QgsEmbedLayerDialog::embeddedGroups() const
2125
{
2226
if( (*itemIt)->data(0, Qt::UserRole).toString() == "group" )
2327
{
24-
result.push_back( qMakePair( (*itemIt)->text( 0 ), mProjectFileLineEdit->text() ) );
28+
result.push_back( qMakePair( (*itemIt)->text( 0 ), mProjectPath ) );
2529
}
2630
}
2731

@@ -38,15 +42,16 @@ QList< QPair < QString, QString > > QgsEmbedLayerDialog::embeddedLayers() const
3842
{
3943
if( (*itemIt)->data(0, Qt::UserRole).toString() == "layer" )
4044
{
41-
result.push_back( qMakePair( (*itemIt)->data(0, Qt::UserRole + 1).toString(), mProjectFileLineEdit->text() ) );
45+
result.push_back( qMakePair( (*itemIt)->data(0, Qt::UserRole + 1).toString(), mProjectPath ) );
4246
}
4347
}
4448
return result;
4549
}
4650

4751
void QgsEmbedLayerDialog::on_mBrowseFileToolButton_clicked()
4852
{
49-
QString projectFile = QFileDialog::getOpenFileName( 0, tr("Select project file"), "",tr("QGIS project files (*.qgs)") );
53+
QSettings s;
54+
QString projectFile = QFileDialog::getOpenFileName( 0, tr("Select project file"), s.value("/qgis/last_embedded_project_path").toString() ,tr("QGIS project files (*.qgs)") );
5055
if( !projectFile.isEmpty() )
5156
{
5257
mProjectFileLineEdit->setText( projectFile );
@@ -61,13 +66,14 @@ void QgsEmbedLayerDialog::on_mProjectFileLineEdit_editingFinished()
6166

6267
void QgsEmbedLayerDialog::changeProjectFile()
6368
{
64-
mTreeWidget->clear();
6569
QFile projectFile( mProjectFileLineEdit->text() );
6670
if( !projectFile.exists() )
6771
{
6872
return;
6973
}
7074

75+
mTreeWidget->clear();
76+
7177
//parse project file and fill tree
7278
if( !projectFile.open( QIODevice::ReadOnly ) )
7379
{
@@ -101,13 +107,20 @@ void QgsEmbedLayerDialog::changeProjectFile()
101107
addLegendGroupToTreeWidget( currentChildElem );
102108
}
103109
}
110+
111+
mProjectPath = mProjectFileLineEdit->text();
104112
}
105113

106114
void QgsEmbedLayerDialog::addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent )
107115
{
108116
QDomNodeList groupChildren = groupElem.childNodes();
109117
QDomElement currentChildElem;
110118

119+
if(groupElem.attribute("embedded") == "1" )
120+
{
121+
return;
122+
}
123+
111124
QTreeWidgetItem* groupItem = 0;
112125
if( !parent )
113126
{
@@ -117,6 +130,7 @@ void QgsEmbedLayerDialog::addLegendGroupToTreeWidget( const QDomElement& groupEl
117130
{
118131
groupItem = new QTreeWidgetItem( parent );
119132
}
133+
groupItem->setIcon( 0, QgisApp::getThemeIcon("mActionFolder.png") );
120134
groupItem->setText( 0, groupElem.attribute("name") );
121135
groupItem->setData( 0, Qt::UserRole, "group" );
122136

@@ -136,6 +150,11 @@ void QgsEmbedLayerDialog::addLegendGroupToTreeWidget( const QDomElement& groupEl
136150

137151
void QgsEmbedLayerDialog::addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent )
138152
{
153+
if(layerElem.attribute("embedded") == "1" )
154+
{
155+
return;
156+
}
157+
139158
QTreeWidgetItem* item = 0;
140159
if( parent )
141160
{
@@ -179,4 +198,15 @@ void QgsEmbedLayerDialog::unselectChildren( QTreeWidgetItem* item )
179198
}
180199
}
181200

201+
void QgsEmbedLayerDialog::on_mButtonBox_accepted()
202+
{
203+
QSettings s;
204+
QFileInfo fi( mProjectPath );
205+
if( fi.exists() )
206+
{
207+
s.setValue("/qgis/last_embedded_project_path", fi.absolutePath() );
208+
}
209+
accept();
210+
}
211+
182212

src/app/qgsembedlayerdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ class QgsEmbedLayerDialog: public QDialog, private Ui::QgsEmbedLayerDialogBase
2222
void on_mBrowseFileToolButton_clicked();
2323
void on_mProjectFileLineEdit_editingFinished();
2424
void on_mTreeWidget_itemSelectionChanged();
25+
void on_mButtonBox_accepted();
2526

2627
private:
2728
void changeProjectFile();
2829
void addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent = 0 );
2930
void addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent = 0 );
3031
void unselectChildren( QTreeWidgetItem* item );
32+
QString mProjectPath;
3133
};
3234

3335
#endif // QGSEMBEDLAYERSDIALOG_H

src/core/qgsproject.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,12 @@ bool QgsProject::createEmbeddedLayer( const QString& layerId, const QString& pro
16051605
QString id = mapLayerElem.firstChildElement("id").text();
16061606
if( id == layerId )
16071607
{
1608+
//layer can be embedded only once
1609+
if( mapLayerElem.attribute("embedded") == "1" )
1610+
{
1611+
return false;
1612+
}
1613+
16081614
mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
16091615
if( addLayer( mapLayerElem, brokenNodes, vectorLayerList ) )
16101616
{

0 commit comments

Comments
 (0)