head 1.27; access; symbols AS_AFTER_RESTRUCTURING:1.2; locks; strict; comment @// @; 1.27 date 2004.08.24.21.47.30; author ms; state Exp; branches; next 1.26; 1.26 date 2004.05.27.21.48.41; author ms; state Exp; branches; next 1.25; 1.25 date 2004.05.27.21.42.26; author ms; state Exp; branches; next 1.24; 1.24 date 2003.11.20.11.31.20; author ms; state Exp; branches; next 1.23; 1.23 date 2003.02.21.10.12.02; author ms; state Exp; branches; next 1.22; 1.22 date 2003.02.14.19.27.03; author ms; state Exp; branches; next 1.21; 1.21 date 2003.02.14.17.31.55; author ms; state Exp; branches; next 1.20; 1.20 date 2002.12.20.18.19.12; author ms; state Exp; branches; next 1.19; 1.19 date 2002.12.20.18.02.36; author ms; state Exp; branches; next 1.18; 1.18 date 2002.12.20.17.42.10; author ms; state Exp; branches; next 1.17; 1.17 date 2002.12.18.14.50.58; author ms; state Exp; branches; next 1.16; 1.16 date 2002.12.17.16.55.08; author ms; state Exp; branches; next 1.15; 1.15 date 2002.12.17.16.47.30; author ms; state Exp; branches; next 1.14; 1.14 date 2002.12.16.17.13.17; author ms; state Exp; branches; next 1.13; 1.13 date 2002.12.13.19.36.24; author ms; state Exp; branches; next 1.12; 1.12 date 2002.12.13.18.55.09; author ms; state Exp; branches; next 1.11; 1.11 date 2002.12.13.18.06.10; author ms; state Exp; branches; next 1.10; 1.10 date 2002.12.13.17.44.42; author ms; state Exp; branches; next 1.9; 1.9 date 2002.12.12.16.20.15; author ms; state Exp; branches; next 1.8; 1.8 date 2002.12.10.12.06.56; author ms; state Exp; branches; next 1.7; 1.7 date 2002.12.09.16.44.37; author ms; state Exp; branches; next 1.6; 1.6 date 2002.12.06.16.16.07; author ms; state Exp; branches; next 1.5; 1.5 date 2002.12.03.17.05.11; author ms; state Exp; branches; next 1.4; 1.4 date 2002.12.02.13.25.36; author ms; state Exp; branches; next 1.3; 1.3 date 2002.12.02.10.45.05; author ms; state Exp; branches; next 1.2; 1.2 date 2002.11.28.20.44.36; author ms; state Exp; branches; next 1.1; 1.1 date 2002.11.27.22.44.48; author ms; state Exp; branches; next ; desc @@ 1.27 log @Repair selection bug when using the tab and shift tab keys with in place edition, and implement in place edition logic for use with the return and enter keys. Also override the QTable::endEdit method to properly deactivate in place edition when finished. @ text @// // OSSP asgui - Accounting system graphical user interface // Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/) // Copyright (c) 2002-2004 Ralf S. Engelschall // Copyright (c) 2002-2004 Michael Schloh von Bennewitz // Copyright (c) 2002-2004 Cable & Wireless Telecommunications Services GmbH // // This file is part of OSSP asgui, an accounting system graphical user // interface which can be found at http://www.ossp.org/pkg/tool/asgui/. // // Permission to use, copy, modify, and distribute this software for // any purpose with or without fee is hereby granted, provided that // the above copyright notice and this permission notice appear in all // copies. // // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // // as_table.cpp: ISO C++ implementation // #include #include "as_const.h" #include "as_table.h" // Implements an event filter for catching header double click events bool TiTable::eventFilter(QObject *pObject, QEvent *pEvent) { if (pObject == horizontalHeader() && pEvent->type() == QEvent::MouseButtonDblClick) return true; if (pEvent->type() == QEvent::MouseButtonPress && // Ignore mid, right clicks ((QMouseEvent *)pEvent)->button() == QMouseEvent::RightButton || ((QMouseEvent *)pEvent)->button() == QMouseEvent::MidButton) return true; else if (pEvent->type() == QEvent::KeyPress) { if (((QKeyEvent *)pEvent)->key() == Qt::Key_Tab) { // Handle tab key if (this->getEdition() >= 0) { int nIter = 1; // Logic to skip invisible or read only columns while (columnWidth((currentColumn() + nIter) % TITRAQ_IDXTAIL) <= 0 || isColumnReadOnly((currentColumn() + nIter) % TITRAQ_IDXTAIL)) nIter++; // Advance the column or both row and column possibly int nColadvance = ((currentColumn() + nIter) % TITRAQ_IDXTAIL); if ((currentColumn() + nIter) >= TITRAQ_IDXTAIL) { this->clearSelection(true); this->setCurrentCell(currentRow() + 1, nColadvance); // this->repaint(false); // Really necessary? } else this->setCurrentCell(currentRow(), nColadvance); this->setReadOnly(false); this->editCell(currentRow(), currentColumn()); this->setEdition(currentColumn()); } return true; // Handle the tab key event and cancel its progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Backtab) { // Handle shift tab key if (this->getEdition() >= 0) { int nIter = 1; // Logic to skip invisible or read only columns while (columnWidth((currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL) <= 0 || isColumnReadOnly((currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL)) nIter++; // Advance the column or both row and column possibly int nColadvance = (currentColumn() - nIter + TITRAQ_IDXTAIL) % TITRAQ_IDXTAIL; if ((currentColumn() - nIter) < 0) { this->clearSelection(true); this->setCurrentCell(currentRow() - 1, nColadvance); // this->repaint(false); // Really necessary? } else this->setCurrentCell(currentRow(), nColadvance); this->setReadOnly(false); this->editCell(currentRow(), currentColumn()); this->setEdition(currentColumn()); } return true; // Handle the shift tab key event and cancel its progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Return && this->getEdition() >= 0) { // Return key this->endEdit(currEditRow(), currEditCol(), true, false); this->setEdition(); // Reset edition return true; // Cancel progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Enter && this->getEdition() >= 0) { // Enter key this->endEdit(currEditRow(), currEditCol(), true, false); this->setEdition(); // Reset edition return true; // Cancel progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Return) { // Return key without edition this->setReadOnly(false); // Allow edition this->editCell(currentRow(), currentColumn()); // Begin edition this->setEdition(currentColumn()); // Store edition state return true; // Cancel further progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Enter) { // Enter key without edition this->setReadOnly(false); // Allow edition this->editCell(currentRow(), currentColumn()); // Begin edition this->setEdition(currentColumn()); // Store edition state return true; // Cancel further progress } else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Escape) // Handle escape key this->setEdition(); else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Up && this->getEdition() >= 0) // Handle up key return true; // Capture else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Down && this->getEdition() >= 0) // Handle down key return true; // Capture // Forward incompletely handled key events return QTable::eventFilter(pObject, pEvent); } else // Default behaviour is to pass the event onwards return QTable::eventFilter(pObject, pEvent); } // Overridden member hack to allow externally connected control // widgets to influence dirty or clean state of table data void TiTable::setText(int nRow, int nCol, const QString &nText) { if (this->numRows() > 0) { // If a cell was edited, emit a signal indicating so // We can't rely on valueChanged for unknown reasons if (nText != this->text(nRow, nCol) && nCol != TITRAQ_IDXLINE) emit textEdited(nRow, nCol); QTable::setText(nRow, nCol, nText); } } // Overridden member hack to allow externally connected control // widgets to influence dirty or clean state of table data void TiTable::sortColumn(int nCol, bool bAscend, bool bWhole) { // Guard against a repeat sort behaviour if (nCol == this->getSortcol() && bAscend == this->getSortdir()) this->setSortdir(!bAscend); else this->setSortdir(bAscend); this->setSortcol(nCol); QTable::sortColumn(nCol, this->getSortdir(), true); // // Announce sorting policy with multiple selections // QTableSelection Testsel = this->selection(this->currentSelection()); // if (Testsel.topRow() != Testsel.bottomRow()) // m_pStatbar->message(trUtf8("Multiple selections dropped when sorting"), 4000); // Move and display the selection highlight this->removeSelection(this->currentSelection()); this->selectRow(this->currentRow()); this->ensureCellVisible(this->currentRow(), 0); // Write nonsaving line numbers for all rows for (int nIter = this->numRows() - 1; nIter >= 0; nIter--) this->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0'))); } // Overriden member to render edge rows differently according to a sort key void TiTable::paintCell(QPainter *pPainter, int nRow, int nCol, const QRect &Recto, bool bSelect, const QColorGroup &Colgroup) { QColorGroup Cgroup(Colgroup); int nRed, nGreen, nBlue; nRed = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTRED, TITRAQ_DEFLIGHTRED); nGreen = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTGREEN, TITRAQ_DEFLIGHTGREEN); nBlue = m_pTiprefs->getNumber(TITRAQ_PREFLIGHTBLUE, TITRAQ_DEFLIGHTBLUE); QColor Bright = QColor(nRed, nGreen, nBlue); nRed = m_pTiprefs->getNumber(TITRAQ_PREFDARKRED, TITRAQ_DEFDARKRED); nGreen = m_pTiprefs->getNumber(TITRAQ_PREFDARKGREEN, TITRAQ_DEFDARKGREEN); nBlue = m_pTiprefs->getNumber(TITRAQ_PREFDARKBLUE, TITRAQ_DEFDARKBLUE); QColor Dark = QColor(nRed, nGreen, nBlue); // Alternate color for nonmatching sort keys QString Cur = this->text(nRow, this->getSortcol()); QString Las = this->text(nRow - 1, this->getSortcol()); // A nice cascade of conditions providing a linewise base color test and set // The algorythm: // 1 Determine if the current row's index key differs from the former one // 2a If they are the same, then current row should have the same color // 2b If they are different, then current row should have an alt color // 3 Store information about which color we chose for the current row if (!Cur.isNull() && !Las.isNull() && Cur == Las) { // Set the base color conditionally if (this->text(nRow - 1, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) == QChar(TITRAQ_BRIGHT)) { Cgroup.setColor(QColorGroup::Base, Bright); // Bright if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_BRIGHT)) this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_BRIGHT))); } else { Cgroup.setColor(QColorGroup::Base, Dark); // Dark if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_DARK)) this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_DARK))); } } else { if (this->text(nRow - 1, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) == QChar(TITRAQ_BRIGHT)) { Cgroup.setColor(QColorGroup::Base, Dark); // Dark if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_DARK)) this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_DARK))); } else { Cgroup.setColor(QColorGroup::Base, Bright); // Bright if (this->text(nRow, TITRAQ_IDXSTATUS).at(TITRAQ_IDXSTATCOLOR) != QChar(TITRAQ_BRIGHT)) this->setText(nRow, TITRAQ_IDXSTATUS, this->text(nRow, TITRAQ_IDXSTATUS).replace(TITRAQ_IDXSTATCOLOR, sizeof(char), QChar(TITRAQ_BRIGHT))); } } QTable::paintCell(pPainter, nRow, nCol, Recto, bSelect, Cgroup); }; // Blah void TiTable::activateNextCell(void) { int nIter = 1; // Logic to skip invisible or read only columns while (columnWidth((currentColumn() + nIter) % TITRAQ_IDXTAIL) <= 0 || isColumnReadOnly((currentColumn() + nIter) % TITRAQ_IDXTAIL)) nIter++; // Advance the column or both row and column possibly int nColadvance = ((currentColumn() + nIter) % TITRAQ_IDXTAIL); if ((currentColumn() + nIter) >= TITRAQ_IDXTAIL) this->setCurrentCell(currentRow() + 1, nColadvance); else this->setCurrentCell(currentRow(), nColadvance); this->setReadOnly(false); this->editCell(currentRow(), currentColumn()); this->setEdition(currentColumn()); } // Overriden member to properly handle read only attribute after edition void TiTable::endEdit(int nRow, int nCol, bool bAccept, bool bReplace) { QTable::endEdit(nRow, nCol, bAccept, bReplace); // Table read only attribute must be set to return to the normal // row highlight and selection behaviour of AS. The reason it was // reset in inplaceEdit() was to allow editing in the first place. this->setReadOnly(true); } @ 1.26 log @Modernize copyright text in source and graphic headers. @ text @d57 2 a58 1 if ((currentColumn() + nIter) >= TITRAQ_IDXTAIL) d60 2 a66 1 this->setReadOnly(true); d79 2 a80 1 if ((currentColumn() - nIter) < 0) d82 2 a88 1 this->setReadOnly(true); d92 24 a119 2 else if (((QKeyEvent *)pEvent)->key() == Qt::Key_Escape) // Handle escape key this->setEdition(); d240 10 @ 1.25 log @Correct file names in source headers. @ text @d3 4 a6 4 // Copyright (c) 2002-2003 The OSSP Project (http://www.ossp.org/) // Copyright (c) 2002-2003 Ralf S. Engelschall // Copyright (c) 2002-2003 Michael Schloh von Bennewitz // Copyright (c) 2002-2003 Cable & Wireless Telecommunications Services GmbH @ 1.24 log @Handle the time consuming bureaucracy of changing a company name. @ text @d29 1 a29 1 // titable.cpp: ISO C++ implementation @ 1.23 log @Reluctantly added Preferences class coupling, because we need to read the row shading colour dynamically. @ text @a3 1 // Copyright (c) 2002-2003 Cable & Wireless Deutschland (http://www.cw.com/de/) d6 1 @ 1.22 log @Added logic to include prefs pixmap in both menu and toolbar, removed optional 'this' parameter from all calls to connect(), ripped out more header includes from monolithic interface header, made call of prefs panel an instance of class QAction, changed .bak file message text in class Prefpanel, and renamed default RPC hosts to show what a proper format is. @ text @d148 10 d171 1 a171 1 Cgroup.setColor(QColorGroup::Base, QColor(248, 248, 240)); // Bright d176 1 a176 1 Cgroup.setColor(QColorGroup::Base, QColor(224, 224, 216)); // Dark d183 1 a183 1 Cgroup.setColor(QColorGroup::Base, QColor(224, 224, 216)); // Dark d188 1 a188 1 Cgroup.setColor(QColorGroup::Base, QColor(248, 248, 240)); // Bright @ 1.21 log @Moved preference data application from panel items to own method, added applyPrefs logic, and a new proxy method to handle applied signals, and reorganized file incusion in throughout to loosen source file coupling. @ text @a33 1 #include "as_gui.h" @ 1.20 log @Tried to be more descriptive of sort policy on multiple selects, but functionality is out of member scope. @ text @d35 2 @ 1.19 log @Fix selection and highlighting problem on row sort. @ text @d128 5 @ 1.18 log @Fixed sorting and added sort direction handling. @ text @d128 5 @ 1.17 log @Fixed row shade logic and moved dirty flag to TiTable class. @ text @d119 6 d126 1 a126 1 QTable::sortColumn(nCol, bAscend, true); @ 1.16 log @Correct cell edition and focus handling on return key in edit mode. @ text @d109 1 a109 1 emit textEdited(); d136 30 a165 5 // Set the base color conditionally if (!Cur.isNull() && !Las.isNull() && Cur == Las) Cgroup.setColor(QColorGroup::Base, QColor(248, 248, 240)); else Cgroup.setColor(QColorGroup::Base, QColor(232, 232, 224)); @ 1.15 log @Implement rudimentary row shading on sort key, and add GUID and APPID. @ text @d127 1 d144 20 @ 1.14 log @Preserve user preferred sort order and don't set dirty flag on renumber ops. @ text @d126 17 @ 1.13 log @Kill up and down arrow key events in editing mode until we have a consistent solution to value increments. @ text @d108 1 a108 1 if (nText != this->text(nRow, nCol)) d113 12 @ 1.12 log @Added initialization data for new field members, and fixed in place advance logic even more. @ text @d87 4 d97 1 a97 1 else // Default behaviour is to pass the event onwards @ 1.11 log @Fix tab and shift tab edit in place advance logic. @ text @d49 6 a54 2 int nIter = 0; // To skip invisible columns while (columnWidth((currentColumn() + ++nIter) % TITRAQ_IDXTAIL) <= 0); // Skip invisibles d56 1 a56 1 if (nColadvance == 0) // Advance the column and possibly the row too d65 1 a65 1 return true; // Handled the tab key event and cancel its progress d69 8 a76 4 int nIter = 0; // To skip invisible columns while (columnWidth((currentColumn() - ++nIter) % TITRAQ_IDXTAIL) <= 0); // Skip invisibles int nColadvance = ((currentColumn() - nIter) % TITRAQ_IDXTAIL); if (nColadvance == 0) // Advance the column and possibly the row too d85 1 a85 1 return true; // Handled the tab key event and cancel its progress @ 1.10 log @Fix display of initialized cells, initialize new cells, and add a shift tab event handler. @ text @d49 3 a51 1 int nColadvance = ((currentColumn() + 1) % TITRAQ_IDXTAIL); d65 3 a67 1 int nColadvance = ((currentColumn() - 1) % TITRAQ_IDXTAIL); @ 1.9 log @Fix closure on clean state bug in a better way. @ text @d47 1 a47 1 if (((QKeyEvent *)pEvent)->key() == Qt::Key_Tab) { // Handle tab key d52 14 @ 1.8 log @In order to prepare for missing data format implementations, replace last globals with constants, remove unused constants, and remove incomplete task truncating until a better solution is found. @ text @d70 14 @ 1.7 log @Disable help menu until implemented, simplify click condition, and adjust autoconf requirements. @ text @d49 1 a49 1 int nColadvance = ((currentColumn() + 1) % TITRAQ_IDXEND); @ 1.6 log @Make table clicking work like a macintosh. @ text @d42 3 a44 3 if (pEvent->type() == QEvent::MouseButtonPress && (((QMouseEvent *)pEvent)->button() == QMouseEvent::RightButton) || (((QMouseEvent *)pEvent)->button() == QMouseEvent::MidButton)) @ 1.5 log @Added TiTable object to MOC Mapping, added normal view menu again, added ugly edition state member flag, fixed double click table header resize bug, added auto advance in place edit feature. @ text @d42 4 @ 1.4 log @Logic changes to correct the buildconf after CVS restructure. @ text @d40 25 a64 4 if (pObject == horizontalHeader()) return false; else return QTable::eventFilter(pObject, pEvent); // Pass the event onwards @ 1.3 log @Remove unused class definition. @ text @d34 1 a34 1 #include "titraq.h" @ 1.2 log @Massive build configuration preparation, added boilerplate header text, and cleaned up whitespace. @ text @a31 1 #include @ 1.1 log @Added eventhandler to catch illegal double clicks, minimized layout of edition controls, changes to slot arrangement. @ text @d1 31 @