198 changes: 106 additions & 92 deletions src/plugins/topology/rulesDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,68 +16,46 @@
***************************************************************************/

#include <QtGui>

#include <qgsvectordataprovider.h>
#include <qgsvectorlayer.h>
//#include <qgssearchstring.h>
//#include <qgssearchtreenode.h>
#include <qgsmaplayer.h>
#include <qgsmaplayerregistry.h>

#include <qgsproviderregistry.h>
#include <qgslogger.h>
#include <qgisinterface.h>
#include <qgsproject.h>

//#include "../../app/qgisapp.h"

#include "rulesDialog.h"
#include "topolTest.h"

rulesDialog::rulesDialog( QList<QString> layerList, QMap<QString, TopologyRule> testMap, QgisInterface* theQgisIface, QWidget *parent )
rulesDialog::rulesDialog( QMap<QString, TopologyRule> testMap, QgisInterface *theQgisIface, QWidget *parent )
: QDialog( parent ), Ui::rulesDialog()
{
setupUi( this );

mQgisIface = theQgisIface;

//setHorizontalHeaderItems();
mTestTable->hideColumn( 4 );
mTestTable->hideColumn( 5 );
mRulesTable->hideColumn( 4 );
mRulesTable->hideColumn( 5 );

mTestConfMap = testMap;
mTestTable->setSelectionBehavior( QAbstractItemView::SelectRows );
mTestBox->addItems( mTestConfMap.keys() );

QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();

for ( int i = 0; i < layerList.size(); ++i )
{
// add layer ID to the layerId list
mLayerIds << layerList[i];
mRulesTable->setSelectionBehavior( QAbstractItemView::SelectRows );
mRuleBox->addItems( mTestConfMap.keys() );

QgsVectorLayer* v1 = ( QgsVectorLayer* )layerRegistry->mapLayers()[layerList[i]];
qDebug() << "layerid = " + layerList[i];

// add layer name to the layer combo boxes
mLayer1Box->addItem( v1->name(), v1->id() );
//mLayer2Box->addItem((( QgsVectorLayer* )layerRegistry->mapLayers()[layerList[i]] )->name() );


}
connect( mAddTestButton, SIGNAL( clicked() ), this, SLOT( addRule() ) );
connect( mAddTestButton, SIGNAL( clicked() ), mRulesTable, SLOT( resizeColumnsToContents() ) );
// attempt to add new test when Ok clicked
//connect( buttonBox, SIGNAL( accepted() ), this, SLOT( addTest() ) );
connect( mDeleteTestButton, SIGNAL( clicked() ), this, SLOT( deleteTest() ) );

connect( mLayer1Box, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( updateRuleItems( const QString& ) ) );
connect( mRuleBox, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( showControls( const QString& ) ) );

connect( mAddTestButton, SIGNAL( clicked() ), this, SLOT( addTest() ) );
connect( mAddTestButton, SIGNAL( clicked() ), mTestTable, SLOT( resizeColumnsToContents() ) );
// attempt to add new test when Ok clicked
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( addTest() ) );
connect( mDeleteTestButton, SIGNAL( clicked() ), this, SLOT( deleteTest() ) );
connect( mTestBox, SIGNAL( currentIndexChanged( const QString& ) ), this, SLOT( showControls( const QString& ) ) );
mTestBox->setCurrentIndex( 4 );
mRuleBox->setCurrentIndex( 0 );

//this resets this plugin up if a project is loaded
connect( mQgisIface->mainWindow(), SIGNAL( projectRead() ), this, SLOT( projectRead() ) );
connect( mQgisIface, SIGNAL( projectRead() ), this, SLOT( projectRead() ) );
//reset plugin if new project is activated
projectRead();
}

Expand All @@ -89,7 +67,7 @@ void rulesDialog::setHorizontalHeaderItems()
{
QStringList labels;
labels << "Test" << "Layer #1" << "Layer #2" << "Tolerance" << "" << "";
mTestTable->setHorizontalHeaderLabels( labels );
mRulesTable->setHorizontalHeaderLabels( labels );
}

