* Renamed AbstractTableModel to AbstractTableModelBase.

* Added listener support to TableModel.
* Table does now listen to the model and adds/removes rows accordingly.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31080 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-06-17 13:31:33 +00:00
parent e5c5e337e4
commit 8c2d467ed7
6 changed files with 165 additions and 41 deletions

View File

@ -10,10 +10,10 @@
#include "table/TableColumn.h"
// #pragma mark - AbstractTableModel
// #pragma mark - AbstractTableModelBase
AbstractTableModel::~AbstractTableModel()
AbstractTableModelBase::~AbstractTableModelBase()
{
}

View File

@ -12,9 +12,9 @@
class TableColumn;
class AbstractTableModel {
class AbstractTableModelBase {
public:
virtual ~AbstractTableModel();
virtual ~AbstractTableModelBase();
virtual int32 CountColumns() const = 0;
};
@ -53,7 +53,7 @@ public:
AbstractColumn(TableColumn* tableColumn);
virtual ~AbstractColumn();
virtual void SetModel(AbstractTableModel* model) = 0;
virtual void SetModel(AbstractTableModelBase* model) = 0;
TableColumn* GetTableColumn() const { return fTableColumn; }

View File

@ -29,6 +29,28 @@ private:
};
// #pragma mark - TableModelListener
TableModelListener::~TableModelListener()
{
}
void
TableModelListener::TableRowsAdded(TableModel* model, int32 rowIndex,
int32 count)
{
}
void
TableModelListener::TableRowsRemoved(TableModel* model, int32 rowIndex,
int32 count)
{
}
// #pragma mark - TableModel
@ -37,6 +59,40 @@ TableModel::~TableModel()
}
void
TableModel::AddListener(TableModelListener* listener)
{
fListeners.Add(listener);
}
void
TableModel::RemoveListener(TableModelListener* listener)
{
fListeners.Remove(listener);
}
void
TableModel::NotifyRowsAdded(int32 rowIndex, int32 count)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
TableModelListener* listener = it.Next();) {
listener->TableRowsAdded(this, rowIndex, count);
}
}
void
TableModel::NotifyRowsRemoved(int32 rowIndex, int32 count)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
TableModelListener* listener = it.Next();) {
listener->TableRowsRemoved(this, rowIndex, count);
}
}
// #pragma mark - TableListener
@ -60,7 +116,7 @@ public:
TableColumn* tableColumn);
virtual ~Column();
virtual void SetModel(AbstractTableModel* model);
virtual void SetModel(AbstractTableModelBase* model);
protected:
virtual void DrawTitle(BRect rect, BView* targetView);
@ -91,7 +147,7 @@ Table::Column::~Column()
void
Table::Column::SetModel(AbstractTableModel* model)
Table::Column::SetModel(AbstractTableModelBase* model)
{
fModel = dynamic_cast<TableModel*>(model);
}
@ -196,6 +252,8 @@ Table::~Table()
{
for (int32 i = CountColumns() - 1; i >= 0; i--)
RemoveColumn(ColumnAt(i));
// rows are deleted by the BColumnListView destructor automatically
}
@ -206,6 +264,9 @@ Table::SetTableModel(TableModel* model)
return;
if (fModel != NULL) {
fModel->RemoveListener(this);
fRows.MakeEmpty();
Clear();
for (int32 i = 0; AbstractColumn* column = fColumns.ItemAt(i); i++)
@ -217,38 +278,12 @@ Table::SetTableModel(TableModel* model)
if (fModel == NULL)
return;
fModel->AddListener(this);
for (int32 i = 0; AbstractColumn* column = fColumns.ItemAt(i); i++)
column->SetModel(fModel);
// create the rows
int32 rowCount = fModel->CountRows();
int32 columnCount = fModel->CountColumns();
for (int32 i = 0; i < rowCount; i++) {
// create row
BRow* row = new(std::nothrow) BRow();
if (row == NULL) {
// TODO: Report error!
return;
}
// add dummy fields to row
for (int32 columnIndex = 0; columnIndex < columnCount; columnIndex++) {
// It would be nice to create only a single field and set it for all
// columns, but the row takes ultimate ownership, so it have to be
// individual objects.
TableField* field = new(std::nothrow) TableField(i);
if (field == NULL) {
// TODO: Report error!
return;
}
row->SetField(field, columnIndex);
}
// add row
AddRow(row);
}
TableRowsAdded(fModel, 0, fModel->CountRows());
}
@ -273,6 +308,59 @@ Table::CreateColumn(TableColumn* column)
}
void
Table::TableRowsAdded(TableModel* model, int32 rowIndex, int32 count)
{
// create the rows
int32 endRow = rowIndex + count;
int32 columnCount = fModel->CountColumns();
for (int32 i = rowIndex; i < endRow; i++) {
// create row
BRow* row = new(std::nothrow) BRow();
if (row == NULL) {
// TODO: Report error!
return;
}
// add dummy fields to row
for (int32 columnIndex = 0; columnIndex < columnCount; columnIndex++) {
// It would be nice to create only a single field and set it for all
// columns, but the row takes ultimate ownership, so it have to be
// individual objects.
TableField* field = new(std::nothrow) TableField(i);
if (field == NULL) {
// TODO: Report error!
return;
}
row->SetField(field, columnIndex);
}
// add row
if (!fRows.AddItem(row, i)) {
// TODO: Report error!
delete row;
return;
}
AddRow(row, i);
}
}
void
Table::TableRowsRemoved(TableModel* model, int32 rowIndex, int32 count)
{
for (int32 i = rowIndex + count - 1; i >= rowIndex; i--) {
if (BRow* row = fRows.RemoveItemAt(i)) {
RemoveRow(row);
delete row;
}
}
}
void
Table::ItemInvoked()
{

View File

@ -7,6 +7,9 @@
#include <ColumnTypes.h>
#include <ObjectList.h>
#include <util/DoublyLinkedList.h>
#include "table/AbstractTable.h"
#include "table/TableColumn.h"
@ -14,9 +17,21 @@
class Table;
class TableModel;
class TableModel : public AbstractTableModel {
class TableModelListener : public DoublyLinkedListLinkImpl<TableModelListener> {
public:
virtual ~TableModelListener();
virtual void TableRowsAdded(TableModel* model,
int32 rowIndex, int32 count);
virtual void TableRowsRemoved(TableModel* model,
int32 rowIndex, int32 count);
};
class TableModel : public AbstractTableModelBase {
public:
virtual ~TableModel();
@ -24,6 +39,19 @@ public:
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex,
Variant& value) = 0;
virtual void AddListener(TableModelListener* listener);
virtual void RemoveListener(TableModelListener* listener);
protected:
typedef DoublyLinkedList<TableModelListener> ListenerList;
protected:
void NotifyRowsAdded(int32 rowIndex, int32 count);
void NotifyRowsRemoved(int32 rowIndex, int32 count);
protected:
ListenerList fListeners;
};
@ -35,7 +63,7 @@ public:
};
class Table : public AbstractTable {
class Table : public AbstractTable, private TableModelListener {
public:
Table(const char* name, uint32 flags,
border_style borderStyle = B_NO_BORDER,
@ -55,16 +83,24 @@ public:
protected:
virtual AbstractColumn* CreateColumn(TableColumn* column);
private:
virtual void TableRowsAdded(TableModel* model,
int32 rowIndex, int32 count);
virtual void TableRowsRemoved(TableModel* model,
int32 rowIndex, int32 count);
private:
class Column;
typedef BObjectList<TableListener> ListenerList;
typedef BObjectList<BRow> RowList;
private:
virtual void ItemInvoked();
private:
TableModel* fModel;
RowList fRows;
ListenerList fListeners;
};

View File

@ -60,7 +60,7 @@ public:
TableColumn* tableColumn);
virtual ~Column();
virtual void SetModel(AbstractTableModel* model);
virtual void SetModel(AbstractTableModelBase* model);
protected:
virtual void DrawTitle(BRect rect, BView* targetView);
@ -91,7 +91,7 @@ TreeTable::Column::~Column()
void
TreeTable::Column::SetModel(AbstractTableModel* model)
TreeTable::Column::SetModel(AbstractTableModelBase* model)
{
fModel = dynamic_cast<TreeTableModel*>(model);
}

View File

@ -16,7 +16,7 @@
class TreeTable;
class TreeTableModel : public AbstractTableModel {
class TreeTableModel : public AbstractTableModelBase {
public:
virtual ~TreeTableModel();