コード例 #1
1
Qt::ItemFlags VirtualSystemModel::flags(const QModelIndex &idx) const
{
    if (!idx.isValid())
        return 0;

    ModelItem *item = static_cast<ModelItem*>(idx.internalPointer());

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | item->itemFlags(idx.column());
}
コード例 #2
0
bool VirtualSystemSortProxyModel::lessThan(const QModelIndex &leftIdx, const QModelIndex &rightIdx) const
{
    if (!leftIdx.isValid() ||
        !rightIdx.isValid())
        return false;

    ModelItem *pLeftItem = static_cast<ModelItem*>(leftIdx.internalPointer());
    ModelItem *pRightItem = static_cast<ModelItem*>(rightIdx.internalPointer());

    /* We sort hardware types only */
    if (!(pLeftItem->type() == HardwareType &&
          pRightItem->type() == HardwareType))
        return false;

    HardwareItem *pHwLeft = static_cast<HardwareItem*>(pLeftItem);
    HardwareItem *pHwRight = static_cast<HardwareItem*>(pRightItem);

    for (unsigned int i = 0; i < RT_ELEMENTS(m_sortList); ++i)
        if (pHwLeft->m_type == m_sortList[i])
        {
            for (unsigned int a = 0; a <= i; ++a)
                if (pHwRight->m_type == m_sortList[a])
                    return true;
            return false;
        }

    return true;
}
コード例 #3
0
ファイル: transfersview.cpp プロジェクト: KDE/kget
void TransfersView::slotItemActivated(const QModelIndex & index)
{
    if (!index.isValid())
        return;

    TransferTreeModel * transferTreeModel = KGet::model();
    ModelItem * item = transferTreeModel->itemFromIndex(index);
    TransfersViewDelegate *view_delegate = static_cast <TransfersViewDelegate *> (itemDelegate());

    if(!item)
        return;

    if(!item->isGroup() && index.column() == 0) {
        if(!view_delegate->isExtended(index)) {
            TransferHandler *handler = item->asTransfer()->transferHandler();
            QWidget *widget = getDetailsWidgetForTransfer(handler);

            m_editingIndexes.append(index);
            view_delegate->extendItem(widget, index);
        }
        else {
            m_editingIndexes.removeAll(index);
            view_delegate->contractItem(index);
        }
        KGet::actionCollection()->action("transfer_show_details")->setChecked(view_delegate->isExtended(index));
    } else if (!item->isGroup() && static_cast<TransferModelItem*>(item)->transferHandler()->status() == Job::Finished) {
        new KRun(static_cast<TransferModelItem*>(item)->transferHandler()->dest(), this);
    }
}
コード例 #4
0
ファイル: ModelTreeElement.cpp プロジェクト: Bazm0/hifi
int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
            ReadBitstreamToTreeParams& args) {

    const unsigned char* dataAt = data;
    int bytesRead = 0;
    uint16_t numberOfModels = 0;
    int expectedBytesPerModel = ModelItem::expectedBytes();

    if (bytesLeftToRead >= (int)sizeof(numberOfModels)) {
        // read our models in....
        numberOfModels = *(uint16_t*)dataAt;
        dataAt += sizeof(numberOfModels);
        bytesLeftToRead -= (int)sizeof(numberOfModels);
        bytesRead += sizeof(numberOfModels);

        if (bytesLeftToRead >= (int)(numberOfModels * expectedBytesPerModel)) {
            for (uint16_t i = 0; i < numberOfModels; i++) {
                ModelItem tempModel;
                int bytesForThisModel = tempModel.readModelDataFromBuffer(dataAt, bytesLeftToRead, args);
                _myTree->storeModel(tempModel);
                dataAt += bytesForThisModel;
                bytesLeftToRead -= bytesForThisModel;
                bytesRead += bytesForThisModel;
            }
        }
    }

    return bytesRead;
}
コード例 #5
0
QVariant VirtualSystemModel::data(const QModelIndex &idx, int role /* = Qt::DisplayRole */) const
{
    if (!idx.isValid())
        return QVariant();

    ModelItem *item = static_cast<ModelItem*>(idx.internalPointer());

    return item->data(idx.column(), role);
}
コード例 #6
0
bool VirtualSystemModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{
    if (!idx.isValid())
        return false;

    ModelItem *item = static_cast<ModelItem*>(idx.internalPointer());

    return item->setData(idx.column(), value, role);
}
コード例 #7
0
ファイル: command.cpp プロジェクト: mcirsta/lignumCAD
void RenameCommand::unexecute ( void )
{
  ModelItem* item = model_->lookup( new_db_url_ );
  if ( item == 0 ) {
    cerr << "Yikes, item did not exist!" << endl;
    return;
  }

  item->setName( old_db_url_.name() );
}
コード例 #8
0
int VirtualSystemModel::rowCount(const QModelIndex &parentIdx /* = QModelIndex() */) const
{
    ModelItem *parentItem;
    if (parentIdx.column() > 0)
        return 0;

    if (!parentIdx.isValid())
        parentItem = m_pRootItem;
    else
        parentItem = static_cast<ModelItem*>(parentIdx.internalPointer());

    return parentItem->childCount();
}
コード例 #9
0
void VirtualSystemDelegate::setModelData(QWidget *pEditor, QAbstractItemModel *pModel, const QModelIndex &idx) const
{
    if (!idx.isValid())
        return QItemDelegate::setModelData(pEditor, pModel, idx);

    QModelIndex index = pModel->index(idx.row(), idx.column());
    if (mProxy)
        index = mProxy->mapToSource(idx);

    ModelItem *item = static_cast<ModelItem*>(index.internalPointer());
    if (!item->setModelData(pEditor, pModel, idx))
        QItemDelegate::setModelData(pEditor, pModel, idx);
}
コード例 #10
0
ファイル: ModelTreeElement.cpp プロジェクト: Bazm0/hifi
bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const {
    if (_box.contains(model.getMinimumPoint()) && _box.contains(model.getMaximumPoint())) {
        int childForMinimumPoint = getMyChildContainingPoint(model.getMinimumPoint());
        int childForMaximumPoint = getMyChildContainingPoint(model.getMaximumPoint());
        
        // If I contain both the minimum and maximum point, but two different children of mine
        // contain those points, then I am the best fit for that model
        if (childForMinimumPoint != childForMaximumPoint) {
            return true;
        }
    }
    return false;
}
コード例 #11
0
QModelIndex VirtualSystemModel::parent(const QModelIndex &idx) const
{
    if (!idx.isValid())
        return QModelIndex();

    ModelItem *childItem = static_cast<ModelItem*>(idx.internalPointer());
    ModelItem *parentItem = childItem->parent();

    if (parentItem == m_pRootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}
コード例 #12
0
void VirtualSystemDelegate::setEditorData(QWidget *pEditor, const QModelIndex &idx) const
{
    if (!idx.isValid())
        return QItemDelegate::setEditorData(pEditor, idx);

    QModelIndex index(idx);
    if (mProxy)
        index = mProxy->mapToSource(idx);

    ModelItem *item = static_cast<ModelItem*>(index.internalPointer());

    if (!item->setEditorData(pEditor, index))
        QItemDelegate::setEditorData(pEditor, index);
}
コード例 #13
0
ファイル: gui.cpp プロジェクト: Jellofishi/Desktop
void AutoMateUi::tweakContextMenu(const QPoint &p) {
	QModelIndex index = tweaks_view->indexAt(p);
	if (!index.isValid())
		return;

	index = tweaksProxyModel->mapToSource(index);
	QMenu *menu = new QMenu(this);
	ModelItem *item = static_cast<ModelItem*>(index.internalPointer());
	selectedTweakFileName = item->data(1).toString();
	if (selectedTweakFileName.size() ==0)
		return;
	QAction *action = menu->addAction(QString("Edit %1").arg(selectedTweakFileName));
	connect(action, SIGNAL(triggered()), SLOT(editSelectedTweak()));

	menu->exec(tweaks_view->viewport()->mapToGlobal(p));
}
コード例 #14
0
void VirtualSystemModel::restoreDefaults(const QModelIndex &parentIdx /* = QModelIndex() */)
{
    ModelItem *parentItem;

    if (!parentIdx.isValid())
        parentItem = m_pRootItem;
    else
        parentItem = static_cast<ModelItem*>(parentIdx.internalPointer());

    for (int i = 0; i < parentItem->childCount(); ++i)
    {
        parentItem->child(i)->restoreDefaults();
        restoreDefaults(index(i, 0, parentIdx));
    }
    emit dataChanged(index(0, 0, parentIdx), index(parentItem->childCount()-1, 0, parentIdx));
}
コード例 #15
0
QWidget *VirtualSystemDelegate::createEditor(QWidget *pParent, const QStyleOptionViewItem &styleOption, const QModelIndex &idx) const
{
    if (!idx.isValid())
        return QItemDelegate::createEditor(pParent, styleOption, idx);

    QModelIndex index(idx);
    if (mProxy)
        index = mProxy->mapToSource(idx);

    ModelItem *item = static_cast<ModelItem*>(index.internalPointer());
    QWidget *editor = item->createEditor(pParent, styleOption, index);

    if (editor == NULL)
        return QItemDelegate::createEditor(pParent, styleOption, index);
    else
        return editor;
}
コード例 #16
0
ファイル: ModelTreeElement.cpp プロジェクト: Bazm0/hifi
void ModelTreeElement::getModelsForUpdate(const AABox& box, QVector<ModelItem*>& foundModels) {
    QList<ModelItem>::iterator modelItr = _modelItems->begin();
    QList<ModelItem>::iterator modelEnd = _modelItems->end();
    AABox modelBox;
    while(modelItr != modelEnd) {
        ModelItem* model = &(*modelItr);
        float radius = model->getRadius();
        // NOTE: we actually do box-box collision queries here, which is sloppy but good enough for now
        // TODO: decide whether to replace modelBox-box query with sphere-box (requires a square root
        // but will be slightly more accurate).
        modelBox.setBox(model->getPosition() - glm::vec3(radius), 2.f * radius);
        if (modelBox.touches(_box)) {
            foundModels.push_back(model);
        }
        ++modelItr;
    }
}
コード例 #17
0
Command *Command::opActivateTexture(const ResourceReference &textureRef) {
	TextureSet *texture = textureRef.resolve<TextureSet>();
	Item *item = texture->findParent<Item>();

	if (!item || (item->getSubType() != Item::kItemGlobalTemplate && item->getSubType() != Item::kItemLevelTemplate && item->getSubType() != Item::kItemModel)) {
		return nextCommand();
	}

	if (item->getSubType() == Item::kItemModel) {
		ModelItem *modelItem = Object::cast<ModelItem>(item);
		modelItem->setTexture(texture->getIndex(), texture->getSubType());
	} else {
		ItemTemplate *templateItem = Object::cast<ItemTemplate>(item);
		templateItem->setTexture(texture->getIndex(), texture->getSubType());
	}

	return nextCommand();
}
コード例 #18
0
Command *Command::opActivateMesh(const ResourceReference &meshRef) {
	BonesMesh *mesh = meshRef.resolve<BonesMesh>();
	Item *item = mesh->findParent<Item>();

	if (!item || (item->getSubType() != Item::kItemGlobalTemplate && item->getSubType() != Item::kItemLevelTemplate && item->getSubType() != Item::kItemModel)) {
		return nextCommand();
	}

	if (item->getSubType() == Item::kItemModel) {
		ModelItem *modelItem = Object::cast<ModelItem>(item);
		modelItem->setBonesMesh(mesh->getIndex());
	} else {
		ItemTemplate *templateItem = Object::cast<ItemTemplate>(item);
		templateItem->setBonesMesh(mesh->getIndex());
	}

	return nextCommand();
}
コード例 #19
0
QModelIndex VirtualSystemModel::index(int row, int column, const QModelIndex &parentIdx /* = QModelIndex() */) const
{
    if (!hasIndex(row, column, parentIdx))
        return QModelIndex();

    ModelItem *parentItem;

    if (!parentIdx.isValid())
        parentItem = m_pRootItem;
    else
        parentItem = static_cast<ModelItem*>(parentIdx.internalPointer());

    ModelItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}
コード例 #20
0
ファイル: ModelTreeElement.cpp プロジェクト: DavidBatty1/hifi
bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const {
    glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f);
    glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f);
    if (_box.contains(clampedMin) && _box.contains(clampedMax)) {
        int childForMinimumPoint = getMyChildContainingPoint(clampedMin);
        int childForMaximumPoint = getMyChildContainingPoint(clampedMax);
        
        // if this is a really small box, then it's close enough!
        if (_box.getScale() <= SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE) {
            return true;
        }
        // If I contain both the minimum and maximum point, but two different children of mine
        // contain those points, then I am the best fit for that model
        if (childForMinimumPoint != childForMaximumPoint) {
            return true;
        }
    }
    return false;
}
コード例 #21
0
void
MainWindow::setupDockWindows()
{
  // Try to read JSBSim legacy files.
  JSBSimReader reader;
  
  reader.addAircraftPath("/home/flightgear/sw/share/FlightGear/Aircraft/FA-18/");
  reader.addEnginePath("/home/flightgear/sw/share/FlightGear/Aircraft/FA-18/Engines/");
  
  reader.loadAircraft("FA-18-cross.xml");
  if (reader.getErrorState()) {
    const ReaderWriter::StringList errors = reader.getErrors();
    ReaderWriter::StringList::const_iterator it;
    for (it = errors.begin(); it != errors.end(); ++it)
      std::cerr << *it << std::endl;
    return;
  }
  
  // Ok, now the Vehicle here contains the imported data
  // When the reflection stuff is ready, we can dump that data to a
  // native format ...
  reader.getVehicle()->getSystem()->init();
  
  ModelItem* model = new ModelItem;
  model->setSystem(reader.getVehicle()->getSystem());

  QDockWidget* dockWidget = new QDockWidget(this);
  QTreeView* treeView = new QTreeView(dockWidget);
  treeView->setModel(model);
  dockWidget->setWidget(treeView);
  addDockWidget(Qt::LeftDockWidgetArea, dockWidget);


  FrameItem* frameModel = new FrameItem;
  frameModel->setRootFrame(reader.getVehicle()->getSystem()->getEnvironment()->getRootFrame());

  dockWidget = new QDockWidget(this);
  treeView = new QTreeView(dockWidget);
  treeView->setModel(frameModel);
  dockWidget->setWidget(treeView);
  addDockWidget(Qt::RightDockWidgetArea, dockWidget);
}
コード例 #22
0
ファイル: transfersview.cpp プロジェクト: KDE/kget
void TransfersView::slotItemCollapsed(const QModelIndex & index)
{
    if (!index.isValid())
        return;

    TransferTreeModel * transferTreeModel = KGet::model();
    ModelItem * item = transferTreeModel->itemFromIndex(index);
    TransfersViewDelegate *view_delegate = static_cast <TransfersViewDelegate *> (itemDelegate());

    if(!item)
        return;
    
    if(item->isGroup()) {
        TransferGroupHandler * groupHandler = item->asGroup()->groupHandler();
        QList<TransferHandler *> transfers = groupHandler->transfers();

        foreach(TransferHandler * transfer, transfers) {
            kDebug(5001) << "Transfer = " << transfer->source().prettyUrl(); 
            view_delegate->contractItem(KGet::model()->itemFromTransferHandler(transfer)->index());
        }
コード例 #23
0
ファイル: anim.cpp プロジェクト: Nitrus/residualvm
void AnimSkeleton::applyToItem(Item *item) {
	Anim::applyToItem(item);

	if (!_loop) {
		_currentTime = 0;
	}

	if (_currentTime > _totalTime) {
		_currentTime = 0;
	}

	ModelItem *modelItem = Object::cast<ModelItem>(item);

	BonesMesh *mesh = modelItem->findBonesMesh();
	TextureSet *texture = modelItem->findTextureSet(TextureSet::kTextureNormal);

	_visual->setModel(mesh->getModel());
	_visual->setTexture(texture->getTexture());
	_visual->setAnim(_seletonAnim);
	_visual->setTime(_currentTime);
}
コード例 #24
0
bool VirtualSystemSortProxyModel::filterAcceptsRow(int srcRow, const QModelIndex & srcParenIdx) const
{
    /* By default enable all, we will explicitly filter out below */
    if (srcParenIdx.isValid())
    {
        QModelIndex i = srcParenIdx.child(srcRow, 0);
        if (i.isValid())
        {
            ModelItem *item = static_cast<ModelItem*>(i.internalPointer());
            /* We filter hardware types only */
            if (item->type() == HardwareType)
            {
                HardwareItem *hwItem = static_cast<HardwareItem*>(item);
                /* The license type shouldn't be displayed */
                if (m_filterList.contains(hwItem->m_type))
                    return false;
            }
        }
    }
    return true;
}
コード例 #25
0
ファイル: ModelServer.cpp プロジェクト: MattiLahtinen/hifi
void ModelServer::modelCreated(const ModelItem& newModel, const SharedNodePointer& senderNode) {
    unsigned char outputBuffer[MAX_PACKET_SIZE];
    unsigned char* copyAt = outputBuffer;

    int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeModelAddResponse);
    int packetLength = numBytesPacketHeader;
    copyAt += numBytesPacketHeader;

    // encode the creatorTokenID
    uint32_t creatorTokenID = newModel.getCreatorTokenID();
    memcpy(copyAt, &creatorTokenID, sizeof(creatorTokenID));
    copyAt += sizeof(creatorTokenID);
    packetLength += sizeof(creatorTokenID);

    // encode the model ID
    uint32_t modelID = newModel.getID();
    memcpy(copyAt, &modelID, sizeof(modelID));
    copyAt += sizeof(modelID);
    packetLength += sizeof(modelID);

    NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, senderNode);
}
コード例 #26
0
ファイル: ModelTreeElement.cpp プロジェクト: DavidBatty1/hifi
int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
            ReadBitstreamToTreeParams& args) {

    // If we're the root, but this bitstream doesn't support root elements with data, then
    // return without reading any bytes
    if (this == _myTree->getRoot() && args.bitstreamVersion < VERSION_ROOT_ELEMENT_HAS_DATA) {
        qDebug() << "ROOT ELEMENT: no root data for "
                    "bitstreamVersion=" << (int)args.bitstreamVersion << " bytesLeftToRead=" << bytesLeftToRead;
        return 0;
    }

    const unsigned char* dataAt = data;
    int bytesRead = 0;
    uint16_t numberOfModels = 0;
    int expectedBytesPerModel = ModelItem::expectedBytes();

    if (bytesLeftToRead >= (int)sizeof(numberOfModels)) {
        // read our models in....
        numberOfModels = *(uint16_t*)dataAt;
        dataAt += sizeof(numberOfModels);
        bytesLeftToRead -= (int)sizeof(numberOfModels);
        bytesRead += sizeof(numberOfModels);
        
        if (bytesLeftToRead >= (int)(numberOfModels * expectedBytesPerModel)) {
            for (uint16_t i = 0; i < numberOfModels; i++) {
                ModelItem tempModel;
                int bytesForThisModel = tempModel.readModelDataFromBuffer(dataAt, bytesLeftToRead, args);
                _myTree->storeModel(tempModel);
                dataAt += bytesForThisModel;
                bytesLeftToRead -= bytesForThisModel;
                bytesRead += bytesForThisModel;
            }
        }
    }

    return bytesRead;
}
コード例 #27
0
ファイル: ModelItem.cpp プロジェクト: Bazm0/hifi
void ModelItemProperties::copyToModelItem(ModelItem& modelItem) const {
    bool somethingChanged = false;
    if (_positionChanged) {
        modelItem.setPosition(_position / (float) TREE_SCALE);
        somethingChanged = true;
    }

    if (_colorChanged) {
        modelItem.setColor(_color);
        somethingChanged = true;
    }

    if (_radiusChanged) {
        modelItem.setRadius(_radius / (float) TREE_SCALE);
        somethingChanged = true;
    }

    if (_shouldDieChanged) {
        modelItem.setShouldDie(_shouldDie);
        somethingChanged = true;
    }

    if (_modelURLChanged) {
        modelItem.setModelURL(_modelURL);
        somethingChanged = true;
    }

    if (_modelRotationChanged) {
        modelItem.setModelRotation(_modelRotation);
        somethingChanged = true;
    }

    if (somethingChanged) {
        bool wantDebug = false;
        if (wantDebug) {
            uint64_t now = usecTimestampNow();
            int elapsed = now - _lastEdited;
            qDebug() << "ModelItemProperties::copyToModelItem() AFTER update... edited AGO=" << elapsed <<
                     "now=" << now << " _lastEdited=" << _lastEdited;
        }
        modelItem.setLastEdited(_lastEdited);
    }
}
コード例 #28
0
ファイル: ModelItem.cpp プロジェクト: Bazm0/hifi
void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) {
    _position = modelItem.getPosition() * (float) TREE_SCALE;
    _color = modelItem.getXColor();
    _radius = modelItem.getRadius() * (float) TREE_SCALE;
    _shouldDie = modelItem.getShouldDie();
    _modelURL = modelItem.getModelURL();
    _modelRotation = modelItem.getModelRotation();

    _id = modelItem.getID();
    _idSet = true;

    _positionChanged = false;
    _colorChanged = false;
    _radiusChanged = false;

    _shouldDieChanged = false;
    _modelURLChanged = false;
    _modelRotationChanged = false;
    _defaultSettings = false;
}
コード例 #29
0
ファイル: ModelTreeElement.cpp プロジェクト: Bazm0/hifi
bool ModelTreeElement::updateModel(const ModelItem& model) {
    // NOTE: this method must first lookup the model by ID, hence it is O(N)
    // and "model is not found" is worst-case (full N) but maybe we don't care?
    // (guaranteed that num models per elemen is small?)
    const bool wantDebug = false;
    uint16_t numberOfModels = _modelItems->size();
    for (uint16_t i = 0; i < numberOfModels; i++) {
        ModelItem& thisModel = (*_modelItems)[i];
        if (thisModel.getID() == model.getID()) {
            int difference = thisModel.getLastUpdated() - model.getLastUpdated();
            bool changedOnServer = thisModel.getLastEdited() < model.getLastEdited();
            bool localOlder = thisModel.getLastUpdated() < model.getLastUpdated();
            if (changedOnServer || localOlder) {
                if (wantDebug) {
                    qDebug("local model [id:%d] %s and %s than server model by %d, model.isNewlyCreated()=%s",
                            model.getID(), (changedOnServer ? "CHANGED" : "same"),
                            (localOlder ? "OLDER" : "NEWER"),
                            difference, debug::valueOf(model.isNewlyCreated()) );
                }
                
                thisModel.copyChangedProperties(model);
                markWithChangedTime();
            } else {
                if (wantDebug) {
                    qDebug(">>> IGNORING SERVER!!! Would've caused jutter! <<<  "
                            "local model [id:%d] %s and %s than server model by %d, model.isNewlyCreated()=%s",
                            model.getID(), (changedOnServer ? "CHANGED" : "same"),
                            (localOlder ? "OLDER" : "NEWER"),
                            difference, debug::valueOf(model.isNewlyCreated()) );
                }
            }
            return true;
        }
    }
    return false;
}
コード例 #30
0
ファイル: ModelItem.cpp プロジェクト: Adrianl3d/hifi
ModelItem ModelItem::fromEditPacket(const unsigned char* data, int length, int& processedBytes, ModelTree* tree, bool& valid) {
    ModelItem newModelItem; // id and _lastUpdated will get set here...
    const unsigned char* dataAt = data;
    processedBytes = 0;

    // the first part of the data is our octcode...
    int octets = numberOfThreeBitSectionsInCode(data);
    int lengthOfOctcode = bytesRequiredForCodeLength(octets);

    // we don't actually do anything with this octcode...
    dataAt += lengthOfOctcode;
    processedBytes += lengthOfOctcode;

    // id
    uint32_t editID;
    memcpy(&editID, dataAt, sizeof(editID));
    dataAt += sizeof(editID);
    processedBytes += sizeof(editID);

    bool isNewModelItem = (editID == NEW_MODEL);

    // special case for handling "new" modelItems
    if (isNewModelItem) {
        // If this is a NEW_MODEL, then we assume that there's an additional uint32_t creatorToken, that
        // we want to send back to the creator as an map to the actual id
        uint32_t creatorTokenID;
        memcpy(&creatorTokenID, dataAt, sizeof(creatorTokenID));
        dataAt += sizeof(creatorTokenID);
        processedBytes += sizeof(creatorTokenID);

        newModelItem.setCreatorTokenID(creatorTokenID);
        newModelItem._newlyCreated = true;
        valid = true;

    } else {
        // look up the existing modelItem
        const ModelItem* existingModelItem = tree->findModelByID(editID, true);

        // copy existing properties before over-writing with new properties
        if (existingModelItem) {
            newModelItem = *existingModelItem;
            valid = true;
        } else {
            // the user attempted to edit a modelItem that doesn't exist
            qDebug() << "user attempted to edit a modelItem that doesn't exist... editID=" << editID;

            // NOTE: even though this is a bad editID, we have to consume the edit details, so that
            // the buffer doesn't get corrupted for further processing...
            valid = false;
        }
        newModelItem._id = editID;
        newModelItem._newlyCreated = false;
    }
    
    // lastEdited
    memcpy(&newModelItem._lastEdited, dataAt, sizeof(newModelItem._lastEdited));
    dataAt += sizeof(newModelItem._lastEdited);
    processedBytes += sizeof(newModelItem._lastEdited);

    // All of the remaining items are optional, and may or may not be included based on their included values in the
    // properties included bits
    uint16_t packetContainsBits = 0;
    if (!isNewModelItem) {
        memcpy(&packetContainsBits, dataAt, sizeof(packetContainsBits));
        dataAt += sizeof(packetContainsBits);
        processedBytes += sizeof(packetContainsBits);
    }


    // radius
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_RADIUS) == MODEL_PACKET_CONTAINS_RADIUS)) {
        memcpy(&newModelItem._radius, dataAt, sizeof(newModelItem._radius));
        dataAt += sizeof(newModelItem._radius);
        processedBytes += sizeof(newModelItem._radius);
    }

    // position
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_POSITION) == MODEL_PACKET_CONTAINS_POSITION)) {
        memcpy(&newModelItem._position, dataAt, sizeof(newModelItem._position));
        dataAt += sizeof(newModelItem._position);
        processedBytes += sizeof(newModelItem._position);
    }

    // color
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_COLOR) == MODEL_PACKET_CONTAINS_COLOR)) {
        memcpy(newModelItem._color, dataAt, sizeof(newModelItem._color));
        dataAt += sizeof(newModelItem._color);
        processedBytes += sizeof(newModelItem._color);
    }

    // shouldDie
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_SHOULDDIE) == MODEL_PACKET_CONTAINS_SHOULDDIE)) {
        memcpy(&newModelItem._shouldDie, dataAt, sizeof(newModelItem._shouldDie));
        dataAt += sizeof(newModelItem._shouldDie);
        processedBytes += sizeof(newModelItem._shouldDie);
    }

    // modelURL
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_MODEL_URL) == MODEL_PACKET_CONTAINS_MODEL_URL)) {
        uint16_t modelURLLength;
        memcpy(&modelURLLength, dataAt, sizeof(modelURLLength));
        dataAt += sizeof(modelURLLength);
        processedBytes += sizeof(modelURLLength);
        QString tempString((const char*)dataAt);
        newModelItem._modelURL = tempString;
        dataAt += modelURLLength;
        processedBytes += modelURLLength;
    }

    // modelRotation
    if (isNewModelItem || ((packetContainsBits & 
                    MODEL_PACKET_CONTAINS_MODEL_ROTATION) == MODEL_PACKET_CONTAINS_MODEL_ROTATION)) {
        int bytes = unpackOrientationQuatFromBytes(dataAt, newModelItem._modelRotation);
        dataAt += bytes;
        processedBytes += bytes;
    }

    // animationURL
    if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_ANIMATION_URL) == MODEL_PACKET_CONTAINS_ANIMATION_URL)) {
        uint16_t animationURLLength;
        memcpy(&animationURLLength, dataAt, sizeof(animationURLLength));
        dataAt += sizeof(animationURLLength);
        processedBytes += sizeof(animationURLLength);
        QString tempString((const char*)dataAt);
        newModelItem._animationURL = tempString;
        dataAt += animationURLLength;
        processedBytes += animationURLLength;
    }

    // animationIsPlaying
    if (isNewModelItem || ((packetContainsBits & 
                    MODEL_PACKET_CONTAINS_ANIMATION_PLAYING) == MODEL_PACKET_CONTAINS_ANIMATION_PLAYING)) {
                    
        memcpy(&newModelItem._animationIsPlaying, dataAt, sizeof(newModelItem._animationIsPlaying));
        dataAt += sizeof(newModelItem._animationIsPlaying);
        processedBytes += sizeof(newModelItem._animationIsPlaying);
    }

    // animationFrameIndex
    if (isNewModelItem || ((packetContainsBits & 
                    MODEL_PACKET_CONTAINS_ANIMATION_FRAME) == MODEL_PACKET_CONTAINS_ANIMATION_FRAME)) {
                    
        memcpy(&newModelItem._animationFrameIndex, dataAt, sizeof(newModelItem._animationFrameIndex));
        dataAt += sizeof(newModelItem._animationFrameIndex);
        processedBytes += sizeof(newModelItem._animationFrameIndex);
    }

    // animationFPS
    if (isNewModelItem || ((packetContainsBits & 
                    MODEL_PACKET_CONTAINS_ANIMATION_FPS) == MODEL_PACKET_CONTAINS_ANIMATION_FPS)) {
                    
        memcpy(&newModelItem._animationFPS, dataAt, sizeof(newModelItem._animationFPS));
        dataAt += sizeof(newModelItem._animationFPS);
        processedBytes += sizeof(newModelItem._animationFPS);
    }

    const bool wantDebugging = false;
    if (wantDebugging) {
        qDebug("ModelItem::fromEditPacket()...");
        qDebug() << "   ModelItem id in packet:" << editID;
        newModelItem.debugDump();
    }

    return newModelItem;
}