-rw-r--r-- | core/pim/todo/mainwindow.cpp | 3 | ||||
-rw-r--r-- | core/pim/todo/todotable.cpp | 49 |
2 files changed, 29 insertions, 23 deletions
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp index 5609211..b7b1da0 100644 --- a/core/pim/todo/mainwindow.cpp +++ b/core/pim/todo/mainwindow.cpp @@ -164,192 +164,195 @@ TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f ) : QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotDelete() ) ); a->addTo( bar ); a->addTo( edit ); a->addTo( contextMenu ); a->setEnabled( FALSE ); deleteAction = a; // delete All in category is missing.... // set All Done // set All Done in category a = new QAction( QString::null, tr( "Delete all..."), 0, this, 0 ); connect(a, SIGNAL( activated() ), this, SLOT( slotDeleteAll() ) ); a->addTo(edit ); a->setEnabled( FALSE ); deleteAllAction = a; edit->insertSeparator(); a = new QAction( QString::null, tr("Duplicate" ), 0, this, 0 ); connect(a, SIGNAL( activated() ), this, SLOT( slotDuplicate() ) ); a->addTo(edit ); a->setEnabled( FALSE ); duplicateAction = a; edit->insertSeparator(); if ( Ir::supported() ) { a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) ); a->addTo( edit ); a->addTo( bar ); } a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotFind() ) ); a->addTo( bar ); a->addTo( options ); options->insertSeparator(); if ( table->numRows() ) a->setEnabled( TRUE ); else a->setEnabled( FALSE ); //a->setEnabled( FALSE ); findAction = a; // qDebug("mainwindow #2: t=%d", t.elapsed() ); completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE ); showdeadlineAction = new QAction( QString::null, tr( "Show Deadline" ), 0, this, 0, TRUE ); catMenu->setCheckable( true ); populateCategories(); completedAction->addTo( options ); completedAction->setOn( table->showCompleted() ); showdeadlineAction->addTo( options ); showdeadlineAction->setOn( table->showDeadline() ); options->insertSeparator( ); QList<QWidget> list; list.append(table ); OFontMenu *menu = new OFontMenu(this, "menu",list ); menu->forceSize( table->horizontalHeader(), 10 ); //catMenu->insertItem(tr("Fonts"), menu ); list.clear(); options->insertItem( tr("Fonts"), menu ); mb->insertItem( tr( "Data" ), edit ); mb->insertItem( tr( "Category" ), catMenu ); mb->insertItem( tr( "Options"), options ); resize( 200, 300 ); if ( table->numRows() > 0 ) currentEntryChanged( 0, 0 ); connect( table, SIGNAL( signalEdit() ), this, SLOT( slotEdit() ) ); connect( table, SIGNAL(signalShowMenu(const QPoint &)), this, SLOT( slotShowPopup(const QPoint &)) ); // qDebug("mainwindow #3: t=%d", t.elapsed() ); table->updateVisible(); table->setUpdatesEnabled( TRUE ); table->setPaintingEnabled( TRUE ); table->viewport()->setUpdatesEnabled( TRUE ); + // Initialize the table + table->updateVisible(); + connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) ); connect( showdeadlineAction, SIGNAL( toggled(bool) ), this, SLOT( showDeadline(bool) ) ); connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) ); connect( table, SIGNAL( currentChanged( int, int ) ), this, SLOT( currentEntryChanged( int, int ) ) ); connect( table, SIGNAL(showDetails(const ToDoEvent &) ), this, SLOT(slotShowDetails(const ToDoEvent & ) ) ); // qDebug("done: t=%d", t.elapsed() ); } void TodoWindow::slotNew() { if(syncing) { QMessageBox::warning(this, tr("Todo"), tr("Can not edit data, currently syncing")); return; } int id; id = -1; QArray<int> ids; ids = table->currentEntry().categories(); if ( ids.count() ) id = ids[0]; NewTaskDialog e( id, this, 0, TRUE ); ToDoEvent todo; #if defined(Q_WS_QWS) || defined(_WS_QWS_) e.showMaximized(); #endif int ret = e.exec(); // qWarning("finished" ); if ( ret == QDialog::Accepted ) { table->setPaintingEnabled( false ); todo = e.todoEntry(); //todo.assignUid(); table->addEntry( todo ); table->setPaintingEnabled( true ); findAction->setEnabled( TRUE ); } // I'm afraid we must call this every time now, otherwise // spend expensive time comparing all these strings... populateCategories(); mStack->raiseWidget(1 ); } TodoWindow::~TodoWindow() { } void TodoWindow::slotDelete() { if(syncing) { QMessageBox::warning(this, tr("Todo"), tr("Can not edit data, currently syncing")); return; } if ( table->currentRow() == -1 ) return; QString strName = table->text( table->currentRow(), 2 ).left( 30 ); if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) ) return; table->setPaintingEnabled( false ); table->removeCurrentEntry(); table->setPaintingEnabled( true ); if ( table->numRows() == 0 ) { currentEntryChanged( -1, 0 ); findAction->setEnabled( FALSE ); } mStack->raiseWidget(1); } void TodoWindow::slotDeleteAll() { if(syncing) { QMessageBox::warning(this, tr("Todo"), tr("Can not edit data, currently syncing")); return; } //QString strName = table->text( table->currentRow(), 2 ).left( 30 ); if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), tr("Delete all tasks?") ) ) return; table->setPaintingEnabled( false ); diff --git a/core/pim/todo/todotable.cpp b/core/pim/todo/todotable.cpp index 877308a..52a3087 100644 --- a/core/pim/todo/todotable.cpp +++ b/core/pim/todo/todotable.cpp @@ -213,206 +213,203 @@ void DueTextItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bo }else if( m_off == 0 ){ cg2.setColor(QColorGroup::Text, QColor(yellow) ); // orange isn't predefined }else if( m_off > 0){ cg2.setColor(QColorGroup::Text, QColor(green ) ); } } QTableItem::paint(p, cg2, cr, selected ); cg2.setColor(QColorGroup::Text, text ); } TodoTable::TodoTable( QWidget *parent, const char *name ) // #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR // : QTable( 0, 3, parent, name, TRUE ), // #else : QTable( 0, 4, parent, name ), // #endif showComp( true ), enablePainting( true ), mCat( 0 ), currFindRow( -2 ), showDeadl( true) { mCat.load( categoryFileName() ); setSorting( TRUE ); setSelectionMode( NoSelection ); setColumnStretchable( 2, TRUE ); setColumnWidth( 0, 20 ); setColumnWidth( 1, 35 ); setLeftMargin( 0 ); verticalHeader()->hide(); horizontalHeader()->setLabel( 0, tr( "C." ) ); horizontalHeader()->setLabel( 1, tr( "Prior." ) ); horizontalHeader()->setLabel( 2, tr( "Description" ) ); setColumnStretchable( 3, FALSE ); setColumnWidth( 3, 20 ); horizontalHeader()->setLabel( 3, tr( "Deadline" ) ); if (showDeadl){ showColumn (3); }else{ hideColumn (3); } connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ), this, SLOT( slotClicked( int, int, int, const QPoint & ) ) ); connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ), this, SLOT( slotPressed( int, int, int, const QPoint & ) ) ); connect( this, SIGNAL( valueChanged( int, int ) ), this, SLOT( slotCheckPriority( int, int ) ) ); connect( this, SIGNAL( currentChanged( int, int ) ), this, SLOT( slotCurrentChanged( int, int ) ) ); menuTimer = new QTimer( this ); connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) ); mDayTimer = new QTimer( this ); connect( mDayTimer, SIGNAL(timeout()), this, SLOT(slotCheckDay() ) ); mDay = QDate::currentDate(); } void TodoTable::addEntry( const ToDoEvent &todo ) { int row = numRows(); setNumRows( row + 1 ); updateJournal( todo, ACTION_ADD ); insertIntoTable( new ToDoEvent(todo), row ); setCurrentCell(row, currentColumn()); updateVisible(); } void TodoTable::slotClicked( int row, int col, int, const QPoint &pos ) { if ( !cellGeometry( row, col ).contains(pos) ) return; // let's switch on the column number... switch ( col ) { case 0: { CheckItem *i = static_cast<CheckItem*>(item( row, col )); if ( i ) { int x = pos.x() - columnPos( col ); int y = pos.y() - rowPos( row ); int w = columnWidth( col ); int h = rowHeight( row ); if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize && y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) { i->toggle(); } emit signalDoneChanged( i->isChecked() ); } } break; case 1: break; case 2: - // may as well edit it... - // menuTimer->stop(); - // emit signalEdit(); // Show detailed view of the selected entry { menuTimer->stop(); ToDoEvent *todo = todoList[static_cast<CheckItem*>(item(row, 0))]; emit showDetails( *todo ); } break; case 3: // may as well edit it... menuTimer->stop(); - // emit signalEdit(); + emit signalEdit(); break; } } void TodoTable::slotPressed( int row, int col, int, const QPoint &pos ) { if ( col == 2 && cellGeometry( row, col ).contains(pos) ) menuTimer->start( 750, TRUE ); } void TodoTable::slotShowMenu() { emit signalShowMenu( QCursor::pos() ); } void TodoTable::slotCurrentChanged( int, int ) { menuTimer->stop(); } void TodoTable::internalAddEntries( QList<ToDoEvent> &list ) { setNumRows( list.count() ); int row = 0; ToDoEvent *it; for ( it = list.first(); it; it = list.next() ) insertIntoTable( it, row++ ); } ToDoEvent TodoTable::currentEntry() const { //qWarning ("in currentEntry\n"); QTableItem *i = item( currentRow(), 0 ); if ( !i || rowHeight( currentRow() ) <= 0 ) return ToDoEvent(); ToDoEvent *todo = todoList[(CheckItem*)i]; todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() ); todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() ); return *todo; } void TodoTable::replaceCurrentEntry( const ToDoEvent &todo, bool fromTableItem ) { int row = currentRow(); updateJournal( todo, ACTION_REPLACE); if ( !fromTableItem ) { journalFreeReplaceEntry( todo, row ); updateVisible(); } } void TodoTable::removeCurrentEntry() { ToDoEvent *oldTodo; int row = currentRow(); CheckItem *chk; chk = static_cast<CheckItem*>(item(row, 0 )); if ( !chk ) return; oldTodo = todoList[chk]; todoList.remove( chk ); oldTodo->setCompleted( chk->isChecked() ); oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() ); realignTable( row ); updateVisible(); updateJournal( *oldTodo, ACTION_REMOVE); delete oldTodo; } bool TodoTable::save( const QString &fn ) { QString strNewFile = fn + ".new"; QFile::remove( strNewFile ); // just to be sure ToDoDB todoDB( strNewFile ); for ( QMap<CheckItem*, ToDoEvent *>::Iterator it = todoList.begin(); it != todoList.end(); ++it ) { if ( !item( it.key()->row(), 0 ) ) continue; ToDoEvent *todo = *it; // sync item with table todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() ); todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() ); todoDB.addEvent( *todo ); } if(!todoDB.save() ){ QFile::remove( strNewFile ); return false; }; // now do the rename if ( ::rename( strNewFile, fn ) < 0 ) qWarning( "problem renaming file %s to %s errno %d", @@ -566,213 +563,219 @@ void TodoTable::updateJournal( const ToDoEvent &todo, journal_action action ) buf += " Completed=\""+ QString::number((int)todo.isCompleted() ) + "\""; buf += " HasDate=\""+ QString::number((int)todo.hasDate() ) +"\""; buf += " Priority=\"" + QString::number( todo.priority() ) + "\""; QArray<int> arrat = todo.categories(); QString attr; for(uint i=0; i < arrat.count(); i++ ){ attr.append(QString::number(arrat[i])+";" ); } if(!attr.isEmpty() ) // remove the last ; attr.remove(attr.length()-1, 1 ); buf += " Categories=\"" + attr + "\""; buf += " Description=\"" + todo.description() + "\""; if(todo.hasDate() ) { buf += " DateYear=\""+QString::number( todo.date().year() ) + "\""; buf += " DateMonth=\"" + QString::number( todo.date().month() ) + "\""; buf += " DateDay=\"" + QString::number( todo.date().day() ) + "\""; } buf += "/>\n"; str = buf.utf8(); f.writeBlock( str.data(), str.length() ); f.close(); } void TodoTable::rowHeightChanged( int row ) { if ( enablePainting ) QTable::rowHeightChanged( row ); } void TodoTable::loadFile( const QString &/*we use the standard*/ ) { QList<ToDoEvent> list; ToDoDB todoDB; QValueList<ToDoEvent> vaList = todoDB.rawToDos(); for(QValueList<ToDoEvent>::ConstIterator it = vaList.begin(); it != vaList.end(); ++it ){ ToDoEvent *event = new ToDoEvent( (*it) ); list.append( event ); } vaList.clear(); // qDebug("parsing done=%d", t.elapsed() ); if ( list.count() > 0 ) { internalAddEntries( list ); list.clear(); } // qDebug("loading done: t=%d", t.elapsed() ); } void TodoTable::journalFreeReplaceEntry( const ToDoEvent &todo, int row ) { QString strTodo; strTodo = todo.description().left(40).simplifyWhiteSpace(); if ( row == -1 ) { QMapIterator<CheckItem*, ToDoEvent *> it; for ( it = todoList.begin(); it != todoList.end(); ++it ) { if ( *(*it) == todo ) { row = it.key()->row(); it.key()->setChecked( todo.isCompleted() ); static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); item( row, 2 )->setText( strTodo ); if (showDeadl){ static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo ); } *(*it) = todo; } } } else { ToDoEvent *t = todoList[static_cast<CheckItem*>(item(row, 0))]; todoList.remove( static_cast<CheckItem*>(item(row, 0)) ); delete t; static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() ); static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); item( row, 2 )->setText( strTodo ); if (showDeadl){ static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo ); } todoList.insert( static_cast<CheckItem*>(item(row,0)), new ToDoEvent(todo) ); } } void TodoTable::journalFreeRemoveEntry( int row ) { CheckItem *chk; chk = static_cast<CheckItem*>(item(row, 0 )); if ( !chk ) return; todoList.remove( chk ); realignTable( row ); } void TodoTable::keyPressEvent( QKeyEvent *e ) { - if ( e->key() == Key_Space || e->key() == Key_Return ) { - switch ( currentColumn() ) { - case 0: { - CheckItem *i = static_cast<CheckItem*>(item(currentRow(), - currentColumn())); - if ( i ) - i->toggle(); - break; - } - case 1: - break; - case 2: - emit signalEdit(); - default: - break; - } - } else { - QTable::keyPressEvent( e ); - } + if ( e->key() == Key_Space || e->key() == Key_Return ) { + switch ( currentColumn() ) { + case 0: { + CheckItem *i = static_cast<CheckItem*>(item(currentRow(), + currentColumn())); + if ( i ) + i->toggle(); + break; + } + case 1: + break; + case 2:{ + ToDoEvent *todo = todoList[static_cast<CheckItem*>(item(currentRow(), 0))]; + emit showDetails(*todo); + break; + } + case 3: + // Future: Let us change the dueDate directly... + emit signalEdit(); + default: + break; + } + } else + QTable::keyPressEvent( e ); } + QStringList TodoTable::categories() { // This is called seldom, so calling a load in here // should be fine. mCat.load( categoryFileName() ); QStringList categoryList = mCat.labels( "Todo List" ); return categoryList; } void TodoTable::slotDoFind( const QString &findString, bool caseSensitive, bool backwards, int category ) { // we have to iterate through the table, this gives the illusion that // sorting is actually being used. if ( currFindRow < -1 ) currFindRow = currentRow() - 1; clearSelection( TRUE ); int rows, row; CheckItem *chk; QRegExp r( findString ); r.setCaseSensitive( caseSensitive ); rows = numRows(); static bool wrapAround = true; if ( !backwards ) { for ( row = currFindRow + 1; row < rows; row++ ) { chk = static_cast<CheckItem*>( item(row, 0) ); if ( taskCompare(*(todoList[chk]), r, category) ) break; } } else { for ( row = currFindRow - 1; row > -1; row-- ) { chk = static_cast<CheckItem*>( item(row, 0) ); if ( taskCompare(*(todoList[chk]), r, category) ) break; } } if ( row >= rows || row < 0 ) { if ( row < 0 ) currFindRow = rows; else currFindRow = -1; if ( wrapAround ) emit signalWrapAround(); else emit signalNotFound(); wrapAround = !wrapAround; } else { currFindRow = row; QTableSelection foundSelection; foundSelection.init( currFindRow, 0 ); foundSelection.expandTo( currFindRow, numCols() - 1 ); addSelection( foundSelection ); setCurrentCell( currFindRow, numCols() - 1 ); // we should always be able to wrap around and find this again, // so don't give confusing not found message... wrapAround = true; } } int TodoTable::showCategoryId() const { int id; id = -1; // if allcategories are selected, you get unfiled... if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) ) id = mCat.id( "Todo List", showCat ); return id; } void TodoTable::applyJournal() { // we need to hack QFile file( journalFileName() ); if( file.open(IO_ReadOnly ) ) { QByteArray ar = file.readAll(); file.close(); QFile file2( journalFileName() + "_new" ); if( file2.open(IO_WriteOnly ) ){ QTextStream str(&file2 ); str << QString::fromLatin1("<Tasks>") << endl; str << ar.data(); str << QString::fromLatin1("</Tasks>") << endl; file2.close(); } XMLElement *root = XMLElement::load(journalFileName()+ "_new"); XMLElement *el = root->firstChild(); el = el->firstChild(); ToDoDB tododb; // allready loaded ;) bool ok; int action; QString dummy; while( el ){ dummy = el->attribute("Action" ); action = dummy.toInt(&ok ); |