diff --git a/src/qgisapp.cpp b/src/qgisapp.cpp index 0dc257ee145..4fe55bbdefc 100644 --- a/src/qgisapp.cpp +++ b/src/qgisapp.cpp @@ -247,6 +247,7 @@ void QgisApp::addLayer() // create the layer QgsShapeFileLayer *lyr = new QgsShapeFileLayer(*it, base); + QObject::connect(lyr,SIGNAL(repaintRequested()),mapCanvas,SLOT(refresh())); // give it a random color if (lyr->isValid()) { diff --git a/src/qgsattributetable.cpp b/src/qgsattributetable.cpp index 0222dba6f94..9186af23e8a 100644 --- a/src/qgsattributetable.cpp +++ b/src/qgsattributetable.cpp @@ -19,21 +19,73 @@ #include #include #include "qgsattributetable.h" +#include -QgsAttributeTable::QgsAttributeTable(QWidget * parent, const char *name):QTable(parent, name) +QgsAttributeTable::QgsAttributeTable(QWidget * parent, const char *name):QTable(parent, name), lockKeyPressed(false) { QFont f( font() ); f.setFamily( "Helvetica" ); f.setPointSize(11); setFont(f); + setSelectionMode(QTable::MultiRow); + QObject::connect(this,SIGNAL(selectionChanged()),this,SLOT(handleChangedSelections())); + setFocus(); } QgsAttributeTable::~QgsAttributeTable() { + } void QgsAttributeTable::columnClicked(int col) { QApplication::setOverrideCursor(Qt::waitCursor); sortColumn(col, true, true); + clearSelection(true); + emit selectionRemoved(); + emit repaintRequested(); QApplication::restoreOverrideCursor(); } + +void QgsAttributeTable::keyPressEvent(QKeyEvent* ev) +{ + if(ev->key()==Qt::Key_Control||ev->key()==Qt::Key_Shift) + { + lockKeyPressed=true; + } +} + +void QgsAttributeTable::keyReleaseEvent(QKeyEvent* ev) +{ + if(ev->key()==Qt::Key_Control||ev->key()==Qt::Key_Shift) + { + lockKeyPressed=false; + } +} + +void QgsAttributeTable::handleChangedSelections() +{ + QTableSelection cselection; + if(lockKeyPressed==false) + { + //clear the list and evaluate the last selection + emit selectionRemoved(); + } + + //if there is no current selection, there is nothing to do + if(currentSelection()==-1) + { + emit repaintRequested(); + return; + } + + cselection=selection(currentSelection()); + + for(int index=cselection.topRow();index<=cselection.bottomRow();index++) + { + emit selected(text(index,0).toInt()); + } + emit repaintRequested(); +} + + + diff --git a/src/qgsattributetable.h b/src/qgsattributetable.h index e7f4bc38a1b..73263070de9 100644 --- a/src/qgsattributetable.h +++ b/src/qgsattributetable.h @@ -27,10 +27,28 @@ class QgsAttributeTable:public QTable { - Q_OBJECT public: - QgsAttributeTable(QWidget * parent = 0, const char *name = 0); - ~QgsAttributeTable(); - public slots:void columnClicked(int col); + Q_OBJECT + + public: + QgsAttributeTable(QWidget * parent = 0, const char *name = 0); + ~QgsAttributeTable(); + + public slots: + void columnClicked(int col); + protected slots: + void handleChangedSelections(); + protected: + /**Flag telling if the ctrl-button or the shift-button is pressed*/ + bool lockKeyPressed; + void keyPressEvent(QKeyEvent* ev); + void keyReleaseEvent(QKeyEvent* ev); + signals: + /**Is emitted when a row was selected*/ + void selected(int); + /**Is emitted when all rows have been deselected*/ + void selectionRemoved(); + /**Is emmited when a set of related selection and deselection signals have been emitted*/ + void repaintRequested(); }; #endif diff --git a/src/qgsattributetabledisplay.cpp b/src/qgsattributetabledisplay.cpp index 023f5d84d87..b7802585f2b 100644 --- a/src/qgsattributetabledisplay.cpp +++ b/src/qgsattributetabledisplay.cpp @@ -18,7 +18,7 @@ #include "qgsattributetabledisplay.h" -QgsAttributeTableDisplay::QgsAttributeTableDisplay(){ +QgsAttributeTableDisplay::QgsAttributeTableDisplay() : QgsAttributeTableBase() { } QgsAttributeTableDisplay::~QgsAttributeTableDisplay(){ } diff --git a/src/qgsattributetabledisplay.h b/src/qgsattributetabledisplay.h index a3eee5d4bea..bc472ad8623 100644 --- a/src/qgsattributetabledisplay.h +++ b/src/qgsattributetabledisplay.h @@ -32,6 +32,9 @@ class QgsAttributeTableDisplay:public QgsAttributeTableBase ~QgsAttributeTableDisplay(); QgsAttributeTable *table(); void setTitle(QString title); + signals: + /**Is emitted before the widget deletes itself*/ + void deleted(); }; #endif diff --git a/src/qgsmapcanvas.cpp b/src/qgsmapcanvas.cpp index aa46bf1de51..79a6c9ed80f 100644 --- a/src/qgsmapcanvas.cpp +++ b/src/qgsmapcanvas.cpp @@ -139,6 +139,12 @@ QgsMapLayer *QgsMapCanvas::layerByName(QString name) } +void QgsMapCanvas::refresh() +{ + dirty=true; + render2(); +} + void QgsMapCanvas::render2() { QString msg = frozen ? "frozen" : "thawed"; diff --git a/src/qgsmapcanvas.h b/src/qgsmapcanvas.h index 7be846d3314..29bf868b6fc 100644 --- a/src/qgsmapcanvas.h +++ b/src/qgsmapcanvas.h @@ -80,6 +80,8 @@ public: void setDirty(bool _dirty); friend class QgsLegend; public slots: + /**Sets dirty=true and calls render2()*/ + void refresh(); void render2(); //! This slot is connected to the visibility change of one or more layers void layerStateChange(); diff --git a/src/qgsshapefilelayer.cpp b/src/qgsshapefilelayer.cpp index 147b4f83f54..083023efd99 100644 --- a/src/qgsshapefilelayer.cpp +++ b/src/qgsshapefilelayer.cpp @@ -29,7 +29,6 @@ #include "qgsshapefilelayer.h" #include "qgsidentifyresults.h" #include "qgsattributetable.h" -#include "qgsattributetabledisplay.h" #include #include @@ -38,7 +37,7 @@ QgsShapeFileLayer::QgsShapeFileLayer(QString vectorLayerPath, QString baseName) { // test ogr access to a shapefile - + ogrDataSource = OGRSFDriverRegistrar::Open((const char *) dataSource); if (ogrDataSource != NULL) { //std::cout << "Adding " << dataSource << std::endl; @@ -67,11 +66,32 @@ QgsShapeFileLayer::QgsShapeFileLayer(QString vectorLayerPath, QString baseName) valid = false; } + //create a boolean vector and set every entry to false + + if(valid) + { + selected=new QValueVector(ogrLayer->GetFeatureCount(),false); + } + else + { + selected=0; + } + tabledisplay=0; + //draw the selected features in yellow + selectionColor.setRgb(255,255,0); } QgsShapeFileLayer::~QgsShapeFileLayer() { //delete ogrDataSource; + if(selected) + { + delete selected; + } + if(tabledisplay) + { + tabledisplay->close(); + } } /** No descriptions */ @@ -111,6 +131,7 @@ void QgsShapeFileLayer::draw(QPainter * p, QgsRect * viewExtent, QgsCoordinateTr OGRErr result = ((OGRPolygon *) filter)->importFromWkt(&wktText); if (result == OGRERR_NONE) { + ogrLayer->SetSpatialFilter(filter); int featureCount = 0; while (OGRFeature * fet = ogrLayer->GetNextFeature()) { @@ -119,6 +140,20 @@ void QgsShapeFileLayer::draw(QPainter * p, QgsRect * viewExtent, QgsCoordinateTr } //std::cout << "reading feautures\n"; //fet->DumpReadable(stdout); + + + //if feature is selected, change the color of the painter + if((*selected)[fet->GetFID()]==true) + { + p->setPen(selectionColor); + brush->setColor(selectionColor); + } + else + { + p->setPen(sym->color()); + brush->setColor(sym->fillColor()); + } + OGRGeometry *geom = fet->GetGeometryRef(); if(!geom){ std::cout << "geom pointer is null" << std::endl; @@ -166,7 +201,6 @@ QString val; //std::cout << "marker draw complete\n"; break; case WKBLineString: - // get number of points in the line ptr = feature + 5; nPoints = (int *) ptr; @@ -182,7 +216,6 @@ QString val; p->moveTo(pt.xToInt(), pt.yToInt()); else p->lineTo(pt.xToInt(), pt.yToInt()); - } break; case WKBMultiLineString: @@ -347,33 +380,44 @@ void QgsShapeFileLayer::identify(QgsRect * r) } void QgsShapeFileLayer::table() { + if(tabledisplay) + { + tabledisplay->raise(); + } + else + { // display the attribute table QApplication::setOverrideCursor(Qt::waitCursor); ogrLayer->SetSpatialFilter(0); OGRFeature *fet = ogrLayer->GetNextFeature(); int numFields = fet->GetFieldCount(); - QgsAttributeTableDisplay *at = new QgsAttributeTableDisplay(); - at->table()->setNumRows(ogrLayer->GetFeatureCount(true)); - at->table()->setNumCols(numFields); + tabledisplay = new QgsAttributeTableDisplay(); + QObject:connect(tabledisplay,SIGNAL(deleted()),this,SLOT(invalidateTableDisplay())); + tabledisplay->table()->setNumRows(ogrLayer->GetFeatureCount(true)); + tabledisplay->table()->setNumCols(numFields+1);//+1 for the id-column int row = 0; // set up the column headers - QHeader *colHeader = at->table()->horizontalHeader(); - for (int h = 0; h < numFields; h++) { - OGRFieldDefn *fldDef = fet->GetFieldDefnRef(h); + QHeader *colHeader = tabledisplay->table()->horizontalHeader(); + colHeader->setLabel(0,"id");//label for the id-column + for (int h = 1; h < numFields+1; h++) { + OGRFieldDefn *fldDef = fet->GetFieldDefnRef(h-1); QString fld = fldDef->GetNameRef(); colHeader->setLabel(h, fld); } while (fet) { - for (int i = 0; i < numFields; i++) { + + //id-field + tabledisplay->table()->setText(row,0,QString::number(fet->GetFID())); + for (int i = 1; i < numFields+1; i++) { // get the field values QString val; //if(fldType == 16604 ) // geometry val = "(geometry column)"; // else - val = fet->GetFieldAsString(i); - - at->table()->setText(row, i, val); + val = fet->GetFieldAsString(i-1); + + tabledisplay->table()->setText(row, i, val); } row++; @@ -381,14 +425,40 @@ void QgsShapeFileLayer::table() fet = ogrLayer->GetNextFeature(); } - // reset the pointer to start of features so + // reset the pointer to start of fetabledisplayures so // subsequent reads will not fail ogrLayer->ResetReading(); - at->table()->setSorting(true); + tabledisplay->table()->setSorting(true); - at->setTitle("Attribute table - " + name()); + tabledisplay->setTitle("Tabledisplaytribute table - " + name()); QApplication::restoreOverrideCursor(); - at->show(); - + QObject::connect(tabledisplay->table(),SIGNAL(selected(int)),this,SLOT(select(int))); + QObject::connect(tabledisplay->table(),SIGNAL(selectionRemoved()),this,SLOT(removeSelection())); + QObject::connect(tabledisplay->table(),SIGNAL(repaintRequested()),this,SLOT(triggerRepaint())); + tabledisplay->show(); + } +} + +void QgsShapeFileLayer::select(int number) +{ + (*selected)[number]=true; +} + +void QgsShapeFileLayer::removeSelection() +{ + for(int i=0;i<(int)selected->size();i++) + { + (*selected)[i]=false; + } +} + +void QgsShapeFileLayer::triggerRepaint() +{ + emit repaintRequested(); +} + +void QgsShapeFileLayer::invalidateTableDisplay() +{ + tabledisplay=0; } diff --git a/src/qgsshapefilelayer.h b/src/qgsshapefilelayer.h index 0c1a4069bfa..b1586bbc0f6 100644 --- a/src/qgsshapefilelayer.h +++ b/src/qgsshapefilelayer.h @@ -24,6 +24,8 @@ class OGRLayer; class OGRDataSource; #include "qgsmaplayer.h" +#include "qvaluevector.h" +#include "qgsattributetabledisplay.h" /*! \class QgsShapeFileLayer * \brief Shapefile layer @@ -48,6 +50,21 @@ class QgsShapeFileLayer:public QgsMapLayer Polygon }; + public slots: + /**Sets the 'tabledisplay' to 0 again*/ + void invalidateTableDisplay(); + void select(int number); + void removeSelection(); + void triggerRepaint(); + + protected: + /**Pointer to the table display object if there is one, else a pointer to 0*/ + QgsAttributeTableDisplay* tabledisplay; + /**Vector holding the information which features are activated*/ + QValueVector* selected; + /**Color to draw and fill the selected features*/ + QColor selectionColor; + private: // Private attributes //! Draws the layer using coordinate transformation void draw(QPainter * p, QgsRect * viewExtent, QgsCoordinateTransform * cXf); @@ -75,6 +92,9 @@ class QgsShapeFileLayer:public QgsMapLayer void registerFormats(); int endian(); + signals: + void repaintRequested(); + }; #endif