OSSP CVS Repository

ossp - ossp-pkg/as/as-gui/as_slot.cpp
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/as/as-gui/as_slot.cpp
//
//  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 <rse@engelschall.com>
//  Copyright (c) 2002-2004 Michael Schloh von Bennewitz <michael@schloh.com>
//  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_slot.cpp: ISO C++ implementation
//

// system headers
#include <memory>
#include <cstring>

// Qt headers
#include <qfiledialog.h>
#include <qcombobox.h>
#include <qclipboard.h>
#include <qmenudata.h>
#include <qdatastream.h>
#include <qstatusbar.h>
#include <qaction.h>
#include <qpopupmenu.h>

// Qt style headers
#include <qcdestyle.h>
#include <qsgistyle.h>
#include <qmotifstyle.h>
#include <qmotifplusstyle.h>
#include <qplatinumstyle.h>
#include <qwindowsstyle.h>

// User interface
#include "as_const.h"           // Application constants
#include "as_except.h"          // Exception classes
#include "as_tableitem.h"       // For our custom table items
#include "as_generic.h"         // Generic classes
#include "as_uuid.h"            // UUID classes
#include "as_datedit.h"         // Derived from QDateEdit
#include "as_amount.h"          // Derived from QTimeEdit
#include "as_crc.h"             // Useful Qualistring class
#include "as_pref.h"            // For Preferences class
#include "as_panel.h"           // For Prefpanel class
#include "as_reportpanel.h"     // For Reportpanel class
#include "as_helpanel.h"        // For Helpanel class
#include "as_sfile.h"           // For Simplefile class
#include "as_table.h"           // For TiTable class

// RPC headers
#ifdef HAVE_ESOAP
#include <easysoap/SOAP.h>
#endif // HAVE_ESOAP
#ifdef HAVE_MICO
#include <coss/CosNaming.h>
#include "as_stub.h"            // CORBA stubs and skeletons
#endif // HAVE_MICO

// Icon pixel maps
#include "as_gfx/cwlogo.xpm"    // static const char *s_kpcCwlogo_xpm[]
#include "as_gfx/ossplogo.xpm"  // static const char *s_kpcOssplogo_xpm[]
#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[]
#include "as_gfx/statvoid.xpm"  // static const char *s_kpcStatvoid_xpm[]


//
// Cut an entry
//
void Titraqform::cutEntry(void)
{
    this->copyEntry();  // Reuse slot
    this->delEntry();   // Reuse slot
}

//
// Copy an entry
//
void Titraqform::copyEntry(void)
{
    QString Selection;  // Will hold the selected text
    QClipboard *pClip;  // Will reference the global clipboard

    // Initialize data and clipboard handle
    Selection = getRowdata();   // Use accessor
    pClip = QApplication::clipboard();

    Q_ASSERT(!Selection.isNull());
    pClip->setText(Selection, QClipboard::Selection); // Doesn't work on Windows
    pClip->setText(Selection, QClipboard::Clipboard); // Works on both equally
}

//
// Paste an entry
//
void Titraqform::pasteEntry(void)
{
    int nRows = 0;              // Paste so many rows as are stored
    QString Selection;          // Will receive the clipboard text
    QClipboard *pClip = NULL;   // Will reference the global clipboard

    pClip = QApplication::clipboard();                  // Prime the clips
    Selection = pClip->text(QClipboard::Clipboard);     // Windows and Unix
    nRows = Selection.contains(QChar('\n'));            // How many rows
    if (Selection != NULL && nRows > 0) { // Ignore empty clipboards
        this->addEntry(nRows);                          // Reuse slot
        setRowdata(Selection);                          // Use accessor

        // Update line numbers for this new row and all subsequent rows
        for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
            m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));

        // Do basic data validation to warn against missing fields
        for (int nIter = 0; nIter < nRows; nIter++)
            this->validateRow(m_pMaintable->currentRow() + nIter, 0);

        m_pStatbar->message(QString::number(nRows) + trUtf8(" rows pasted"), 4000);
        updEdit(m_pMaintable->currentRow()); // Reflect in the update controls
    }
    else // Well, I guess the user tried to paste an empty clipboard
        m_pStatbar->message(trUtf8("The clipboard is empty"), 4000);
}

//
// Append a blank row entry
//
void Titraqform::addEntry(int nRows)
{
    QTableSelection Select; // Highlighted text
    int nTotal = 0;         // Total row select
    int nCurrent = 0;       // Current row
    std::auto_ptr<AS::Uuid> pGuid(new AS::Uuid); // For GUID production

    // Decide how many rows to add
    Select = m_pMaintable->selection(0);
    if (nRows > 0)
        nTotal = nRows;
    else
        nTotal = Select.bottomRow() - Select.topRow() + 1;

    // Optimize viewing by repainting cells only once after processing
    m_pMaintable->setUpdatesEnabled(false);

    // Add a row after selection and focus to the new row
    if (Select.bottomRow() + 1 != m_pMaintable->numRows()) { // Add upwards
        m_pMaintable->insertRows(Select.topRow(), nTotal);
        m_pMaintable->setDirty();   // Set data to dirty state
        m_pMaintable->setCurrentCell(Select.topRow(), m_pMaintable->currentColumn());

        // According to Trolltech, insertRows() "clears the selection(s)".
        // They are pretty wrong about that, so unfortunately we'll have to
        // take care of the dirty work ourselves with a clearSelection().
        m_pMaintable->clearSelection(false);
        m_pMaintable->selectRow(m_pMaintable->currentRow());

        // Update relevant data fields for all new rows
        for (int nIter = 0; nIter < nTotal; nIter++) {
            m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXSTATUS, QString(QChar('W')));
            m_pMaintable->setPixmap(Select.topRow() + nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatwarn_xpm));
            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"); // 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(Qt::ISODate));
            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
        m_pMaintable->insertRows(Select.bottomRow() + 1, nTotal);
        m_pMaintable->setDirty();   // Set data to dirty state
        m_pMaintable->setCurrentCell(Select.bottomRow() + 1, m_pMaintable->currentColumn());

        // According to Trolltech, insertRows() "clears the selection(s)".
        // They are pretty wrong about that, so unfortunately we'll have to
        // take care of the dirty work ourselves with a clearSelection().
        m_pMaintable->clearSelection(false);
        m_pMaintable->selectRow(m_pMaintable->currentRow());

        // Update relevant data fields for all new rows
        for (int nIter = 1; nIter <= nTotal; nIter++) {
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXSTATUS, QString(QChar('W')));
            m_pMaintable->setPixmap(Select.bottomRow() + nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatwarn_xpm));
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
            pGuid->genId();
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXGUID, pGuid->getString());
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXCRC, "0");
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXREV, "0");
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXDATE, QDate::currentDate().toString(Qt::ISODate));
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXSTART, "00:00");
            m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXFINISH, "00:00");
            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);
        }
    }

    // Update line numbers for this new row and all subsequent rows
    for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
        m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));

    updEdit(m_pMaintable->currentRow()); // Reflect in the update controls
    m_pStatusedit->setPixmap(QPixmap(s_kpcStatwarn_xpm)); // Show pixmap

    m_pMaintable->setUpdatesEnabled(true);  // Turn updates back on
    m_pMaintable->repaintContents(true);    // Do a general repaint of table
    m_pMaintable->ensureCellVisible(m_pMaintable->currentRow() + nTotal - 1, m_pMaintable->currentColumn());
    m_pMaintable->ensureCellVisible(m_pMaintable->currentRow(), m_pMaintable->currentColumn());

    // In case we added the first and only row entry,
    // do post state adjustments like icon undimming
    if (m_pMaintable->numRows() == 1) {
        m_pDelrowact->setEnabled(true);
        m_pRefreshact->setEnabled(true);
        m_pCutact->setEnabled(true);
        m_pCopyact->setEnabled(true);

        // Brighten all the edit controls also
        m_pLineedit->setEnabled(true);
        m_pUseredit->setEnabled(true);
        m_pGuidedit->setEnabled(true);
        m_pCrcedit->setEnabled(true);
        m_pRevedit->setEnabled(true);
        m_pDateedit->setEnabled(true);
        m_pStarttime->setEnabled(true);
        m_pEndtime->setEnabled(true);
        m_pAmount->setEnabled(true);
        m_pTasks->setEnabled(true);
        m_pRemark->setEnabled(true);

        // And optionally the RPC actions, too
#if defined HAVE_MICO || defined HAVE_ESOAP
        m_pSyncact->setEnabled(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON)
            | m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
#endif // HAVE_MICO || defined HAVE_ESOAP
    }
}

