Skip to content

Commit

Permalink
improved restoring of checkbox states from project files. Fix for seg…
Browse files Browse the repository at this point in the history
…fault in QgsMapCanvas::removeAllLayers

git-svn-id: http://svn.osgeo.org/qgis/trunk@4373 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Dec 24, 2005
1 parent 9261431 commit 1ac2e2e
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 22 deletions.
66 changes: 54 additions & 12 deletions src/legend/qgslegend.cpp
Expand Up @@ -443,7 +443,21 @@ void QgsLegend::addLayer( QgsMapLayer * layer )
mStateOfCheckBoxes.insert(std::make_pair(llayer, Qt::Checked)); //insert the check state into the map to query for changes later
QgsLegendLayerFileGroup * llfgroup = new QgsLegendLayerFileGroup(llayer,QString("Files"));
QgsLegendLayerFile * llfile = new QgsLegendLayerFile(llfgroup, QgsLegendLayerFile::nameFromLayer(layer), layer);
mStateOfCheckBoxes.insert(std::make_pair(llfile, Qt::Checked)); //insert the check state into the map to query for changes later

//set the correct check state
blockSignals(true);
if(layer->visible())
{
llfile->setCheckState(0, Qt::Checked);
mStateOfCheckBoxes.insert(std::make_pair(llfile, Qt::Checked)); //insert the check state into the map to query for changes later
}
else
{
llfile->setCheckState(0, Qt::Unchecked);
mStateOfCheckBoxes.insert(std::make_pair(llfile, Qt::Unchecked)); //insert the check state into the map to query for changes later
}
blockSignals(false);

QgsLegendSymbologyGroup * lsgroup = new QgsLegendSymbologyGroup(llayer,QString("Symbology"));
layer->setLegendSymbologyGroupParent(lsgroup);
QgsLegendPropertyGroup * lpgroup = new QgsLegendPropertyGroup(llayer,QString("Properties"));
Expand Down Expand Up @@ -850,6 +864,24 @@ bool QgsLegend::readXML(QDomNode& legendnode)

//if there are several legend layer files in this group, create the additional items
std::map<QString,QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();

//find out the check state of the QgsLegendLayer in the while(true) loop below
Qt::CheckState legendLayerCheckState;
std::map<QString,QgsMapLayer*>::iterator it = layers.find(layerfileelem.attribute("layerid"));
if(it != layers.end())
{
QgsMapLayer* newlayer = it->second;
if(newlayer->visible())
{
legendLayerCheckState = Qt::Checked;
}
else
{
legendLayerCheckState = Qt::Unchecked;
}
}

blockSignals(true);
while(true)
{
if(layerfilenode.isNull())
Expand All @@ -861,28 +893,37 @@ bool QgsLegend::readXML(QDomNode& legendnode)
if(it != layers.end())
{
QgsMapLayer* newlayer = it->second;
QgsLegendLayerFile* newfile = new QgsLegendLayerFile(secondLevelItem, QgsLegendLayerFile::nameFromLayer(newlayer), newlayer);
QgsLegendLayerFile* newfile = new QgsLegendLayerFile(QgsLegendLayerFile::nameFromLayer(newlayer), newlayer);
if(newlayer->visible())
{
if(legendLayerCheckState == Qt::Unchecked)
{
legendLayerCheckState = Qt::PartiallyChecked;
}
newfile->setCheckState(0, Qt::Checked);
mStateOfCheckBoxes.insert(std::make_pair(newfile, Qt::Checked));
}
else
{
if(legendLayerCheckState == Qt::Checked)
{
legendLayerCheckState = Qt::PartiallyChecked;
}
newfile->setCheckState(0, Qt::Unchecked);
mStateOfCheckBoxes.insert(std::make_pair(newfile, Qt::Unchecked));
}
newlayer->setLegendLayerFile(newfile);
newlayer->initContextMenu(mApp);

//move newfile as the last child of the legendlayerfilegroup
QgsLegendItem* curitem = newfile;
while(curitem = newfile->nextSibling())
{
moveItem(newfile, curitem);
}
secondLevelItem->addChild(newfile);
}
layerfilenode = layerfilenode.nextSibling();
layerfileelem = layerfilenode.toElement();
}
secondLevelItem->parent()->setCheckState(0, legendLayerCheckState);
mStateOfCheckBoxes[secondLevelItem->parent()] = legendLayerCheckState;
blockSignals(false);

