Skip to content

Commit

Permalink
Added sorting on multiple columns
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbowman committed Oct 28, 2002
1 parent 0406c23 commit d2c5a6b
Show file tree
Hide file tree
Showing 16 changed files with 728 additions and 53 deletions.
6 changes: 6 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2002-10-28 #################### PortaBase 1.1 ####################

2002-10-28 JMB Multiple column sorting

Added support for sorting on multiple columns.

2002-10-26 JMB Note column type, minor bugfixes

Added support for "Note" columns (a.k.a. multi-line text fields).
Expand Down
25 changes: 19 additions & 6 deletions README
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
PortaBase 1.0 (October 2002)
PortaBase 1.1 (October 2002)
----------------------------
PortaBase (portable database) is a personal database application written for
the Linux-based models of Sharp Zaurus PDA (and should work on any other Linux
PDA using the Qtopia environment.)

The main features PortaBase currently has are:
- One data table per file
- String, Integer, Decimal, and Boolean column types
- String, Integer, Decimal, Boolean, and Note (multi-line text) column types
- Add, edit, and delete rows of data
- Custom data views (subsets of the columns in any order)
- Sort the rows by any column in ascending or descending order
- Sort the rows by any combination of columns, each in ascending or descending
order
- Page navigation buttons, with a custom number of rows per page
- Add, delete, rearrange, and rename columns at any time
- Specify default values for columns
- View summary statistics for columns (total, average, min, max, etc.)
- Import data from CSV files
- Export data to CSV files

See the help file (help/portabase.html) for more information on features and
usage. This help file is also the online help for the application, available
by clicking the "?" button at the top right of any screen in PortaBase.
See the help file (help/html/portabase.html) for more information on features
and usage. This help file is also the online help for the application,
available by clicking the "?" button at the top right of any screen in
PortaBase.

Installation
------------
Note that there are *two* packages that must be installed in order to run
PortaBase; since many people didn't realize this for version 1.0, they are
now only distributed together in a zip file along with this README file. First
install the libmetakit1 .ipk file onto the Zaurus, then install the
portabase .ipk file. (The MetaKit library is packaged separately because
it is likely to be used by other applications in the near future.) Once
both packages have been installed, PortaBase can be launched from the
Applications tab and the two .ipk files may be safely deleted.

Technical Info
--------------
Expand Down
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Multiple column sorting
Filtering/Searching
Date column type
Date and time column type
Expand Down
186 changes: 158 additions & 28 deletions database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,35 @@
#include "portabase.h"
#include "view.h"