//
// Delete a row entry
//
void Titraqform::delEntry(int nRows)
{
    QTableSelection Select = m_pMaintable->selection(0);    // Highlighted text
    int nTotal = Select.bottomRow() - Select.topRow() + 1;  // Total row select
    QMemArray<int> Rowselect(nTotal);                       // Row array

    // Calculate rows to delete from selection highlight
    for (int nIter = 0; nIter < nTotal; ++nIter)
        Rowselect[nIter] = Select.topRow() + nIter;

    // Remove the row at selection and focus to the next row
    if (m_pMaintable->currentRow() + 1 != m_pMaintable->numRows()) {
        m_pMaintable->setCurrentCell(Select.bottomRow() + 1, m_pMaintable->currentColumn());
        m_pMaintable->removeRows(Rowselect);
        m_pMaintable->setDirty();   // Set data to dirty state
    }
    else {  // Special case to handle removing of only row or last row
        m_pMaintable->removeRows(Rowselect);
        m_pMaintable->setDirty();   // Set data to dirty state
    }

    // Update line numbers for this new row and all subsequent rows
    for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
        m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter));

    // In case we removed the last remaining row,
    // do post state adjustments like icon dimming
    if (m_pMaintable->numRows() <= 0) {
        m_pDelrowact->setEnabled(false);
        m_pRefreshact->setEnabled(false);
        m_pCutact->setEnabled(false);
        m_pCopyact->setEnabled(false);

        // Dim all the edit controls also
        m_pStatusedit->setPixmap(s_kpcStatvoid_xpm);
        m_pLineedit->setEnabled(false);
        m_pUseredit->setEnabled(false);
        m_pGuidedit->setEnabled(false);
        m_pCrcedit->setEnabled(false);
        m_pRevedit->setEnabled(false);
        m_pDateedit->setEnabled(false);
        m_pStarttime->setEnabled(false);
        m_pEndtime->setEnabled(false);
        m_pAmount->setEnabled(false);
        m_pTasks->setEnabled(false);
        m_pRemark->setEnabled(false);

        // And optionally dim the RPC actions
#if defined HAVE_MICO || defined HAVE_ESOAP
        m_pSyncact->setEnabled(false);
#endif // HAVE_MICO || defined HAVE_ESOAP
    }
}

//
// Refresh the display of all data items
//
void Titraqform::refreshDisplay(void)
{
    int nIter = 0;                          // Matrix iterator
    int nRows = m_pMaintable->numRows();    // Total number of rows

    // Sweep through matrix validating linewise
    // data and updating line numbers for all rows
    while (nIter < nRows) {
        this->validateRow(nIter, 0);
        m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
        nIter++;
    }

    m_pMaintable->repaintContents(false);   // Do a general repaint of table
    m_pStatbar->message(trUtf8("Display was refreshed"), 4000); // Announce result
}

//
// Make and display a new document window
//
void Titraqform::newDoc(void)
{
    int nResult = 0; // Holds return value from save first messagebox

    // Check modification state of current data
    if (m_pMaintable->isDirty()) {
        nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
                + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
                  trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);

        switch (nResult) {
        case 0: // First button selected, so save first
            this->saveFile();   // Save changes first
            break;
        case 1: // Second button selected, so don't save
            break;
        case 2: // Third button selected, so return sofort
        default:
            m_pStatbar->message(trUtf8("New aborted"), 4000);
            return;
            break;
        }
    }

    if (!m_pMaintable->isDirty() || nResult == 1) { // Check modification state
        // Fall through to implicit new doc code
        this->setCaption(trUtf8("No file name"));
        m_pStatbar->message(trUtf8("New document"), 4000);
        this->enableIface(true);            // Enable the interface
        m_pMaintable->setNumRows(0);        // Remove all data in table
        this->setFilename("");               // Signal a closed doc state
        this->addEntry(1);                  // Default new op adds a row
        m_pMaintable->setDirty(false);      // Start out clean
    }
}

//
// Open and display an existing document
//
void Titraqform::openDoc(void)
{
    int nResult = 0; // Holds return value from save first messagebox

//
// This block will guide the user to saving the contents of the timesheet
// before losing them in an open operation. The question and dialog box will
// not be raised if no open timesheet exists or if it was just serialized.
//
    if (m_pMaintable->isDirty()) { // Check modification state
        nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
                + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
                  trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);

        switch (nResult) {
        case 0: // Save first
            this->saveFile(); // Save changes first
            break;
        case 1: // Don't save first but do load
            break;
        case 2: // Don't do a load timesheet
        default:
            m_pStatbar->message(trUtf8("Loading aborted"), 4000);
            return;
            break;
        }
    }

//
// This block ensures that conditions of first block logic were met if
// applicable. If so, the user gives a file name to open or cancels the
// operation. The corresponding file will be opened, and if this is
// unsuccessful then the post state is exactly the same as the pre state.
//
    if (!m_pMaintable->isDirty() || nResult == 1) { // Check modification state
        // Make sure we correctly get the name of the default file to open
        QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
        if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
            Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);

        // This dialog asks which file the user wants to open
        QString Filestring = QFileDialog::getOpenFileName(Openas,
            trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"),
            this, trUtf8("ChooserDialog"), trUtf8("Choose a file to open"), NULL, false);

        // We might have a filename to work on, so do something with it
        if (!Filestring.isEmpty()) {
            QFile Filetemp(Filestring);             // File to load
            try {
                if (Filetemp.exists() && validateData(Filetemp)) { // Be extra sure
                    setFilename(Filestring);        // Set the new file name
                    m_pMaintable->setNumRows(0);    // Clear out old data
                    m_pMaintable->setDirty(false);  // Reset dirty flag
                    loadData(Filetemp);             // Pass to helper method
                    this->setCaption(Filestring);   // Caption in the titlebar
                    m_pStatbar->message(trUtf8("Loaded document ") + Filestring, 4000);
                    this->enableIface(true);        // Turn on the lights
                    this->setOpen(true);            // Indicate doc is open
                }
            }
            catch (Genexcept& Genex) { // Crap, we failed
                m_pStatbar->message(trUtf8("Loading failed"), 4000);
                Genex.reportErr();
                return;
            }
        }
        else // An empty filename returning from the file dialog means cancel
            m_pStatbar->message(trUtf8("Loading aborted"), 4000);
    }
}

