Index: ossp-pkg/as/as-gui/ChangeLog RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/ChangeLog,v rcsdiff -q -kk '-r1.10' '-r1.11' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/ChangeLog,v' 2>/dev/null --- ChangeLog 2003/01/23 14:41:02 1.10 +++ ChangeLog 2003/01/24 16:32:18 1.11 @@ -1,8 +1,15 @@ Geschichte des OSSP titraq in Vorwaerts Cronordnung +030124 Added CRC and basic revision management logic + Removed sort on load to allow easier file diffs + Allow only reasonable fields to transmit to server + Improved invalid data signaling in both Titable and ctrls + 030123 Added logic to make IIOP and SOAP connections optional Fixed potentially disastrous bug with current file overwrite Fixed broken Linux build problem with -R linker arguments + Improved RPC data transmission by selecting current row + Made pasted rows receive new GUIDs to avoid duplicates 030122 Added IIOP and SOAP connection operations Added menu items for remote reporting over IIOP or SOAP Index: ossp-pkg/as/as-gui/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/Makefile.in,v rcsdiff -q -kk '-r1.33' '-r1.34' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/Makefile.in,v' 2>/dev/null --- Makefile.in 2003/01/22 23:57:01 1.33 +++ Makefile.in 2003/01/24 16:32:18 1.34 @@ -44,6 +44,8 @@ CXX = @CXX@ CFLAGS = @CFLAGS@ @DEFS@ CXXFLAGS = @CXXFLAGS@ @DEFS@ +#CFLAGS = @CFLAGS@ @DEFS@ -Wl,-Bstatic +#CXXFLAGS = @CXXFLAGS@ @DEFS@ -Wl,-Bstatic CPPFLAGS = @CPPFLAGS@ CXXCPP = @CXXCPP@ LDFLAGS = @LDFLAGS@ Index: ossp-pkg/as/as-gui/TODO RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/TODO,v rcsdiff -q -kk '-r1.60' '-r1.61' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/TODO,v' 2>/dev/null --- TODO 2003/01/16 08:26:29 1.60 +++ TODO 2003/01/24 16:32:18 1.61 @@ -47,6 +47,8 @@ Make edit control window optional through preferences Add customizable column ordering by click and drag Soll mehr intuitive, mit sekondaer/dritte Keycolumn +CRC und Rev sollen nicht in gleiche Methode berechnet +No need to have upd slots for non-changeable upd controls Win32 ----- Index: ossp-pkg/as/as-gui/as_assist.cpp RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_assist.cpp,v rcsdiff -q -kk '-r1.82' '-r1.83' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_assist.cpp,v' 2>/dev/null --- as_assist.cpp 2003/01/22 23:57:01 1.82 +++ as_assist.cpp 2003/01/24 16:32:18 1.83 @@ -655,11 +655,8 @@ // Table update signals connect(m_pMaintable, SIGNAL(currentChanged(int, int)), this, SLOT(updEdit(int, int))); - connect(m_pMaintable, SIGNAL(currentChanged(int, int)), this, SLOT(validateData(int, int))); connect(m_pMaintable, SIGNAL(doubleClicked(int, int, int, const QPoint&)), this, SLOT(inplaceEdit(int, int, int, const QPoint&))); connect(m_pTablehead, SIGNAL(sizeChange(int, int, int)), this, SLOT(updSizes(int, int, int))); - connect(m_pMaintable, SIGNAL(valueChanged(int, int)), this, SLOT(dataChanged(int, int))); - connect(m_pMaintable, SIGNAL(valueChanged(int, int)), this, SLOT(validateData(int, int))); connect(m_pMaintable, SIGNAL(textEdited(int, int)), this, SLOT(dataChanged(int, int))); } @@ -918,6 +915,23 @@ connect(m_pAmount, SIGNAL(valueChanged(const QString &)), this, SLOT(updateAmount(const QString &))); connect(m_pTasks, SIGNAL(textChanged(const QString &)), this, SLOT(updateTask(const QString &))); connect(m_pRemark, SIGNAL(textChanged(const QString &)), this, SLOT(updateRemark(const QString &))); + + // Validate data just as it is being entered + connect(m_pDateedit, SIGNAL(valueChanged(const QDate &)), this, SLOT(validateData(void))); + connect(m_pStarttime, SIGNAL(valueChanged(const QTime &)), this, SLOT(validateData(void))); + connect(m_pEndtime, SIGNAL(valueChanged(const QTime &)), this, SLOT(validateData(void))); + connect(m_pAmount, SIGNAL(valueChanged(const QString &)), this, SLOT(validateData(void))); + connect(m_pTasks, SIGNAL(textChanged(const QString &)), this, SLOT(validateData(void))); + connect(m_pRemark, SIGNAL(textChanged(const QString &)), this, SLOT(validateData(void))); + + // Correctly update checksum and revision fields also + connect(m_pUseredit, SIGNAL(textChanged(const QString &)), this, SLOT(calcCrc(void))); + connect(m_pDateedit, SIGNAL(valueChanged(const QDate &)), this, SLOT(calcCrc(void))); + connect(m_pStarttime, SIGNAL(valueChanged(const QTime &)), this, SLOT(calcCrc(void))); + connect(m_pEndtime, SIGNAL(valueChanged(const QTime &)), this, SLOT(calcCrc(void))); + connect(m_pAmount, SIGNAL(valueChanged(const QString &)), this, SLOT(calcCrc(void))); + connect(m_pTasks, SIGNAL(textChanged(const QString &)), this, SLOT(calcCrc(void))); + connect(m_pRemark, SIGNAL(textChanged(const QString &)), this, SLOT(calcCrc(void))); } // Index: ossp-pkg/as/as-gui/as_dataop.cpp RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_dataop.cpp,v rcsdiff -q -kk '-r1.32' '-r1.33' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_dataop.cpp,v' 2>/dev/null --- as_dataop.cpp 2002/12/20 17:42:10 1.32 +++ as_dataop.cpp 2003/01/24 16:32:18 1.33 @@ -262,11 +262,11 @@ } } - // Start sorting order and direction correctly according to user preferences - int nSortcol = (int)m_pPrefs->getNumber(TITRAQ_PREFSORTCOL, TITRAQ_DEFSORTCOL); - bool bSortdir = m_pPrefs->getBool(TITRAQ_PREFSORTDIR, TITRAQ_DEFSORTDIR); - m_pMaintable->setSortdir(!bSortdir); // Hack! Fake sortdir so we start right - m_pMaintable->sortColumn(nSortcol, bSortdir); +// // Start sorting order and direction correctly according to user preferences +// int nSortcol = (int)m_pPrefs->getNumber(TITRAQ_PREFSORTCOL, TITRAQ_DEFSORTCOL); +// bool bSortdir = m_pPrefs->getBool(TITRAQ_PREFSORTDIR, TITRAQ_DEFSORTDIR); +// m_pMaintable->setSortdir(!bSortdir); // Hack! Fake sortdir so we start right +// m_pMaintable->sortColumn(nSortcol, bSortdir); // Write nonsaving line numbers for all rows for (int nIter = m_pMaintable->numRows() - 1; nIter >= 0; nIter--) @@ -436,9 +436,9 @@ Remark = Rowstream.readLine(); // Remark is a whole line // Set the table row data one field at a time, skipping seps inbetween + // Importantly, do not copy over the GUID, which must be unique each row m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXLINE, Line); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXUSER, User); - m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXGUID, Guid); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXCRC, Crc); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREV, Rev); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXDATE, Date); Index: ossp-pkg/as/as-gui/as_gui.h RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_gui.h,v rcsdiff -q -kk '-r1.61' '-r1.62' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_gui.h,v' 2>/dev/null --- as_gui.h 2003/01/22 23:57:01 1.61 +++ as_gui.h 2003/01/24 16:32:18 1.62 @@ -168,8 +168,11 @@ void selAll(void); // Edit menu select all void inplaceEdit(int, int, int, const QPoint &); // Enter in place edit mode void updEdit(int, int nCol = 0); // Update edit controls - void validateData(int, int); // Validate one row of matrix data + void validateData(void); // Validate current row of matrix data + void validateData(int, int); // Validate specified row of matrix data void updSizes(int, int, int); // Update edit sizes + void calcCrc(void); // Calculate CRC of current row + void calcCrc(int, int); // Calculate CRC of specified row void dataChanged(int, int); // Timesheet data changed void updateLine(const QString &); // Update line number column void updateUser(const QString &); // Update user column Index: ossp-pkg/as/as-gui/as_slot.cpp RCS File: /v/ossp/cvs/ossp-pkg/as/as-gui/as_slot.cpp,v rcsdiff -q -kk '-r1.84' '-r1.85' -u '/v/ossp/cvs/ossp-pkg/as/as-gui/as_slot.cpp,v' 2>/dev/null --- as_slot.cpp 2003/01/23 18:04:45 1.84 +++ as_slot.cpp 2003/01/24 16:32:18 1.85 @@ -146,14 +146,16 @@ m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER)); pGuid->genId(); m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXGUID, pGuid->getString()); - m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXCRC, "0"); - m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXREV, "0"); + m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXCRC, "0"); // 0 = invalid entry + m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXREV, "0"); // Entry not revised m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXDATE, QDate::currentDate().toString("yyyy.MM.dd")); m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXSTART, "00:00"); m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXFINISH, "00:00"); m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXAMOUNT, "00:00"); // m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXTASK, "/"); // m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXREMARK, "Remark"); + m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXCRC, "1"); // 0 = invalid entry + this->calcCrc(Select.topRow() + nIter, -1); } } else { // Special case on last row add downwards @@ -177,6 +179,7 @@ m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXAMOUNT, "00:00"); // m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXTASK, "/"); // m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXREMARK, "Remark"); + this->calcCrc(Select.bottomRow() + nIter, -1); } } @@ -575,6 +578,54 @@ } // +// Convenience member calculates CRC for current row +// +void Titraqform::calcCrc(void) +{ + this->calcCrc(-1, -1); +} + +// +// Calculates CRC for the specified row, fires when data is changed +// +void Titraqform::calcCrc(int nRow, int nCol) +{ + if (nCol != TITRAQ_IDXSTATUS && nCol != TITRAQ_IDXLINE \ + && m_pMaintable->numRows() > 0) { + Q_UINT16 Valcrc, Testcrc; + QString Wholerow; + int nRealrow = -1; +// int nNewrev = -1; + + // Build the data that will be used in testing CRC calculation + nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow(); + Wholerow = m_pMaintable->text(nRealrow, TITRAQ_IDXUSER); + for (int nIter = TITRAQ_IDXUSER + 1; nIter < TITRAQ_IDXTAIL; nIter++) + if (nIter != TITRAQ_IDXCRC) // Don't checksum the checksum! + Wholerow += ' ' + m_pMaintable->text(nRealrow, nIter); + + // Update the checksum and revision only if necessary + Testcrc = qChecksum(Wholerow.ascii(), Wholerow.length()); + if (Testcrc != m_pMaintable->text(nRealrow, TITRAQ_IDXCRC).toUInt()) { + +// // Bump the revision number of our entry to control conflicts +// nNewrev = m_pMaintable->text(nRealrow, TITRAQ_IDXREV).toInt() + 1; +// m_pMaintable->setText(nRealrow, TITRAQ_IDXREV, QString::number(nNewrev)); + + // Build the data that will be used in setting CRC calculation + Wholerow = m_pMaintable->text(nRealrow, TITRAQ_IDXUSER); + for (int nIter = TITRAQ_IDXUSER + 1; nIter < TITRAQ_IDXTAIL; nIter++) + if (nIter != TITRAQ_IDXCRC) // Don't checksum the checksum! + Wholerow += ' ' + m_pMaintable->text(nRealrow, nIter); + + // Finally set the checksum to its new value + Valcrc = qChecksum(Wholerow.ascii(), Wholerow.length()); + m_pMaintable->setText(nRealrow, TITRAQ_IDXCRC, QString::number(Valcrc)); + } + } +} + +// // Update the edit controls contents // void Titraqform::updEdit(int nRow, int nCol) @@ -629,43 +680,54 @@ } // -// Validate one row of matrix data +// Validate current row of matrix data +// +void Titraqform::validateData(void) +{ + this->validateData(-1, -1); +} + +// +// Validate specified row of matrix data // void Titraqform::validateData(int nRow, int nCol) { + int nRealrow = -1; + if (!m_pMaintable->numRows() > 0) { // If no rows exist then short circuit m_pStatbar->message(trUtf8("Timesheet contains no data"), 4000); return; } - QString Statis = m_pMaintable->text(nRow, TITRAQ_IDXSTATUS); // Get text + nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow(); + QString Statis = m_pMaintable->text(nRealrow, TITRAQ_IDXSTATUS); // Get text // Quick review of data validity, and set pixmaps accordingly - if (m_pMaintable->text(nRow, TITRAQ_IDXUSER).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXGUID).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXCRC).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXREV).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXDATE).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXSTART).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXFINISH).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXAMOUNT).isEmpty() || - m_pMaintable->text(nRow, TITRAQ_IDXTASK).isEmpty()) + if (m_pMaintable->text(nRealrow, TITRAQ_IDXUSER).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXGUID).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXCRC).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXREV).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXDATE).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXSTART).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXAMOUNT).isEmpty() || + m_pMaintable->text(nRealrow, TITRAQ_IDXTASK).isEmpty()) { // No K&R style to show where actual code begins if (Statis.startsWith(QString("W"))) { // Conditionally set pixmap to avoid overhead // FIXME: Next line commented out, and I see that this algorythm needs help -// m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRow, TITRAQ_IDXSTATUS)); +// m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS)); } else if (!Statis.startsWith(QString("E"))) { // Conditionally set pixmap to avoid overhead - m_pMaintable->setText(nRow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'E')); - m_pMaintable->setPixmap(nRow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStaterror_xpm)); - m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRow, TITRAQ_IDXSTATUS)); + m_pMaintable->setText(nRealrow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'E')); + m_pMaintable->setPixmap(nRealrow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStaterror_xpm)); + m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS)); } } else { if (!Statis.startsWith(QString("O"))) { // Conditionally set pixmap to avoid overhead - m_pMaintable->setText(nRow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'O')); - m_pMaintable->setPixmap(nRow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatokay_xpm)); - m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRow, TITRAQ_IDXSTATUS)); + m_pMaintable->setText(nRealrow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'O')); + m_pMaintable->setPixmap(nRealrow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatokay_xpm)); + m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS)); } } } @@ -1264,8 +1326,8 @@ // A quasi diff summary to transmit to the server QString Syncthis; int nRow = m_pMaintable->currentRow(); - Syncthis += m_pMaintable->text(nRow, 0); - for (int nIter = 1; nIter < TITRAQ_IDXTAIL; nIter++) + Syncthis += m_pMaintable->text(nRow, TITRAQ_IDXUSER); + for (int nIter = TITRAQ_IDXUSER + 1; nIter < TITRAQ_IDXTAIL; nIter++) Syncthis += ' ' + m_pMaintable->text(nRow, nIter); Clistr = Syncthis; // Build RPC parameter