void rulesDialog::readTest( int index, QgsMapLayerRegistry* layerRegistry )
Expand Down Expand Up @@ -132,59 +110,72 @@ void rulesDialog::readTest( int index, QgsMapLayerRegistry* layerRegistry )
layer2Name = "No layer";

int row = index;
mTestTable->insertRow( row );
mRulesTable->insertRow( row );

QTableWidgetItem* newItem;
newItem = new QTableWidgetItem( testName );
newItem->setFlags( newItem->flags() & ~Qt::ItemIsEditable );
mTestTable->setItem( row, 0, newItem );
mRulesTable->setItem( row, 0, newItem );

newItem = new QTableWidgetItem( layer1Name );
newItem->setFlags( newItem->flags() & ~Qt::ItemIsEditable );
mTestTable->setItem( row, 1, newItem );
mRulesTable->setItem( row, 1, newItem );

newItem = new QTableWidgetItem( layer2Name );
newItem->setFlags( newItem->flags() & ~Qt::ItemIsEditable );
mTestTable->setItem( row, 2, newItem );
mRulesTable->setItem( row, 2, newItem );

if ( mTestConfMap[testName].useTolerance )
newItem = new QTableWidgetItem( tolerance );
else
newItem = new QTableWidgetItem( QString( "No tolerance" ) );

newItem->setFlags( newItem->flags() & ~Qt::ItemIsEditable );
mTestTable->setItem( row, 3, newItem );
mRulesTable->setItem( row, 3, newItem );

// add layer ids to hidden columns
newItem = new QTableWidgetItem( layer1Id );
mTestTable->setItem( row, 4, newItem );
mRulesTable->setItem( row, 4, newItem );
newItem = new QTableWidgetItem( layer2Id );
mTestTable->setItem( row, 5, newItem );
mRulesTable->setItem( row, 5, newItem );
}

void rulesDialog::projectRead()
{
clearRules();
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
int testCount = QgsProject::instance()->readNumEntry( "Topol", "/testCount" );
mTestTable->clearContents();
mRulesTable->clearContents();

for ( int i = 0; i < testCount; ++i )
readTest( i, layerRegistry );
}