Database::Database(QString path, bool *ok) : curView(0), Id("_id"), cIndex("_cindex"), cName("_cname"), cType("_ctype"), cDefault("_cdefault"), vName("_vname"), vRpp("_vrpp"), vcView("_vcview"), vcIndex("_vcindex"), vcName("_vcname"), vcWidth("_vcwidth"), vcSortIndex("_vcsortindex"), vcAscending("_vcascending"), vcFilter("_vcfilter"), gVersion("_gversion"), gView("_gview")
Database::Database(QString path, bool *ok) : curView(0), Id("_id"), cIndex("_cindex"), cName("_cname"), cType("_ctype"), cDefault("_cdefault"), vName("_vname"), vRpp("_vrpp"), vcView("_vcview"), vcIndex("_vcindex"), vcName("_vcname"), vcWidth("_vcwidth"), sName("_sname"), scSort("_scsort"), scIndex("_scindex"), scName("_scname"), scDesc("_scdesc"), gVersion("_gversion"), gView("_gview"), gSort("_gsort")
{
checkedPixmap = Resource::loadPixmap("portabase/checked");
uncheckedPixmap = Resource::loadPixmap("portabase/unchecked");

file = new c4_Storage(path, TRUE);
global = file->GetAs("_global[_gversion:I,_gview:S]");
global = file->GetAs("_global[_gversion:I,_gview:S,_gsort:S]");
if (global.GetSize() == 0) {
global.Add(gVersion [FILE_VERSION] + gView ["_all"]);
global.Add(gVersion [FILE_VERSION] + gView ["_all"] + gSort [""]);
*ok = TRUE;
}
else if (gVersion (global[0]) > FILE_VERSION) {
*ok = FALSE;
}
else if (gVersion (global[0]) == 1) {
// sorting name added in file version 2
gSort (global[0]) = "";
gVersion (global[0]) = FILE_VERSION;
*ok = TRUE;
}
else {
*ok = TRUE;
}
if (*ok) {
columns = file->GetAs("_columns[_cindex:I,_cname:S,_ctype:I,_cdefault:S]");
views = file->GetAs("_views[_vname:S,_vrpp:I]");
viewColumns = file->GetAs("_viewcolumns[_vcview:S,_vcindex:I,_vcname:S,_vcwidth:I,_vcsortindex:I,_vcascending:I,_vcfilter:S]");
viewColumns = file->GetAs("_viewcolumns[_vcview:S,_vcindex:I,_vcname:S,_vcwidth:I]");
sorts = file->GetAs("_sorts[_sname:S]");
sortColumns = file->GetAs("_sortcolumns[_scsort:S,_scindex:I,_scname:S,_scdesc:I]");
data = file->GetAs(formatString());
maxId = data.GetSize() - 1;
*ok = TRUE;
Expand Down Expand Up @@ -110,9 +118,6 @@ void Database::addView(QString name, QStringList names)
vcIndex (colRow) = i;
vcName (colRow) = names[i];
vcWidth (colRow) = 60;
vcSortIndex (colRow) = 0;
vcAscending (colRow) = 0;
vcFilter (colRow) = "";
viewColumns.Add(colRow);
}
}
Expand Down Expand Up @@ -283,6 +288,12 @@ void Database::deleteColumn(QString name)
QString viewName(vName (views[i]));
deleteViewColumn(viewName, name);
}
// remove the column from any sortings containing it
count = sorts.GetSize();
for (int i = 0; i < count; i++) {
QString sortName(sName (sorts[i]));
deleteSortingColumn(sortName, name);
}
// remove the column from the definition
columns.RemoveAt(index);
}
Expand All @@ -295,6 +306,12 @@ void Database::renameColumn(QString oldName, QString newName)
vcName (viewColumns[nextIndex]) = newName;
nextIndex = viewColumns.Find(vcName [oldName]);
}
// rename the column in any sortings containing it
nextIndex = sortColumns.Find(scName [oldName]);
while (nextIndex != -1) {
scName (sortColumns[nextIndex]) = newName;
nextIndex = sortColumns.Find(scName [oldName]);
}
// rename the column in the format definition
int index = columns.Find(cName [oldName]);
cName (columns[index]) = newName;
Expand Down Expand Up @@ -358,36 +375,152 @@ QStringList Database::getRow(int rowId)
return results;
}