//
// Serialize current state to the current file
//
void Titraqform::saveFile(void)
{
    QString Fname;
    Simplefile Filevents;

    try {
        Fname = *this->getFilename();

        // First time saves are really just saveName in disguise
        if (Fname.isEmpty()) {
            try {
                this->saveName();       // Try to 'save as'
                return;                 // and short circuit
            }
            catch (Genexcept& Genex) {
//                Genex.reportErr();      // Report the error
                return;                 // and short circuit
            }
        }

        Filevents.setName(Fname);   // Construct a file to write
        if (m_pPrefs->getBool(TITRAQ_PREFBAKON, TITRAQ_DEFBAKON))
            Filevents.makeBackup(); // Back up to filename.bak
        this->saveData(Filevents);  // Pass to helper method
    }
    catch (Genexcept& Genex) {
        Genex.reportErr();
    }
    // Reset and give output to main window
    this->setCaption(Fname);
    m_pStatbar->message(trUtf8("File %1 saved").arg(Fname), 4000);
    m_pMaintable->setDirty(false);  // Set the clean state to allow close
}

//
// Serialize current state to a selected file
//
void Titraqform::saveAs(void)
{
    int nResult = 0; // For checking user's answer

    // Make sure we correctly get the name of the default file to open
    QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
    if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
        Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);

    // And then get the name of the selected file to save to
    QString Filestring = QFileDialog::getSaveFileName(Openas, trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
    if (!Filestring.isEmpty()) {
        if (QFile::exists(Filestring)) {
            nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
                    + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
                      trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
            switch (nResult) {
            case 0: // Overwrite contents
                this->setFilename(Filestring);
                this->saveFile();
                break;
            case 1: // Don't overwrite
            default:
                break;
            }
        }
        else {
            // Conditionally use a unique extension like '.as' if user prefers
            if (m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON)) {
                QString Extension = TITRAQ_FEXTENSION;  // Logic to handle
                if (!Filestring.endsWith(Extension))    // AS file extension
                    Filestring += Extension;            // insertion
            }
            this->setFilename(Filestring);  // Set filename of object first
            this->saveFile();               // Finish by calling the save action
        }
    }
    else
        // User did not select a valid file and push okay button
        m_pStatbar->message(trUtf8("Saving aborted"), 4000);
}

//
// Implicitly serialize current state to a selected file
// The main difference with saveAs is that this uses exceptions
//
void Titraqform::saveName(void)
{
    int nResult = 0; // For checking user's answer

    // Make sure we correctly get the name of the default file to open
    QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
    if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
        Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);

    nResult = 1;            // We loop on this dialog only if an indecisive user
    while (nResult > 0) {   // is hesitant to overwrite a file over and over again
        QString Filestring = QFileDialog::getSaveFileName(Openas, trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
        if (!Filestring.isEmpty()) {
            if (QFile::exists(Filestring)) {
                nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
                        + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
                          trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
                switch (nResult) {
                case 0: // Overwrite contents
                    this->setFilename(Filestring);
                    this->saveFile();
                    break;
                case 1: // Don't overwrite
                default:
                    break;
                }
            }
            else {

                // Conditionally use a unique extension like '.as' if user prefers
                if (m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON)) {
                    QString Extension = TITRAQ_FEXTENSION;  // Logic to handle
                    if (!Filestring.endsWith(Extension))    // AS file extension
                        Filestring += Extension;            // insertion
                }
                this->setFilename(Filestring);  // Set filename of object first
                nResult = 0;                    // Reset our loop control
                this->saveFile();               // Finish by calling the save action
            }
        }
        else {
            // User did not select a valid file and push okay button
            m_pStatbar->message(trUtf8("Saving aborted"), 4000);
            throw Genexcept(TITRAQ_SAVECANCELLED);
        }
    }
}

//
// Close current document, and then quit the application
//
void Titraqform::quitApp(void)
{
    int nResult = 0;

    if (m_pMaintable->isDirty()) {
        nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
                + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
                  trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);

        switch (nResult) {      // Maybe save before closing
        case 0: // Save first
            this->saveFile();   // Save changes first
            break;
        case 1: // Don't save first
            m_pMaintable->setDirty(false);
            break;
        case 2: // Do nothing
        default:
            return; // Go away without closing
            break;
        }
    }

    // We should be clean now, but double check just in case
    if (!m_pMaintable->isDirty())
        qApp->quit();
}

//
// Close current document, displaying in main window
//
void Titraqform::closeEvent(QCloseEvent *pClosit)
{
    int nResult = 0;

    if (!this->isOpen())    // Short circuit if user
        qApp->quit();       // selects close twice

    // Check modification state of current data
    if (m_pMaintable->isDirty()) {
        nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
                + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
                  trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);

        switch (nResult) {      // Maybe save before closing
        case 0: // Save first
            this->saveFile();   // Save changes first
            break;
        case 1: // Don't save first
            m_pMaintable->setDirty(false);
            break;
        case 2: // Do nothing
        default:
            pClosit->ignore();
            return; // Go away without closing
            break;
        }
    }

    if (!m_pMaintable->isDirty()) { // Check again
        // Fall through to implicit close code
        this->setCaption(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short);
        try { // There might be problems, so wrap these last ops with error handling
            QString Lightsout;          // It's late, go to bed
            if (this->isOpen())
                Lightsout = trUtf8("Closed document ") + *this->getFilename();
            this->setOpen(false);       // Set doc state to closed
            this->enableIface(false);   // Turn off the lights
            m_pStatbar->message(Lightsout, 4000);
        }
        catch (Genexcept& Genex) {
            Genex.reportErr();
        }
    }
    pClosit->ignore();  // Finish off by not closing
}

//
// Edit menu select all entries
//
void Titraqform::selAll(void)
{
    Prototype Unimp;
    Unimp.doMbox();
}

//
// Edit a table entry in place, without the usual edit controls
//
void Titraqform::inplaceEdit(int nRow, int nCol, int nButton, const QPoint &Mousepos)
{
    // Table read only attribute must be reset here, so that editing can take
    // place. Otherwise calls to editCell are ignored (for obvious reasons).
    m_pMaintable->setReadOnly(false);

    // After editCell() is called, beginEdit() and endEdit() execute. The read
    // only attribute is reset in endEdit() to return everything to normal.
    m_pMaintable->editCell(nRow, nCol);

    m_pMaintable->setEdition(nCol);
}

//
// Update the edit controls widget sizes
//
void Titraqform::updSizes(int nSection, int nOldsize, int nNewsize)
{
    switch (nSection) {
    case TITRAQ_IDXALLCTRLS:
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) > 0)
            m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) > 0)
            m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) > 0)
            m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) > 0)
            m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) > 0)
            m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) > 0)
            m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) > 0)
            m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) > 0)
            m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) > 0)
            m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) > 0)
            m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING);
        if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) > 0)
            m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING);
//        if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXRCOL)))
//            m_pRemark->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREMARK) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXSTATUS:
        m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXLINE:
        m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXUSER:
        m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXGUID:
        m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXCRC:
        m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXREV:
        m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXDATE:
        m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXSTART:
        m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXFINISH:
        m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXAMOUNT:
        m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXTASK:
        m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING);
        break;
    case TITRAQ_IDXREMARK:
//        m_pRemark->setFixedWidth(nNewsize);
        break;
    default:
        throw Genexcept("Unrecognized main window column header.");
        break;
    }

    // As a last and redundant step, adjust size of first visible control
    switch(this->getFirstcol()) {
    case TITRAQ_IDXSTATUS:
        m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXLINE:
        m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXUSER:
        m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXGUID:
        m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXCRC:
        m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXREV:
        m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXDATE:
        m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXSTART:
        m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXFINISH:
        m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXAMOUNT:
        m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    case TITRAQ_IDXTASK:
        m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
        break;
    default:    // Probably no columns are visible?
        break;
    }
}

