/*************************************************************************** * Copyright (C) 2005 by Tavarez Arnaud Bakoula * * tbakoula@yahoo.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "cellmanager.h" #include "cell.h" #include "cellrow.h" #include #include CellManager::CellManager( uint r, uint c, QWidget* parent, const char* name ) : QFrame( parent, name, WNoAutoErase ), row(r), col(c) { margin = 4; read_only = FALSE; dragging = FALSE; delivered = FALSE; dirty = FALSE; active_ctr = 0; intern_ctr = 0; activeRow = 0; m_showLabels = FALSE; m_showHLabel = FALSE; m_showVLabel = FALSE; hLabel = 0; vLabel = 0; showLabels( TRUE, TRUE ); cellrow_list = new std::vector(); } CellManager::~CellManager() { cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end() ; it++ ) delete *it; delete cellrow_list; cellrow_list = 0; activeRow = 0; } void CellManager::resizeEvent( QResizeEvent* ) { placeRows(); refreshPixmap(); } QSize CellManager::minimumSizeHint() const { int sz = Cell::getSize(); int w = sz * col + 2 * margin + vLabel; int h = sz * row + 2 * margin + hLabel; return QSize( w, h ); } QSize CellManager::sizeHint() const { int sz = Cell::getSize(); int w = (sz + 2) * col + 2 * margin + vLabel; int h = sz * row + 2 * margin + hLabel; return QSize( w, h ); } /** This function places all the rows of the widget */ void CellManager::placeRows() { if ( cellrow_list->empty() ) return; uint i=0; dirty = true; cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end(); it++, i++ ) { (*it)->updateMe(); computePosition( (*it), i ); (*it)->placeCells(); } setMinimumSize( sizeHint() ); } /** This function computes the position of the specified row whose row index is \a r. */ void CellManager::computePosition( CellRow* cellrow, uint r ) { QPoint point; int hr = height() - 2*margin - hLabel; int hc = Cell::getSize(); int space = int((hr - row*hc) / (row+1)); int y = margin + space + r*(space + hc); point.setX( margin + vLabel ); point.setY( y ); cellrow->rect().moveTopLeft( point ); cellrow->rect().setWidth( width() - 2*margin - vLabel ); } /** This function is in charged of removing the specified number of rows. After this function has been called the widget must be repainted and resized so the appropriated form. */ void CellManager::removeCellRow( uint rm ) { if ( cellrow_list->empty() ) return; uint i=0; for ( ; i < rm; i++ ) { cellrow_list->pop_back(); } row -= rm; setMinimumSize( sizeHint() ); placeRows(); // the widget must be redrawn refreshPixmap(); } /** This function adds the specified number of cells. More precisely, it adds \a rm columns to each row. */ void CellManager::appendCells( uint ap ) { if ( cellrow_list->empty() ) return; cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end() ; it++ ) { (*it)->appendCells( ap ); } col += ap; setMinimumSize( sizeHint() ); placeRows(); // the widget must be redrawn refreshPixmap(); } /** This function removes the specified number of cells. More precisely, it removes the \a rm last columns of each row. */ void CellManager::removeCells( uint rm ) { if ( cellrow_list->empty() ) return; cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end() ; it++ ) { (*it)->removeCells( rm ); } col -= rm; setMinimumSize( sizeHint() ); placeRows(); // the widget must be redrawn refreshPixmap(); } /** Returns the cell at the specified (row=r, column=c). */ Cell* CellManager::getCellAt( uint r, uint c ) { if ( cellrow_list->empty() ) return 0; return getCellRowAt(r)->getCellAt(c); } /** Returns the row of cells whose index is \a idx. */ CellRow* CellManager::getCellRowAt( uint idx ) { if ( cellrow_list->empty() ) return 0; return cellrow_list->at( idx ); } /** Returns the row of cells which is located at the specified coordinates. */ CellRow* CellManager::getCellRowAt( int x, int y ) { if ( cellrow_list->empty() ) return 0; cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end() ; it++ ) { if ( (*it)->rect().contains( x, y ) ) return (*it); } return 0; } CellRow* CellManager::getCellRowAt( QPoint p ) { return getCellRowAt( p.x(), p.y() ); } void CellManager::resetAll() { dragging = FALSE; delivered = FALSE; active_ctr = 1; intern_ctr = 0; if ( cellrow_list->empty() ) return; cellrow_iterator it = cellrow_list->begin(); activeRow = cellrow_list->at( row-1); for ( ; it != cellrow_list->end() ; it++ ) { (*it)->reset(); } dirty = true; refreshPixmap(); } void CellManager::nextRow() { if ( active_ctr != row + 1 ) { active_ctr++; activeRow = getCellRowAt( row - active_ctr ); intern_ctr = 0; } } void CellManager::showReady() { if ( activeRow ) { activeRow->ready(); dirty = true; refreshPixmap(); } } void CellManager::paintEvent( QPaintEvent* ) { QPainter p(this); p.drawPixmap( contentsRect().topLeft(), my_pixmap ); drawFrame( &p ); } void CellManager::paintCellRow( CellRow* cellrow, QPainter* p ) { for ( uint i=0; i < col; i++ ) { paintCell( cellrow->getCellAt(i), p ); } } void CellManager::drawCellContent( QPainter* painter ) { if ( cellrow_list->empty() ) return; cellrow_iterator it = cellrow_list->begin(); for ( ; it != cellrow_list->end() ; it++ ) { paintCellRow( (*it), painter ); } } void CellManager::refreshPixmap() { // use the double buffering method if ( dirty ) { my_pixmap.resize( contentsRect().size() ); my_pixmap.fill( this, contentsRect().topLeft() ); QPainter painter( &my_pixmap, this ); drawLabels( &painter ); drawCellContent( &painter ); repaint( contentsRect(), FALSE); dirty = false; } } /** This function is in charged of erasing the specified cell. So it repaints the background at the location of the cell. */ void CellManager::eraseCell( Cell* ) { // Draw the background pixmap where the cell is located } void CellManager::eraseCellRow( CellRow* cellrow ) { for ( uint i=0; i < col; i++ ) { eraseCell( cellrow->getCellAt(i) ); } } void CellManager::addItem() { intern_ctr++; if ( intern_ctr == col ) emit ready( TRUE ); } void CellManager::delItem() { if ( intern_ctr == col ) emit ready( FALSE ); intern_ctr--; } void CellManager::updateMe() { dirty = true; refreshPixmap(); } void CellManager::showLabels( bool b, bool link ) { m_showLabels = b; if ( link ) { showHLabel( b ); showVLabel( b ); return; } hLabel = (m_showLabels && m_showHLabel) ? 22 : 0; vLabel = (m_showLabels && m_showVLabel) ? 22 : 0; } void CellManager::showHLabel( bool b ) { m_showHLabel = b; hLabel = b ? 22 : 0; } void CellManager::showVLabel( bool b ) { m_showVLabel = b; vLabel = b ? 22 : 0; } void CellManager::drawLabels( QPainter* p ) { if ( m_showLabels ) { drawVLabel( p ); drawHLabel( p ); } } void CellManager::drawHLabel( QPainter* p ) { if ( m_showHLabel ) { p->setPen( palette().active().background() ); p->setBrush( palette().active().background() ); p->drawRect( 0, height() - hLabel, width(), hLabel ); qDrawShadeLine( p, 0, height() - hLabel, width(), height() - hLabel, palette().active(), FALSE, 1, 1 ); for ( uint i=0; iat(row-1)->getCellAt( i )->rect().topLeft().x(); QRect rect( xPos, height() - hLabel, sz, hLabel ); p->setPen( palette().active().foreground() ); p->drawText( rect, Qt::AlignHCenter | Qt::AlignVCenter, QString::number( i+1 ) ); } } } void CellManager::drawVLabel( QPainter* p ) { if ( m_showVLabel ) { p->setPen( palette().active().background() ); p->setBrush( palette().active().background() ); p->drawRect( 0, 0, vLabel, height() ); qDrawShadeLine( p, vLabel, 0, vLabel, height() - hLabel, palette().active(), FALSE, 1, 1 ); for ( uint j=0; jrect().topLeft().y(); QRect rect( 0, yPos, vLabel, sz ); p->setPen( palette().active().foreground() ); p->drawText( rect, Qt::AlignHCenter | Qt::AlignVCenter, QString::number( row-j ) ); } } } #include "cellmanager.moc"