Added selection support to Table.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31096 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -82,3 +82,24 @@ AbstractTable::ResizeAllColumnsToPreferred()
|
|||||||
{
|
{
|
||||||
BColumnListView::ResizeAllColumnsToPreferred();
|
BColumnListView::ResizeAllColumnsToPreferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
list_view_type
|
||||||
|
AbstractTable::SelectionMode() const
|
||||||
|
{
|
||||||
|
return BColumnListView::SelectionMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractTable::SetSelectionMode(list_view_type type)
|
||||||
|
{
|
||||||
|
BColumnListView::SetSelectionMode(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AbstractTable::DeselectAll()
|
||||||
|
{
|
||||||
|
BColumnListView::DeselectAll();
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ public:
|
|||||||
void ResizeColumnToPreferred(int32 index);
|
void ResizeColumnToPreferred(int32 index);
|
||||||
void ResizeAllColumnsToPreferred();
|
void ResizeAllColumnsToPreferred();
|
||||||
|
|
||||||
|
list_view_type SelectionMode() const;
|
||||||
|
void SetSelectionMode(list_view_type type);
|
||||||
|
void DeselectAll();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class AbstractColumn;
|
class AbstractColumn;
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,83 @@ TableModel::NotifyRowsRemoved(int32 rowIndex, int32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - TableSelectionModel
|
||||||
|
|
||||||
|
TableSelectionModel::TableSelectionModel(Table* table)
|
||||||
|
:
|
||||||
|
fTable(table),
|
||||||
|
fRows(NULL),
|
||||||
|
fRowCount(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TableSelectionModel::~TableSelectionModel()
|
||||||
|
{
|
||||||
|
delete[] fRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TableSelectionModel::CountRows()
|
||||||
|
{
|
||||||
|
_Update();
|
||||||
|
|
||||||
|
return fRowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TableSelectionModel::RowAt(int32 index)
|
||||||
|
{
|
||||||
|
_Update();
|
||||||
|
|
||||||
|
return index >= 0 && index < fRowCount ? fRows[index] : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TableSelectionModel::_SelectionChanged()
|
||||||
|
{
|
||||||
|
if (fRowCount >= 0) {
|
||||||
|
fRowCount = -1;
|
||||||
|
delete[] fRows;
|
||||||
|
fRows = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TableSelectionModel::_Update()
|
||||||
|
{
|
||||||
|
if (fRowCount >= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// count the rows
|
||||||
|
fRowCount = 0;
|
||||||
|
BRow* row = NULL;
|
||||||
|
while ((row = fTable->CurrentSelection(row)) != NULL)
|
||||||
|
fRowCount++;
|
||||||
|
|
||||||
|
if (fRowCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// allocate row array
|
||||||
|
fRows = new(std::nothrow) int32[fRowCount];
|
||||||
|
if (fRows == NULL) {
|
||||||
|
fRowCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the rows
|
||||||
|
row = NULL;
|
||||||
|
int32 index = 0;
|
||||||
|
while ((row = fTable->CurrentSelection(row)) != NULL)
|
||||||
|
fRows[index++] = fTable->_ModelIndexOfRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - TableListener
|
// #pragma mark - TableListener
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +178,12 @@ TableListener::~TableListener()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TableListener::TableSelectionChanged(Table* table)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TableListener::TableRowInvoked(Table* table, int32 rowIndex)
|
TableListener::TableRowInvoked(Table* table, int32 rowIndex)
|
||||||
{
|
{
|
||||||
@@ -233,7 +316,9 @@ Table::Table(const char* name, uint32 flags, border_style borderStyle,
|
|||||||
bool showHorizontalScrollbar)
|
bool showHorizontalScrollbar)
|
||||||
:
|
:
|
||||||
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
|
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
|
||||||
fModel(NULL)
|
fModel(NULL),
|
||||||
|
fSelectionModel(this),
|
||||||
|
fIgnoreSelectionChange(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +327,9 @@ Table::Table(TableModel* model, const char* name, uint32 flags,
|
|||||||
border_style borderStyle, bool showHorizontalScrollbar)
|
border_style borderStyle, bool showHorizontalScrollbar)
|
||||||
:
|
:
|
||||||
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
|
AbstractTable(name, flags, borderStyle, showHorizontalScrollbar),
|
||||||
fModel(NULL)
|
fModel(NULL),
|
||||||
|
fSelectionModel(this),
|
||||||
|
fIgnoreSelectionChange(0)
|
||||||
{
|
{
|
||||||
SetTableModel(model);
|
SetTableModel(model);
|
||||||
}
|
}
|
||||||
@@ -287,6 +374,38 @@ Table::SetTableModel(TableModel* model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TableSelectionModel*
|
||||||
|
Table::SelectionModel()
|
||||||
|
{
|
||||||
|
return &fSelectionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Table::SelectRow(int32 rowIndex, bool extendSelection)
|
||||||
|
{
|
||||||
|
BRow* row = fRows.ItemAt(rowIndex);
|
||||||
|
if (row == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!extendSelection) {
|
||||||
|
fIgnoreSelectionChange++;
|
||||||
|
DeselectAll();
|
||||||
|
fIgnoreSelectionChange--;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddToSelection(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Table::DeselectRow(int32 rowIndex)
|
||||||
|
{
|
||||||
|
if (BRow* row = fRows.ItemAt(rowIndex))
|
||||||
|
Deselect(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Table::AddTableListener(TableListener* listener)
|
Table::AddTableListener(TableListener* listener)
|
||||||
{
|
{
|
||||||
@@ -301,6 +420,22 @@ Table::RemoveTableListener(TableListener* listener)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Table::SelectionChanged()
|
||||||
|
{
|
||||||
|
if (fIgnoreSelectionChange > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fSelectionModel._SelectionChanged();
|
||||||
|
|
||||||
|
if (!fListeners.IsEmpty()) {
|
||||||
|
int32 listenerCount = fListeners.CountItems();
|
||||||
|
for (int32 i = listenerCount - 1; i >= 0; i--)
|
||||||
|
fListeners.ItemAt(i)->TableSelectionChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AbstractTable::AbstractColumn*
|
AbstractTable::AbstractColumn*
|
||||||
Table::CreateColumn(TableColumn* column)
|
Table::CreateColumn(TableColumn* column)
|
||||||
{
|
{
|
||||||
@@ -367,15 +502,25 @@ Table::ItemInvoked()
|
|||||||
if (fListeners.IsEmpty())
|
if (fListeners.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BRow* row = CurrentSelection();
|
int32 index = _ModelIndexOfRow(CurrentSelection());
|
||||||
if (row == NULL)
|
if (index < 0)
|
||||||
return;
|
|
||||||
|
|
||||||
TableField* field = dynamic_cast<TableField*>(row->GetField(0));
|
|
||||||
if (field == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32 listenerCount = fListeners.CountItems();
|
int32 listenerCount = fListeners.CountItems();
|
||||||
for (int32 i = listenerCount - 1; i >= 0; i--)
|
for (int32 i = listenerCount - 1; i >= 0; i--)
|
||||||
fListeners.ItemAt(i)->TableRowInvoked(this, field->RowIndex());
|
fListeners.ItemAt(i)->TableRowInvoked(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Table::_ModelIndexOfRow(BRow* row)
|
||||||
|
{
|
||||||
|
if (row == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
TableField* field = dynamic_cast<TableField*>(row->GetField(0));
|
||||||
|
if (field == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return field->RowIndex();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,10 +55,33 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TableSelectionModel {
|
||||||
|
public:
|
||||||
|
TableSelectionModel(Table* table);
|
||||||
|
~TableSelectionModel();
|
||||||
|
|
||||||
|
int32 CountRows();
|
||||||
|
int32 RowAt(int32 index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Table;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _SelectionChanged();
|
||||||
|
void _Update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Table* fTable;
|
||||||
|
int32* fRows;
|
||||||
|
int32 fRowCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TableListener {
|
class TableListener {
|
||||||
public:
|
public:
|
||||||
virtual ~TableListener();
|
virtual ~TableListener();
|
||||||
|
|
||||||
|
virtual void TableSelectionChanged(Table* table);
|
||||||
virtual void TableRowInvoked(Table* table, int32 rowIndex);
|
virtual void TableRowInvoked(Table* table, int32 rowIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,10 +100,17 @@ public:
|
|||||||
void SetTableModel(TableModel* model);
|
void SetTableModel(TableModel* model);
|
||||||
TableModel* GetTableModel() const { return fModel; }
|
TableModel* GetTableModel() const { return fModel; }
|
||||||
|
|
||||||
|
TableSelectionModel* SelectionModel();
|
||||||
|
|
||||||
|
void SelectRow(int32 rowIndex, bool extendSelection);
|
||||||
|
void DeselectRow(int32 rowIndex);
|
||||||
|
|
||||||
bool AddTableListener(TableListener* listener);
|
bool AddTableListener(TableListener* listener);
|
||||||
void RemoveTableListener(TableListener* listener);
|
void RemoveTableListener(TableListener* listener);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void SelectionChanged();
|
||||||
|
|
||||||
virtual AbstractColumn* CreateColumn(TableColumn* column);
|
virtual AbstractColumn* CreateColumn(TableColumn* column);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -92,16 +122,22 @@ private:
|
|||||||
private:
|
private:
|
||||||
class Column;
|
class Column;
|
||||||
|
|
||||||
|
friend class TableSelectionModel;
|
||||||
|
|
||||||
typedef BObjectList<TableListener> ListenerList;
|
typedef BObjectList<TableListener> ListenerList;
|
||||||
typedef BObjectList<BRow> RowList;
|
typedef BObjectList<BRow> RowList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void ItemInvoked();
|
virtual void ItemInvoked();
|
||||||
|
|
||||||
|
int32 _ModelIndexOfRow(BRow* row);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TableModel* fModel;
|
TableModel* fModel;
|
||||||
RowList fRows;
|
RowList fRows;
|
||||||
|
TableSelectionModel fSelectionModel;
|
||||||
ListenerList fListeners;
|
ListenerList fListeners;
|
||||||
|
int32 fIgnoreSelectionChange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user