//
// What to do if a data cell is modified
//
void Titraqform::dataChanged(int nRow, int nCol)
{
    if (nCol != TITRAQ_IDXSTATUS && nCol != TITRAQ_IDXLINE)
        m_pMaintable->setDirty();   // Mark this timesheet dirty, changes pending save
}

//
// 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) {
        U32 Testcrc, Valcrc;
        QString Crcstr;
        std::auto_ptr<Qualistring>pWholerow(new Qualistring);
        int nRealrow = -1;

        // Build the data that will be used in testing CRC calculation
        nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow();
        *pWholerow = 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!
                *pWholerow += m_pMaintable->text(nRealrow, nIter);

        // Update the checksum and revision only if necessary
        Testcrc = pWholerow->getCrc();

        // FIXME: This thing is not very unportable, because toUInt != U32
        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
            *pWholerow = 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!
                    *pWholerow += m_pMaintable->text(nRealrow, nIter);

            Valcrc = pWholerow->getCrc(); // Finally set the checksum to its new value
            Crcstr = QString::number(Valcrc, 16).rightJustify(8, '0');
            m_pMaintable->setText(nRealrow, TITRAQ_IDXCRC, "0x" + Crcstr);
            m_pCrcedit->setText("0x" + Crcstr);
        }
    }
}

//
// Gets a hit on every table click
//
void Titraqform::onClick(int nRow, int nCol, int nButton, const QPoint &Mousepos)
{
    // Give the clueless user some hints when clicking an empty timesheet
    if (m_pMaintable->numRows() <= 0)
        m_pStatbar->message(trUtf8("Empty timesheet, add entries first please"), 2000);
}

//
// Update the edit controls contents
//
void Titraqform::updEdit(int nRow, int nCol)
{
    // Why is the app sending negative row signal? I don't know yet,
    // so add in this nasty hack to fend off the debug spew on stderr
    if (m_pMaintable->numRows() > 0 && nRow >= 0) {
        // Field strings to check for validity and process
        QString Textline(m_pMaintable->text(nRow, TITRAQ_IDXLINE));
        QString Textuser(m_pMaintable->text(nRow, TITRAQ_IDXUSER));
        QString Textguid(m_pMaintable->text(nRow, TITRAQ_IDXGUID));
        QString Textcrc(m_pMaintable->text(nRow, TITRAQ_IDXCRC));
        QString Textrev(m_pMaintable->text(nRow, TITRAQ_IDXREV));
        QString Textdate(m_pMaintable->text(nRow, TITRAQ_IDXDATE));
        QString Textstart(m_pMaintable->text(nRow, TITRAQ_IDXSTART));
        QString Textfinish(m_pMaintable->text(nRow, TITRAQ_IDXFINISH));
        QString Textamount(m_pMaintable->text(nRow, TITRAQ_IDXAMOUNT));
        QString Texttask(m_pMaintable->text(nRow, TITRAQ_IDXTASK));
        QString Textremark(m_pMaintable->text(nRow, TITRAQ_IDXREMARK));

        // Reset the edition state member
        m_pMaintable->setEdition();

        // Set text of member edit controls
        if (m_pMaintable->text(nRow, TITRAQ_IDXSTATUS).isEmpty())   // If row is empty
            m_pStatusedit->setPixmap(s_kpcStatvoid_xpm);            // add a placeholder
        else
            m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRow, TITRAQ_IDXSTATUS));
        m_pLineedit->setText(Textline);
        m_pUseredit->setText(Textuser);
        m_pGuidedit->setText(Textguid);
        m_pCrcedit->setText(Textcrc);
        m_pRevedit->setText(Textrev);

//        QRegExp Shorten("/(\\w+)$");    // For stripping prefix off the current task
//        Texttask.remove(0, Shorten.search(Texttask) + 1); // Strip leading slash

        m_pRemark->setText(Textremark);
        m_pTasks->setCurrentText(Texttask);

        // Date field not suitable for empty string text
        if (Textdate == ".")
            m_pDateedit->setDate(QDate::currentDate());
        else if (Textdate.isEmpty())
            m_pDateedit->setDate(QDate::fromString("0000-00-00", Qt::ISODate));
        else
            m_pDateedit->setDate(QDate::fromString(Textdate, Qt::ISODate));

        // Start time not suitable for empty string text
        if (Textstart == ".")
            m_pStarttime->setTime(QTime::currentTime());
        else if (Textstart.isEmpty())
            m_pStarttime->setTime(QTime::QTime(0, 0));
        else
            m_pStarttime->setTime(QTime::fromString(Textstart, Qt::ISODate));

        // Finish time not suitable for empty string text
        if (Textfinish == ".")
            m_pEndtime->setTime(QTime::currentTime());
        else if (Textfinish.isEmpty())
            m_pEndtime->setTime(QTime::QTime(0, 0));
        else
            m_pEndtime->setTime(QTime::fromString(Textfinish, Qt::ISODate));

        // Amount time not suitable for empty string text
        if (Textamount == ".") {
            int nDifference = m_pStarttime->time().secsTo(m_pEndtime->time());
            m_pAmount->setTime(QTime(0, 0).addSecs(nDifference));
        }
        else if (Textamount.isEmpty())
            m_pAmount->setTime(QTime::QTime(0, 0));
        else
            m_pAmount->setTime(QTime::fromString(Textamount, Qt::ISODate));
    }
}

//
// Validate current row of the matrix
//
void Titraqform::validateRow(void)
{
    this->validateRow(-1, -1);
}

//
// Validate specified row of the matrix
//
void Titraqform::validateRow(int nRow, int nCol)
{
    int nRealrow = -1;

    if (!this->isOpen()) { // If no data is loaded then short circuit
        m_pStatbar->message(trUtf8("Timesheet contains no data"), 4000);
        return;
    }

    nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow();
    QString Statis = m_pMaintable->text(nRealrow, TITRAQ_IDXSTATUS); // Get text

    // Review whole data validity, and set pixmap accordingly
    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(nRealrow, TITRAQ_IDXSTATUS));
        }
        else if (!Statis.startsWith(QString("E"))) { // Conditionally set pixmap to avoid overhead
            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(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));
        }
    }

    // Test for blank user field, and set to default if so
    if (m_pMaintable->text(nRealrow, TITRAQ_IDXUSER).isEmpty())
        m_pMaintable->setText(nRealrow, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));

    // Test for blank date field, and set to default if so
    if (m_pMaintable->text(nRealrow, TITRAQ_IDXDATE) == ".")
        m_pMaintable->setText(nRealrow, TITRAQ_IDXDATE, QDate::currentDate().toString(Qt::ISODate));

    // Test for blank start field, and set to default if so
    if (m_pMaintable->text(nRealrow, TITRAQ_IDXSTART) == ".")
        m_pMaintable->setText(nRealrow, TITRAQ_IDXSTART, QTime::currentTime().toString("hh:mm"));

    // Test for blank finish field, and set to default if so
    if (m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH) == ".")
        m_pMaintable->setText(nRealrow, TITRAQ_IDXFINISH, QTime::currentTime().toString("hh:mm"));

    // Test for blank amount field, and set to default if so
    if (m_pMaintable->text(nRealrow, TITRAQ_IDXAMOUNT) == ".") {
        QTime Begin  = QTime::fromString(m_pMaintable->text(nRealrow, TITRAQ_IDXSTART), Qt::ISODate);
        QTime End    = QTime::fromString(m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH), Qt::ISODate);
        QString Diff = QTime(0, 0).addSecs(Begin.secsTo(End)).toString("hh:mm");
        m_pMaintable->setText(nRealrow, TITRAQ_IDXAMOUNT, Diff);
    }
}

//
// Update the current line number column item
//
void Titraqform::updateLine(const QString &Instring)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXLINE, Instring);
}

