head 1.56; access; symbols AS_AFTER_RESTRUCTURING:1.9; locks; strict; comment @// @; 1.56 date 2004.08.26.19.12.48; author ms; state Exp; branches; next 1.55; 1.55 date 2004.08.20.17.47.07; author ms; state Exp; branches; next 1.54; 1.54 date 2004.05.27.21.48.41; author ms; state Exp; branches; next 1.53; 1.53 date 2004.05.27.21.42.26; author ms; state Exp; branches; next 1.52; 1.52 date 2003.11.20.11.31.20; author ms; state Exp; branches; next 1.51; 1.51 date 2003.02.28.17.12.24; author ms; state Exp; branches; next 1.50; 1.50 date 2003.02.19.18.19.19; author ms; state Exp; branches; next 1.49; 1.49 date 2003.02.14.19.27.03; author ms; state Exp; branches; next 1.48; 1.48 date 2003.02.14.17.31.54; author ms; state Exp; branches; next 1.47; 1.47 date 2003.02.11.22.17.17; author ms; state Exp; branches; next 1.46; 1.46 date 2003.02.11.14.19.57; author ms; state Exp; branches; next 1.45; 1.45 date 2003.02.06.15.27.39; author ms; state Exp; branches; next 1.44; 1.44 date 2003.02.06.14.10.33; author ms; state Exp; branches; next 1.43; 1.43 date 2003.02.05.13.58.02; author ms; state Exp; branches; next 1.42; 1.42 date 2003.02.04.19.30.31; author ms; state Exp; branches; next 1.41; 1.41 date 2003.02.03.21.14.58; author ms; state Exp; branches; next 1.40; 1.40 date 2003.02.03.14.12.09; author ms; state Exp; branches; next 1.39; 1.39 date 2003.01.30.20.26.03; author ms; state Exp; branches; next 1.38; 1.38 date 2003.01.30.18.23.00; author ms; state Exp; branches; next 1.37; 1.37 date 2003.01.30.18.18.30; author ms; state Exp; branches; next 1.36; 1.36 date 2003.01.28.17.33.55; author ms; state Exp; branches; next 1.35; 1.35 date 2003.01.27.17.56.56; author ms; state Exp; branches; next 1.34; 1.34 date 2003.01.27.12.39.19; author ms; state Exp; branches; next 1.33; 1.33 date 2003.01.24.16.32.18; author ms; state Exp; branches; next 1.32; 1.32 date 2002.12.20.17.42.10; author ms; state Exp; branches; next 1.31; 1.31 date 2002.12.20.15.13.52; author ms; state Exp; branches; next 1.30; 1.30 date 2002.12.19.20.46.26; author ms; state Exp; branches; next 1.29; 1.29 date 2002.12.19.12.53.56; author ms; state Exp; branches; next 1.28; 1.28 date 2002.12.18.12.36.16; author ms; state Exp; branches; next 1.27; 1.27 date 2002.12.17.14.08.33; author ms; state Exp; branches; next 1.26; 1.26 date 2002.12.16.17.13.17; author ms; state Exp; branches; next 1.25; 1.25 date 2002.12.16.12.11.40; author ms; state Exp; branches; next 1.24; 1.24 date 2002.12.16.10.45.25; author ms; state Exp; branches; next 1.23; 1.23 date 2002.12.16.09.58.34; author ms; state Exp; branches; next 1.22; 1.22 date 2002.12.13.23.42.37; author ms; state Exp; branches; next 1.21; 1.21 date 2002.12.13.20.50.18; author ms; state Exp; branches; next 1.20; 1.20 date 2002.12.13.11.46.38; author ms; state Exp; branches; next 1.19; 1.19 date 2002.12.12.18.48.16; author ms; state Exp; branches; next 1.18; 1.18 date 2002.12.12.17.14.49; author ms; state Exp; branches; next 1.17; 1.17 date 2002.12.10.13.08.29; author ms; state Exp; branches; next 1.16; 1.16 date 2002.12.06.15.40.50; author ms; state Exp; branches; next 1.15; 1.15 date 2002.12.05.12.37.18; author ms; state Exp; branches; next 1.14; 1.14 date 2002.12.04.19.57.11; author ms; state Exp; branches; next 1.13; 1.13 date 2002.12.04.11.18.12; author ms; state Exp; branches; next 1.12; 1.12 date 2002.12.03.18.46.25; author ms; state Exp; branches; next 1.11; 1.11 date 2002.12.03.17.34.19; author ms; state Exp; branches; next 1.10; 1.10 date 2002.12.02.13.25.36; author ms; state Exp; branches; next 1.9; 1.9 date 2002.11.28.20.44.36; author ms; state Exp; branches; next 1.8; 1.8 date 2002.11.26.23.26.07; author ms; state Exp; branches; next 1.7; 1.7 date 2002.11.26.14.10.32; author ms; state Exp; branches; next 1.6; 1.6 date 2002.11.24.23.11.56; author ms; state Exp; branches; next 1.5; 1.5 date 2002.11.22.21.51.58; author ms; state Exp; branches; next 1.4; 1.4 date 2002.11.22.21.14.27; author ms; state Exp; branches; next 1.3; 1.3 date 2002.11.22.19.49.19; author ms; state Exp; branches; next 1.2; 1.2 date 2002.11.22.19.42.25; author ms; state Exp; branches; next 1.1; 1.1 date 2002.11.22.11.46.32; author ms; state Exp; branches; next ; desc @@ 1.56 log @Draw a smoother loadData() display, eliminating unappealing flashes. @ text @// // OSSP asgui - Accounting system graphical user interface // Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/) // Copyright (c) 2002-2004 Ralf S. Engelschall // Copyright (c) 2002-2004 Michael Schloh von Bennewitz // Copyright (c) 2002-2004 Cable & Wireless Telecommunications Services GmbH // // This file is part of OSSP asgui, an accounting system graphical user // interface which can be found at http://www.ossp.org/pkg/tool/asgui/. // // Permission to use, copy, modify, and distribute this software for // any purpose with or without fee is hereby granted, provided that // the above copyright notice and this permission notice appear in all // copies. // // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // // as_dataops.cpp: ISO C++ implementation // // System headers #include #include // Qt general headers #include // Portable regular expressions #include #include #include #include #include // User interface #include "as_const.h" // Application constants #include "as_tableitem.h" // For class RtTableItem #include "as_crc.h" // For quality strings #include "as_uuid.h" // UUID classes #include "as_table.h" // TiTable class // Icon pixel maps #include "as_gfx/statok.xpm" // static const char *s_kpcStatokay_xpm[] #include "as_gfx/staterr.xpm" // static const char *s_kpcStaterror_xpm[] #include "as_gfx/statwrn.xpm" // static const char *s_kpcStatwarn_xpm[] // // Convenience method to load accounts from a file // void Titraqform::loadAccounts(QFile &Fileobj) { if (Fileobj.isOpen()) { // Check state of file Fileobj.flush(); // Begin processing file cleanly QTextStream Account(&Fileobj); // Convert data to stream this->loadAccounts(Account); // Pass off to do the real work } else { if (!Fileobj.open(IO_ReadOnly)) { // Try to open file QString Readerrstr; Readerrstr = trUtf8(TITRAQ_READAFILFAIL).arg(Fileobj.name()); throw Genexcept(Readerrstr.ascii()); } else Fileobj.flush(); // Begin processing file cleanly QTextStream Account(&Fileobj); // Convert data to stream this->loadAccounts(Account); // Pass off to do the real work Fileobj.close(); // Finish fileop by closing } } // // Load accounts themselves data from a stream // void Titraqform::loadAccounts(QTextStream &Tstream) { using namespace std; // Needed for hash tables with hmap map Hashnames; // Hashtable for storing names map Hashnums; // Hashtable for storing repetitions map::iterator Nameiter; // The hashtable name iterator map::iterator Numiter; // The hashtable number iterator QString Line; // Used for linewise editing and whitespace eating // Eat lines until reading the start accounts token while (!Line.startsWith(trUtf8("%!AS-ACCOUNTS")) && !Tstream.atEnd()) { Line = QString(""); // Empty line for later inspection Line = Tstream.readLine(); // Get a new line to examine } // Strip out extra line feeds in stream while (Line.isEmpty() && !Tstream.atEnd()) { Tstream.skipWhiteSpace(); // Strip and get Line = Tstream.readLine(); // the new line if (Line.at(0) == QChar('#')) // Remove comments Line = QString(""); } // Set the accounts choices by linewise reading from the input // stream and parsing the corresponding account fields out of it while (!Line.isEmpty()) { QString Temp; // For reading from stream QTextStream Asline(&Line, IO_ReadOnly); // Convert a single line Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Temp; // Copy revision indicator if (Temp == QString(QChar('R'))) { // Copy the account field Asline >> Temp; // to temporary for transfer string Convstring = Temp; // Convert to string (can't cast?) Hashnames[Convstring] += Hashnames[Convstring]; } Line = QString(""); // Clear line for next round while (Line.isEmpty() && !Tstream.atEnd()) { Tstream.skipWhiteSpace(); // Strip and get Line = Tstream.readLine(); // the new line if (Line.at(0) == QChar('#')) // Remove comments Line = QString(""); } } // Hashnames.insert(map::value_type((string)QString, int)); for (Nameiter = Hashnames.begin(); Nameiter != Hashnames.end(); Nameiter++) Hashnums[Nameiter->second] += Nameiter->first + '\n'; // FIXME: Put this in loadData, to load custom and most used task names before // FIXME: default listings are sorted and inserted for (Numiter = Hashnums.begin(); Numiter != Hashnums.end(); Numiter++) { // Count the number of lines of sorted task names int nNumlines = QString(Numiter->second).contains('\n'); // Iterate through the lines of task names, feeding them into the menu for (int nIter = 0; nIter < nNumlines; nIter++) *m_pTaskentries << QString(Numiter->second).section('\n', nIter, nIter); } } // // Convenience method to load personal data from a file // void Titraqform::loadData(QFile &Fileobj) { if (Fileobj.isOpen()) { // Check state of file Fileobj.flush(); // Begin processing file cleanly QTextStream Asentry(&Fileobj); // Convert data to stream this->loadData(Asentry); // Pass off to do the real work } else { if (!Fileobj.open(IO_ReadOnly)) // Try to open file throw Genexcept(trUtf8(TITRAQ_READPFILFAIL)); else Fileobj.flush(); // Begin processing file cleanly QTextStream Asentry(&Fileobj); // Convert data to stream this->loadData(Asentry); // Pass off to do the real work Fileobj.close(); // Finish fileop by closing } } // // Load personal data from a stream // void Titraqform::loadData(QTextStream &Tstream) { bool bValid = true; // Used to warn on globally invalid accounting data int nIter = 0; // Iterator used in loop and also as a count QString Line; // Used for linewise editing and whitespace eating QString Bitbucket; // Used for null device until we find a better way QPixmap Statokay(s_kpcStatokay_xpm); QPixmap Statwarn(s_kpcStatwarn_xpm); QPixmap Staterror(s_kpcStaterror_xpm); // Strip out extra line feeds at stream start while (Line.isEmpty() && !Tstream.atEnd()) { Tstream.skipWhiteSpace(); // Strip and get Line = Tstream.readLine(); // the new line if (Line.at(0) == QChar('#')) // Remove comments Line = QString(""); } // Strip out extra line feeds after reading the data symbol Line = QString(""); // Reset our line while (Line.isEmpty() && !Tstream.atEnd()) { Tstream.skipWhiteSpace(); // Strip and get Line = Tstream.readLine(); // the new line if (Line.at(0) == QChar('#')) // Remove comments Line = QString(""); } // // Going into data churning, so prepare date and time parsing and conversion // Converdate.setSeparator(trUtf8(".")); // Convertime.setSeparator(trUtf8(":")); // Optimize viewing by repainting cells only once after processing m_pMaintable->setUpdatesEnabled(false); // Set the table text by linewise reading from the input stream // and parsing date, time, account, and other columns out of it while (!Line.isEmpty()) { bool bValid = true; // Warns on linewise invalid accounting data QString User, Guid, Crc, Rev; // Valid admin fields QString Date, Start, Finish, Account, Amount, Remark; // Valid user fields QTextStream Asline(&Line, IO_ReadOnly); // Convert a single line now if (nIter % g_knBlocks == 0) // Add blocks of rows to optimize loading m_pMaintable->setNumRows(m_pMaintable->numRows() + g_knBlocks); Asline.skipWhiteSpace(); // Remove whitespaces Asline >> User; // Copy the user field if (!User.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXUSER, User); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Guid; // Copy the GUID field // Postpone actual text delivery, to autoinsert GUIDs! Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Crc; // Copy the CRC field // Postpone actual text delivery, to autoinsert CRCs! Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Rev; // Copy the rev field if (!Rev.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXREV, Rev); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Date; // Copy the date field if (!Date.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXDATE, Date); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Start; // Copy the start field if (!Start.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXSTART, Start); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Finish; // Copy the finish field if (!Finish.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXFINISH, Finish); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Amount; // Copy the amount field if (!Amount.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXAMOUNT, Amount); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Account; // Copy the account field if (!Account.isEmpty()) { QTableItem *pOld = m_pMaintable->item(nIter, TITRAQ_IDXTASK); delete(pOld); // Get rid of the old before going with the new RtTableItem *pSwapitem = new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Account); pSwapitem->setAlignment(AlignLeft | AlignVCenter); m_pMaintable->setItem(nIter, TITRAQ_IDXTASK, pSwapitem); } else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces Remark = Asline.read(); // Copy the remark field QRegExp Quoted("\"(.*[^\\\\])\""); // Get rid of Quoted.search(Remark); // surrounding double Remark = Quoted.cap(Quoted.numCaptures()); // quotes, and Remark.replace(QRegExp("\\\\(.)"), QString("\\1")); // escape backslashes if (!Remark.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXREMARK, Remark); if (bValid) { // Show a bitmap to signal valid or error state m_pMaintable->setText(nIter, TITRAQ_IDXSTATUS, QString(QChar('O'))); m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, Statokay); } else { m_pMaintable->setText(nIter, TITRAQ_IDXSTATUS, QString(QChar('E'))); m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, Staterror); } // Set the GUID text here, in case we need to generate a fresh value if (!Guid.isEmpty()) { if (Guid != ".") // This means, generate a fresh GUID value m_pMaintable->setText(nIter, TITRAQ_IDXGUID, Guid); else { AS::Uuid Guidi; // For GUID production Guidi.genId(); m_pMaintable->setText(nIter, TITRAQ_IDXGUID, Guidi.getString()); } } else // if isEmpty() bValid = false; // Set the CRC text here, in case we need to generate a fresh value if (!Crc.isEmpty()) { if (Crc != ".") // This means, generate a fresh CRC value m_pMaintable->setText(nIter, TITRAQ_IDXCRC, "0x" + Crc); else { // Make our long tuple to run through the CRC32 generator Qualistring Testuple = User + Guid + Rev + Date + Start; Testuple += Finish + Amount + Account + Remark; U32 Valcrc = Testuple.getCrc(); // Finally set the checksum to its new value QString Crcstr = QString::number(Valcrc, 16).rightJustify(8, '0'); m_pMaintable->setText(nIter, TITRAQ_IDXCRC, "0x" + Crcstr); } } else // if isEmpty() bValid = false; nIter++; // The big increment Line = QString(""); // Clear line for next round while (Line.isEmpty() && !Tstream.atEnd()) { // Strip and get Tstream.skipWhiteSpace(); // Remove white Line = Tstream.readLine(); // the new line if (Line.at(0) == QChar('#')) // Remove comments Line = QString(""); } } // // 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--) m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0'))); m_pMaintable->setNumRows(nIter); // No excess rows m_pMaintable->setCurrentCell(nIter - 1, 0); // Move focus to last row m_pMaintable->setUpdatesEnabled(true); // Update m_pMaintable->ensureCellVisible(nIter - 1, 0); // Scroll please if (!bValid) throw Genexcept("Warning: invalid accounting data."); } // // Convenience method to save accounting data to a file // void Titraqform::saveData(QFile &Fileobj) { if (Fileobj.isOpen()) { // Check state of file Fileobj.flush(); // Begin processing file cleanly QTextStream Asentry(&Fileobj); // Convert data to stream this->saveData(Asentry); // Pass off to do the real work } else { if (!Fileobj.open(IO_WriteOnly)) // Try to open file throw Genexcept(trUtf8(TITRAQ_READPFILFAIL)); QTextStream Asentry(&Fileobj); // Convert data to stream this->saveData(Asentry); // Pass off to do the real work Fileobj.close(); // Finish fileop by closing } } // // Save accounting data to a stream // void Titraqform::saveData(QTextStream &Tstream) { const int nRows = m_pMaintable->numRows(); // Max rows used in loop QString Tempfield; // Current field string QString Strsearch; // String to strip search QRegExp Stripper("\\s*$"); // Pattern to strip off // Start by prepending the AS data format version symbol Tstream << TITRAQ_DATAPATTERN << TITRAQ_DATAVERSIONMAJ << QChar('.') << TITRAQ_DATAVERSIONMIN << endl; // Linewise save from the main table date, time, account, and others for (int nIter = 0; nIter < nRows; nIter++) { Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXUSER); // Load user field text if (Tempfield != NULL) Tstream << Tempfield; // Save user field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXGUID); // Load GUID field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save GUID field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXCRC); // Load CRC field text Tempfield.remove("0x"); if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save CRC field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXREV); // Load rev field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save rev field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXDATE); // Load date field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save date field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXSTART); // Load start field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save start field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXFINISH); // Load end field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save end field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXAMOUNT); // Load amount field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save amount Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXTASK); // Load acct field text if (Tempfield != NULL) Tstream << trUtf8(" ") << Tempfield; // Save acct field text Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXREMARK); // Load remark field text Tstream << trUtf8(" \""); // Save beginning double quote if (Tempfield != NULL) { Strsearch = QRegExp::escape(Tempfield); // Incoming string escaped Stripper.search(Strsearch); Tempfield.truncate(Stripper.pos()); // Cut off whitespace Tempfield.replace(QChar('\\'), QString("\\\\")); // Escape back slashes Tempfield.replace(QChar('\"'), QString("\\\"")); // Escape double quotes Tstream << Tempfield; // Save remark field text } Tstream << trUtf8("\""); // Save ending double quote Tstream << endl; // Append a newline } } // // Convenience method to validate AS data in a file // const bool Titraqform::validateData(QFile &Filin) const { QString Firstline; // Will contain the first line of text bool bRet = false; // Set the initial return value if (Filin.isOpen()) { // Check open state of file Filin.flush(); // Not sure if this is needed Filin.reset(); // Set the file index position to 0 Filin.readLine(Firstline, QString(TITRAQ_DATAPATTERN).length() + 2L); } else { if (!Filin.open(IO_ReadOnly)) // Try to open file throw Genexcept(trUtf8(TITRAQ_READPFILFAIL)); else { // File is now open Filin.readLine(Firstline, QString(TITRAQ_DATAPATTERN).length() + 2L); Filin.close(); // Remember to close } } try { // Pass off to worker method bRet = this->validateData(Firstline); } catch (Genexcept &) { throw; // Rethrow onwards } return bRet; } // // Validate the AS data pattern in a line // const bool Titraqform::validateData(QString &Linin) const { bool bRet = false; // Initial return value // Ensure that the right data version pattern precedes the data QString Datapattern = QString(TITRAQ_DATAPATTERN); if (!Linin.startsWith(Datapattern)) { // Incompatible data format QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_NOPATTERNFOUND + QString(TITRAQ_DATAPATTERN) + TITRAQ_WASNOTFOUNDIN, QMessageBox::Critical, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INVALIDDATA); } else if (Linin.section(Datapattern, 1).section('.', 0, 0).toInt() != TITRAQ_DATAVERSIONMAJ) { QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_BADVERSIONMAJ, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INCOMPATDATA); } else if (Linin.section(Datapattern, 1).section('.', 1, 1).toInt() > TITRAQ_DATAVERSIONMIN) { QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_BADVERSIONMIN, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INCOMPATDATA); } else bRet = true; return bRet; // Not reached in case of failure } // // Get a whole row of data // const QString Titraqform::getRowdata(void) const { QString Rowdata, Tempstring; // For output string QTableSelection Select = m_pMaintable->selection(0); // Highlighted text int nTotal = Select.bottomRow() - Select.topRow() + 1; // Total row select // Calculate rows to delete from selection highlight for (int nIter = 0; nIter < nTotal; ++nIter) { // Build the row data string one field at a time, adding seps inbetween Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXLINE); if (!Tempstring.isEmpty()) Rowdata += Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXGUID); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXCRC); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXTASK); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREMARK); if (!Tempstring.isEmpty()) Rowdata += TITRAQ_SEPARATORTOK + Tempstring; Rowdata += trUtf8("\n"); // Finish off line } return Rowdata; } // // Set a whole row of data // void Titraqform::setRowdata(QString &Rowdata) const { int nRows = Rowdata.contains(QChar('\n')); // Set so many rows int nCurrentrow = m_pMaintable->currentRow(); // Current table row QTableItem *pItem = NULL; // Old item to change out QString Line, User, Guid, Crc, Rev; // Admin fields in table QString Date, Start, Finish, Amount, Task, Remark; // Viewable fields in table QTextStream Datastream(&Rowdata, IO_ReadOnly); // Convert data to stream for (int nIter = 0; nIter < nRows; ++nIter) { QString Singlerow = Datastream.readLine(); // For linewise operation QTextStream Rowstream(&Singlerow, IO_ReadOnly); // Convert row to stream Rowstream >> Line >> User >> Guid >> Crc >> Rev; // Stream data fields Rowstream >> Date >> Start >> Finish >> Amount >> Task; // to corresponding vars 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_IDXCRC, Crc); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREV, Rev); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXDATE, Date); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXSTART, Start); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXFINISH, Finish); m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXAMOUNT, Amount); // // FIXME: Why doesn't this code change the RtTableItem text in place? // RtTableItem *pTask = NULL; // Derived and special // pItem = m_pMaintable->item(nCurrentrow + nIter, TITRAQ_IDXTASK); // pTask = static_cast(pItem); // pTask->setText(Task); // Change out old item and replace with new task data pItem = m_pMaintable->item(nCurrentrow + nIter, TITRAQ_IDXTASK); delete(pItem); // Get rid of the old before going with the new RtTableItem *pSwapitem = new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Task); pSwapitem->setAlignment(AlignLeft | AlignVCenter); m_pMaintable->setItem(nCurrentrow + nIter, TITRAQ_IDXTASK, pSwapitem); // Continue with field processing business as usual m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREMARK, Remark.simplifyWhiteSpace()); } } // // Discover which column is the first in view // const int Titraqform::getFirstcol(void) const { int nIter = 0; // Is both iterator in loop and column number returned // Use column selector menu popup as sole key to determining column state while (nIter < TITRAQ_IDXTAIL && !m_pColspopup->isItemChecked(m_pColspopup->idAt(++nIter))) TITRAQ_NOP; return nIter - 1; // Return one less to account for start of item offset } @ 1.55 log @Unload validation of personal data file from load logic, move new validation block to validateData, change all cases of preexisting validateData to new name validateRow, test for valid data from now on before calling loadData, and place read data file error strings in constants header. @ text @a350 1 m_pMaintable->setUpdatesEnabled(true); // Update and repaint d353 1 @ 1.54 log @Modernize copyright text in source and graphic headers. @ text @d68 5 a72 2 if (!Fileobj.open(IO_ReadOnly)) // Try to open file throw Genexcept("Could not open account file for reading."); d161 1 a161 1 throw Genexcept("Could not open personal data file for reading."); a191 25 // Ensure that the right data version pattern precedes the data QString Datapattern = QString(TITRAQ_DATAPATTERN); if (!Line.startsWith(Datapattern)) { // Incompatible data format QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_NOPATTERNFOUND + QString(TITRAQ_DATAPATTERN) + TITRAQ_WASNOTFOUNDIN, QMessageBox::Critical, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INVALIDDATA); } else if (Line.section(Datapattern, 1).section('.', 0, 0).toInt() != TITRAQ_DATAVERSIONMAJ) { QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_BADVERSIONMAJ, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INCOMPATDATA); } else if (Line.section(Datapattern, 1).section('.', 1, 1).toInt() > TITRAQ_DATAVERSIONMIN) { QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short, TITRAQ_BADVERSIONMIN, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, QMessageBox::NoButton, QMessageBox::NoButton); Problema.exec(); // Give the user the bad news throw Genexcept(TITRAQ_INCOMPATDATA); } d372 1 a372 1 throw Genexcept("Could not open personal data file for writing."); d449 68 @ 1.53 log @Correct file names in source headers. @ text @d3 4 a6 4 // Copyright (c) 2002-2003 The OSSP Project (http://www.ossp.org/) // Copyright (c) 2002-2003 Ralf S. Engelschall // Copyright (c) 2002-2003 Michael Schloh von Bennewitz // Copyright (c) 2002-2003 Cable & Wireless Telecommunications Services GmbH @ 1.52 log @Handle the time consuming bureaucracy of changing a company name. @ text @d29 1 a29 1 // tidatops.cpp: ISO C++ implementation @ 1.51 log @Changed CRC calculation string algorhythm to pad with '0' to 8 places. @ text @a3 1 // Copyright (c) 2002-2003 Cable & Wireless Deutschland (http://www.cw.com/de/) d6 1 @ 1.50 log @Clean up, and remove unneeded QString constructors. @ text @d345 2 a346 1 m_pMaintable->setText(nIter, TITRAQ_IDXCRC, "0x" + QString::number(Valcrc, 16)); @ 1.49 log @Added logic to include prefs pixmap in both menu and toolbar, removed optional 'this' parameter from all calls to connect(), ripped out more header includes from monolithic interface header, made call of prefs panel an instance of class QAction, changed .bak file message text in class Prefpanel, and renamed default RPC hosts to show what a proper format is. @ text @d483 1 a483 1 Rowdata = Rowdata + Tempstring; d486 1 a486 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d489 1 a489 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d492 1 a492 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d495 1 a495 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d498 1 a498 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d501 1 a501 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d504 1 a504 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d507 1 a507 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d510 1 a510 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; d513 1 a513 1 Rowdata = Rowdata + trUtf8(TITRAQ_SEPARATORTOK) + Tempstring; @ 1.48 log @Moved preference data application from panel items to own method, added applyPrefs logic, and a new proxy method to handle applied signals, and reorganized file incusion in throughout to loosen source file coupling. @ text @d40 3 a44 1 #include "as_gui.h" // Main classes @ 1.47 log @Implemented thl idea, sorted task listing. Began codeblock for dynamically placed task names. @ text @d43 1 d47 1 @ 1.46 log @Hard coded left alignment into task table items, made amount control appearance and behaviour consistent with amount table items, and split remote host name and switches out of prefs panel paths page to its own remote page. @ text @d32 4 d79 7 a85 1 QString Line; // Used for linewise editing and whitespace eating d112 2 a113 1 *m_pTaskentries << Temp; // to internal account bank d123 16 @ 1.45 log @Implemented embedding of escape characters into event data file. @ text @d265 3 a267 1 m_pMaintable->setItem(nIter, TITRAQ_IDXTASK, new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Account)); d529 3 a531 1 m_pMaintable->setItem(nCurrentrow + nIter, TITRAQ_IDXTASK, new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Task)); @ 1.44 log @Ignore new autoconf file, just like Thomas does. @ text @d273 4 a276 4 QRegExp Quoted("\"(.*)[^\\]\""); // Get rid of Quoted.search(Remark); // surrounding double Remark = Quoted.cap(Quoted.numCaptures()); // quotes, and Remark.replace("\\(.)", "\1"); // escape backslashes d425 3 a427 1 Tempfield.truncate(Stripper.pos()); @ 1.43 log @Unconditionally escape remarks. @ text @d273 4 a276 4 // Get rid of surrounding double quotes QRegExp Quoted("\"(.*)\"$"); Quoted.search(Remark); Remark = Quoted.cap(Quoted.numCaptures()); @ 1.42 log @Implemented auto field completion for start and finish and auto subtraction for amount, added period for GUID replacement, and added version text to widget labels. @ text @d421 1 d426 1 a426 1 Tstream << trUtf8(" \"") << Tempfield << trUtf8("\""); // Save remark field text d428 1 @ 1.41 log @Implemented a quality string class including CRC32 generation logic, used throghout for checksum computation, added automatic fake CRC field detection and correction on load operations, and backed out inconsistent date and time field format changes. @ text @d41 1 d161 1 a161 1 QMessageBox Problema(TITRAQ_APPTITLE, d169 2 a170 2 QMessageBox Problema(TITRAQ_APPTITLE, TITRAQ_BADVERSIONMAJ, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, d176 2 a177 2 QMessageBox Problema(TITRAQ_APPTITLE, TITRAQ_BADVERSIONMIN, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape, d219 1 a219 4 if (!Guid.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXGUID, Guid); else bValid = false; d289 13 @ 1.40 log @Back out logic to recognize '-', '+', and '=' as separator symbols. @ text @d40 1 d225 1 a225 4 if (!Crc.isEmpty()) m_pMaintable->setText(nIter, TITRAQ_IDXCRC, Crc); else bValid = false; d292 15 d381 1 @ 1.39 log @Implemented writing and testing of a data version symbol. @ text @a141 1 QString Parstring; // Used to parse all extra '-' and '=' token delimiters a202 1 QString Timepack; // Packed start finish amount field d238 1 a238 3 if (!Date.isEmpty()) { Date.insert(TITRAQ_OFFSETYEAR, QChar('.')); // Format year Date.insert(TITRAQ_OFFSETMONTH, QChar('.')); // Format month a239 1 } d244 2 a245 10 Asline >> Timepack; // Hack to hard code regex parsing logic into the document format Start = Timepack.section('-', 0, 0, QString::SectionDefault); Finish = Timepack.section('-', 1, 1, QString::SectionDefault); Finish = Finish.section('=', 0, 0, QString::SectionDefault); Amount = Timepack.section('=', 1, 1, QString::SectionDefault); if (!Start.isEmpty()) { // Write start Start.insert(TITRAQ_OFFSETHOUR, QChar(':')); // Format hour a246 1 } d250 3 a252 2 if (!Finish.isEmpty()) { // Write finish Finish.insert(TITRAQ_OFFSETHOUR, QChar(':')); // Format hour a253 1 } d257 3 a259 2 if (!Amount.isEmpty()) { // Write amount Amount.insert(TITRAQ_OFFSETHOUR, QChar(':')); // Format hour a260 1 } a375 1 Tempfield.remove(QChar('.')); a379 1 Tempfield.remove(QChar(':')); a381 1 Tstream << trUtf8("-"); // Save start field text a383 1 Tempfield.remove(QChar(':')); d385 1 a385 2 Tstream << Tempfield; // Save end field text Tstream << trUtf8("="); // Save start field text a387 1 Tempfield.remove(QChar(':')); d389 1 a389 1 Tstream << Tempfield; // Save amount field text @ 1.38 log @Don't translate empty lines. @ text @d35 1 d150 34 @ 1.37 log @Write a special version symbol when serializing data to files. @ text @d76 2 a77 2 Line = trUtf8(""); // Empty line for later inspection Line = Tstream.readLine(); // Get a new line to examine d85 1 a85 1 Line = trUtf8(""); d102 1 a102 1 Line = trUtf8(""); // Clear line for next round d107 1 a107 1 Line = trUtf8(""); d153 1 a153 1 Line = trUtf8(""); d274 1 a274 1 Line = trUtf8(""); // Clear line for next round d280 1 a280 1 Line = trUtf8(""); @ 1.36 log @Fix the initial data loading a little more, and remove the logic from the first level gui object. @ text @d332 3 a334 2 // Optimize viewing by repainting cells only once after processing m_pMaintable->setUpdatesEnabled(false); a389 2 m_pMaintable->setUpdatesEnabled(true); // Update and repaint @ 1.35 log @Break the orthogonal data format and include new token separators '-' and '='. Also, add automatic file backup code back in again. @ text @d297 1 @ 1.34 log @Change all date and time data entries from ISO format to AS specific. @ text @d141 1 d169 1 d214 9 a222 2 Asline >> Start; // Copy the start field if (!Start.isEmpty()) { d229 1 a229 3 Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Finish; // Copy the finish field if (!Start.isEmpty()) { d236 1 a236 3 Asline.skipWhiteSpace(); // Remove whitespaces Asline >> Amount; // Copy the amount field if (!Amount.isEmpty()) { d361 1 d366 2 a367 1 Tstream << trUtf8(" ") << Tempfield; // Save end field text d372 1 a372 1 Tstream << trUtf8(" ") << Tempfield; // Save amount field text @ 1.33 log @Implemented checksum in all forms, and implemented a revision management system that is so primitive that I commented it out until further design. @ text @d34 1 d155 4 d203 3 a205 1 if (!Date.isEmpty()) d207 1 d213 2 a214 1 if (!Start.isEmpty()) d216 1 d222 2 a223 1 if (!Start.isEmpty()) d225 1 d231 2 a232 1 if (!Amount.isEmpty()) d234 1 d348 1 d353 1 d358 1 d363 1 @ 1.32 log @Fixed sorting and added sort direction handling. @ text @d265 5 a269 5 // 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); d439 1 a441 1 m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXGUID, Guid); @ 1.31 log @Fixed data loading bug, causing overwriting of last row with first row's data. @ text @d265 5 a269 2 // Start sorting order correctly according to user preferences m_pMaintable->sortColumn((int)m_pPrefs->getNumber(TITRAQ_PREFSORT, TITRAQ_DEFSORT)); @ 1.30 log @Added full close document and disable handling, added new dimmed icons for showing disabled state, fixed status edit control pixmap redraw, fixed remaining edit pixmap on old data, fixed get/set empy Rowdata for cut/copy/paste ops, fixed member filename corruption and data loss problem, optimized addRow and pasteRow graphic drawing, added better file name handling by accessors, and streamlined widget enablement logic in slots. @ text @a43 1 #include @ 1.29 log @Fixed pasting invalid data bug, and improved getRowdata whitespace format. @ text @a36 1 #include "as_except.h" // Exception classes @ 1.28 log @Optimize data validation algorythm for speed, using a sneaky technique by writing unviewable control text to the status bitmap field. @ text @d371 1 a371 1 QString Rowdata; // For output string d378 33 a410 21 Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXLINE); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXGUID); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXCRC); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXTASK); Rowdata += trUtf8(TITRAQ_SEPARATORTOK); Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREMARK); d430 6 a435 3 Datastream >> Line >> User >> Guid >> Crc >> Rev; // Stream data fields Datastream >> Date >> Start >> Finish >> Amount >> Task; // to corresponding vars Remark = Datastream.readLine(); // Remark is a whole line @ 1.27 log @Fix some hard to find bad saving problems, add file extension filter, and make file op exception strings more descriptive. @ text @d247 2 a248 1 if (bValid) // Show a bitmap to signal valid or error state d250 3 a252 1 else d254 1 @ 1.26 log @Preserve user preferred sort order and don't set dirty flag on renumber ops. @ text @d59 1 a59 1 throw Genexcept("Could not open account file."); d125 1 a125 1 throw Genexcept("Could not open personal data file."); d290 1 a290 1 throw Genexcept("Could not write open accounting file."); @ 1.25 log @Removed hardcoded tasks, implemented dynamic account loading, renamed conf file, corrected comment and empty line handling in load ops. @ text @a251 3 // Insert a line number dynamically m_pMaintable->setText(nIter, TITRAQ_IDXLINE, (QString::number(nIter)).rightJustify(4, QChar('0'))); d263 7 d275 1 a275 1 throw Genexcept("Warning, invalid accounting data."); @ 1.24 log @Implement missing logic for remaining new field linewise load and save ops. @ text @d48 67 a114 1 // Convenience method to load accounting data from a file d125 6 a130 4 throw Genexcept("Could not read open accounting file."); QTextStream Asentry(&Fileobj); // Convert data to stream this->loadData(Asentry); // Pass off to do the real work Fileobj.close(); // Finish fileop by closing d135 1 a135 1 // Load accounting data from a stream d149 6 a154 2 while (Line.isEmpty() && !Tstream.atEnd()) Line = Tstream.readLine(); @ 1.23 log @Fine tune before adding conf file location search, and fix a whitespace bug. @ text @d298 2 d302 6 d333 1 a333 1 QString User; // Admin fields in table d338 3 a340 3 Datastream >> User >> Date >> Start; // Stream data fields Datastream >> Finish >> Amount >> Task; // to corresponding vars Remark = Datastream.readLine(); // Remark is a whole line d343 1 d345 3 @ 1.22 log @Smooth out transition from closed to open document state, and add placeholding pixmap. Fixed row add and paste logic to include initialization and validation. Implement cut and past of user data. Fix cut and paste line feed bug. Disable edit controls until first document is created. @ text @d353 1 a353 2 Remark.simplifyWhiteSpace(); // First get rid of and simplify whitespace m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREMARK, Remark); @ 1.21 log @Implemented basic validation logic, reflected by pixmaps in both table and edit control. @ text @d298 2 a301 2 // Rowdata += m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER); // Rowdata += trUtf8(TITRAQ_SEPARATORTOK); d325 2 a326 1 QString Date, Start, Finish, Amount, Task, Remark; // Text fields in table d330 1 a330 1 Datastream >> Date >> Start; // Stream data fields a331 1 Datastream.skipWhiteSpace(); // Remove whitespaces d335 1 a336 1 // m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXUSER, User); d353 1 @ 1.20 log @Render status pixmaps more efficiently and add quote logic to load and save remark column. @ text @d231 3 d282 2 @ 1.19 log @Moved methods from as_util to as_dataop, corrected load empty field validation, use new bitmaps for validation. @ text @d45 2 d76 4 d166 6 d176 1 a176 1 m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatokay_xpm)); d178 1 a178 1 m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStaterror_xpm)); d274 1 a274 1 Tstream << trUtf8(" ") << Tempfield; // Save remark field text @ 1.18 log @Added groovey valid check mark graphic for status column, and process line numbers during load operation. @ text @d33 1 a33 1 #include // Portable regular expressions d36 3 a38 3 #include "as_gui.h" // Main classes #include "as_except.h" // Exception classes #include "as_tableitem.h" // For class RtTableItem d41 3 a43 1 #include "as_gfx/statok.xpm" // static const char *s_kpcStatokay_xpm[] d69 1 a69 1 bool bValid = true; // Used to warn on invalid accounting data d84 1 d94 1 a94 1 if (User != NULL) d101 1 a101 1 if (Guid != NULL) d108 1 a108 1 if (Crc != NULL) d115 1 a115 1 if (Rev != NULL) d122 1 a122 1 if (Date != NULL) d129 1 a129 1 if (Start != NULL) d136 1 a136 1 if (Start != NULL) d143 1 a143 1 if (Amount != NULL) d150 1 a150 1 if (Account != NULL) { d160 1 a160 1 if (Remark != NULL) d163 6 a168 2 // Dynamically display status and line numbers m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatokay_xpm)); d267 85 @ 1.17 log @Integrate formal data fields GUID, CRC, and rev to load and save ops. @ text @d32 1 d35 1 d40 2 d159 4 @ 1.16 log @Strip trailing whitespace from remark field on save operations. @ text @d78 2 a79 1 QString Date, Start, Finish, Account, Amount, Remark; // Valid fields d86 28 a119 2 Asline >> Bitbucket; // Ignore user field d121 1 a121 1 Asline >> Start; // Copy the date field d128 1 a128 1 Asline >> Finish; // Copy the date field d135 7 a151 7 Asline >> Amount; // Copy the amount field if (Amount != NULL) m_pMaintable->setText(nIter, TITRAQ_IDXAMOUNT, Amount); else bValid = false; Asline.skipWhiteSpace(); // Remove whitespaces a199 1 bool bValid = true; // Warn on invalid data d206 9 a214 1 Tempfield = m_pMaintable->text(nIter, 0); // Load date field text d216 5 a220 3 Tstream << Tempfield; // Save date field text else bValid = false; d222 3 a224 2 // Save user field text Tstream << trUtf8(" ") << m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER); d226 1 a226 1 Tempfield = m_pMaintable->text(nIter, 1); // Load start field text d228 1 a228 3 Tstream << trUtf8(" ") << Tempfield; // Save start field text // else // bValid = false; d230 1 a230 1 Tempfield = m_pMaintable->text(nIter, 2); // Load end field text d232 1 a232 3 Tstream << trUtf8(" ") << Tempfield; // Save end field text // else // bValid = false; d234 1 a234 1 Tempfield = m_pMaintable->text(nIter, 4); // Load amount field text d236 1 a236 3 Tstream << trUtf8(" ") << Tempfield; // Save amount field text else bValid = false; d238 1 a238 1 Tempfield = m_pMaintable->text(nIter, 3); // Load acct field text d240 1 a240 3 Tstream << trUtf8(" ") << Tempfield; // Save acct field text else bValid = false; d242 1 a242 1 Tempfield = m_pMaintable->text(nIter, 5); // Load remark field text d244 1 a244 1 Strsearch = QRegExp::escape(Tempfield); // Incoming string escaped d247 1 a247 1 Tstream << trUtf8(" ") << Tempfield; // Save remark field text a248 2 else bValid = false; d250 1 a250 1 Tstream << endl; // Append a newline @ 1.15 log @Improve line handling on data load. @ text @d173 1 d175 2 a176 1 bool bValid = true; // Warn on invalid data d214 4 a217 1 if (Tempfield != NULL) d219 1 @ 1.14 log @Plug memory leak in data loader. @ text @d129 2 a130 2 nIter++; // The big increment Line = ""; // Clear line for next round d132 6 a137 2 while (Line.isEmpty() && !Tstream.atEnd()) // Strip and get Line = Tstream.readLine(); // the new line @ 1.13 log @Integrate mandatory start and finish time fields into current load processing. @ text @d110 2 @ 1.12 log @Add windows and unix logic to retreive current user name, and apply it in preferences, loading, and saving data. @ text @d66 1 d78 1 a78 1 QString Date, Account, Amount, Remark; // Fields of a valid AS file d87 1 a87 1 m_pMaintable->setText(nIter, 0, Date); d91 15 a105 1 Asline >> Account; // Copy to the bit bucket d110 1 a110 1 m_pMaintable->setItem(nIter, 4, new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Account)); d118 1 a118 1 m_pMaintable->setText(nIter, 3, Amount); d125 1 a125 1 m_pMaintable->setText(nIter, 5, Remark); @ 1.11 log @Fix empty or last line loading and saving problem, and compress spaces more efficiently. @ text @d163 2 a164 1 Tstream << trUtf8(" ") << trUtf8("user"); // Save user field text @ 1.10 log @Logic changes to correct the buildconf after CVS restructure. @ text @d65 5 d76 3 a78 7 while (!Tstream.atEnd()) { QString Date, Account, Amount, Remark; // Fields of a valid AS file QString Temp; // Used for linewise editing while (Temp.isEmpty() && !Tstream.atEnd()) // Strip out extra line feed Temp = Tstream.readLine(); QTextStream Asline(&Temp, IO_ReadOnly); // Convert a single line now d83 2 a84 1 Asline >> Date; // Copy the date field d90 4 a93 2 Asline >> Account; // Copy to the bit bucket Asline >> Account; // Copy the account field d100 2 a101 1 Asline >> Amount; // Copy the amount field d107 2 a108 1 Remark = Asline.read(); // Copy the remark field d112 5 a116 1 nIter++; // The big increment d120 1 a120 1 m_pMaintable->setNumRows(nIter - 1); // Trim excess rows d156 1 a156 1 for (int nIter = 0; nIter <= nRows; nIter++) { @ 1.9 log @Massive build configuration preparation, added boilerplate header text, and cleaned up whitespace. @ text @d32 1 a32 1 #include // Portable regular expressions d34 3 a36 3 #include "titraq.h" // Main classes #include "titrex.h" // Exception classes #include "titabitem.h" // For class RtTableItem @ 1.8 log @Implemented edition controls, corrected amount formatting, and corrected file format saving. @ text @d1 31 d158 2 a159 2 /* else bValid = false;*/ d164 2 a165 2 /* else bValid = false;*/ @ 1.7 log @Add edit toolbar to eventually replace bottom button matrix, and correct edit control update logic to avoid needlessly updating controls from empty fields. @ text @d118 1 a118 1 Tstream << Tempfield << trUtf8(" "); // Save date field text d122 1 a122 1 Tstream << trUtf8("user "); // Save user field text d124 1 a124 1 /* Tempfield = m_pMaintable->text(nIter, 1); // Load start field text d126 3 a128 3 Tstream << Tempfield << trUtf8(" "); // Save start field text else bValid = false; d132 2 a133 2 Tstream << Tempfield << trUtf8(" "); // Save end field text else d138 1 a138 1 Tstream << Tempfield << trUtf8(" "); // Save amount field text d144 1 a144 1 Tstream << Tempfield << trUtf8(" "); // Save acct field text d150 1 a150 1 Tstream << Tempfield << trUtf8(" "); // Save remark field text @ 1.6 log @Implemented table data saving to a local file, and began new accessor method group with setDirty(). @ text @d78 3 a80 4 m_pMaintable->setUpdatesEnabled(true); // Repaint all m_pMaintable->setNumRows(nIter - 1); // Trim unneeded rows m_pRemark->setText(trUtf8("Loaded text goes here")); m_pRemark->setEdited(false); // Reset widget @ 1.5 log @Some final fine tunes before putting the pig to bed. @ text @d7 1 d20 1 a20 1 throw Genexcept("Could not open accounting file."); d33 1 a33 1 int i = 0; // Iterator used in loop and also as a count d48 1 a48 1 if (i % g_knBlocks == 0) // Add blocks of rows to optimize loading speed d53 1 a53 1 m_pMaintable->setText(i, 0, Date); d60 1 a60 1 m_pMaintable->setItem(i, 4, new RtTableItem(m_pMaintable, QTableItem::WhenCurrent, Account)); d67 1 a67 1 m_pMaintable->setText(i, 3, Amount); d73 1 a73 1 m_pMaintable->setText(i, 5, Remark); d75 1 a75 1 i++; // The big increment d79 1 a79 1 m_pMaintable->setNumRows(i - 1); // Trim unneeded rows d85 72 @ 1.4 log @Improved account table viewing and movement, fixed whatsthis text and images, refitted columns to new text dimensions. @ text @d78 1 a78 2 m_pMaintable->setNumRows(i); // Trim unneeded rows m_pMaintable->repaint(); // Force repaint d80 1 a80 1 m_pRemark->setEdited(false); // Reset widget @ 1.3 log @Wrote class RtTableItem to replace right-aligned table cells, missing from the stock Qt widgets. @ text @d32 4 d39 1 a39 1 for (int i = 0; !Tstream.atEnd(); i++) { d73 2 d77 3 @ 1.2 log @Added exceptions to data ops, completed main static file loading logic, and removed hard coded table limits. @ text @d5 1 a5 1 d55 1 a55 4 QRegExp Shorten("/(\\w+)$"); Account = QRegExp::escape(Account); Account.remove(0, Shorten.search(Account)); m_pMaintable->setText(i, 4, Shorten.cap(Shorten.numCaptures())); @ 1.1 log @Start using real AS data, correct load logic, and move data operations to tidatops. @ text @d1 4 a4 1 #include "titraq.h" d15 1 a15 1 loadData(Asentry); // Pass off to do the real work d18 2 a19 2 if (!Fileobj.open(IO_ReadOnly)) // Need a wrapped exception here, return; // instead of a short circuit d21 1 a21 1 loadData(Asentry); // Pass off to do the real work d31 48 a78 2 m_pRemark->setText(Tstream.readLine()); // Read from stream m_pRemark->setEdited(false); // Reset widget a79 1 @