// $Id: ClientDlg_EntityItemModel.cpp $ // // QAbstractItemModel implementation for a Qt4 QTreeView used in the // ... ... // // class ClientDlg::EntityItemModel : public QAbstractItemModel (Qt4) // class ClientDlg::EntityItemData // // Row items correspond to ... // //--- #ifndef ClientDlgINCLUDED #include "ClientDlg.hpp" #endif // *************************************************** // *** ClientDlg::EntityItemModel Implementation *** // *************************************************** ClientDlg::EntityItemModel::EntityItemModel (QObject* parentObj) : QAbstractItemModel (parentObj), _itemDataList() { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- ClientDlg::EntityItemModel::~EntityItemModel() { clear(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- ClientDlg::EntityItemModel::EntityItemData* ClientDlg::EntityItemModel::getEntityItemData (int inx) const { const int itemListSize = _itemDataList.size(); if ((inx >= 0) && (inx < itemListSize)) { EntityItemData* itemDat = _itemDataList [inx]; return (itemDat); } return (NULL); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int ClientDlg::EntityItemModel::findEntityItemDataIndex ( const EntityItemData* itemDat) const { if (itemDat != NULL) { const int itemListSize = _itemDataList.size(); for (int inx = 0; inx < itemListSize; ++inx) { const EntityItemData* listItemDat = _itemDataList [inx]; if (listItemDat) { if (*itemDat == *listItemDat) { return (inx); //--------->> } } } } return (-1); // EntityItemData not found in _itemDataList } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // EXAMPLE ... void ClientDlg::EntityItemModel::addItem (const SlotColRef& slotColRef) { static const char* mname ("ClientDlg::EntityItemModel::addItem"); // std::cout << mname << ": " // << qPrintable (slotColRef.getQuotedCompleteName()) // << std::endl; int newItemCnt (0); // Insert normal SlotColRef item if it doesn't already exist in list. const int existingInx1 = findSlotColItemIndex (slotColRef, false); if (existingInx1 < 0) { EntityItemData* newItemDat1 = new EntityItemData (this, slotColRef, false); // not isColumnMap _itemDataList.append (newItemDat1); ++newItemCnt; } // If slot has a column map, create a list item to represent the column // map configuration. const TableSlot* tslot = dynamic_cast (slotColRef.slot()); if (tslot && tslot->hasColumnMap()) { // Insert "column map" item if it doesn't already exist in list. const int existingInx2 = findSlotColItemIndex (slotColRef, true); if (existingInx2 < 0) { EntityItemData* newItemDat2 = new EntityItemData (this, slotColRef, true); // isColumnMap _itemDataList.append (newItemDat2); ++newItemCnt; } } if (newItemCnt > 0) { reset(); // QAbstractItemModel } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemModel::markItemForDeletion (int inx) { const int cnt = _itemDataList.size(); if ((inx >= 0) && (inx < cnt)) { EntityItemData* itemDat = _itemDataList [inx]; if (itemDat) { itemDat->markForDeletion (true); } } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemModel::deleteMarkedItems() { // ************************************************************ // *** (1) Seperate out the Items to be Saved and Deleted *** // ************************************************************ QList saveEntityItemDataList; QList delEntityItemDataList; const int cnt = _itemDataList.size(); for (int inx = 0; inx < cnt; ++inx) { EntityItemData* itemDat = _itemDataList [inx]; if (itemDat) { if (itemDat->markedForDeletion()) delEntityItemDataList.append (itemDat); else saveEntityItemDataList.append (itemDat); } } // ********************************************* // *** (2) Keep only the Items to be Saved *** // ********************************************* _itemDataList = saveEntityItemDataList; saveEntityItemDataList.clear(); // ******************************************** // *** (3) Delete the Items to be Deleted *** // ******************************************** const int delCnt = delEntityItemDataList.size(); for (int delInx = 0; delInx < delCnt; ++delInx) { EntityItemData* delItemDat = delEntityItemDataList [delInx]; if (delItemDat) { // Delete the item. This cancels callbacks and resets the model. // Note that the model state (represented by _itemDataList) has // already been set to the ultimate state (with all items to be // deleted already removed). // delete delItemDat; } } delEntityItemDataList.clear(); // Do one final reset. reset(); // QAbstractItemModel } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemModel::clear() { QList saveEntityItemDataList = _itemDataList; _itemDataList.clear(); const int cnt = saveEntityItemDataList.size(); for (int inx = 0; inx < cnt; ++inx) { EntityItemData* itemDat = saveEntityItemDataList [inx]; if (itemDat) { delete itemDat; } } saveEntityItemDataList.clear(); reset(); // QAbstractItemModel } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************** // *** QAbstractItemModel Interface *** // ************************************** // virtual from QAbstractItemModel -- Basic Method QModelIndex ClientDlg::EntityItemModel::index (int row, int col, const QModelIndex& parentInx /*=QModelIndex()*/) const { if (hasIndex (row, col, parentInx)) { return createIndex (row, col, 0); } return QModelIndex(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Display Method int ClientDlg::EntityItemModel::rowCount ( const QModelIndex& parentInx /*=QModelIndex()*/) const { if (parentInx.isValid()) { // For table-based models parent indices are not used. This means // that if a valid parent index is provided, zero should be returned. return (0); //------->> } return (_itemDataList.size()); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Display Method int ClientDlg::EntityItemModel::columnCount ( const QModelIndex& parentInx /*=QModelIndex()*/) const { if (parentInx.isValid()) { // For table-based models parent indices are not used. This means // that if a valid parent index is provided, zero should be returned. return (0); //------->> } return (COLUMN_COUNT); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Display Method QVariant ClientDlg::EntityItemModel::data (const QModelIndex& index, int role /*=Qt::DisplayRole*/) const { static const QVariant NullVar; static const QString SP1 (" "); const int row = index.row(); const int col = index.column(); EntityItemData* itemDat (NULL); const int itemListSize = _itemDataList.size(); if ((row >= 0) && (row < itemListSize)) { itemDat = _itemDataList [row]; } if (role == Qt::TextAlignmentRole) { static const QVariant lftAlign (Qt::AlignLeft | Qt::AlignVCenter); static const QVariant rgtAlign (Qt::AlignRight | Qt::AlignVCenter); // switch (col) // { // return (rgtAlign); // //-------------->> // } return (lftAlign); //-------------->> } if (itemDat == NULL) { return NullVar; //----------->> } if (role == ClientDlg::EntityItemModel::UserSortRole) { return itemDat->sortKey (col); } if (role == Qt::DisplayRole) { QString dispTxt (""); if (itemDat) { dispTxt = itemDat->displayText (col); } else { dispTxt = QString ("%1:%2") .arg (row) .arg (col); } if (!dispTxt.isEmpty()) dispTxt += QChar (' '); return QVariant (dispTxt); } if (role == Qt::DecorationRole) { QPixmap pmap; if (itemDat) { pmap = itemDat->displayPmap (col); } if (pmap.isNull()) { return NullVar; } return QVariant (pmap); } return NullVar; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Display Method QVariant ClientDlg::EntityItemModel::headerData (int section, Qt::Orientation, int role /*=Qt::DisplayRole*/) const { static const QVariant NullVar; if (role == Qt::DisplayRole) { QString hdrStr (""); switch (section) { case COL_OBJECT: hdrStr = "Object"; break; // XXX -- EXAMPLE case COL_SLOT: hdrStr = "Slot"; break; // XXX -- EXAMPLE case COL_SLOTCOL: hdrStr = "Column"; break; // XXX -- EXAMPLE ... ... ... } return QVariant (hdrStr); } return NullVar; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Basic Private Method QModelIndex ClientDlg::EntityItemModel::parent ( const QModelIndex& /*childInx*/) const { return QModelIndex(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QAbstractItemModel -- Basic Private Method bool ClientDlg::EntityItemModel::hasChildren (const QModelIndex& parentInx) const { if (parentInx.model() == this || !parentInx.isValid()) { return ( (rowCount (parentInx) > 0) && (columnCount (parentInx) > 0) ); } return false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemModel::itemDeleted (const EntityItemData* delItemDat) { EntityItemData* mutableItemData = const_cast (delItemDat); const bool itemFound = _itemDataList.removeOne (mutableItemData); if (itemFound) { reset(); // QAbstractItemModel } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ************************************************** // *** ClientDlg::EntityItemData Implementation *** // ************************************************** ClientDlg::EntityItemData::EntityItemData ( ClientDlg* parentModel, ... data ...) // XXX -- Primary Data Values : ... ... ... // XXX -- Primary Data Field ... ... ... // XXX -- Primary Data Field _parentModel (parentModel), _markedForDeletion (false), _entityCallback (NULL) { static const char* mname ("ClientDlg::EntityItemData ctor"); // std::cout << mname << ": " // << qPrintable (_entityColRef.getQuotedCompleteName()) // << std::endl; addEntityCallback(); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- ClientDlg::EntityItemData::~EntityItemData() { deleteEntityCallback(); if (_parentModel) { _parentModel->itemDeleted (this); _parentModel = NULL; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- double ClientDlg::EntityItemData::numericValue ( int col, bool& supported) const { switch (col) { case EntityItemModel::COL_OBJECT: // XXX -- EXAMPLE case EntityItemModel::COL_SLOT: // XXX -- EXAMPLE case EntityItemModel::COL_SLOTCOL: // XXX -- EXAMPLE ... ... ... supported = false; return (INVALIDVALUE); //------------------>> } // The indicated column supports numeric values. supported = true; // return parameter double retVal (INVALIDVALUE); // tentative ... ... ... // XXX ... ... ... // XXX return retVal; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- QString ClientDlg::EntityItemData::displayText (int col) const { static const QString emptyStr (""); QString retText (emptyStr); ... ... ... // XXX ... ... ... // XXX return retText; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- QPixmap ClientDlg::EntityItemData::displayPmap (int col) const { QPixmap retPmap; // isNull() ... ... ... // XXX ... ... ... // XXX return retPmap; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- QVariant ClientDlg::EntityItemData::sortKey (int col) const { bool numericSupported (false); // tentative const double colVal = numericValue (col, numericSupported); if (numericSupported) { return QVariant (colVal); //--------------------->> } const QString dispText = displayText (col); return QVariant (dispText); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemData::updateItemDisplay() const { if (_parentModel) { const int itemRow = _parentModel->findEntityItemDataIndex (this); const int lastCol = COLUMN_COUNT-1; if (itemRow >= 0) { const QModelIndex index1 = _parentModel->index (itemRow, 0); const QModelIndex index2 = _parentModel->index (itemRow, lastCol); _parentModel->emit dataChanged (index1, index2); } } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemData::markForDeletion (bool doMark /*=true*/) { _markedForDeletion = doMark; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // equality operator: consider only Primary Data Fields bool ClientDlg::EntityItemData::operator== (const EntityItemData& rhs) const { // return (Primary Data Fields are Equal); // XXX } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemData::addEntityCallback() { static const char (*mname) ("ClientDlg::EntityItemData::addEntityCallback"); // Register Entity callbacks for both the top-level Entity and, // if applicable the AccSeriesEntity Column's SeriesEntity. Entity* entityInstance = // XXX // ****************************************** // *** Regsiter Callback on the Top Entity *** // ****************************************** if (rwAssert (entityInstance != NULL) && rwAssert (_entityCallback == NULL)) { // std::cout << mname << " [T] " // << entityInstance->getCompleteName() << std::endl; MethodCb* cb = new MethodCb( this, &ClientDlg::EntityItemData::entityCallbackHandler, ANY_CALLBACK_TYPE); entityInstance->addCCallback (ANY_CALLBACK_TYPE, cb); _entityCallback = cb; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void ClientDlg::EntityItemData::deleteEntityCallback() { Entity* entityInstance = _entityColRef.entity(); Entity* compEntity = _entityColRefComposite; if (_entityCallback) { if (entityInstance) { entityInstance->deleteCallback (_entityCallback); } _entityCallback = NULL; } } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int ClientDlg::EntityItemData::entityCallbackHandler ( CallbackType cbType, CallbackData* cbData, void*) { static const char (*mname) ("ClientDlg::EntityItemData::entityCallbackHandler"); bool doDelete (false); // tentative bool doUpdateAll (false); // tentative switch (cbType) { ... ... ... // XXX ... ... ... // XXX } if (doDelete) { // std::cout << mname << " DELETE " // << _entityColRef.entity()->getCompleteName() // << " [" << _entityColRef.col() << "]" << std::endl; deleteEntityCallback(); // SELF DELETION! delete this; } else if (doUpdateAll) { if (_parentModel) { _parentModel->reset(); } } return (true); } // --- (end ClientDlg_EntityItemModel.cpp) ---