//
// Update the current user column item
//
void Titraqform::updateUser(const QString &Instring)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXUSER, Instring);
}

//
// Update the current GUID column item
//
void Titraqform::updateGuid(const QString &Instring)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXGUID, Instring);
}

//
// Update the current CRC column item
//
void Titraqform::updateCrc(const QString &Instring)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXCRC, Instring);
}

//
// Update the current rev column item
//
void Titraqform::updateRev(const QString &Instring)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREV, Instring);
}

//
// Update the current date column item
//
void Titraqform::updateDate(const QDate &Dateup)
{
        m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXDATE, Dateup.toString(Qt::ISODate));
}

//
// Update the current start column item
//
void Titraqform::updateStart(const QTime &Startup)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXSTART, Startup.toString("hh:mm"));
}

//
// Update the current finish column item
//
void Titraqform::updateFinish(const QTime &Finishup)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXFINISH, Finishup.toString("hh:mm"));
}

//
// Update the current amount column item
//
void Titraqform::updateAmount(const QTime &Amountup)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXAMOUNT, Amountup.toString("hh:mm"));
}

//
// Update the current task column item
//
void Titraqform::updateTask(const QString &Taskup)
{
//    // FIXME: Broken
//    RtTableItem *pTask = NULL;
//    pTask = static_cast<RtTableItem *>(m_pMaintable->item(m_pMaintable->currentRow(), TITRAQ_IDXTASK));
//    pTask->setText(Taskup);

    // Don't try to use the Taskup string, because it ignores autocompletion
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXTASK, m_pTasks->currentText());
}

//
// Update the current remark column item
//
void Titraqform::updateRemark(const QString &Remarkup)
{
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREMARK, Remarkup);
}

//
// Confirm any recent editions on a whole row
//
void Titraqform::confirmEdit(void)
{
    RtTableItem *pTask = NULL;  // Task item is a derived class

    // Conversions from edit control data formats to native tabular format
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXDATE, m_pDateedit->date().toString(Qt::ISODate));
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXSTART, m_pStarttime->time().toString(Qt::ISODate));
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXFINISH, m_pEndtime->time().toString(Qt::ISODate));
    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXAMOUNT, m_pAmount->time().toString(Qt::ISODate));

    // Specially handle task fields
    pTask = static_cast<RtTableItem *>(m_pMaintable->item(m_pMaintable->currentRow(), TITRAQ_IDXTASK));
    pTask->setText(m_pTasks->currentText());

    m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREMARK, m_pRemark->text());
}

//
// Edit menu configure preferences
//
void Titraqform::configPrefs(void)
{
    QString Templine;               // Used for preferences resetting
    Prefpanel *pUserpanel = NULL;   // The user preferences panel itself

    // Create a new preferences panel window
    pUserpanel = new Prefpanel(this, "Userprefpanel");
    connect(pUserpanel, SIGNAL(applied(void)), SLOT(applyPrefs(void)));

    // Set default values to appear in initialized panel widgets
    pUserpanel->setAccounts(m_pPrefs->getString(TITRAQ_PREFACCOUNTS, TITRAQ_DEFACCOUNTS));
    pUserpanel->setEvents(m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR));
    pUserpanel->setUser(m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
    pUserpanel->setHome(m_pPrefs->getString(TITRAQ_PREFHOME, TITRAQ_DEFHOME));
    pUserpanel->setCorbahost(m_pPrefs->getString(TITRAQ_PREFCORBHOST, TITRAQ_DEFCORBHOST));
    pUserpanel->setSoaphost(m_pPrefs->getString(TITRAQ_PREFSOAPHOST, TITRAQ_DEFSOAPHOST));
#ifdef HAVE_MICO
    pUserpanel->setCorbaon(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON));
#else
    pUserpanel->setCorbaon(false);
    pUserpanel->lockCorba();
#endif
#ifdef HAVE_ESOAP
    pUserpanel->setSoapon(m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
#else
    pUserpanel->setSoapon(false);
    pUserpanel->lockSoap();
#endif
    pUserpanel->setBackon(m_pPrefs->getBool(TITRAQ_PREFBAKON, TITRAQ_DEFBAKON));
    pUserpanel->setExtendon(m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON));
    pUserpanel->setDetailon(m_pPrefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON));
    pUserpanel->setSignaton(m_pPrefs->getBool(TITRAQ_PREFSIGNATON, TITRAQ_DEFSIGNATON));

    // Set default style which can be more complicated due to mapping...
    switch (m_pPrefs->getNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE)) {
    case TITRAQ_STYLECDE:
        pUserpanel->setStyle(TITRAQ_STRCDE);
        break;
    case TITRAQ_STYLESGI:
        pUserpanel->setStyle(TITRAQ_STRSGI);
        break;
    case TITRAQ_STYLEMOTIF:
        pUserpanel->setStyle(TITRAQ_STRMOTIF);
        break;
    case TITRAQ_STYLEMPLUS:
        pUserpanel->setStyle(TITRAQ_STRMPLUS);
        break;
    case TITRAQ_STYLEPLAT:
        pUserpanel->setStyle(TITRAQ_STRPLAT);
        break;
    case TITRAQ_STYLEMSOFT:
        pUserpanel->setStyle(TITRAQ_STRMSOFT);
        break;
    default:
        pUserpanel->setStyle(TITRAQ_STRCDE);    // My personal favourite ;-)
        break;
    }

    // Colour preferences
    int nRed, nGreen, nBlue;
    QColorGroup Origcolour, Altcolour;
    const QColor Origlight = QColor(TITRAQ_DEFLIGHTRED, TITRAQ_DEFLIGHTGREEN, TITRAQ_DEFLIGHTBLUE);
    const QColor Origdark  = QColor(TITRAQ_DEFDARKRED, TITRAQ_DEFDARKGREEN, TITRAQ_DEFDARKBLUE);
    const QColor Altlight = QColor(TITRAQ_DEFLTALTRED, TITRAQ_DEFLTALTGREEN, TITRAQ_DEFLTALTBLUE);
    const QColor Altdark  = QColor(TITRAQ_DEFDKALTRED, TITRAQ_DEFDKALTGREEN, TITRAQ_DEFDKALTBLUE);

    // Set colours to revert to if user screws up and wants out
    Origcolour.setColor(QColorGroup::Foreground, Origlight);
    Origcolour.setColor(QColorGroup::Background, Origdark);
    pUserpanel->setOrigcolour(&Origcolour);
    Altcolour.setColor(QColorGroup::Foreground, Altlight);
    Altcolour.setColor(QColorGroup::Background, Altdark);
    pUserpanel->setAltcolour(&Altcolour);

    // Set colour preferences saved from last session
    nRed   = m_pPrefs->getNumber(TITRAQ_PREFLIGHTRED, TITRAQ_DEFLIGHTRED);
    nGreen = m_pPrefs->getNumber(TITRAQ_PREFLIGHTGREEN, TITRAQ_DEFLIGHTGREEN);
    nBlue  = m_pPrefs->getNumber(TITRAQ_PREFLIGHTBLUE, TITRAQ_DEFLIGHTBLUE);
    const QColor Lightshade = QColor(nRed, nGreen, nBlue);
    pUserpanel->setLight(&Lightshade);
    nRed   = m_pPrefs->getNumber(TITRAQ_PREFDARKRED, TITRAQ_DEFDARKRED);
    nGreen = m_pPrefs->getNumber(TITRAQ_PREFDARKGREEN, TITRAQ_DEFDARKGREEN);
    nBlue  = m_pPrefs->getNumber(TITRAQ_PREFDARKBLUE, TITRAQ_DEFDARKBLUE);
    const QColor Darkshade = QColor(nRed, nGreen, nBlue);
    pUserpanel->setDark(&Darkshade);

    // Modal panel handler
    if (pUserpanel->exec() == QDialog::Accepted)
        this->applyPrefs(pUserpanel);

    // Dispose Panel object
    delete pUserpanel;
}