void rulesDialog::showControls( const QString& testName )
{
if ( testName.isEmpty() )
{
return;
}

mLayer2Box->clear();
mLayer2Box->addItem( "No layer" );
TopologyRule topologyRule = mTestConfMap[testName];
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
QList<QString> layerList = layerRegistry->mapLayers().keys();

if ( topologyRule.useSecondLayer )
{
mLayer2Box->setVisible( true );
for ( int i = 0; i < mLayerIds.count(); ++i )
for ( int i = 0; i < layerList.count(); ++i )
{
QgsVectorLayer* v1 = ( QgsVectorLayer* )layerRegistry->mapLayers()[mLayerIds.at( i )];
QgsVectorLayer* v1 = ( QgsVectorLayer* )layerRegistry->mapLayers()[layerList[i]];

if ( !v1 )
{
continue;
}


if ( v1->name() == mLayer1Box->currentText() )
{
Expand All @@ -193,7 +184,7 @@ void rulesDialog::showControls( const QString& testName )

if ( topologyRule.layer2AcceptsType( v1->geometryType() ) )
{
mLayer2Box->addItem( v1->name() );
mLayer2Box->addItem( v1->name() , v1->id() );
}
}
}
Expand All @@ -216,32 +207,10 @@ void rulesDialog::showControls( const QString& testName )

}

void rulesDialog::addLayer( QgsMapLayer* layer )
{
mLayerIds << layer->id();

// add layer name to the layer combo boxes
mLayer1Box->addItem( layer->name() );
mLayer2Box->addItem( layer->name() );
}

void rulesDialog::removeLayer( QString layerId )
{
int index = mLayerIds.indexOf( layerId );

mLayerIds.removeAt( index );
// + 1 for "No layer" string
mLayer1Box->removeItem( index + 1 );
mLayer2Box->removeItem( index + 1 );

// TODO: Maybe tell the dock that we have no layers under
//if (mLayer1Box->size() == 1) do something
}

void rulesDialog::addTest()
void rulesDialog::addRule()
{
//sanity checks
QString test = mTestBox->currentText();
QString test = mRuleBox->currentText();
QString layer1 = mLayer1Box->currentText();
if ( layer1 == "No layer" )
return;
Expand All @@ -250,54 +219,54 @@ void rulesDialog::addTest()
if ( layer2 == "No layer" && mTestConfMap[test].useSecondLayer )
return;

for ( int i = 0; i < mTestTable->rowCount(); ++i )
for ( int i = 0; i < mRulesTable->rowCount(); ++i )
{
if ( mTestTable->item( i, 0 )->text() == test &&
mTestTable->item( i, 1 )->text() == layer1 &&
mTestTable->item( i, 2 )->text() == layer2 )
if ( mRulesTable->item( i, 0 )->text() == test &&
mRulesTable->item( i, 1 )->text() == layer1 &&
mRulesTable->item( i, 2 )->text() == layer2 )
{
return;
}
}

int row = mTestTable->rowCount();
mTestTable->insertRow( row );
int row = mRulesTable->rowCount();
mRulesTable->insertRow( row );

QTableWidgetItem* newItem;
newItem = new QTableWidgetItem( test );
mTestTable->setItem( row, 0, newItem );
mRulesTable->setItem( row, 0, newItem );
newItem = new QTableWidgetItem( layer1 );
mTestTable->setItem( row, 1, newItem );
mRulesTable->setItem( row, 1, newItem );

if ( mTestConfMap[test].useSecondLayer )
newItem = new QTableWidgetItem( layer2 );
else
newItem = new QTableWidgetItem( "No layer" );

mTestTable->setItem( row, 2, newItem );
mRulesTable->setItem( row, 2, newItem );

if ( mTestConfMap[test].useTolerance )
newItem = new QTableWidgetItem( QString( "%1" ).arg( mToleranceBox->value() ) );
else
newItem = new QTableWidgetItem( QString( "No tolerance" ) );

mTestTable->setItem( row, 3, newItem );
mRulesTable->setItem( row, 3, newItem );

QString layer1ID, layer2ID;
// add layer ids to hidden columns
// -1 for "No layer" string
if ( mTestConfMap[test].useSecondLayer )
layer2ID = mLayerIds[mLayer2Box->currentIndex() - 1];
layer2ID = mLayer2Box->itemData( mLayer2Box->currentIndex() ).toString();
else
layer2ID = "No layer";

layer1ID = mLayerIds[mLayer1Box->currentIndex() - 1];
layer1ID = mLayer1Box->itemData( mLayer1Box->currentIndex() ).toString();

//TODO: use setItemData (or something like that) instead of hidden columns
newItem = new QTableWidgetItem( layer1ID );
mTestTable->setItem( row, 4, newItem );
mRulesTable->setItem( row, 4, newItem );
newItem = new QTableWidgetItem( layer2ID );
mTestTable->setItem( row, 5, newItem );
mRulesTable->setItem( row, 5, newItem );

// save state to the project file.....
QString postfix = QString( "%1" ).arg( row );
Expand All @@ -310,22 +279,27 @@ void rulesDialog::addTest()
project->writeEntry( "Topol", "/layer2_" + postfix, layer2ID );

// reset controls to default
mTestBox->setCurrentIndex( 0 );
mRuleBox->setCurrentIndex( 0 );
mLayer1Box->setCurrentIndex( 0 );
mLayer2Box->setCurrentIndex( 0 );
mToleranceBox->setValue( 0 );
}

void rulesDialog::deleteTest()
{
int row = mTestTable->currentRow();
if ( 0 <= row && row < mTestTable->rowCount() )
mTestTable->removeRow( row );
int row = mRulesTable->currentRow();
if ( 0 <= row && row < mRulesTable->rowCount() )
mRulesTable->removeRow( row );
}

void rulesDialog::updateRuleItems( const QString &layerName )
{
mTestBox->clear();
if ( layerName.isEmpty() )
{
return;
}

mRuleBox->clear();

if ( layerName == "No layer" )
{
Expand All @@ -337,13 +311,53 @@ void rulesDialog::updateRuleItems( const QString &layerName )
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
QgsVectorLayer* vlayer = ( QgsVectorLayer* )layerRegistry->mapLayers()[layerId];

if ( !vlayer )
{
qDebug() << "not a vector layer";
return;
}

for ( QMap<QString, TopologyRule>::iterator it = mTestConfMap.begin(); it != mTestConfMap.end(); ++it )
{
TopologyRule rule = it.value();
if ( rule.layer1AcceptsType( vlayer->geometryType() ) )
{
mTestBox->addItem( it.key() );
mRuleBox->addItem( it.key() );
}

}
}

void rulesDialog::initGui()
{
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();

QList<QString> layerList = layerRegistry->mapLayers().keys();

mLayer1Box->clear();
mLayer1Box->addItem( "No layer" );

mLayer2Box->clear();
mLayer2Box->addItem( "No layer" );

mLayer1Box->blockSignals( true );
for ( int i = 0; i < layerList.size(); ++i )
{
QgsVectorLayer* v1 = ( QgsVectorLayer* )layerRegistry->mapLayers()[layerList[i]];
qDebug() << "layerid = " + layerList[i];

// add layer name to the layer combo boxes

mLayer1Box->addItem( v1->name(), v1->id() );
}
mLayer1Box->blockSignals( false );

}

void rulesDialog::clearRules()
{
while ( mRulesTable->rowCount() > 0 )
{
mRulesTable->removeRow( 0 );
}
}
32 changes: 17 additions & 15 deletions src/plugins/topology/rulesDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,21 @@ class rulesDialog : public QDialog, public Ui::rulesDialog
* @param theQgisIface pointer to a QgisInterface instance
* @param parent parent widget
*/
rulesDialog( QList<QString> layerList, QMap<QString, TopologyRule> testMap, QgisInterface* theQgisIface, QWidget *parent );
rulesDialog( QMap<QString, TopologyRule> testMap, QgisInterface* theQgisIface, QWidget *parent );
~rulesDialog();
/*
* Returns pointer to the test table
*/
QTableWidget* testTable() { return mTestTable; }
QTableWidget* rulesTable() { return mRulesTable; }
/*
* Returns pointer to the test combobox
*/
QComboBox* testBox() { return mTestBox; }
QComboBox* rulesBox() { return mRuleBox; }

/*
* Initialize Rules UI with layers and rules
*/
void initGui();

private:
QMap<QString, TopologyRule> mTestConfMap;
Expand All @@ -67,6 +72,8 @@ class rulesDialog : public QDialog, public Ui::rulesDialog
*/
void setHorizontalHeaderItems();



private slots:
/*
* Shows or hides controls according to test settings
Expand All @@ -76,7 +83,7 @@ class rulesDialog : public QDialog, public Ui::rulesDialog
/*
* Adds test to the table
*/
void addTest();
void addRule();
/*
* Deletes test from the table
*/
Expand All @@ -86,22 +93,17 @@ class rulesDialog : public QDialog, public Ui::rulesDialog
*/
void projectRead();
/*
* Adds layer to layer comboboxes
* @param layer layer pointer
*/
void addLayer( QgsMapLayer* layer );
/*
* Deletes layer to layer comboboxes
* Updates Rule combobox to mach first layer
* @param layerId layer ID
*/
void removeLayer( QString layerId );

void updateRuleItems( const QString& layerName );

/*
* Updates Rule combobox to mach first layer
* @param layerId layer ID
* Deletes all rules from rules dialog
*/
void updateRuleItems( const QString& layerName );
void clearRules();



};

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/topology/rulesDialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Test settings</string>
<string>Topology Rule Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
Expand Down