as_table.cpp

Fri, 28 Nov 2008 14:20:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 28 Nov 2008 14:20:00 +0100
changeset 2
e8292658d5b3
child 3
c1941114ca88
permissions
-rw-r--r--

Added tag ASGUI_0.7.7 for changeset d64aaa7d146f

     1 //
     2 //  OSSP asgui - Accounting system graphical user interface
     3 //  Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/)
     4 //  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
     5 //  Copyright (c) 2002-2004 Michael Schloh von Bennewitz <michael@schloh.com>
     6 //  Copyright (c) 2002-2004 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://www.ossp.org/pkg/tool/asgui/.
    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_table.cpp: ISO C++ implementation
    30 //
    32 #include <qheader.h>
    34 #include "as_const.h"
    35 #include "as_table.h"
    38 // Implements an event filter for catching header double click events
    39 bool TiTable::eventFilter(QObject *pObject, QEvent *pEvent)
    40 {
    41     if (pObject == horizontalHeader() && pEvent->type() == QEvent::MouseButtonDblClick)
    42         return true;
    43     if (pEvent->type() == QEvent::MouseButtonPress &&   // Ignore mid, right clicks
    44         ((QMouseEvent *)pEvent)->button() == QMouseEvent::RightButton ||
    45         ((QMouseEvent *)pEvent)->button() == QMouseEvent::MidButton)
    46         return true;
    47     else if (pEvent->type() == QEvent::KeyPress) {
    48         if (((QKeyEvent *)pEvent)->key() == Qt::Key_Tab) { // Handle tab key
    49             if (this->getEdition() >= 0) {
    50                 int nIter = 1; // Logic to skip invisible or read only columns
    51                 while (columnWidth((currentColumn() + nIter) % TITRAQ_IDXTAIL) <= 0
    52                     || isColumnReadOnly((currentColumn() + nIter) % TITRAQ_IDXTAIL))
    53                     nIter++;
    55                 // Advance the column or both row and column possibly
    56                 int nColadvance = ((currentColumn() + nIter) % TITRAQ_IDXTAIL);
    57                 if ((currentColumn() + nIter) >= TITRAQ_IDXTAIL) {
    58                     this->clearSelection(true);
    59                     this->setCurrentCell(currentRow() + 1, nColadvance);
    60 //                    this->repaint(false);   // Really necessary?
    61                 }
    62                 else
    63                     this->setCurrentCell(currentRow(), nColadvance);
    64                 this->setReadOnly(false);
    65                 this->editCell(currentRow(), currentColumn());
    66                 this->setEdition(currentColumn());
    67             }
    68             return true; // Handle the tab key event and cancel its progress
    69         }
    70         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Backtab) { // Handle shift tab key
    71             if (this->getEdition() >= 0) {
    72                 int nIter = 1; // Logic to skip invisible or read only columns
    73                 while (columnWidth((currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL) <= 0
    74                     || isColumnReadOnly((currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL))
    75                     nIter++;
    77                 // Advance the column or both row and column possibly
    78                 int nColadvance = (currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL;
    79                 if ((currentColumn() - nIter) < 0) {
    80                     this->clearSelection(true);
    81                     this->setCurrentCell(currentRow() - 1, nColadvance);
    82 //                    this->repaint(false);   // Really necessary?
    83                 }
    84                 else
    85                     this->setCurrentCell(currentRow(), nColadvance);
    86                 this->setReadOnly(false);
    87                 this->editCell(currentRow(), currentColumn());
    88                 this->setEdition(currentColumn());
    89             }
    90             return true; // Handle the shift tab key event and cancel its progress
    91         }
    92         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Return && this->getEdition() >= 0) { // Return key
    93             this->endEdit(currEditRow(), currEditCol(), true, false);
    94             this->setEdition();                             // Reset edition
    95             return true;                                    // Cancel progress
    96         }
    97         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Enter && this->getEdition() >= 0) { // Enter key
    98             this->endEdit(currEditRow(), currEditCol(), true, false);
    99             this->setEdition();                             // Reset edition
   100             return true;                                    // Cancel progress
   101         }
   102         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Return) { // Return key without edition
   103             this->setReadOnly(false);                       // Allow edition
   104             this->editCell(currentRow(), currentColumn());  // Begin edition
   105             this->setEdition(currentColumn());              // Store edition state
   106             return true;                                    // Cancel further progress
   107         }
   108         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Enter) { // Enter key without edition
   109             this->setReadOnly(false);                       // Allow edition
   110             this->editCell(currentRow(), currentColumn());  // Begin edition
   111             this->setEdition(currentColumn());              // Store edition state
   112             return true;                                    // Cancel further progress
   113         }
   114         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Escape)    // Handle escape key
   115             this->setEdition();
   116         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Up && this->getEdition() >= 0) // Handle up key
   117             return true;                                            // Capture
   118         else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Down && this->getEdition() >= 0) // Handle down key
   119             return true;                                            // Capture
   121         // Forward incompletely handled key events
   122         return QTable::eventFilter(pObject, pEvent);
   123     }
   124     else // Default behaviour is to pass the event onwards
   125         return QTable::eventFilter(pObject, pEvent);
   126 }
   128 // Overridden member hack to allow externally connected control
   129 // widgets to influence dirty or clean state of table data
   130 void TiTable::setText(int nRow, int nCol, const QString &nText)
   131 {
   132     if (this->numRows() > 0) {
   133         // If a cell was edited, emit a signal indicating so
   134         // We can't rely on valueChanged for unknown reasons
   135         if (nText != this->text(nRow, nCol) && nCol != TITRAQ_IDXLINE)
   136             emit textEdited(nRow, nCol);
   138         QTable::setText(nRow, nCol, nText);
   139     }
   140 }
   142 // Overridden member hack to allow externally connected control
   143 // widgets to influence dirty or clean state of table data
   144 void TiTable::sortColumn(int nCol, bool bAscend, bool bWhole)
   145 {
   146     // Guard against a repeat sort behaviour
   147     if (nCol == this->getSortcol() && bAscend == this->getSortdir())
   148         this->setSortdir(!bAscend);
   149     else
   150         this->setSortdir(bAscend);
   152     this->setSortcol(nCol);
   153     QTable::sortColumn(nCol, this->getSortdir(), true);
   155 //    // Announce sorting policy with multiple selections
   156 //    QTableSelection Testsel = this->selection(this->currentSelection());
   157 //    if (Testsel.topRow() != Testsel.bottomRow())
   158 //        m_pStatbar->message(trUtf8("Multiple selections dropped when sorting"), 4000);
   160     // Move and display the selection highlight
   161     this->removeSelection(this->currentSelection());
   162     this->selectRow(this->currentRow());
   163     this->ensureCellVisible(this->currentRow(), 0);
   165     // Write nonsaving line numbers for all rows
   166     for (int nIter = this->numRows() - 1; nIter >= 0; nIter--)
   167         this->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
   168 }
   170 // Overriden member to render edge rows differently according to a sort key
   171 void TiTable::paintCell(QPainter *pPainter, int nRow, int nCol, const QRect &Recto, bool bSelect, const QColorGroup &Colgroup)
   172 {
   173     QColorGroup Cgroup(Colgroup);
   174     int nRed, nGreen, nBlue;
   176     nRed = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTRED, TITRAQ_DEFLIGHTRED);
   177     nGreen = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTGREEN, TITRAQ_DEFLIGHTGREEN);
   178     nBlue = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTBLUE, TITRAQ_DEFLIGHTBLUE);
   179     QColor Bright = QColor(nRed, nGreen, nBlue);
   180     nRed = m_pTiprefs->getNumber(TITRAQ_PREFDARKRED, TITRAQ_DEFDARKRED);
   181     nGreen = m_pTiprefs->getNumber(TITRAQ_PREFDARKGREEN, TITRAQ_DEFDARKGREEN);
   182     nBlue = m_pTiprefs->getNumber(TITRAQ_PREFDARKBLUE, TITRAQ_DEFDARKBLUE);
   183     QColor Dark = QColor(nRed, nGreen, nBlue);
   185     // Alternate color for nonmatching sort keys
   186     QString Cur = this->text(nRow, this->getSortcol());
   187     QString Las = this->text(nRow - 1, this->getSortcol());
   189     // A nice cascade of conditions providing a linewise base color test and set
   190     // The algorythm:
   191     //   1  Determine if the current row's index key differs from the former one
   192     //   2a If they are the same, then current row should have the same color
   193     //   2b If they are different, then current row should have an alt color
   194     //   3  Store information about which color we chose for the current row
   195     if (!Cur.isNull() && !Las.isNull() && Cur == Las) { // Set the base color conditionally
   196         if (this->text(nRow - 1, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) == QChar(TITRAQ_BRIGHT)) {
   197             Cgroup.setColor(QColorGroup::Base, Bright); // Bright
   198             if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_BRIGHT))
   199                 this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_BRIGHT)));
   200         }
   201         else {
   202             Cgroup.setColor(QColorGroup::Base, Dark);   // Dark
   203             if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_DARK))
   204                 this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_DARK)));
   205         }
   206     }
   207     else {
   208         if (this->text(nRow - 1, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) == QChar(TITRAQ_BRIGHT)) {
   209             Cgroup.setColor(QColorGroup::Base, Dark);   // Dark
   210             if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_DARK))
   211                 this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_DARK)));
   212         }
   213         else {
   214             Cgroup.setColor(QColorGroup::Base, Bright); // Bright
   215             if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_BRIGHT))
   216                 this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_BRIGHT)));
   217         }
   218     }
   220     QTable::paintCell(pPainter, nRow, nCol, Recto, bSelect, Cgroup);
   221 };
   223 // Blah
   224 void TiTable::activateNextCell(void)
   225 {
   226     int nIter = 1; // Logic to skip invisible or read only columns
   227     while (columnWidth((currentColumn() + nIter) % TITRAQ_IDXTAIL) <= 0
   228         || isColumnReadOnly((currentColumn() + nIter) % TITRAQ_IDXTAIL))
   229         nIter++;
   231     // Advance the column or both row and column possibly
   232     int nColadvance = ((currentColumn() + nIter) % TITRAQ_IDXTAIL);
   233     if ((currentColumn() + nIter) >= TITRAQ_IDXTAIL)
   234         this->setCurrentCell(currentRow() + 1, nColadvance);
   235     else
   236         this->setCurrentCell(currentRow(), nColadvance);
   237     this->setReadOnly(false);
   238     this->editCell(currentRow(), currentColumn());
   239     this->setEdition(currentColumn());
   240 }
   242 // Overriden member to properly handle read only attribute after edition
   243 void TiTable::endEdit(int nRow, int nCol, bool bAccept, bool bReplace)
   244 {
   245     QTable::endEdit(nRow, nCol, bAccept, bReplace);
   247     // Table read only attribute must be set to return to the normal
   248     // row highlight and selection behaviour of AS. The reason it was
   249     // reset in inplaceEdit() was to allow editing in the first place.
   250     this->setReadOnly(true);
   251 }

mercurial