//
// View menu normal
//
void Titraqform::normalView(void)
{
    // All view types except normal are disabled until implemention, so
    // this body can remain empty, causing nothing to happen on selection.
}

//
// View menu editing
//
void Titraqform::editingView(void)
{
    // All view types except normal are disabled until implemention, so
    // this body can remain empty, causing nothing to happen on selection.
}

//
// View menu timing
//
void Titraqform::timingView(void)
{
    // All view types except normal are disabled until implemention, so
    // this body can remain empty, causing nothing to happen on selection.
}

//
// View menu show file toolbar
//
void Titraqform::showFilebar(void)
{
    if (m_pFiletools->isVisible()) {
        m_pFiletools->hide();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR), false);
    }
    else {
        m_pFiletools->show();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR), true);
    }
}

//
// View menu show edit toolbar
//
void Titraqform::showEditbar(void)
{
    if (m_pEdittools->isVisible()) {
        m_pEdittools->hide();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR), false);
    }
    else {
        m_pEdittools->show();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR), true);
    }
}

//
// View menu show view toolbar
//
void Titraqform::showViewbar(void)
{
    if (m_pViewtools->isVisible()) {
        m_pViewtools->hide();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR), false);
    }
    else {
        m_pViewtools->show();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR), true);
    }
}

//
// View menu show prefs toolbar
//
void Titraqform::showPrefsbar(void)
{
    if (m_pPrefstools->isVisible()) {
        m_pPrefstools->hide();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR), false);
    }
    else {
        m_pPrefstools->show();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR), true);
    }
}

//
// View menu show whats this toolbar
//
void Titraqform::showWhatsbar(void)
{
    if (m_pWhatstools->isVisible()) {
        m_pWhatstools->hide();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR), false);
    }
    else {
        m_pWhatstools->show();
        m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR), true);
    }
}

//
// View menu show status column
//
void Titraqform::showStatcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXSTATUS);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL), false);
        m_pStatusedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXSTATUS);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL), true);
        m_pStatusedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXSTATCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show line numbers column
//
void Titraqform::showLinecol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXLINE);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL), false);
        m_pLineedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXLINE);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL), true);
        m_pLineedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXLCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show users column
//
void Titraqform::showUsercol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXUSER);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL), false);
        m_pUseredit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXUSER);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL), true);
        m_pUseredit->show();
    }

    // Make sure switch take place right away and sizes are handled
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXUCOL));
}

//
// View menu show GUIDs column
//
void Titraqform::showGuidcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXGUID);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL), false);
        m_pGuidedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXGUID);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL), true);
        m_pGuidedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXGCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show CRC column
//
void Titraqform::showCrccol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXCRC);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL), false);
        m_pCrcedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXCRC);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL), true);
        m_pCrcedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXCCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show Rev column
//
void Titraqform::showRevcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXREV);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL), false);
        m_pRevedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXREV);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL), true);
        m_pRevedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXREVCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show dates column
//
void Titraqform::showDatecol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXDATE);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL), false);
        m_pDateedit->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXDATE);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL), true);
        m_pDateedit->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXDCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show start time column
//
void Titraqform::showStartcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXSTART);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL), false);
        m_pStarttime->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXSTART);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL), true);
        m_pStarttime->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show finish time column
//
void Titraqform::showFinishcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXFINISH);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL), false);
        m_pEndtime->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXFINISH);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL), true);
        m_pEndtime->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXFCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show Amounts column
//
void Titraqform::showAmountcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXAMOUNT);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL), false);
        m_pAmount->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXAMOUNT);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL), true);
        m_pAmount->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXACOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show tasks column
//
void Titraqform::showTaskcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXTASK);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL), false);
        m_pTasks->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXTASK);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL), true);
        m_pTasks->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXTCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// View menu show Remarks column
//
void Titraqform::showRemarkcol(void)
{
    // Test if column is currently shown, conditionally show or hide it
    if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL))) {
        m_pMaintable->hideColumn(TITRAQ_IDXREMARK);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL), false);
        m_pRemark->hide();
    }
    else {
        m_pMaintable->showColumn(TITRAQ_IDXREMARK);
        m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL), true);
        m_pRemark->show();
    }

    // Make sure switch take place right away and sizes are handled
    m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXREMCOL));
    this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
}

//
// Generate a local formatted report
//
void Titraqform::genReport(void)
{
    try { // Create and execute a new local report window
        std::auto_ptr<AS::Reportpanel> pReport(new AS::Reportpanel
            (m_pMaintable, m_pPrefs, this, "Locreportpanel"));
        pReport->exec();
        delete pReport.release(); // Technically unnecessary, smart pointer
    }
    catch (Genexcept& Genex) {
        Genex.reportErr();
        return;
    }
}

//
// Syncronize data with server using IIOP
//
void Titraqform::syncIiop(void)
{
#ifdef HAVE_MICO
    // Short circuit if user has disabled CORBA transmission in prefs
    if (!m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON))
        return;

    char **ppcInargv = NULL;    // Parameters to the ORB
    CORBA::ORB_var Orb;         // The ORB iself

    CORBA::Object_var Nameobj;      // Name service reference
    CosNaming::NamingContext_var Namectx; // COSS ns context
    CosNaming::Name Cosname;        // Our requested obj name

    CORBA::Object_var Objcaster;    // Generic CORBA object
    Asdatabase_var Asdbase;         // Casted object to ASDB
    Astuple Singlerow;              // A single row of AS data

    QString *pOrbargv = new QString(TITRAQ_ORBINIT);
    int nCount = pOrbargv->contains(' ');
    int nNamesize = 0;

    // Build a false incoming argv with which we initialize the ORB
    ppcInargv = new char *[nCount + 3]; // 3 = arg0 + last section + COSS host
    *ppcInargv = new char[strlen(*qApp->argv() + 2)]; // For cmd name
    strcpy(ppcInargv[0], *qApp->argv());              // Copy cmd name
    for (int nIter = 0; nIter <= nCount; nIter++) {
        QString Section = pOrbargv->section(' ', nIter, nIter);
        ppcInargv[nIter + 1] = new char[strlen(Section.ascii() + 2)];
        strcpy(ppcInargv[nIter + 1], Section.ascii());
    }

    // Build the single string COSS naming host name with associated port number
    *pOrbargv = TITRAQ_COSSPART1
              + m_pPrefs->getString(TITRAQ_PREFCORBHOST, TITRAQ_DEFCORBHOST)
              + TITRAQ_COSSPART2;
    nNamesize = strlen(pOrbargv->ascii());
    ppcInargv[nCount + 2] = new char[nNamesize];
    strcpy(ppcInargv[nCount + 2], pOrbargv->ascii());

    try {
        // Initialization of the ORB and COSS naming service
        nCount = nCount + 3; // Raise the count to include app, last sec, COSS
        Orb = CORBA::ORB_init(nCount, ppcInargv, "mico-local-orb");
        Nameobj = Orb->resolve_initial_references("NameService");
        Namectx = CosNaming::NamingContext::_narrow(Nameobj);
        if (CORBA::is_nil(Namectx)) { // Verify sanity
            m_pStatbar->message(trUtf8("Could not find the COSS naming service"));
            qWarning("Could not find the COSS naming service\n");
        }

        // Clean up our dynamically allocated array
        for (int nIter = 0; nIter < nCount; nIter++)
            delete ppcInargv[nIter];
        delete ppcInargv; // Free the array itself
        delete pOrbargv;  // Free the intermediate string

        // Prepare the COSS name request
        Cosname.length(1);
        Cosname[0].id = CORBA::string_dup("Asdatabase");
        Cosname[0].kind = CORBA::string_dup("");

        try { // Resolve to a CORBA object
            Objcaster = Namectx->resolve(Cosname);
        }
        catch (CosNaming::NamingContext::NotFound &Cossex) {
            m_pStatbar->message(trUtf8("NotFound exception thrown"));
            qWarning("NotFound exception thrown\n");
            return;
        }
        catch (CosNaming::NamingContext::CannotProceed &Cossex) {
            m_pStatbar->message(trUtf8("CannotProceed exception thrown"));
            qWarning("CannotProceed exception thrown\n");
            return;
        }
        catch (CosNaming::NamingContext::InvalidName &Cossex) {
            m_pStatbar->message(trUtf8("InvalidName exception thrown"));
            qWarning("InvalidName exception thrown\n");
            return;
        }

        // Cast the generic CORBA object to a AS database type
        Asdbase = Asdatabase::_narrow(Objcaster);
        if (CORBA::is_nil(Asdbase)) { // Verify sanity
            m_pStatbar->message(trUtf8("Could not find the AS database"));
            qWarning("Could not find the AS database\n");
            return;
        }

        // Open an account object on the remote server
        Account_var Account = Asdbase->Open("/tmp/events.as");
        if (CORBA::is_nil(Account)) { // Verify sanity
            m_pStatbar->message(trUtf8("Could not create an account object on the server"));
            qWarning("Could not create an account object on the server\n");
            return;
        }

        // Fill account log object(s) to marshall and transmit
        int nRow = m_pMaintable->currentRow();
        QTableSelection Select = m_pMaintable->selection(0);    // Capture selected rows
        int nTotal = Select.bottomRow() - Select.topRow() + 1;  // Total rows selected

        // Remember, CORBA::stri_dup creates smart pointers
        for (int nIter = 0; nIter < nTotal; nIter++) {
            Singlerow.szUser   = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER));
            Singlerow.szGuid   = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXGUID));
            Singlerow.szCrc    = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXCRC).remove("0x"));
            Singlerow.szRev    = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV));
            Singlerow.szDate   = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE));
            Singlerow.szStart  = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART));
            Singlerow.szFinish = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH));
            Singlerow.szAmount = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT));
