Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tgrid.h"
Toshihiro Shimizu 890ddd
#include "tw/colors.h"
Toshihiro Shimizu 890ddd
#include "tw/event.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TwConsts;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TGridColumn::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  vector<tgridcell> m_cells;</tgridcell>
Shinya Kitaoka 120a6e
  string m_name;
Shinya Kitaoka 120a6e
  TGridColumn::Alignment m_alignment;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Imp(const string &name, Alignment alignment)
Shinya Kitaoka 120a6e
      : m_name(name), m_alignment(alignment) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~Imp() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Imp &operator=(const Imp &src) {
Shinya Kitaoka 120a6e
    m_cells = src.m_cells;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  Imp(const Imp &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TGridColumn::TGridColumn(const string &name, Alignment alignment)
Shinya Kitaoka 120a6e
    : m_imp(new Imp(name, alignment)) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGridColumn::~TGridColumn() { delete m_imp; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGridColumn *TGridColumn::createEmpty() { return new TGridColumn(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGridColumn::getRowCount() const { return m_imp->m_cells.size(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TGridCell &TGridColumn::getCell(int row) const {
Shinya Kitaoka 120a6e
  assert(row >= 0 && row < (int)m_imp->m_cells.size());
Shinya Kitaoka 120a6e
  return m_imp->m_cells[row];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGridColumn::setCell(int row, const TGridCell &cell) {
Shinya Kitaoka 120a6e
  assert(m_imp);
Shinya Kitaoka 120a6e
  assert(row >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // checkColumn();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int firstRow = 0;
Shinya Kitaoka 120a6e
  if (m_imp->m_cells.empty())  // se la colonna e' vuota
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
    //    if(!cell.isEmpty())
Toshihiro Shimizu 890ddd
    {
Shinya Kitaoka 120a6e
      m_imp->m_cells.push_back(cell);
Shinya Kitaoka 120a6e
      firstRow = row;
Toshihiro Shimizu 890ddd
    }
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int oldCellCount = m_imp->m_cells.size();
Shinya Kitaoka 120a6e
  assert(oldCellCount > 0);
Shinya Kitaoka 120a6e
  int lastRow = firstRow + oldCellCount - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row < firstRow)  // prima
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    //    if(cell.isEmpty()) return; //non faccio nulla
Shinya Kitaoka 120a6e
    int delta = firstRow - row;
Shinya Kitaoka 120a6e
    assert(delta > 0);
Shinya Kitaoka 120a6e
    m_imp->m_cells.insert(m_imp->m_cells.begin(), delta - 1,
Shinya Kitaoka 120a6e
                          TGridCell());  // celle vuote
Shinya Kitaoka 120a6e
    m_imp->m_cells.insert(m_imp->m_cells.begin(),
Shinya Kitaoka 120a6e
                          cell);  // devo settare la prima comp. del vettore
Shinya Kitaoka 120a6e
    firstRow = row;               // row 'e la nuova firstrow
Shinya Kitaoka 120a6e
    //    updateIcon();
Shinya Kitaoka 120a6e
    //    checkColumn();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else if (row > lastRow)  // dopo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    //    if(cell.isEmpty()) return; //non faccio nulla
Shinya Kitaoka 120a6e
    int count = row - lastRow - 1;
Shinya Kitaoka 120a6e
    // se necessario, inserisco celle vuote
Shinya Kitaoka 120a6e
    for (int i = 0; i < count; ++i) m_imp->m_cells.push_back(TGridCell());
Shinya Kitaoka 120a6e
    m_imp->m_cells.push_back(cell);
Shinya Kitaoka 120a6e
    //    checkColumn();
Shinya Kitaoka 120a6e
    return;
Toshihiro Shimizu 890ddd
  }
Shinya Kitaoka 120a6e
  //"[r0,r1]"
Shinya Kitaoka 120a6e
  int index = row - firstRow;
Shinya Kitaoka 120a6e
  assert(0 <= index && index < (int)m_imp->m_cells.size());
Shinya Kitaoka 120a6e
  m_imp->m_cells[index] = cell;
Shinya Kitaoka 120a6e
  //  if(index == 0) updateIcon();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if(cell.isEmpty())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
if(row==lastRow)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
// verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
while(!m_imp->m_cells.empty() && m_imp->m_cells.back().isEmpty())
Shinya Kitaoka 120a6e
  m_imp->m_cells.pop_back();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
if(row==firstRow)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
// verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
while(!m_imp->m_cells.empty() && m_imp->m_cells.front().isEmpty())
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
 m_imp->m_cells.erase(m_imp->m_cells.begin());
Shinya Kitaoka 120a6e
 firstRow++;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
if(m_imp->m_cells.empty())
Shinya Kitaoka 120a6e
firstRow = 0;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
checkColumn();
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGridColumn::getCells(int row, int rowCount, TGridCell cells[]);
Toshihiro Shimizu 890ddd
void TGridColumn::setCells(int row, int rowCount, const TGridCell cells[]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGridColumn::insertEmptyCells(int row, int rowCount) {
Shinya Kitaoka 120a6e
  assert(m_imp);
Shinya Kitaoka 120a6e
  if (m_imp->m_cells.empty())
Shinya Kitaoka 120a6e
    return;  // se la colonna e' vuota non devo inserire celle
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int firstRow = 0;
Shinya Kitaoka 120a6e
  if (row >= firstRow + (int)m_imp->m_cells.size())
Shinya Kitaoka 120a6e
    return;             // dopo:non inserisco nulla
Shinya Kitaoka 120a6e
  if (row <= firstRow)  // prima
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    firstRow += rowCount;
Shinya Kitaoka 120a6e
  } else  // in mezzo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int delta                           = row - firstRow;
Shinya Kitaoka 120a6e
    std::vector<tgridcell>::iterator it = m_imp->m_cells.begin();</tgridcell>
Shinya Kitaoka 120a6e
    std::advance(it, delta);
Shinya Kitaoka 120a6e
    m_imp->m_cells.insert(it, rowCount, TGridCell());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGridColumn::removeCells(int row, int rowCount) {
Shinya Kitaoka 120a6e
  if (rowCount <= 0) return;
Shinya Kitaoka 120a6e
  if (m_imp->m_cells.empty()) return;  // se la colonna e' vuota
Shinya Kitaoka 120a6e
  assert(m_imp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int firstRow  = 0;  // m_imp->m_first;
Shinya Kitaoka 120a6e
  int cellCount = m_imp->m_cells.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row >= firstRow + cellCount) return;  // sono "sotto" l'ultima cella
Shinya Kitaoka 120a6e
  if (row < firstRow) {
Shinya Kitaoka 120a6e
    if (row + rowCount <= firstRow)  //"sono sopra la prima cella"
Shinya Kitaoka 120a6e
    {                                // aggiorno solo m_first
Shinya Kitaoka 120a6e
      firstRow -= rowCount;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rowCount += row - firstRow;  // rowCount = row+rowCount-firstRow;
Shinya Kitaoka 120a6e
    firstRow = row;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(row >= firstRow);
Shinya Kitaoka 120a6e
  // le celle sotto firstRow+cellCount sono gia' vuote
Shinya Kitaoka 120a6e
  if (rowCount > firstRow + cellCount - row)
Shinya Kitaoka 120a6e
    rowCount = firstRow + cellCount - row;
Shinya Kitaoka 120a6e
  if (rowCount <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row == firstRow) {
Shinya Kitaoka 120a6e
    // cancello all'inizio
Shinya Kitaoka 120a6e
    assert(rowCount <= cellCount);
Shinya Kitaoka 120a6e
    std::vector<tgridcell>::iterator it  = m_imp->m_cells.begin();</tgridcell>
Shinya Kitaoka 120a6e
    std::vector<tgridcell>::iterator it2 = m_imp->m_cells.begin();</tgridcell>
Shinya Kitaoka 120a6e
    std::advance(it2, rowCount);
Shinya Kitaoka 120a6e
    // m_imp->m_cells.erase(&m_imp->m_cells[0],&m_imp->m_cells[rowCount]);
Shinya Kitaoka 120a6e
    m_imp->m_cells.erase(it, it2);
Shinya Kitaoka 120a6e
    // verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
    while (!m_imp->m_cells.empty() /*&& m_imp->m_cells.front().isEmpty()*/) {
Shinya Kitaoka 120a6e
      m_imp->m_cells.erase(m_imp->m_cells.begin());
Shinya Kitaoka 120a6e
      firstRow++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // cancello dopo l'inizio
Shinya Kitaoka 120a6e
    int d                                = row - firstRow;
Shinya Kitaoka 120a6e
    std::vector<tgridcell>::iterator it  = m_imp->m_cells.begin();</tgridcell>
Shinya Kitaoka 120a6e
    std::vector<tgridcell>::iterator it2 = m_imp->m_cells.begin();</tgridcell>
Shinya Kitaoka 120a6e
    std::advance(it, d);
Shinya Kitaoka 120a6e
    std::advance(it2, d + rowCount);
Shinya Kitaoka 120a6e
    // m_imp->m_cells.erase(&m_imp->m_cells[d],&m_imp->m_cells[d+rowCount]);
Shinya Kitaoka 120a6e
    m_imp->m_cells.erase(it, it2);
Shinya Kitaoka 120a6e
    if (row + rowCount == firstRow + cellCount) {
Shinya Kitaoka 120a6e
      // verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
      while (!m_imp->m_cells.empty() /*&& m_imp->m_cells.back().isEmpty()*/) {
Shinya Kitaoka 120a6e
        m_imp->m_cells.pop_back();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_imp->m_cells.empty()) {
Shinya Kitaoka 120a6e
    firstRow = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // updateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGridColumn::clearCells(int row, int rowCount) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
string TGridColumn::getName() const { return m_imp->m_name; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TGridColumn::Alignment TGridColumn::getAlignment() const {
Shinya Kitaoka 120a6e
  return m_imp->m_alignment;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TGrid::Data {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Data(TWidget *w)
Shinya Kitaoka 120a6e
      : m_w(w)
Shinya Kitaoka 120a6e
      , m_selAction(0)
Shinya Kitaoka 120a6e
      , m_dblClickAction(0)
Shinya Kitaoka 120a6e
      , m_scrollbar(new TScrollbar(w))
Shinya Kitaoka 120a6e
      , m_yoffset(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~Data() {
Shinya Kitaoka 120a6e
    if (m_selAction) delete m_selAction;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_dblClickAction) delete m_dblClickAction;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int posToRow(const TPoint &p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void updateScrollBarStatus() {
Shinya Kitaoka 120a6e
    if (!m_scrollbar) return;
Shinya Kitaoka 120a6e
    int ly = m_w->getLy();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    assert(m_columnSet.getColumnCount() > 0);
Shinya Kitaoka 120a6e
    TGridColumnP col = m_columnSet.getColumn(0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if ((col->getRowCount() * m_rowHeight) > ly)
Shinya Kitaoka 120a6e
      m_scrollbar->show();  // m_scrollbar->setValue(m_yoffset,0, yrange-ly,
Shinya Kitaoka 120a6e
                            // ly);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_scrollbar->hide();  // m_scrollbar->setValue(0,0, 0, 0);
Shinya Kitaoka 120a6e
    m_scrollbar->invalidate();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TWidget *m_w;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TColumnSetT<tgridcolumn> m_columnSet;</tgridcolumn>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  vector<int> m_selectedRows;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGenericGridAction *m_selAction;
Shinya Kitaoka 120a6e
  TGenericGridAction *m_dblClickAction;
Shinya Kitaoka 120a6e
  TScrollbar *m_scrollbar;
Shinya Kitaoka 120a6e
  int m_yoffset;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_colSeparatorDragged;
Shinya Kitaoka 120a6e
  int m_prevColSeparatorX;
Shinya Kitaoka 120a6e
  int m_colSeparatorX;
Shinya Kitaoka 120a6e
  int m_colIndex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static int m_rowHeight;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TGrid::Data::m_rowHeight = 20;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::Data::posToRow(const TPoint &p) {
Shinya Kitaoka 120a6e
  int y    = m_w->getSize().ly - p.y + m_yoffset;
Shinya Kitaoka 120a6e
  int item = y / m_rowHeight;
Shinya Kitaoka 120a6e
  return item;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGrid::TGrid(TWidget *parent, string name) : TWidget(parent, name), m_data(0) {
Shinya Kitaoka 120a6e
  m_data = new Data(this);
Shinya Kitaoka 120a6e
  m_data->m_scrollbar->setAction(
Shinya Kitaoka 120a6e
      new TScrollbarAction<tgrid>(this, &TGrid::scrollTo));</tgrid>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // setBackgroundColor(White);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TGrid::~TGrid() { delete m_data; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::addColumn(const string &name, int width,
Shinya Kitaoka 120a6e
                      TGridColumn::Alignment align) {
Shinya Kitaoka 120a6e
  TGridColumnP column = new TGridColumn(name, align);
Shinya Kitaoka 120a6e
  column->setWidth(width);
Shinya Kitaoka 120a6e
  m_data->m_columnSet.insertColumn(m_data->m_columnSet.getColumnCount(),
Shinya Kitaoka 120a6e
                                   column);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::addRow() {
Shinya Kitaoka 120a6e
  int colCount = m_data->m_columnSet.getColumnCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < colCount; ++i) {
Shinya Kitaoka 120a6e
    TGridColumnP col = m_data->m_columnSet.getColumn(i);
Shinya Kitaoka 120a6e
    col->setCell(col->getRowCount(), "");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::removeRow(int row) {
Shinya Kitaoka 120a6e
  int colCount = m_data->m_columnSet.getColumnCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < colCount; ++i) {
Shinya Kitaoka 120a6e
    TGridColumnP col = m_data->m_columnSet.getColumn(i);
Shinya Kitaoka 120a6e
    col->removeCells(row);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::getColIndex(const string &colName) {
Shinya Kitaoka 120a6e
  int colCount = m_data->m_columnSet.getColumnCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < colCount; ++i) {
Shinya Kitaoka 120a6e
    TGridColumnP col = m_data->m_columnSet.getColumn(i);
Shinya Kitaoka 120a6e
    if (colName == col->getName()) return i;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::setCell(int row, int col, const string &text) {
Shinya Kitaoka 120a6e
  assert(row >= 0 && col >= 0);
Shinya Kitaoka 120a6e
  TGridColumnP column = m_data->m_columnSet.touchColumn(col);
Shinya Kitaoka 120a6e
  column->setCell(row, TGridCell(text));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::getColCount() const { return m_data->m_columnSet.getColumnCount(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::getRowCount() const {
Shinya Kitaoka 120a6e
  assert(m_data->m_columnSet.getColumnCount() > 0);
Shinya Kitaoka 120a6e
  TGridColumnP col = m_data->m_columnSet.getColumn(0);
Shinya Kitaoka 120a6e
  return col->getRowCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::getSelectedRowCount() const { return m_data->m_selectedRows.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TGrid::getSelectedRowIndex(int i) const {
Shinya Kitaoka 120a6e
  assert(i >= 0 && i < (int)m_data->m_selectedRows.size());
Shinya Kitaoka 120a6e
  return m_data->m_selectedRows[i];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::select(int row, bool on) {
Shinya Kitaoka 120a6e
  assert(row >= 0 && row < (int)getRowCount());
Shinya Kitaoka 120a6e
  std::vector<int>::iterator it = std::find(m_data->m_selectedRows.begin(),</int>
Shinya Kitaoka 120a6e
                                            m_data->m_selectedRows.end(), row);
Shinya Kitaoka 120a6e
  if (on) {
Shinya Kitaoka 120a6e
    if (it == m_data->m_selectedRows.end())
Shinya Kitaoka 120a6e
      m_data->m_selectedRows.push_back(row);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (it != m_data->m_selectedRows.end()) m_data->m_selectedRows.erase(it);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_data->m_selAction) m_data->m_selAction->sendCommand(row);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::unselectAll() {
Shinya Kitaoka 120a6e
  m_data->m_selectedRows.clear();
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TGrid::isSelected(int row) const {
Shinya Kitaoka 120a6e
  std::vector<int>::iterator it = std::find(m_data->m_selectedRows.begin(),</int>
Shinya Kitaoka 120a6e
                                            m_data->m_selectedRows.end(), row);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return it != m_data->m_selectedRows.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::scrollTo(int y) {
Shinya Kitaoka 120a6e
  if (m_data->m_yoffset == y) return;
Shinya Kitaoka 120a6e
  m_data->m_yoffset = y;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::draw() {
Shinya Kitaoka 120a6e
  TDimension size = getSize();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TRect gridHeaderPlacement(TPoint(0,size.ly-1), TDimension(size.lx-1,
Shinya Kitaoka 120a6e
  // -m_data->m_rowHeight));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRect gridHeaderPlacement(0, size.ly - 1 - m_data->m_rowHeight, size.lx - 1,
Shinya Kitaoka 120a6e
                            size.ly - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setColor(Gray180 /*White*/);
Shinya Kitaoka 120a6e
  fillRect(gridHeaderPlacement);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int gridHeaderY0 = gridHeaderPlacement.getP00().y;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < m_data->m_columnSet.getColumnCount(); ++i) {
Shinya Kitaoka 120a6e
    TGridColumnP col = m_data->m_columnSet.getColumn(i);
Shinya Kitaoka 120a6e
    int x0, x1;
Shinya Kitaoka 120a6e
    col->getCoords(x0, x1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // draw column header
Shinya Kitaoka 120a6e
    setColor(Black);
Shinya Kitaoka 120a6e
    drawText(
Shinya Kitaoka 120a6e
        TRect(x0, gridHeaderY0, x1, gridHeaderY0 + m_data->m_rowHeight - 1),
Shinya Kitaoka 120a6e
        col->getName());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int rowY = gridHeaderY0;  // - m_data->m_rowHeight;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int y = size.ly - 1 - m_data->m_rowHeight;
Shinya Kitaoka 120a6e
    for (int j = m_data->m_yoffset / m_data->m_rowHeight;
Shinya Kitaoka 120a6e
         j < col->getRowCount() && y; ++j, y -= m_data->m_rowHeight) {
Shinya Kitaoka 120a6e
      drawHLine(TPoint(0, rowY), size.lx);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TRect cellRect(x0, rowY - m_data->m_rowHeight - 1, x1, rowY);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (isSelected(j)) {
Shinya Kitaoka 120a6e
        setColor(Blue, 1);
Shinya Kitaoka 120a6e
        fillRect(cellRect);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      setColor(Black);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TWidget::Alignment align = TWidget::CENTER;
Shinya Kitaoka 120a6e
      switch (col->getAlignment()) {
Shinya Kitaoka 120a6e
      case TGridColumn::CenterAlignment:
Shinya Kitaoka 120a6e
        align = TWidget::CENTER;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      case TGridColumn::RightAlignment:
Shinya Kitaoka 120a6e
        align = TWidget::END;
Shinya Kitaoka 120a6e
        break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      case TGridColumn::LeftAlignment:
Shinya Kitaoka 120a6e
        align = TWidget::BEGIN;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      drawText(cellRect, col->getCell(j).m_text, align);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      rowY -= m_data->m_rowHeight;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    setColor(Gray210);
Shinya Kitaoka 120a6e
    drawVLine(TPoint(x0, 0), size.ly);
Shinya Kitaoka 120a6e
    drawVLine(TPoint(x1, 0), size.ly);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_data->m_colSeparatorDragged) {
Shinya Kitaoka 120a6e
    drawVLine(TPoint(m_data->m_colSeparatorX, 0), size.ly);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::configureNotify(const TDimension &d) {
Shinya Kitaoka 120a6e
  m_data->m_scrollbar->setGeometry(d.lx - 20, 1, d.lx - 2, d.ly - 2);
Shinya Kitaoka 120a6e
  m_data->updateScrollBarStatus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::leftButtonDown(const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  m_data->m_colSeparatorDragged = false;
Shinya Kitaoka 120a6e
  int rowCount                  = getRowCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i = m_data->posToRow(e.m_pos);
Shinya Kitaoka 120a6e
  if (i == 0) {
Shinya Kitaoka 120a6e
    // la riga 0 e' l'header della tabella
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int j = 0; j < m_data->m_columnSet.getColumnCount(); ++j) {
Shinya Kitaoka 120a6e
      TGridColumnP col = m_data->m_columnSet.getColumn(j);
Shinya Kitaoka 120a6e
      int x0, x1;
Shinya Kitaoka 120a6e
      col->getCoords(x0, x1);
Shinya Kitaoka 120a6e
      if (x0 - 3 < e.m_pos.x && e.m_pos.x < x0 + 3) {
Shinya Kitaoka 120a6e
        m_data->m_colSeparatorDragged = true;
Shinya Kitaoka 120a6e
        m_data->m_colSeparatorX       = x0;
Shinya Kitaoka 120a6e
        m_data->m_prevColSeparatorX   = x0;
Shinya Kitaoka 120a6e
        m_data->m_colIndex            = j;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    i--;
Shinya Kitaoka 120a6e
    if (i >= 0 && i < (int)rowCount) {
Shinya Kitaoka 120a6e
      if (!e.isShiftPressed()) unselectAll();
Shinya Kitaoka 120a6e
      select(i, !isSelected(i));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::leftButtonDrag(const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_data->m_colSeparatorDragged) {
Shinya Kitaoka 120a6e
    m_data->m_colSeparatorX += (e.m_pos.x - m_data->m_prevColSeparatorX);
Shinya Kitaoka 120a6e
    m_data->m_prevColSeparatorX = e.m_pos.x;
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TGrid::leftButtonUp(const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_data->m_colSeparatorDragged) {
Shinya Kitaoka 120a6e
    TGridColumnP col0 = m_data->m_columnSet.getColumn(m_data->m_colIndex - 1);
Shinya Kitaoka 120a6e
    TGridColumnP col1 = m_data->m_columnSet.getColumn(m_data->m_colIndex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int col0X0, col0X1;
Shinya Kitaoka 120a6e
    col0->getCoords(col0X0, col0X1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int newWidth = m_data->m_colSeparatorX - col0X0;
Shinya Kitaoka 120a6e
    int totWidth = col0->getWidth() + col1->getWidth();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    col0->setWidth(newWidth);
Shinya Kitaoka 120a6e
    col1->setWidth(totWidth - newWidth);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_data->m_colSeparatorDragged = false;
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}