00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <stdlib.h>
00032 #include <cmath>
00033 #include <cctype>
00034
00035 #include <opie2/odebug.h>
00036 #include <opie2/opimrecurrence.h>
00037 #include <opie2/oresource.h>
00038
00039 #include <qpe/config.h>
00040 #include <qpe/qpeapplication.h>
00041
00042 #include <qcombobox.h>
00043 #include <qlineedit.h>
00044 #include <qpopupmenu.h>
00045
00046 #include "mainwindow.h"
00047
00048 #include "tableview.h"
00049
00050 using namespace Todo;
00051
00052 namespace {
00053 static const int BoxSize = 14;
00054 static const int RowHeight = 20;
00055 }
00056
00057 TableView::EditorWidget::EditorWidget() : m_wid(0l), m_row(-1), m_col(-1) {
00058 }
00059 void TableView::EditorWidget::setCellWidget(QWidget* wid, int row, int col ) {
00060 m_wid = wid;
00061 m_row = row;
00062 m_col = col;
00063 }
00064 void TableView::EditorWidget::releaseCellWidget() {
00065 m_wid = 0;
00066 m_row = m_col = -1;
00067 }
00068 QWidget* TableView::EditorWidget::cellWidget()const {
00069 return m_wid;
00070 }
00071 int TableView::EditorWidget::cellRow()const {
00072 return m_row;
00073 }
00074 int TableView::EditorWidget::cellCol()const {
00075 return m_col;
00076 }
00077
00078
00079 void TableView::initConfig() {
00080 Config config( "todo" );
00081 config.setGroup( "Options" );
00082 m_completeStrokeWidth = config.readNumEntry( "CompleteStrokeWidth", 8 );
00083 for (int i = 0; i < numCols(); i++ ) {
00084 int width = config.readNumEntry("Width"+QString::number(i), -1 );
00085 setColumnWidth(i, width == -1 ? columnWidth(i) : width );
00086 }
00087 }
00088
00089 TableView::TableView( MainWindow* window, QWidget* wid )
00090 : QTable( wid ), TodoView( window ) {
00091
00092 setName("TableView");
00093
00094
00095
00096 m_pic_completed = Opie::Core::OResource::loadPixmap( "todo/completed" );
00097 QString namestr;
00098 for ( unsigned int i = 1; i < 6; i++ ) {
00099 namestr = "todo/priority";
00100 namestr.append( QString::number( i ) );
00101 m_pic_priority[ i - 1 ] = Opie::Core::OResource::loadPixmap( namestr );
00102 }
00103
00104 setUpdatesEnabled( false );
00105 viewport()->setUpdatesEnabled( false );
00106 m_enablePaint = false;
00107 setNumRows(0);
00108 setNumCols(4);
00109
00110 horizontalHeader()->setLabel( 0, QWidget::tr("C.") );
00111 horizontalHeader()->setLabel( 1, QWidget::tr("Priority") );
00112 horizontalHeader()->setLabel( 2, QWidget::tr("Summary" ) );
00113 horizontalHeader()->setLabel( 3, QWidget::tr("Deadline") );
00114
00115 setShowDeadline( todoWindow()->showDeadline() );
00116
00117 setSorting( TRUE );
00118 setSelectionMode( NoSelection );
00119
00120 setLeftMargin( 0 );
00121 verticalHeader()->hide();
00122
00123 QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
00124 connect((QTable*)this, SIGNAL( clicked(int,int,int,const QPoint&) ),
00125 this, SLOT( slotClicked(int,int,int,const QPoint&) ) );
00126 connect((QTable*)this, SIGNAL(valueChanged(int,int) ),
00127 this, SLOT( slotValueChanged(int,int) ) );
00128 connect((QTable*)this, SIGNAL(currentChanged(int,int) ),
00129 this, SLOT( slotCurrentChanged(int,int) ) );
00130
00131
00132 initConfig();
00133
00134
00135 m_enablePaint = true;
00136 setUpdatesEnabled( true );
00137 viewport()->setUpdatesEnabled( true );
00138 viewport()->update();
00139 setSortOrder( Opie::OPimTodoAccess::Completed );
00140 setAscending( TRUE );
00141 m_first = true;
00142
00143
00144 }
00145
00146
00147
00148 void TableView::newDay() {
00149 clear();
00150 updateView();
00151 }
00152 TableView::~TableView() {
00153 Config config( "todo" );
00154 config.setGroup( "Options" );
00155 for (int i = 0; i < numCols(); i++ )
00156 config.writeEntry("Width"+QString::number(i), columnWidth(i) );
00157 }
00158 QString TableView::type() const {
00159 return QString::fromLatin1( tr("Table View") );
00160 }
00161 int TableView::current() {
00162 if (numRows() == 0 ) return 0;
00163 int uid = sorted().uidAt(currentRow() );
00164
00165 return uid;
00166 }
00167 int TableView::next() {
00168 if ( numRows() == 0 ) return 0;
00169 if ( currentRow() + 1 >= numRows() ) return 0;
00170 setCurrentCell( currentRow() +1, currentColumn() );
00171 return sorted().uidAt( currentRow() );
00172 }
00173 int TableView::prev() {
00174 if ( numRows() == 0 ) return 0;
00175 if ( currentRow() - 1 < 0 ) return 0;
00176 setCurrentCell( currentRow() -1, currentColumn() );
00177 return sorted().uidAt( currentRow() );
00178
00179 }
00180 QString TableView::currentRepresentation() {
00181 OPimTodo to = sorted()[currentRow()];
00182 return to.summary().isEmpty() ? to.description().left(20) : to.summary() ;
00183 }
00184
00185 void TableView::showOverDue( bool ) {
00186 clear();
00187 updateView();
00188 }
00189
00190 void TableView::updateView( ) {
00191 m_row = false;
00192 static int id;
00193 id = startTimer(4000 );
00194
00195
00196
00197
00198 todoWindow()->setReadAhead( 4 );
00199 sort();
00200 OPimTodoAccess::List::Iterator it, end;
00201 it = sorted().begin();
00202 end = sorted().end();
00203
00204 QTime time;
00205 time.start();
00206 m_enablePaint = false;
00207 setUpdatesEnabled( false );
00208 viewport()->setUpdatesEnabled( false );
00209
00210 setNumRows( it.count() );
00211 if ( it.count() == 0 )
00212 killTimer(id);
00213
00214
00215 setUpdatesEnabled( true );
00216 viewport()->setUpdatesEnabled( true );
00217 viewport()->update();
00218
00219 m_enablePaint = true;
00220
00221 }
00222 void TableView::setTodo( int, const OPimTodo&) {
00223 sort();
00224
00225
00226 repaint();
00227 }
00228 void TableView::addEvent( const OPimTodo&) {
00229
00230
00231 updateView();
00232 }
00233
00234
00235
00236
00237 void TableView::replaceEvent( const OPimTodo& ev) {
00238 addEvent( ev );
00239 }
00240
00241
00242
00243
00244
00245 void TableView::removeEvent( int ) {
00246 updateView();
00247 }
00248 void TableView::setShowCompleted( bool ) {
00249 updateView();
00250 }
00251 void TableView::setShowDeadline( bool b ) {
00252 if ( b )
00253 showColumn( 3 );
00254 else
00255 hideColumn( 3 );
00256
00257
00258
00259 int col2width = 238;
00260 int width = m_pic_completed.width();
00261 setColumnWidth( 0, width );
00262 col2width -= width;
00263 width = fontMetrics().boundingRect( horizontalHeader()->label( 1 ) ).width() + 8;
00264 setColumnWidth( 1, width );
00265 col2width -= width;
00266 if ( b ) {
00267 width = fontMetrics().boundingRect( horizontalHeader()->label( 3 ) ).width() + 8;
00268 setColumnWidth( 3, width );
00269 col2width -= width;
00270 }
00271 setColumnWidth( 2, col2width );
00272 }
00273 void TableView::setShowCategory( const QString& str) {
00274 if ( str != m_oleCat || m_first )
00275 updateView();
00276
00277 m_oleCat = str;
00278 m_first = false;
00279 }
00280 void TableView::clear() {
00281 setNumRows(0);
00282 }
00283 void TableView::slotClicked(int row, int col, int,
00284 const QPoint& point) {
00285 if ( m_editorWidget.cellWidget() ) {
00286
00287 endEdit(m_editorWidget.cellRow(), m_editorWidget.cellCol(),
00288 true, true );
00289 m_editorWidget.releaseCellWidget();
00290 }
00291
00292 if ( !cellGeometry(row, col ).contains(point ) )
00293 return;
00294
00295 int ui= sorted().uidAt( row );
00296
00297
00298 switch( col ) {
00299 case 0:{
00300 int x = point.x() -columnPos( col );
00301 int y = point.y() -rowPos( row );
00302 int w = columnWidth( col );
00303 int h = rowHeight( row );
00304 if ( x >= ( w - BoxSize ) / 2 &&
00305 x <= ( w - BoxSize ) / 2 + BoxSize &&
00306 y >= ( h - BoxSize ) / 2 &&
00307 y <= ( h - BoxSize ) / 2 + BoxSize ) {
00308 TodoView::complete(sorted()[row] );
00309 }
00310 }
00311 break;
00312
00313
00314 case 1:{
00315 QWidget* wid = beginEdit( row, col, FALSE );
00316 m_editorWidget.setCellWidget( wid, row, col );
00317 }
00318 break;
00319
00320 case 2: {
00321 showTodo( ui );
00322 break;
00323 }
00324 case 3: {
00325 TodoView::edit( ui );
00326 break;
00327 }
00328 }
00329
00330
00331 }
00332 QWidget* TableView::widget() {
00333 return this;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 void TableView::sortColumn( int col, bool asc, bool ) {
00343 switch(col) {
00344 case 1:
00345 col = Opie::OPimTodoAccess::Priority;
00346 break;
00347 case 2:
00348 col = Opie::OPimTodoAccess::SortSummary;
00349 break;
00350 case 3:
00351 col = Opie::OPimTodoAccess::Deadline;
00352 break;
00353 case 0:
00354 default:
00355 col = Opie::OPimTodoAccess::Completed;
00356 break;
00357 }
00358
00359 setSortOrder( col );
00360 setAscending( asc );
00361 updateView();
00362 }
00363 void TableView::viewportPaintEvent( QPaintEvent* e) {
00364 if (m_enablePaint )
00365 QTable::viewportPaintEvent( e );
00366 }
00367
00368
00369
00370
00371
00372 void TableView::paintCell(QPainter* p, int row, int col, const QRect& cr, bool ) {
00373 const QColorGroup &cg = colorGroup();
00374
00375 p->save();
00376
00377 OPimTodo task = sorted()[row];
00378
00379
00380
00381
00382 if ( (row % 2 ) == 0 ) {
00383 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
00384 p->setPen( QPen( cg.text() ) );
00385 }
00386 else {
00387 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Background ) );
00388 p->setPen( QPen( cg.buttonText() ) );
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 QFont f = p->font();
00400 QFontMetrics fm(f);
00401
00402 int marg = ( cr.width() - BoxSize ) / 2;
00403 int x = 0;
00404 int y = ( cr.height() - BoxSize ) / 2;
00405
00406 switch(col) {
00407 case 0:
00408 {
00409
00410
00411
00412 if ( task.isCompleted() ) {
00413 p->drawPixmap( x + marg, y, m_pic_completed );
00414 }
00415 }
00416 break;
00417 case 1:
00418 {
00419 p->drawPixmap( x + marg, y, m_pic_priority[ task.priority() - 1 ] );
00420 }
00421 break;
00422 case 2:
00423 {
00424 QString text = task.summary().isEmpty() ?
00425 task.description().left(20) :
00426 task.summary();
00427 p->drawText(2,2 + fm.ascent(), text);
00428 }
00429 break;
00430 case 3:
00431 {
00432 QString text;
00433 if (task.hasDueDate()) {
00434 int off = QDate::currentDate().daysTo( task.dueDate() );
00435 text = tr( "%1 day(s)").arg(QString::number(off));
00436
00437
00438
00439 if (!task.isCompleted() ) {
00440 QColor color = Qt::black;
00441 if ( off < 0 )
00442 color = Qt::red;
00443 else if ( off == 0 )
00444 color = Qt::yellow;
00445 else if ( off > 0 )
00446 color = Qt::green;
00447 p->setPen(color );
00448 }
00449 } else {
00450 text = tr("None");
00451 }
00452 p->drawText(2,2 + fm.ascent(), text);
00453 }
00454 break;
00455 }
00456 p->restore();
00457 }
00458 QWidget* TableView::createEditor(int row, int col, bool )const {
00459 switch( col ) {
00460 case 1: {
00461
00462 QComboBox* combo = new QComboBox( viewport() );
00463 for ( int i = 0; i < 5; i++ ) {
00464 combo->insertItem( m_pic_priority[ i ] );
00465 }
00466 combo->setCurrentItem( sorted()[row].priority()-1 );
00467 return combo;
00468 }
00469
00470 case 2:{
00471 QLineEdit* edit = new QLineEdit( viewport() );
00472 edit->setText( sorted()[row].summary() );
00473 return edit;
00474 }
00475 case 0:
00476 default:
00477 return 0l;
00478 }
00479 }
00480 void TableView::setCellContentFromEditor(int row, int col ) {
00481 if ( col == 1 ) {
00482 QWidget* wid = cellWidget(row, 1 );
00483 if ( wid->inherits("QComboBox") ) {
00484 int pri = ((QComboBox*)wid)->currentItem() + 1;
00485 OPimTodo todo = sorted()[row];
00486 if ( todo.priority() != pri ) {
00487 todo.setPriority( pri );
00488 TodoView::update( todo.uid(), todo );
00489 updateView();
00490 }
00491 }
00492 }else if ( col == 2) {
00493 QWidget* wid = cellWidget(row, 2);
00494 if ( wid->inherits("QLineEdit") ) {
00495 QString text = ((QLineEdit*)wid)->text();
00496 OPimTodo todo = sorted()[row];
00497 if ( todo.summary() != text ) {
00498 todo.setSummary( text );
00499 TodoView::update( todo.uid(), todo );
00500 updateView();
00501 }
00502 }
00503 }
00504 }
00505 void TableView::slotPriority() {
00506 setCellContentFromEditor( currentRow(), currentColumn() );
00507 }
00508
00509
00510
00511
00512
00513
00514
00515 void TableView::timerEvent( QTimerEvent* ) {
00516 if (sorted().count() == 0 )
00517 return;
00518
00519 int row = currentRow();
00520 if ( m_row ) {
00521 int ro = row-4;
00522 if (ro < 0 ) ro = 0;
00523 sorted()[ro];
00524
00525 ro = row+4;
00526 sorted()[ro];
00527 } else {
00528 int ro = row + 8;
00529 sorted()[ro];
00530
00531 ro = row-8;
00532 if (ro < 0 ) ro = 0;
00533 sorted()[ro];
00534 }
00535
00536 m_row = !m_row;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 void TableView::contentsMouseReleaseEvent( QMouseEvent *e ) {
00560 int row = rowAt(m_prevP.y());
00561 int colOld = columnAt(m_prevP.x() );
00562 int colNew = columnAt(e->x() );
00563 if ( row == rowAt( e->y() ) && row != -1 &&
00564 colOld != colNew ) {
00565 TodoView::complete( sorted()[row] );
00566 return;
00567 }
00568 QTable::contentsMouseReleaseEvent( e );
00569 }
00570 void TableView::contentsMousePressEvent( QMouseEvent *e ) {
00571 if ( e->button() == RightButton ) {
00572 QPopupMenu *menu = todoWindow()->contextMenu( current(), sorted()[currentRow()].recurrence().doesRecur() );
00573 menu->exec( QCursor::pos() );
00574 }
00575 else {
00576 m_prevP = e->pos();
00577 QTable::contentsMousePressEvent( e );
00578 }
00579 }
00580 void TableView::keyPressEvent( QKeyEvent* event) {
00581 if ( m_editorWidget.cellWidget() ) {
00582
00583 endEdit(m_editorWidget.cellRow(), m_editorWidget.cellCol(),
00584 true, true );
00585 m_editorWidget.releaseCellWidget();
00586 setFocus();
00587 }
00588
00589 if ( sorted().count() < 1 ) {
00590 QTable::keyPressEvent( event );
00591 return;
00592 }
00593
00594 int row = currentRow();
00595 int col = currentColumn();
00596
00597 char key = ::toupper( event->ascii() );
00598
00599 if ( key == 'D' ) {
00600 event->accept();
00601 removeQuery( sorted().uidAt( row ) );
00602 return;
00603 }
00604
00605
00606 switch( event->key() ) {
00607 case Qt::Key_F33:
00608 case Qt::Key_Enter:
00609 case Qt::Key_Return:
00610 case Qt::Key_Space:
00611 if ( col == 0 ) {
00612 TodoView::complete(sorted()[row]);
00613 }else if ( col == 1 ) {
00614 QWidget* wid = beginEdit(row, col, FALSE );
00615 m_editorWidget.setCellWidget( wid, row, col );
00616 }else if ( col == 2 ) {
00617 showTodo( sorted().uidAt( currentRow() ) );
00618 }else if ( col == 3 ) {
00619 TodoView::edit( sorted().uidAt(row) );
00620 }
00621 event->accept();
00622 break;
00623 default:
00624 QTable::keyPressEvent( event );
00625 }
00626 }
00627