//            Singlerow.nRev     = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV).toUInt();
//            Singlerow.nDate    = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE).toUInt();
//            Singlerow.nStart   = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART).toUInt();
//            Singlerow.nFinish  = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH).toUInt();
//            Singlerow.nAmount  = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT).toUInt();
            Singlerow.szTask   = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXTASK));
            Singlerow.szRemark = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREMARK));
            Account->Log(Singlerow); // Finally transmit to server
        }

        m_pStatbar->message(trUtf8("Successful transmission of accounting data"));
    }
    catch (const CORBA::Exception &Corbex) {
        m_pStatbar->message(trUtf8("Caught CORBA exception: %1").arg(Corbex._repoid()));
        qWarning("Caught CORBA exception: %s", Corbex._repoid());
    }
    catch (...) {
        qWarning("Caught unknown exception\n");
    }
#endif // HAVE_MICO
}

//
// Syncronize data with server using SOAP
//
void Titraqform::syncSoap(void)
{
#ifdef HAVE_ESOAP
    // Short circuit if user has disabled SOAP transmission in prefs
    if (!m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON))
        return;

    USING_EASYSOAP_NAMESPACE

    try {
        SOAPMethod Logmeth("Log", TITRAQ_SOAPSPACE); // SOAP namespace
        SOAPString Clistr;                  // Outgoing parameter to marshall
        int nCrc;                           // SOAP unmarshalled return value

        // Build the single string SOAP end point which look like this:
        //   "http://www.europalab.com/cgi-bin/asdbserv"
        QString Endpoint;
        Endpoint = TITRAQ_PREFIXHTTP + m_pPrefs->getString(TITRAQ_PREFSOAPHOST, TITRAQ_DEFSOAPHOST);
        SOAPProxy Proxy(Endpoint.ascii());

        // Fill account log object(s) to marshall and transmit
        QTableSelection Select = m_pMaintable->selection(0);    // Capture selected rows
        int nTotal = Select.bottomRow() - Select.topRow() + 1;  // Total rows selected

        // Iterate through the selection of row entries to transmit
        for (int nRowiter = 0; nRowiter < nTotal; nRowiter++) {
            QString Syncthis = m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXUSER);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXGUID);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXCRC).remove("0x");
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXREV);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXDATE);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXSTART);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXFINISH);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXAMOUNT);
            Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXTASK);
            Syncthis += ' ' + ('"' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXREMARK)) + '"';
            Clistr = Syncthis;                          // Build RPC parameter
            Logmeth.AddParameter("Tuple") << Clistr;    // Prepare for marshalling
            const SOAPResponse &Logresp = Proxy.Execute(Logmeth);
            Logresp.GetReturnValue() >> nCrc;
        }
        m_pStatbar->message(trUtf8("Successful transmission, CRC returned %1").arg(nCrc));
    }
    catch (SOAPException& Soapex) { // Announce the exception we received
        m_pStatbar->message(trUtf8("Caught SOAP exception: %1").arg(Soapex.What().Str()));
        qDebug("Caught SOAP exception: %s", Soapex.What().Str());
    }
    catch (...) {
        qDebug("Caught unknown exception\n");
    }
#endif // HAVE_ESOAP
}

//
// Save user preferences
//
void Titraqform::savePrefs(void)
{
    // Get check status from column menu and pass it to prefs handler
    m_pPrefs->setBool(TITRAQ_PREFSTATCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL)));
    m_pPrefs->setBool(TITRAQ_PREFLCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL)));
    m_pPrefs->setBool(TITRAQ_PREFUCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL)));
    m_pPrefs->setBool(TITRAQ_PREFGCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL)));
    m_pPrefs->setBool(TITRAQ_PREFCCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL)));
    m_pPrefs->setBool(TITRAQ_PREFREVCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL)));
    m_pPrefs->setBool(TITRAQ_PREFDCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL)));
    m_pPrefs->setBool(TITRAQ_PREFSTARTCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL)));
    m_pPrefs->setBool(TITRAQ_PREFFCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL)));
    m_pPrefs->setBool(TITRAQ_PREFACOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL)));
    m_pPrefs->setBool(TITRAQ_PREFFCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL)));
    m_pPrefs->setBool(TITRAQ_PREFREMCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL)));

    // Get check status from toolbar menu and pass it to prefs handler
    m_pPrefs->setBool(TITRAQ_PREFFILEBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR)));
    m_pPrefs->setBool(TITRAQ_PREFEDITBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR)));
    m_pPrefs->setBool(TITRAQ_PREFVIEWBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR)));
    m_pPrefs->setBool(TITRAQ_PREFPREFBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR)));
    m_pPrefs->setBool(TITRAQ_PREFWHATBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR)));

    // Get column widths from main table and pass it to prefs handler
    if (m_pMaintable->columnWidth(TITRAQ_IDXSTATUS) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFSTATCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXSTATUS));
    if (m_pMaintable->columnWidth(TITRAQ_IDXLINE) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFLCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXLINE));
    if (m_pMaintable->columnWidth(TITRAQ_IDXUSER) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFUCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXUSER));
    if (m_pMaintable->columnWidth(TITRAQ_IDXGUID) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFGCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXGUID));
    if (m_pMaintable->columnWidth(TITRAQ_IDXCRC) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFCCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXCRC));
    if (m_pMaintable->columnWidth(TITRAQ_IDXREV) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFREVCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXREV));
    if (m_pMaintable->columnWidth(TITRAQ_IDXDATE) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFDCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXDATE));
    if (m_pMaintable->columnWidth(TITRAQ_IDXSTART) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFSTARTCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXSTART));
    if (m_pMaintable->columnWidth(TITRAQ_IDXFINISH) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFFCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXFINISH));
    if (m_pMaintable->columnWidth(TITRAQ_IDXAMOUNT) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFACOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXAMOUNT));
    if (m_pMaintable->columnWidth(TITRAQ_IDXTASK) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFTCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXTASK));
    if (m_pMaintable->columnWidth(TITRAQ_IDXREMARK) > 0)
        m_pPrefs->setNumber(TITRAQ_PREFREMCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXREMARK));

    // Get sorting order and direction from table and pass it to prefs handler
    m_pPrefs->setNumber(TITRAQ_PREFSORTCOL, (long)m_pMaintable->getSortcol());
    m_pPrefs->setBool(TITRAQ_PREFSORTDIR, (long)m_pMaintable->getSortdir());

    // Set frame geometry preferences
    m_pPrefs->setNumber(TITRAQ_PREFFRAMEWIDTH, (long)this->width());
    m_pPrefs->setNumber(TITRAQ_PREFFRAMEHEIGHT, (long)this->height());

    // Remember main window layout and doc positions
    QString Laystring;
    QTextStream Laystream(&Laystring, IO_WriteOnly);
    Laystream << *this; // Persist the main window
    m_pPrefs->setString(TITRAQ_PREFFRAMELAY, Laystring);
}

