as_dataop.cpp

Thu, 06 Aug 2009 13:21:30 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 06 Aug 2009 13:21:30 +0200
changeset 15
0e0eb7c91312
parent 12
ceb4ba3d2d00
permissions
-rw-r--r--

Remove seemingly declarations unnecessary according to Qt 4.5.2 headers.

     1 //
     2 //  OSSP asgui - Accounting system graphical user interface
     3 //  Copyright (c) 2002-2009 The OSSP Project (http://www.ossp.org/)
     4 //  Copyright (c) 2002-2009 Ralf S. Engelschall <rse@engelschall.com>
     5 //  Copyright (c) 2002-2009 Michael Schloh von Bennewitz <michael@schloh.com>
     6 //  Copyright (c) 2002-2009 Cable & Wireless Telecommunications Services GmbH
     7 //
     8 //  This file is part of OSSP asgui, an accounting system graphical user
     9 //  interface which can be found at http://asgui.europalab.com/.
    10 //
    11 //  Permission to use, copy, modify, and distribute this software for
    12 //  any purpose with or without fee is hereby granted, provided that
    13 //  the above copyright notice and this permission notice appear in all
    14 //  copies.
    15 //
    16 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    17 //  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    18 //  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    19 //  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    20 //  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    21 //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    22 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    23 //  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    24 //  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    25 //  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    26 //  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    27 //  SUCH DAMAGE.
    28 //
    29 //  as_dataops.cpp: ISO C++ implementation
    30 //
    32 // System headers
    33 #include <map>
    34 #include <string>
    36 // Qt general headers
    37 #include <qregexp.h>            // Portable regular expressions
    38 #include <qdatetime.h>
    39 #include <qmessagebox.h>
    40 #include <q3textstream.h>
    41 #include <q3popupmenu.h>
    42 #include <qfile.h>
    43 //Added by qt3to4:
    44 #include <QPixmap>
    46 // User interface
    47 #include "as_const.h"           // Application constants
    48 #include "as_tableitem.h"       // For class RtTableItem
    49 #include "as_crc.h"             // For quality strings
    50 #include "as_uuid.h"            // UUID classes
    51 #include "as_table.h"           // TiTable class
    53 // Icon pixel maps
    54 #include "as_gfx/statok.xpm"    // static const char *s_kpcStatokay_xpm[]
    55 #include "as_gfx/staterr.xpm"   // static const char *s_kpcStaterror_xpm[]
    56 #include "as_gfx/statwrn.xpm"   // static const char *s_kpcStatwarn_xpm[]
    59 //
    60 // Convenience method to load accounts from a file
    61 //
    62 void Titraqform::loadAccounts(QFile &Fileobj)
    63 {
    64     if (Fileobj.isOpen()) {             // Check state of file
    65         Fileobj.flush();                // Begin processing file cleanly
    66         Q3TextStream Account(&Fileobj);  // Convert data to stream
    67         this->loadAccounts(Account);    // Pass off to do the real work
    68     }
    69     else {
    70         if (!Fileobj.open(QIODevice::ReadOnly)) {   // Try to open file
    71             QString Readerrstr;
    72             Readerrstr = trUtf8(TITRAQ_READAFILFAIL).arg(Fileobj.name());
    73             throw Genexcept(Readerrstr.ascii());
    74         }
    75         else
    76             Fileobj.flush();                // Begin processing file cleanly
    77             Q3TextStream Account(&Fileobj);  // Convert data to stream
    78             this->loadAccounts(Account);    // Pass off to do the real work
    79             Fileobj.close();                // Finish fileop by closing
    80     }
    81 }
    83 //
    84 // Load accounts themselves data from a stream
    85 //
    86 void Titraqform::loadAccounts(Q3TextStream &Tstream)
    87 {
    88     using namespace std;                // Needed for hash tables with hmap
    89     map<string, int> Hashnames;         // Hashtable for storing names
    90     map<int, string> Hashnums;          // Hashtable for storing repetitions
    91     map<string, int>::iterator Nameiter; // The hashtable name iterator
    92     map<int, string>::iterator Numiter;  // The hashtable number iterator
    94     QString Line;           // Used for linewise editing and whitespace eating
    96     // Eat lines until reading the start accounts token
    97     while (!Line.startsWith(trUtf8("%!AS-ACCOUNTS")) && !Tstream.atEnd()) {
    98         Line = QString("");         // Empty line for later inspection
    99         Line = Tstream.readLine();  // Get a new line to examine
   100     }
   102     // Strip out extra line feeds in stream
   103     while (Line.isEmpty() && !Tstream.atEnd()) {
   104         Tstream.skipWhiteSpace();       // Strip and get
   105         Line = Tstream.readLine();      // the new line
   106         if (Line.at(0) == QChar('#'))   // Remove comments
   107             Line = QString("");
   108     }
   110     // Set the accounts choices by linewise reading from the input
   111     // stream and parsing the corresponding account fields out of it
   112     while (!Line.isEmpty()) {
   113         QString Temp;                           // For reading from stream
   114         Q3TextStream Asline(&Line, QIODevice::ReadOnly); // Convert a single line
   116         Asline.skipWhiteSpace();            // Remove whitespaces
   117         Asline >> Temp;                     // Copy revision indicator
   119         if (Temp == QString(QChar('R'))) {  // Copy the account field
   120             Asline >> Temp;                 // to temporary for transfer
   121             string Convstring = Temp.toStdString();  // Convert to string (can't cast?)
   122             Hashnames[Convstring] += Hashnames[Convstring];
   123         }
   125         Line = QString(""); // Clear line for next round
   126         while (Line.isEmpty() && !Tstream.atEnd()) {
   127             Tstream.skipWhiteSpace();       // Strip and get
   128             Line = Tstream.readLine();      // the new line
   129             if (Line.at(0) == QChar('#'))   // Remove comments
   130                 Line = QString("");
   131         }
   132     }
   134 //    Hashnames.insert(map<string, int>::value_type((string)QString, int));
   135     for (Nameiter = Hashnames.begin(); Nameiter != Hashnames.end(); Nameiter++)
   136         Hashnums[Nameiter->second] += Nameiter->first + '\n';
   138 // FIXME: Put this in loadData, to load custom and most used task names before
   139 // FIXME: default listings are sorted and inserted
   140     for (Numiter = Hashnums.begin(); Numiter != Hashnums.end(); Numiter++) {
   142         // Count the number of lines of sorted task names
   143         int nNumlines = QString::fromStdString(Numiter->second).count('\n');
   145         // Iterate through the lines of task names, feeding them into the menu
   146         for (int nIter = 0; nIter < nNumlines; nIter++)
   147             *m_pTaskentries << QString::fromStdString(Numiter->second).section('\n', nIter, nIter);
   148     }
   149 }
   151 //
   152 // Convenience method to load personal data from a file
   153 //
   154 void Titraqform::loadData(QFile &Fileobj)
   155 {
   156     if (Fileobj.isOpen()) {             // Check state of file
   157         Fileobj.flush();                // Begin processing file cleanly
   158         Q3TextStream Asentry(&Fileobj);  // Convert data to stream
   159         this->loadData(Asentry);        // Pass off to do the real work
   160     }
   161     else {
   162         if (!Fileobj.open(QIODevice::ReadOnly)) // Try to open file
   163             throw Genexcept(trUtf8(TITRAQ_READPFILFAIL));
   164         else
   165             Fileobj.flush();                // Begin processing file cleanly
   166             Q3TextStream Asentry(&Fileobj);  // Convert data to stream
   167             this->loadData(Asentry);        // Pass off to do the real work
   168             Fileobj.close();                // Finish fileop by closing
   169     }
   170 }
   172 //
   173 // Load personal data from a stream
   174 //
   175 void Titraqform::loadData(Q3TextStream &Tstream)
   176 {
   177     bool bValid = true; // Used to warn on globally invalid accounting data
   178     int nIter = 0;      // Iterator used in loop and also as a count
   179     QString Line;       // Used for linewise editing and whitespace eating
   180     QString Bitbucket;  // Used for null device until we find a better way
   182     QPixmap Statokay(s_kpcStatokay_xpm);
   183     QPixmap Statwarn(s_kpcStatwarn_xpm);
   184     QPixmap Staterror(s_kpcStaterror_xpm);
   186     // Strip out extra line feeds at stream start
   187     while (Line.isEmpty() && !Tstream.atEnd()) {
   188         Tstream.skipWhiteSpace();       // Strip and get
   189         Line = Tstream.readLine();      // the new line
   190         if (Line.at(0) == QChar('#'))   // Remove comments
   191             Line = QString("");
   192     }
   194     // Strip out extra line feeds after reading the data symbol
   195     Line = QString("");                 // Reset our line
   196     while (Line.isEmpty() && !Tstream.atEnd()) {
   197         Tstream.skipWhiteSpace();       // Strip and get
   198         Line = Tstream.readLine();      // the new line
   199         if (Line.at(0) == QChar('#'))   // Remove comments
   200             Line = QString("");
   201     }
   203 //    // Going into data churning, so prepare date and time parsing and conversion
   204 //    Converdate.setSeparator(trUtf8("."));
   205 //    Convertime.setSeparator(trUtf8(":"));
   207     // Optimize viewing by repainting cells only once after processing
   208     m_pMaintable->setUpdatesEnabled(false);
   210     // Set the table text by linewise reading from the input stream
   211     // and parsing date, time, account, and other columns out of it
   212     while (!Line.isEmpty()) {
   213         bool bValid = true; // Warns on linewise invalid accounting data
   214         QString User, Guid, Crc, Rev;                           // Valid admin fields
   215         QString Date, Start, Finish, Account, Amount, Remark;   // Valid user fields
   216         Q3TextStream Asline(&Line, QIODevice::ReadOnly); // Convert a single line now
   218         if (nIter % g_knBlocks == 0) // Add blocks of rows to optimize loading
   219             m_pMaintable->setNumRows(m_pMaintable->numRows() + g_knBlocks);
   221         Asline.skipWhiteSpace();    // Remove whitespaces
   222         Asline >> User;             // Copy the user field
   223         if (!User.isEmpty())
   224             m_pMaintable->setText(nIter, TITRAQ_IDXUSER, User);
   225         else
   226             bValid = false;
   228         Asline.skipWhiteSpace();    // Remove whitespaces
   229         Asline >> Guid;             // Copy the GUID field
   230         // Postpone actual text delivery, to autoinsert GUIDs!
   232         Asline.skipWhiteSpace();    // Remove whitespaces
   233         Asline >> Crc;              // Copy the CRC field
   234         // Postpone actual text delivery, to autoinsert CRCs!
   236         Asline.skipWhiteSpace();    // Remove whitespaces
   237         Asline >> Rev;              // Copy the rev field
   238         if (!Rev.isEmpty())
   239             m_pMaintable->setText(nIter, TITRAQ_IDXREV, Rev);
   240         else
   241             bValid = false;
   243         Asline.skipWhiteSpace();    // Remove whitespaces
   244         Asline >> Date;             // Copy the date field
   245         if (!Date.isEmpty())
   246             m_pMaintable->setText(nIter, TITRAQ_IDXDATE, Date);
   247         else
   248             bValid = false;
   250         Asline.skipWhiteSpace();    // Remove whitespaces
   251         Asline >> Start;            // Copy the start field
   252         if (!Start.isEmpty())
   253             m_pMaintable->setText(nIter, TITRAQ_IDXSTART, Start);
   254         else
   255             bValid = false;
   257         Asline.skipWhiteSpace();    // Remove whitespaces
   258         Asline >> Finish;           // Copy the finish field
   259         if (!Finish.isEmpty())
   260             m_pMaintable->setText(nIter, TITRAQ_IDXFINISH, Finish);
   261         else
   262             bValid = false;
   264         Asline.skipWhiteSpace();    // Remove whitespaces
   265         Asline >> Amount;           // Copy the amount field
   266         if (!Amount.isEmpty())
   267             m_pMaintable->setText(nIter, TITRAQ_IDXAMOUNT, Amount);
   268         else
   269             bValid = false;
   271         Asline.skipWhiteSpace();    // Remove whitespaces
   272         Asline >> Account;          // Copy the account field
   273         if (!Account.isEmpty()) {
   274             Q3TableItem *pOld = m_pMaintable->item(nIter, TITRAQ_IDXTASK);
   275             delete(pOld);   // Get rid of the old before going with the new
   276             RtTableItem *pSwapitem = new RtTableItem(m_pMaintable, Q3TableItem::WhenCurrent, Account);
   277             pSwapitem->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
   278             m_pMaintable->setItem(nIter, TITRAQ_IDXTASK, pSwapitem);
   279         }
   280         else
   281             bValid = false;
   283         Asline.skipWhiteSpace();    // Remove whitespaces
   284         Remark = Asline.read();     // Copy the remark field
   286         QRegExp Quoted("\"(.*[^\\\\])\"");                  // Get rid of
   287         Quoted.search(Remark);                              // surrounding double
   288         Remark = Quoted.cap(Quoted.numCaptures());          // quotes, and
   289         Remark.replace(QRegExp("\\\\(.)"), QString("\\1")); // escape backslashes
   291         if (!Remark.isEmpty())
   292             m_pMaintable->setText(nIter, TITRAQ_IDXREMARK, Remark);
   294         if (bValid) { // Show a bitmap to signal valid or error state
   295             m_pMaintable->setText(nIter, TITRAQ_IDXSTATUS, QString(QChar('O')));
   296             m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, Statokay);
   297         }
   298         else {
   299             m_pMaintable->setText(nIter, TITRAQ_IDXSTATUS, QString(QChar('E')));
   300             m_pMaintable->setPixmap(nIter, TITRAQ_IDXSTATUS, Staterror);
   301         }
   303         // Set the GUID text here, in case we need to generate a fresh value
   304         if (!Guid.isEmpty()) {
   305             if (Guid != ".")    // This means, generate a fresh GUID value
   306                 m_pMaintable->setText(nIter, TITRAQ_IDXGUID, Guid);
   307             else {
   308                 AS::Uuid Guidi; // For GUID production
   309                 Guidi.genId();
   310                 m_pMaintable->setText(nIter, TITRAQ_IDXGUID, QString::fromStdString(Guidi.getString()));
   311             }
   312         }
   313         else // if isEmpty()
   314             bValid = false;
   316         // Set the CRC text here, in case we need to generate a fresh value
   317         if (!Crc.isEmpty()) {
   318             if (Crc != ".") // This means, generate a fresh CRC value
   319                 m_pMaintable->setText(nIter, TITRAQ_IDXCRC, "0x" + Crc);
   320             else {
   321                 // Make our long tuple to run through the CRC32 generator
   322                 Qualistring Testuple = User + Guid + Rev + Date + Start;
   323                             Testuple += Finish + Amount + Account + Remark;
   324                 U32 Valcrc = Testuple.getCrc(); // Finally set the checksum to its new value
   325                 QString Crcstr = QString::number(Valcrc, 16).rightJustify(8, '0');
   326                 m_pMaintable->setText(nIter, TITRAQ_IDXCRC, "0x" + Crcstr);
   327             }
   328         }
   329         else // if isEmpty()
   330             bValid = false;
   332         nIter++;            // The big increment
   333         Line = QString(""); // Clear line for next round
   335         while (Line.isEmpty() && !Tstream.atEnd()) {    // Strip and get
   336             Tstream.skipWhiteSpace();                   // Remove white
   337             Line = Tstream.readLine();                  // the new line
   338             if (Line.at(0) == QChar('#'))               // Remove comments
   339                 Line = QString("");
   340         }
   341     }
   343 //    // Start sorting order and direction correctly according to user preferences
   344 //    int nSortcol = (int)m_pPrefs->getNumber(TITRAQ_PREFSORTCOL, TITRAQ_DEFSORTCOL);
   345 //    bool bSortdir = m_pPrefs->getBool(TITRAQ_PREFSORTDIR, TITRAQ_DEFSORTDIR);
   346 //    m_pMaintable->setSortdir(!bSortdir); // Hack! Fake sortdir so we start right
   347 //    m_pMaintable->sortColumn(nSortcol, bSortdir);
   349     // Write nonsaving line numbers for all rows
   350     for (int nIter = m_pMaintable->numRows() - 1; nIter >= 0; nIter--)
   351         m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
   353     m_pMaintable->setUpdatesEnabled(true);      // Update and repaint
   354     m_pMaintable->setNumRows(nIter);            // No excess rows
   355     m_pMaintable->setCurrentCell(nIter - 1, 0); // Move focus to last row
   356     m_pMaintable->ensureCellVisible(nIter - 1, 0); // Scroll please
   358     if (!bValid)
   359         throw Genexcept("Warning: invalid accounting data.");
   360 }
   362 //
   363 // Convenience method to save accounting data to a file
   364 //
   365 void Titraqform::saveData(QFile &Fileobj)
   366 {
   367     if (Fileobj.isOpen()) {             // Check state of file
   368         Fileobj.flush();                // Begin processing file cleanly
   369         Q3TextStream Asentry(&Fileobj);  // Convert data to stream
   370         this->saveData(Asentry);        // Pass off to do the real work
   371     }
   372     else {
   373         if (!Fileobj.open(QIODevice::WriteOnly)) // Try to open file
   374             throw Genexcept(trUtf8(TITRAQ_READPFILFAIL));
   375         Q3TextStream Asentry(&Fileobj);  // Convert data to stream
   376         this->saveData(Asentry);        // Pass off to do the real work
   377         Fileobj.close();                // Finish fileop by closing
   378     }
   379 }
   381 //
   382 // Save accounting data to a stream
   383 //
   384 void Titraqform::saveData(Q3TextStream &Tstream)
   385 {
   386     const int nRows = m_pMaintable->numRows();      // Max rows used in loop
   387     QString Tempfield;                              // Current field string
   388     QString Strsearch;                              // String to strip search
   389     QRegExp Stripper("\\s*$");                      // Pattern to strip off
   391     // Start by prepending the AS data format version symbol
   392     Tstream << TITRAQ_DATAPATTERN << TITRAQ_DATAVERSIONMAJ
   393             << QChar('.') << TITRAQ_DATAVERSIONMIN << endl;
   395     // Linewise save from the main table date, time, account, and others
   396     for (int nIter = 0; nIter < nRows; nIter++) {
   397         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXUSER);      // Load user field text
   398         if (!Tempfield.isNull())
   399             Tstream << Tempfield;                                   // Save user field text
   401         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXGUID);      // Load GUID field text
   402         if (!Tempfield.isNull())
   403             Tstream << trUtf8(" ") << Tempfield;                    // Save GUID field text
   405         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXCRC);       // Load CRC field text
   406         Tempfield.remove("0x");
   407         if (!Tempfield.isNull())
   408             Tstream << trUtf8(" ") << Tempfield;                    // Save CRC field text
   410         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXREV);       // Load rev field text
   411         if (!Tempfield.isNull())
   412             Tstream << trUtf8(" ") << Tempfield;                    // Save rev field text
   414         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXDATE);      // Load date field text
   415         if (!Tempfield.isNull())
   416             Tstream << trUtf8(" ") << Tempfield;                    // Save date field text
   418         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXSTART);     // Load start field text
   419         if (!Tempfield.isNull())
   420             Tstream << trUtf8(" ") << Tempfield;                    // Save start field text
   422         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXFINISH);    // Load end field text
   423         if (!Tempfield.isNull())
   424             Tstream << trUtf8(" ") << Tempfield;                    // Save end field text
   426         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXAMOUNT);    // Load amount field text
   427         if (!Tempfield.isNull())
   428             Tstream << trUtf8(" ") << Tempfield;                    // Save amount
   430         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXTASK);      // Load acct field text
   431         if (!Tempfield.isNull())
   432             Tstream << trUtf8(" ") << Tempfield;                    // Save acct field text
   434         Tempfield = m_pMaintable->text(nIter, TITRAQ_IDXREMARK);    // Load remark field text
   435         Tstream << trUtf8(" \"");                                   // Save beginning double quote
   436         if (!Tempfield.isNull()) {
   437             Strsearch = QRegExp::escape(Tempfield);                 // Incoming string escaped
   438             Stripper.search(Strsearch);
   439             Tempfield.truncate(Stripper.pos());                     // Cut off whitespace
   440             Tempfield.replace(QChar('\\'), QString("\\\\"));        // Escape back slashes
   441             Tempfield.replace(QChar('\"'), QString("\\\""));        // Escape double quotes
   442             Tstream << Tempfield;                                   // Save remark field text
   443         }
   444         Tstream << trUtf8("\"");                                    // Save ending double quote
   446         Tstream << endl;                                            // Append a newline
   447     }
   448 }
   450 //
   451 // Convenience method to validate AS data in a file
   452 //
   453 const bool Titraqform::validateData(QFile &Filin) const
   454 {
   455     QString Firstline;      // Will contain the first line of text
   456     char szReadline[QString(TITRAQ_DATAPATTERN).length() + 4L];  // File line
   457     bool bRet = false;      // Set the initial return value
   459     if (Filin.isOpen()) {   // Check open state of file
   460         Filin.flush();      // Not sure if this is needed
   461         Filin.reset();      // Set the file index position to 0
   462         Filin.readLine(szReadline, QString(TITRAQ_DATAPATTERN).length() + 2L);
   463     }
   464     else {
   465         if (!Filin.open(QIODevice::ReadOnly))   // Try to open file
   466             throw Genexcept(trUtf8(TITRAQ_READPFILFAIL));
   467         else {                          // File is now open
   468             Filin.readLine(szReadline, QString(TITRAQ_DATAPATTERN).length() + 2L);
   469             Filin.close();              // Remember to close
   470         }
   471     }
   473     try {   // Pass off to worker method
   474         Firstline = QString::fromAscii(szReadline);
   475         bRet = this->validateData(Firstline);
   476     }
   477     catch (Genexcept &) {
   478         throw;  // Rethrow onwards
   479     }
   480     return bRet;
   481 }
   483 //
   484 // Validate the AS data pattern in a line
   485 //
   486 const bool Titraqform::validateData(QString &Linin) const
   487 {
   488     bool bRet = false;  // Initial return value
   490     // Ensure that the right data version pattern precedes the data
   491     QString Datapattern = QString(TITRAQ_DATAPATTERN);
   492     if (!Linin.startsWith(Datapattern)) { // Incompatible data format
   493         QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short,
   494             TITRAQ_NOPATTERNFOUND + QString(TITRAQ_DATAPATTERN) + TITRAQ_WASNOTFOUNDIN,
   495             QMessageBox::Critical, QMessageBox::Ok | QMessageBox::Escape,
   496             Qt::NoButton, Qt::NoButton);
   497         Problema.exec(); // Give the user the bad news
   498         throw Genexcept(TITRAQ_INVALIDDATA);
   499     }
   500     else if (Linin.section(Datapattern, 1).section('.', 0, 0).toInt() != TITRAQ_DATAVERSIONMAJ) {
   501         QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short,
   502             TITRAQ_BADVERSIONMAJ, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape,
   503             Qt::NoButton, Qt::NoButton);
   504         Problema.exec(); // Give the user the bad news
   505         throw Genexcept(TITRAQ_INCOMPATDATA);
   506     }
   507     else if (Linin.section(Datapattern, 1).section('.', 1, 1).toInt() > TITRAQ_DATAVERSIONMIN) {
   508         QMessageBox Problema(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short,
   509             TITRAQ_BADVERSIONMIN, QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Escape,
   510             Qt::NoButton, Qt::NoButton);
   511         Problema.exec(); // Give the user the bad news
   512         throw Genexcept(TITRAQ_INCOMPATDATA);
   513     }
   514     else
   515         bRet = true;
   517     return bRet;    // Not reached in case of failure
   518 }
   520 //
   521 // Get a whole row of data
   522 //
   523 const QString Titraqform::getRowdata(void) const
   524 {
   525     QString Rowdata, Tempstring;                            // For output string
   526     Q3TableSelection Select = m_pMaintable->selection(0);    // Highlighted text
   527     int nTotal = Select.bottomRow() - Select.topRow() + 1;  // Total row select
   529     // Calculate rows to delete from selection highlight
   530     for (int nIter = 0; nIter < nTotal; ++nIter) {
   531         // Build the row data string one field at a time, adding seps inbetween
   532         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXLINE);
   533         if (!Tempstring.isEmpty())
   534             Rowdata += Tempstring;
   535         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER);
   536         if (!Tempstring.isEmpty())
   537             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   538         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXGUID);
   539         if (!Tempstring.isEmpty())
   540             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   541         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXCRC);
   542         if (!Tempstring.isEmpty())
   543             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   544         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV);
   545         if (!Tempstring.isEmpty())
   546             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   547         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE);
   548         if (!Tempstring.isEmpty())
   549             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   550         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART);
   551         if (!Tempstring.isEmpty())
   552             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   553         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH);
   554         if (!Tempstring.isEmpty())
   555             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   556         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT);
   557         if (!Tempstring.isEmpty())
   558             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   559         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXTASK);
   560         if (!Tempstring.isEmpty())
   561             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   562         Tempstring = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREMARK);
   563         if (!Tempstring.isEmpty())
   564             Rowdata += TITRAQ_SEPARATORTOK + Tempstring;
   565         Rowdata += trUtf8("\n");    // Finish off line
   566     }
   568     return Rowdata;
   569 }
   571 //
   572 // Set a whole row of data
   573 //
   574 void Titraqform::setRowdata(QString &Rowdata) const
   575 {
   576     int nRows = Rowdata.count(QChar('\n'));             // Set so many rows
   577     int nCurrentrow = m_pMaintable->currentRow();       // Current table row
   578     Q3TableItem *pItem = NULL;                          // Old item to change out
   579     QString Line, User, Guid, Crc, Rev;                 // Admin fields in table
   580     QString Date, Start, Finish, Amount, Task, Remark;  // Viewable fields in table
   581     Q3TextStream Datastream(&Rowdata, QIODevice::ReadOnly);      // Convert data to stream
   583     for (int nIter = 0; nIter < nRows; ++nIter) {
   584         QString Singlerow = Datastream.readLine();              // For linewise operation
   585         Q3TextStream Rowstream(&Singlerow, QIODevice::ReadOnly);         // Convert row to stream
   587         Rowstream >> Line >> User >> Guid >> Crc >> Rev;        // Stream data fields
   588         Rowstream >> Date >> Start >> Finish >> Amount >> Task; // to corresponding vars
   589         Remark = Rowstream.readLine();                          // Remark is a whole line
   591         // Set the table row data one field at a time, skipping seps inbetween
   592         // Importantly, do not copy over the GUID, which must be unique each row
   593         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXLINE, Line);
   594         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXUSER, User);
   595         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXCRC, Crc);
   596         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREV, Rev);
   597         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXDATE, Date);
   598         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXSTART, Start);
   599         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXFINISH, Finish);
   600         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXAMOUNT, Amount);
   602 //        // FIXME: Why doesn't this code change the RtTableItem text in place?
   603 //        RtTableItem *pTask = NULL;                      // Derived and special
   604 //        pItem = m_pMaintable->item(nCurrentrow + nIter, TITRAQ_IDXTASK);
   605 //        pTask = static_cast<RtTableItem *>(pItem);
   606 //        pTask->setText(Task);
   608         // Change out old item and replace with new task data
   609         pItem = m_pMaintable->item(nCurrentrow + nIter, TITRAQ_IDXTASK);
   610         delete(pItem);  // Get rid of the old before going with the new
   611         RtTableItem *pSwapitem = new RtTableItem(m_pMaintable, Q3TableItem::WhenCurrent, Task);
   612         pSwapitem->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
   613         m_pMaintable->setItem(nCurrentrow + nIter, TITRAQ_IDXTASK, pSwapitem);
   615         // Continue with field processing business as usual
   616         m_pMaintable->setText(nCurrentrow + nIter, TITRAQ_IDXREMARK, Remark.simplifyWhiteSpace());
   617     }
   618 }
   620 //
   621 // Discover which column is the first in view
   622 //
   623 const int Titraqform::getFirstcol(void) const
   624 {
   625     int nIter = 0;  // Is both iterator in loop and column number returned
   627     // Use column selector menu popup as sole key to determining column state
   628     while (nIter < TITRAQ_IDXTAIL && !m_pColspopup->isItemChecked(m_pColspopup->idAt(++nIter)))
   629         TITRAQ_NOP;
   631     return nIter - 1; // Return one less to account for start of item offset
   632 }

mercurial