// $Id: DiagMsgDataModel.cpp,v 1.2 2012/02/26 19:50:52 philw Exp $ // Diagnostic Message List QAbstractTableModel // // CLASSES: // class DiagMsgDataModel : public QAbstractTableModel // ... devised for use with QTreeViews (not QTableViews). // // class DiagMsgDataModel::Rec // message line record // class DiagMsgDataModel::Block // block of message line records //-- #include #include static const QBrush BrushOptInfo (QColor (0x00, 0x00, 0x00)); static const QBrush BrushReqInfo (QColor (0x15, 0x82, 0x16)); static const QBrush BrushUser (QColor (0x00, 0x0E, 0xD8)); static const QBrush BrushWarn (QColor (0x73, 0x4E, 0x00)); static const QBrush BrushErr (QColor (0xB9, 0x00, 0x00)); static const QBrush BrushIntern (QColor (0xA9, 0x0C, 0x88)); #ifndef DiagMsgDataModelINCLUDED #include "DiagMsgDataModel.hpp" #endif #ifndef rwErrorINCLUDED #include "rwError.hpp" //--- for rwAssert #endif #include #include #include #include // for std::max //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ****************************************************** // *** class DiagMsgDataModel : QAbstractTableModel *** // ****************************************************** DiagMsgDataModel::DiagMsgDataModel (QObject* parentObj) : QAbstractTableModel (parentObj), _messageBlockList(), _ctxMaxCharCnt (0), // [chars] _msgMaxCharCnt (0), // [chars] _ctxColDataWidth (0), // [pixels] _msgColDataWidth (0) // [pixels] { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DiagMsgDataModel::~DiagMsgDataModel() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractTableModel int DiagMsgDataModel::rowCount ( const QModelIndex& parentInx /*=QModelIndex()*/) const { if (parentInx == QModelIndex()) { const int cnt = itemCount(); return (cnt); } return (0); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractTableModel int DiagMsgDataModel::columnCount ( const QModelIndex& parentInx /*=QModelIndex()*/) const { if (parentInx == QModelIndex()) { return (COL_COUNT); } return (0); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractTableModel QVariant DiagMsgDataModel::data (const QModelIndex& minx, int role /*=Qt::DisplayRole*/) const { if (role == Qt::DisplayRole) { const int row = minx.row(); const int col = minx.column(); QString str (""); switch (col) { case COL_LNUM: str = QString ("%1: ") .arg (row+1); break; case COL_CTX: str = ctxStr (row); break; case COL_MSG: str = msgStr (row); break; default: str = QString ("[%1,%2]") .arg (row) .arg (col); break; } return QVariant (str); //------------------>> } else if (role == Qt::ToolTipRole) { // Note: special processing in the custom QTreeView subclass // is required to prevent this tooltip from being shown if it // isn't necessary -- i.e. if the column is sufficiently wide // to show the cell text. See DiagOutputListView::viewportEvent(), // a reimplementation of the QAbstractItemView virtual method. const int row = minx.row(); const int col = minx.column(); switch (col) { case COL_CTX: return QVariant (ctxStr (row)); case COL_MSG: return QVariant (msgStr (row)); } } else if (role == Qt::ForegroundRole) { const cwDiagLevel lev = level (minx.row()); switch (lev) { case cwDiagOptInfo: return QVariant (BrushOptInfo); case cwDiagReqInfo: return QVariant (BrushReqInfo); case cwDiagUser: return QVariant (BrushUser); case cwDiagWarning: return QVariant (BrushWarn); case cwDiagError: return QVariant (BrushErr); case cwDiagInternError: return QVariant (BrushIntern); } return QVariant (QBrush (Qt::black)); //--------------------------------->> } else if (role == Qt::TextAlignmentRole) { if (minx.column() == COL_LNUM) { return QVariant (Qt::AlignRight); //----------------------------->> } } return QVariant(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractTableModel QVariant DiagMsgDataModel::headerData (int section, Qt::Orientation orient, int role /*=Qt::DisplayRole*/) const { if (orient != Qt::Horizontal) { // return default value return QAbstractTableModel::headerData (section, orient, role); } // ******************************** // *** Horizontal Header Data *** // ******************************** if (role == Qt::DisplayRole) { QString colStr (""); switch (section) // column { case COL_LNUM: colStr = ""; break; case COL_CTX: colStr = "Context"; break; case COL_MSG: colStr = "Diagnostics Message"; break; default: colStr = QString ("Col %1") .arg (section); break; } return QVariant (colStr); //--------------------->> } // return default value return QAbstractTableModel::headerData (section, orient, role); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void DiagMsgDataModel::clearItems() { //---------------- beginResetModel(); //---------------- _messageBlockList.clear(); _ctxMaxCharCnt = 0; // [chars] _msgMaxCharCnt = 0; // [chars] _ctxColDataWidth = 0; // [pixels] _msgColDataWidth = 0; // [pixels] //---------------- endResetModel(); //---------------- } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int DiagMsgDataModel::itemCount() const { const int blockCnt = _messageBlockList.count(); const int itemCnt = (blockCnt == 0) ? 0 : ( ((blockCnt-1) * Block::CAPACITY) + _messageBlockList [blockCnt-1].recCount() ); return (itemCnt); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void DiagMsgDataModel::appendItem ( cwDiagLevel level, const QString& ctx, const QString& msg, const QWidget* refWid) { const int initBlockCnt = _messageBlockList.count(); const int initItemCnt = (initBlockCnt == 0) ? 0 : ( ((initBlockCnt-1) * Block::CAPACITY) + _messageBlockList [initBlockCnt-1].recCount() ); //-------------------------------------------------------- beginInsertRows (QModelIndex(), initItemCnt, initItemCnt); //-------------------------------------------------------- // ********************* // *** Append Item *** // ********************* const bool addBlock = (initBlockCnt == 0) || _messageBlockList [initBlockCnt-1] .isFull(); if (addBlock) { _messageBlockList.append (Block()); } const int targetBlockIndex = _messageBlockList.count() - 1; _messageBlockList [targetBlockIndex] .appendItem (level, ctx, msg); // **************************** // *** Measure Text Width *** // **************************** // Perform actual pixel measurements only if the character counts // are above prior encountered character counts. const bool longerCtx = (ctx.length() > _ctxMaxCharCnt); const bool longerMsg = (msg.length() > _msgMaxCharCnt); if ((longerCtx || longerMsg) && rwAssert (refWid != NULL)) { const QFontMetrics fm = refWid->fontMetrics(); if (longerCtx) { const int ctxWidth = fm.width (ctx); _ctxColDataWidth = std::max (_ctxColDataWidth, ctxWidth); _ctxMaxCharCnt = ctx.length(); } if (longerMsg) { const int msgWidth = fm.width (msg); _msgColDataWidth = std::max (_msgColDataWidth, msgWidth); _msgMaxCharCnt = msg.length(); } } //-------------------------------------------------------- endInsertRows(); //-------------------------------------------------------- } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const DiagMsgDataModel::Rec& DiagMsgDataModel::record (int lineInx) const { if (lineInx >= 0) { const int blockCnt = _messageBlockList.count(); const int blockInx = lineInx / Block::CAPACITY; if (blockInx < blockCnt) { const int recInx = lineInx % Block::CAPACITY; return (_messageBlockList [blockInx] .record (recInx)); //--------------------------------------------------->> } } static const Rec NullRec; return NullRec; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const QString& DiagMsgDataModel::ctxStr (int lineInx) const { if (lineInx >= 0) { const int blockCnt = _messageBlockList.count(); const int blockInx = lineInx / Block::CAPACITY; if (blockInx < blockCnt) { const int recInx = lineInx % Block::CAPACITY; return (_messageBlockList [blockInx] .ctxStr (recInx)); //--------------------------------------------------->> } } static const QString UndStr (""); return UndStr; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const QString& DiagMsgDataModel::msgStr (int lineInx) const { if (lineInx >= 0) { const int blockCnt = _messageBlockList.count(); const int blockInx = lineInx / Block::CAPACITY; if (blockInx < blockCnt) { const int recInx = lineInx % Block::CAPACITY; return (_messageBlockList [blockInx] .msgStr (recInx)); //--------------------------------------------------->> } } static const QString UndStr (""); return UndStr; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- cwDiagLevel DiagMsgDataModel::level (int lineInx) const { if (lineInx >= 0) { const int blockCnt = _messageBlockList.count(); const int blockInx = lineInx / Block::CAPACITY; if (blockInx < blockCnt) { const int recInx = lineInx % Block::CAPACITY; return (_messageBlockList [blockInx] .level (recInx)); //--------------------------------------------------->> } } return cwDiagNone; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- QString DiagMsgDataModel::displayText (int lineInx, int col) const { const int rowCnt = rowCount(); const int colCnt = columnCount(); QString dispStr (""); if ( (lineInx >= 0) && (lineInx < rowCnt) && (col >= 0) && (col < colCnt) ) { const QModelIndex minx = index (lineInx, col); dispStr = data (minx, Qt::DisplayRole) .toString(); } return dispStr; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- QString DiagMsgDataModel::headerText (int col) const { const int colCnt = columnCount(); QString hdrText (""); if ( (col >= 0) && (col < colCnt) ) { hdrText = headerData (col, Qt::Horizontal, Qt::DisplayRole) .toString(); } return hdrText; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************************************* // *** class DiagMsgDataModel : Rec (message line record) *** // ************************************************************* //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************************************************* // *** class DiagMsgDataModel : Block (block of message line records) *** // ************************************************************************* okstat DiagMsgDataModel::Block::appendItem ( cwDiagLevel level, const QString& ctxStr, const QString& msgStr) { if (isFull()) { return okstat ("Diag Msg Block already full"); //------------------------------------------>> } _recArray [_count++] = Rec (ctxStr, msgStr, level); return okstat (true); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const DiagMsgDataModel::Rec& DiagMsgDataModel::Block::record (int recIndex) const { if ((recIndex >= 0) && (recIndex < _count)) { return _recArray [recIndex]; } static const Rec NullRec; return NullRec; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const QString& DiagMsgDataModel::Block::ctxStr (int recIndex) const { if ((recIndex >= 0) && (recIndex < _count)) { return _recArray [recIndex] .ctxStr(); } static const QString UndStr (""); return UndStr; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- const QString& DiagMsgDataModel::Block::msgStr (int recIndex) const { if ((recIndex >= 0) && (recIndex < _count)) { return _recArray [recIndex] .msgStr(); } static const QString UndStr (""); return UndStr; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- cwDiagLevel DiagMsgDataModel::Block::level (int recIndex) const { if ((recIndex >= 0) && (recIndex < _count)) { return _recArray [recIndex] .level(); } return cwDiagNone; } //--- (end DiagMsgDataModel.cpp) ---