//symbology group
secondLevelItem = secondLevelItem->nextSibling();
Expand Down Expand Up @@ -1019,19 +1060,20 @@ QTreeWidgetItem* QgsLegend::nextItem(QTreeWidgetItem* item)
{
return 0;
}
//todo: implement this in a nicer and safer way
else if(dynamic_cast<QgsLegendItem*>(litem->parent())->nextSibling())
//go to other levels to find the next item
else if(litem->parent() && ((QgsLegendItem*)(litem->parent()))->nextSibling())
{
return (dynamic_cast<QgsLegendItem*>(litem->parent())->nextSibling());
}
else if(dynamic_cast<QgsLegendItem*>(litem->parent()->parent())->nextSibling())
else if(litem->parent() && litem->parent()->parent() && ((QgsLegendItem*)(litem->parent()->parent()))->nextSibling())
{
return (dynamic_cast<QgsLegendItem*>(litem->parent()->parent())->nextSibling());
}
/*else if(dynamic_cast<QgsLegendItem*>(litem->parent()->parent()->parent())->nextSibling())//maximum four nesting states in the current legend
else if(litem->parent() && litem->parent()->parent() && litem->parent()->parent()->parent() &&\
((QgsLegendItem*)(litem->parent()->parent()->parent()))->nextSibling())//maximum four nesting states in the current legend
{
return (dynamic_cast<QgsLegendItem*>(litem->parent()->parent()->parent())->nextSibling());
}*/
}
else
{
return 0;
Expand Down
24 changes: 24 additions & 0 deletions src/legend/qgslegendlayerfile.cpp
Expand Up @@ -48,6 +48,30 @@ QgsLegendLayerFile::QgsLegendLayerFile(QTreeWidgetItem * theLegendItem, QString
setIcon(0, originalIcon);
}

QgsLegendLayerFile::QgsLegendLayerFile(QString theString, QgsMapLayer* theLayer)
: QgsLegendItem(), mLayer(theLayer)
{
mType = LEGEND_LAYER_FILE;
QPixmap originalPixmap = getOriginalPixmap();
//ensure the overview glasses is painted if necessary
if(mLayer->showInOverviewStatus())
{
#if defined(Q_OS_MACX) || defined(WIN32)
QString pkgDataPath(QCoreApplication::applicationDirPath()+QString("/share/qgis"));
#else
QString pkgDataPath(PKGDATAPATH);
#endif
QPixmap inOverviewPixmap(pkgDataPath+QString("/images/icons/inoverview.png"));
QPainter p(&originalPixmap);
p.drawPixmap(0,0,inOverviewPixmap);
}
QIcon originalIcon(originalPixmap);
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
setCheckState (0, Qt::Checked );
setText(0, theString);
setIcon(0, originalIcon);
}


QgsLegendLayerFile::~QgsLegendLayerFile()
{
Expand Down
1 change: 1 addition & 0 deletions src/legend/qgslegendlayerfile.h
Expand Up @@ -32,6 +32,7 @@ class QgsLegendLayerFile : public QgsLegendItem
{
public:
QgsLegendLayerFile(QTreeWidgetItem * theLegendItem, QString theString, QgsMapLayer* theLayer);
QgsLegendLayerFile(QString theString, QgsMapLayer* theLayer);
~QgsLegendLayerFile();
bool isLeafNode() {return true;}
DRAG_ACTION accept(LEGEND_ITEM_TYPE type);
Expand Down
20 changes: 12 additions & 8 deletions src/qgsmapcanvas.cpp
Expand Up @@ -2830,20 +2830,24 @@ void QgsMapCanvas::removeAll()

QString current_key;

//don't disconnect because the maplayers are already deleted in
//QgsMapLayerRegistry::removeAllMapLayers(). Therefore this would
//cause a segfault

// first disconnnect all layer signals from this canvas
while ( mi != mCanvasProperties->layers.end() )
{
//while ( mi != mCanvasProperties->layers.end() )
//{
// save the current key
current_key = mi->first;
//current_key = mi->first;

QgsMapLayer * layer = mCanvasProperties->layers[current_key];
//QgsMapLayer * layer = mCanvasProperties->layers[current_key];

// disconnect layer signals
QObject::disconnect(layer, SIGNAL(visibilityChanged()), this, SLOT(layerStateChange()));
QObject::disconnect(layer, SIGNAL(repaintRequested()), this, SLOT(refresh()));
//QObject::disconnect(layer, SIGNAL(visibilityChanged()), this, SLOT(layerStateChange()));
//QObject::disconnect(layer, SIGNAL(repaintRequested()), this, SLOT(refresh()));

++mi;
}
//++mi;
//}

// then empty all the other state containers

Expand Down
4 changes: 2 additions & 2 deletions src/qgssymbol.cpp
Expand Up @@ -392,7 +392,7 @@ bool QgsSymbol::readXML( QDomNode & synode )
int red = oulcelement.attribute("red").toInt();
int green = oulcelement.attribute("green").toInt();
int blue = oulcelement.attribute("blue").toInt();
setColor(QColor(Qt::red, Qt::green, Qt::blue));
setColor(QColor(red, green, blue));

QDomNode outlstnode = synode.namedItem("outlinestyle");
QDomElement outlstelement = outlstnode.toElement();
Expand All @@ -407,7 +407,7 @@ bool QgsSymbol::readXML( QDomNode & synode )
red = fillcelement.attribute("red").toInt();
green = fillcelement.attribute("green").toInt();
blue = fillcelement.attribute("blue").toInt();
setFillColor(QColor(Qt::red, Qt::green, Qt::blue));
setFillColor(QColor(red, green, blue));

QDomNode fillpnode = synode.namedItem("fillpattern");
QDomElement fillpelement = fillpnode.toElement();
Expand Down

0 comments on commit 1ac2e2e

Please sign in to comment.