//
// Get help on Titraq functionality
//
void Titraqform::helpContents(void)
{
    try { // Create and execute a new help contents window
        std::auto_ptr<AS::Helpanel> pHelpcont(new AS::Helpanel(TITRAQ_REFHELP, this, "Helpanel"));
        pHelpcont->exec();
        delete pHelpcont.release(); // Technically unnecessary, smart pointer
    }
    catch (Genexcept& Genex) {
        Genex.reportErr();
        return;
    }
}

//
// Learn more about this program itself
//
void Titraqform::aboutTitraq(void)
{
    QString Namever = QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short;
    QMessageBox *pCwmsg = new QMessageBox(Namever,
        QObject::trUtf8("The as-gui is a time and task-based accounting\n"
               "system that acts as both a work-like punch card and\n"
               "time tracker. Development of as-gui is sponsored by\n"
               "Cable & Wireless Telecommunications Services GmbH."),
        QMessageBox::NoIcon, QMessageBox::Ok | QMessageBox::Default,
        QMessageBox::NoButton, QMessageBox::NoButton,
        NULL, "Titraqmessage", true, Qt::WStyle_NormalBorder);

    pCwmsg->setIconPixmap(QPixmap(s_kpcCwlogo_xpm));
    pCwmsg->exec();
}

//
// Learn more about the OSSP
//
void Titraqform::aboutOSSP(void)
{
    QString Namever = QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short;
    QMessageBox *pOsspmsg = new QMessageBox(Namever,
        QObject::trUtf8("The open source software project (OSSP) is\n"
               "a collective effort aimed at implementing\n"
               "high-quality Unix software components,\n"
               "ranging from networking, multi-threading\n"
               "and algorithmic libraries to networking\n"
               "servers and development tools."),
        QMessageBox::NoIcon, QMessageBox::Ok | QMessageBox::Default,
        QMessageBox::NoButton, QMessageBox::NoButton,
        NULL, "Osspmessage", true, Qt::WStyle_NormalBorder);

    pOsspmsg->setIconPixmap(QPixmap(s_kpcOssplogo_xpm));
    pOsspmsg->exec();
}

//
// Learn more about this program and Qt
//
void Titraqform::aboutQt(void)
{
    QMessageBox::aboutQt(this, QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short);
}

//
// Apply preference values from a signal emitting object
//
void Titraqform::applyPrefs(void)
{
    Prefpanel *pPan = (Prefpanel *)QObject::sender();
    this->applyPrefs(pPan);
}

//
// Accept preference values from a inbound Panel object
//
void Titraqform::applyPrefs(Prefpanel *pPrefpanel)
{
    m_pPrefs->setString(TITRAQ_PREFACCOUNTS, pPrefpanel->getAccounts());
    m_pPrefs->setString(TITRAQ_PREFASDIR, pPrefpanel->getEvents());
    m_pPrefs->setString(TITRAQ_PREFUSER, pPrefpanel->getUser());
    m_pPrefs->setString(TITRAQ_PREFHOME, pPrefpanel->getHome());
    m_pPrefs->setString(TITRAQ_PREFCORBHOST, pPrefpanel->getCorbahost());
    m_pPrefs->setString(TITRAQ_PREFSOAPHOST, pPrefpanel->getSoaphost());
    m_pPrefs->setBool(TITRAQ_PREFCORBON, pPrefpanel->getCorbaon());
    m_pPrefs->setBool(TITRAQ_PREFSOAPON, pPrefpanel->getSoapon());
    m_pPrefs->setBool(TITRAQ_PREFBAKON, pPrefpanel->getBackon());
    m_pPrefs->setBool(TITRAQ_PREFEXTENDON, pPrefpanel->getExtendon());
    m_pPrefs->setBool(TITRAQ_PREFDETAILON, pPrefpanel->getDetailon());
    m_pPrefs->setBool(TITRAQ_PREFSIGNATON, pPrefpanel->getSignaton());
    m_pPrefs->setNumber(TITRAQ_PREFLIGHTRED, pPrefpanel->getLight()->red());
    m_pPrefs->setNumber(TITRAQ_PREFLIGHTGREEN, pPrefpanel->getLight()->green());
    m_pPrefs->setNumber(TITRAQ_PREFLIGHTBLUE, pPrefpanel->getLight()->blue());
    m_pPrefs->setNumber(TITRAQ_PREFDARKRED, pPrefpanel->getDark()->red());
    m_pPrefs->setNumber(TITRAQ_PREFDARKGREEN, pPrefpanel->getDark()->green());
    m_pPrefs->setNumber(TITRAQ_PREFDARKBLUE, pPrefpanel->getDark()->blue());

    // Dim the lights if no RPC transports are available
    if (this->isOpen())
        m_pSyncact->setEnabled(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON)
            | m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
    else
        m_pSyncact->setEnabled(false);

    // Get the selected style which can be more complicated due to mapping...
    if (pPrefpanel->getStyle() == TITRAQ_STRCDE) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE);
        qApp->setStyle(new QCDEStyle);
    }
    else if (pPrefpanel->getStyle() == TITRAQ_STRSGI) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLESGI);
        qApp->setStyle(new QSGIStyle);
    }
    else if (pPrefpanel->getStyle() == TITRAQ_STRMOTIF) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMOTIF);
        qApp->setStyle(new QMotifStyle);
    }
    else if (pPrefpanel->getStyle() == TITRAQ_STRMPLUS) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMPLUS);
        qApp->setStyle(new QMotifPlusStyle);
    }
    else if (pPrefpanel->getStyle() == TITRAQ_STRPLAT) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEPLAT);
        qApp->setStyle(new QPlatinumStyle);
    }
    else if (pPrefpanel->getStyle() == TITRAQ_STRMSOFT) {
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMSOFT);
        qApp->setStyle(new QWindowsStyle);
    }
    else // My personal favourite ;-)
        m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE);
}

CVSTrac 2.0.1