c4_View Database::sortData(QString column, bool ascending)
QString Database::currentSorting()
{
int type = getType(column);
if (type == INTEGER || type == BOOLEAN) {
c4_IntProp prop(column);
if (ascending) {
return data.SortOn(prop);
}
else {
return data.SortOnReverse(prop, prop);
QString sortName(gSort (global[0]));
return sortName;
}

QStringList Database::listSortings()
{
c4_View sorted = sorts.SortOn(sName);
int size = sorted.GetSize();
QStringList list;
for (int i = 0; i < size; i++) {
QString name(sName (sorted[i]));
list.append(name);
}
return list;
}

bool Database::getSortingInfo(QString sortingName, QStringList *allCols,
QStringList *descCols)
{
c4_View temp = sortColumns.Select(scSort [sortingName]);
int count = temp.GetSize();
if (count == 0) {
// non-existent or empty sorting; nothing to do
return FALSE;
}
temp = temp.SortOn(scIndex);
for (int i = 0; i < count; i++) {
QString name(scName (temp[i]));
allCols->append(name);
if (scDesc (temp[i]) == 1) {
descCols->append(name);
}
}
else if (type == FLOAT) {
c4_FloatProp prop(column);
if (ascending) {
return data.SortOn(prop);
return TRUE;
}

void Database::addSorting(QString name, QStringList allCols,
QStringList descCols)
{
sorts.Add(sName [name]);
int count = allCols.count();
for (int i = 0; i < count; i++) {
c4_Row colRow;
scSort (colRow) = name;
scIndex (colRow) = i;
scName (colRow) = allCols[i];
if (descCols.findIndex(allCols[i]) == -1) {
scDesc (colRow) = 0;
}
else {
return data.SortOnReverse(prop, prop);
scDesc (colRow) = 1;
}
sortColumns.Add(colRow);
}
}

void Database::deleteSorting(QString name)
{
int index = sorts.Find(sName [name]);
if (index == -1) {
return;
}
sorts.RemoveAt(index);
// delete the sorting's columns
int nextIndex = sortColumns.Find(scSort [name]);
while (nextIndex != -1) {
sortColumns.RemoveAt(nextIndex);
nextIndex = sortColumns.Find(scSort [name]);
}
}

void Database::deleteSortingColumn(QString sortName, QString columnName)
{
int removeIndex = sortColumns.Find(scSort [sortName]
+ scName [columnName]);
if (removeIndex == -1) {
// no such column in this sorting
return;
}
int position = scIndex (sortColumns[removeIndex]);
position++;
int nextIndex = sortColumns.Find(scSort [sortName] + scIndex [position]);
while (nextIndex != -1) {
scIndex (sortColumns[nextIndex]) = position - 1;
position++;
nextIndex = sortColumns.Find(scSort [sortName] + scIndex [position]);
}
sortColumns.RemoveAt(removeIndex);
}

c4_View Database::sortData(QString column, bool ascending)
{
QStringList colNames;
colNames.append(column);
QStringList descNames;
if (!ascending) {
descNames.append(column);
}
deleteSorting("_single");
addSorting("_single", colNames, descNames);
gSort (global[0]) = "_single";
c4_View sortView = createEmptyView(colNames);
if (ascending) {
return data.SortOn(sortView);
}
else {
c4_StringProp prop(column);
if (ascending) {
return data.SortOn(prop);
return data.SortOnReverse(sortView, sortView);
}
}

c4_View Database::sortData(QString sortingName)
{
gSort (global[0]) = sortingName;
QStringList allCols;
QStringList descCols;
if (!getSortingInfo(sortingName, &allCols, &descCols)) {
return data;
}
c4_View allView = createEmptyView(allCols);
c4_View descView = createEmptyView(descCols);
return data.SortOnReverse(allView, descView);
}

c4_View Database::createEmptyView(QStringList colNames)
{
int count = colNames.count();
c4_View result;
for (int i = 0; i < count; i++) {
QString name = colNames[i];
int type = getType(name);
if (type == INTEGER || type == BOOLEAN) {
c4_IntProp prop(name);
result.AddProperty(prop);
}
else if (type == FLOAT) {
c4_FloatProp prop(name);
result.AddProperty(prop);
}
else {
return data.SortOnReverse(prop, prop);
c4_StringProp prop(name);
result.AddProperty(prop);
}
}
return result;
}

QString Database::addRow(QStringList values)
Expand Down Expand Up @@ -487,9 +620,6 @@ void Database::addViewColumn(QString viewName, QString columnName)
vcIndex (colRow) = cols.GetSize();
vcName (colRow) = columnName;
vcWidth (colRow) = 60;
vcSortIndex (colRow) = 0;
vcAscending (colRow) = 0;
vcFilter (colRow) = "";
viewColumns.Add(colRow);
}

Expand Down
26 changes: 23 additions & 3 deletions database.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ class Database
public:
Database(QString path, bool *ok);
~Database();

QString currentView();
View *getView(QString name);
QStringList listViews();
void addView(QString name, QStringList names);
void deleteView(QString name);
void setViewColWidths(int *widths);
void setViewRowsPerPage(int rpp);

QStringList listColumns();
int getIndex(QString column);
void setIndex(QString column, int index);
Expand All @@ -51,7 +53,17 @@ class Database
void setViewColumnSequence(QString viewName, QStringList colNames);
void updateDataFormat();
QStringList getRow(int rowId);

QString currentSorting();
QStringList listSortings();
bool getSortingInfo(QString sortingName, QStringList *allCols,
QStringList *descCols);
void addSorting(QString name, QStringList allCols, QStringList descCols);
void deleteSorting(QString name);
void deleteSortingColumn(QString sortName, QString columnName);
c4_View sortData(QString column, bool ascending);
c4_View sortData(QString sortingName);

QString addRow(QStringList values);
void updateRow(int rowId, QStringList values);
void deleteRow(int id);
Expand All @@ -62,6 +74,7 @@ class Database

private:
int *listTypes();
c4_View createEmptyView(QStringList colNames);
QString formatString();

private:
Expand All @@ -71,6 +84,8 @@ class Database
c4_View columns;
c4_View views;
c4_View viewColumns;
c4_View sorts;
c4_View sortColumns;
c4_View global;
c4_View data;
View *curView;
Expand All @@ -89,12 +104,17 @@ class Database
c4_IntProp vcIndex;
c4_StringProp vcName;
c4_IntProp vcWidth;
c4_IntProp vcSortIndex;
c4_IntProp vcAscending;
c4_StringProp vcFilter;
// "_sorts" view
c4_StringProp sName;
// "_sortcolumns" view
c4_StringProp scSort;
c4_IntProp scIndex;
c4_StringProp scName;
c4_IntProp scDesc;
// "_global" view
c4_IntProp gVersion;
c4_StringProp gView;
c4_StringProp gSort;
};

#endif
Loading

0 comments on commit d2c5a6b

Please sign in to comment.