/*************************************************************************** * 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 "tickmanager.h" #include "tick.h" #include "tickrow.h" #include "dragmark.h" #include "utilities.h" TickManager::TickManager( uint r, uint c, QWidget* parent, const char* name ) : CellManager( r, c, parent, name ) { activeCell = 0; showVLabel( FALSE ); setMinimumSize( minimumSizeHint() ); setAcceptDrops( TRUE ); } TickManager::~TickManager() { activeCell = 0; } /** This function must be called after the instanciation of the widget. So it will create the appropriate type of cells it has to manage. */ void TickManager::createRows() { for ( uint i=0; ipush_back( cellrow ); computePosition( cellrow, i ); cellrow->createCells(); } activeRow = (TickRow*) cellrow_list->at(row-1); } /** This function adds the specified number of rows. */ void TickManager::appendCellRow( uint ap ) { for ( uint i=0; ipush_back( cellrow ); computePosition( cellrow, row+i ); cellrow->createCells(); } row += ap; setMinimumSize( minimumSizeHint() ); placeRows(); // the widget must be redrawn refreshPixmap(); } /** Installs the content of the row \a cellrow in the active row of this manager. The cellrow argument must be of type TickRow for the expected behaviour. If it is not the case there's no warranty on its behaviour. */ bool TickManager::installActiveRow( CellRow* cellrow ) { uint i; uint dim = activeRow->getDim(); if( dim != cellrow->getDim() ) return false; for ( i=0; i < dim; i++ ) { Tick* tick1 = (Tick*) cellrow->getCellAt( i ); Tick* tick2 = (Tick*) activeRow->getCellAt( i ); tick2->setState( tick1->getState() ); } dirty = true; refreshPixmap(); return true; } /** This is an overload of the previous function. Use this function to specify the number \a black of well placed pieces in the combination and the number \a white of misplaced. So, there's no correspondance between the place of the mark and the place of the piece. If \a hard is true, the well placed piece are considered as misplaced. */ bool TickManager::installActiveRow( uint black, uint white, bool hard ) { uint i; uint dim = activeRow->getDim(); if ( black + white > dim ) return false; for ( i=0; i < black; i++ ) { Tick* tick = (Tick*) activeRow->getCellAt( i ); if ( hard ) tick->setState( MISPLACED ); else tick->setState( PLACED ); } for ( i=black; i < (white + black); i++ ) { Tick* tick = (Tick*) activeRow->getCellAt( i ); tick->setState( MISPLACED ); } dirty = true; refreshPixmap(); return true; } void TickManager::paintCell( Cell* cell, QPainter* p ) { cell->draw( p, cell->rect().topLeft() ); } void TickManager::drawReady( Cell* ) { } /** * This reimplementation is used to start the displacement the tick of a cell * to another one or to remove it. */ void TickManager::mousePressEvent( QMouseEvent* event ) { if ( read_only ) return; delivered = FALSE; TickRow* cellrow = (TickRow*) getCellRowAt( event->x(), event->y() ); if ( activeRow == cellrow ) { activeCell = (Tick*) activeRow->getCellAt( event->x(), event->y() ); if ( activeCell && !activeCell->isEmpty() ) { dragging = TRUE; } } } void TickManager::mouseMoveEvent( QMouseEvent* ) { if ( read_only ) return; if ( dragging /*activeCell*/ ) { DragMark* d = new DragMark( activeCell->getState(), this, "mark" ); d->setPixmap( stateToPixmap( activeCell->getState() ), QPoint(8,8) ); d->dragMove(); if ( !delivered ) // has it been delivered { activeCell->setState( ABSENT ); activeCell->empty( TRUE ); dirty = true; delItem(); refreshPixmap(); } activeCell = 0; dragging = FALSE; } } void TickManager::mouseReleaseEvent( QMouseEvent* ) { dragging = FALSE; activeCell = 0; } void TickManager::dragEnterEvent( QDragEnterEvent* event ) { if ( read_only ) return; event->accept( DragMark::canDecode(event) ); } void TickManager::dropEvent( QDropEvent* event ) { uint state; // where the mouse was it dropped ? int x = event->pos().x(); int y = event->pos().y(); // on which cellrow ? TickRow* cellrow = (TickRow*) getCellRowAt( x, y ); if ( !DragMark::decode( event, state ) ) { activeCell = 0; return; } // if the row is the active one we can // continue to process the event if ( cellrow && cellrow == activeRow ) { // we retrieve the cell at the specified position Tick* cell = (Tick*) activeRow->getCellAt( x, y ); // can the cell receive the drag ? if ( cell ) { if ( cell->isEmpty() ) { // the drag comes from another tick if( activeCell && cell != activeCell ) { activeCell->setState( ABSENT ); activeCell->empty( TRUE ); delivered = TRUE; // the internal counter must NOT be modified // and the ready state must be displayed } else{ /* the internal counter MUST be modified*/ addItem(); } cell->setState( state ); cell->empty( FALSE ); // the cell must be drawn dirty = true; refreshPixmap(); } else { // we cancel the operation delivered = TRUE; } } else if( !cell && activeCell ) { // we want to remove the mark from the activeCell // cause we drag it on a invalid cell activeCell->setState( ABSENT ); activeCell->empty( TRUE ); dirty = true; refreshPixmap(); } } }