mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
added a new sorting method (based on quicksort) which sorts numerically or alphanumerically. If the entry of the first row contains no letter, the sorting is numerical, otherwise alphanumerical. An extension to quicksort avoiding the worst case (an already sorted column) will be added soon.
git-svn-id: http://svn.osgeo.org/qgis/trunk@278 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
023c32195f
commit
78b59e91f2
@ -22,7 +22,7 @@
|
||||
#include "qgsattributetable.h"
|
||||
#include <iostream>
|
||||
|
||||
QgsAttributeTable::QgsAttributeTable(QWidget * parent, const char *name):QTable(parent, name), lockKeyPressed(false)
|
||||
QgsAttributeTable::QgsAttributeTable(QWidget * parent, const char *name):QTable(parent, name), lockKeyPressed(false), sort_ascending(true)
|
||||
{
|
||||
QFont f( font() );
|
||||
f.setFamily( "Helvetica" );
|
||||
@ -51,7 +51,7 @@ void QgsAttributeTable::columnClicked(int col)
|
||||
}
|
||||
}
|
||||
|
||||
sortColumn(col, true, true);
|
||||
sortColumn(col, sort_ascending, true);
|
||||
|
||||
//clear and rebuild rowIdMap. Overwrite sortColumn later and sort rowIdMap there
|
||||
rowIdMap.clear();
|
||||
@ -74,9 +74,83 @@ void QgsAttributeTable::columnClicked(int col)
|
||||
}
|
||||
QObject::connect(this,SIGNAL(selectionChanged()),this,SLOT(handleChangedSelections()));
|
||||
|
||||
//change the sorting order after each sort
|
||||
if(sort_ascending==true)
|
||||
{
|
||||
sort_ascending=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sort_ascending=true;
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
int QgsAttributeTable::compareItems(QString s1, QString s2, bool ascending, bool alphanumeric)
|
||||
{
|
||||
if(alphanumeric)
|
||||
{
|
||||
if(s1>s2)
|
||||
{
|
||||
if(ascending)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if(s1<s2)
|
||||
{
|
||||
if(ascending)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(s1==s2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else//numeric
|
||||
{
|
||||
double d1=s1.toDouble();
|
||||
double d2=s2.toDouble();
|
||||
if(d1>d2)
|
||||
{
|
||||
if(ascending)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if(d1<d2)
|
||||
{
|
||||
if(ascending)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(d1==d2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsAttributeTable::keyPressEvent(QKeyEvent* ev)
|
||||
{
|
||||
if(ev->key()==Qt::Key_Control||ev->key()==Qt::Key_Shift)
|
||||
@ -131,4 +205,53 @@ void QgsAttributeTable::selectRowWithId(int id)
|
||||
selectRow(it.data());
|
||||
}
|
||||
|
||||
|
||||
void QgsAttributeTable::sortColumn(int col, bool ascending, bool wholeRows)
|
||||
{
|
||||
//if the first entry contains a letter, sort alphanumerically, otherwise numerically
|
||||
QString firstentry=text(0,col);
|
||||
bool containsletter=false;
|
||||
for(uint i=0;i<firstentry.length();i++)
|
||||
{
|
||||
if(firstentry.ref(i).isLetter())
|
||||
{
|
||||
containsletter=true;
|
||||
}
|
||||
}
|
||||
|
||||
if(containsletter)
|
||||
{
|
||||
qsort(0,numRows()-1,col,ascending,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qsort(0,numRows()-1,col,ascending,false);
|
||||
}
|
||||
|
||||
repaintContents();
|
||||
}
|
||||
|
||||
void QgsAttributeTable::qsort(int lower, int upper, int col, bool ascending, bool alphanumeric)
|
||||
{
|
||||
//add the following modifications later: avoid worst case, call selection sort for short ranges
|
||||
int i,j;
|
||||
QString v;
|
||||
if(upper>lower)
|
||||
{
|
||||
v=text(upper,col);
|
||||
i=lower-1;
|
||||
j=upper;
|
||||
for(;;)
|
||||
{
|
||||
while(compareItems(text(++i,col),v,ascending,alphanumeric)==-1);
|
||||
while(compareItems(text(--j,col),v,ascending,alphanumeric)==1&&j>0);//make sure that j does not get negative
|
||||
if(i>=j)
|
||||
{
|
||||
break;
|
||||
}
|
||||
swapRows(i,j);
|
||||
}
|
||||
swapRows(i,upper);
|
||||
qsort(lower, i-1, col, ascending, alphanumeric);
|
||||
qsort(i+1, upper, col, ascending, alphanumeric);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ class QgsAttributeTable:public QTable
|
||||
void insertFeatureId(int id);
|
||||
/**Selects the row which belongs to the feature with the specified id*/
|
||||
void selectRowWithId(int id);
|
||||
/**Sorts a column. This method replaces the one from QTable to allow alphanumeric sorting*/
|
||||
virtual void sortColumn(int col, bool ascending=true, bool wholeRows=false);
|
||||
|
||||
public slots:
|
||||
void columnClicked(int col);
|
||||
@ -48,9 +50,15 @@ class QgsAttributeTable:public QTable
|
||||
bool lockKeyPressed;
|
||||
/**Search tree to find a row corresponding to a feature id*/
|
||||
QMap<int,int> rowIdMap;
|
||||
/**Flag indicating, which sorting order should be used*/
|
||||
bool sort_ascending;
|
||||
/**Compares the content of two cells either alphanumeric or numeric. If 'ascending' is true, -1 means s1 is less, 0 equal, 1 greater. If 'ascending' is false, -1 means s1 is more, 0 equal, 1 greater. This method is used mainly to sort a column*/
|
||||
int compareItems(QString s1, QString s2, bool ascending, bool alphanumeric);
|
||||
void keyPressEvent(QKeyEvent* ev);
|
||||
void keyReleaseEvent(QKeyEvent* ev);
|
||||
signals:
|
||||
/**Method used by sortColumn (implementation of a quicksort)*/
|
||||
void qsort(int lower, int upper, int col, bool ascending, bool alphanumeric);
|
||||
signals:
|
||||
/**Is emitted when a row was selected*/
|
||||
void selected(int);
|
||||
/**Is emitted when all rows have been deselected*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user