Exemplo n.º 1
0
/*!
 * This method returns the length of the footnote. This is such that 
 * getDocPosition() + getLength() is one value beyond the the EndFootnote
 * strux
 */
UT_uint32 fl_EmbedLayout::getLength(void)
{
	UT_return_val_if_fail( m_pLayout, 0 );
	PT_DocPosition startPos = getDocPosition();
	pf_Frag_Strux* sdhEnd = NULL;
	pf_Frag_Strux* sdhStart = getStruxDocHandle();
	UT_DebugOnly<bool> bres;
	if(getContainerType() == FL_CONTAINER_FOOTNOTE)
	{
		bres = m_pLayout->getDocument()->getNextStruxOfType(sdhStart,PTX_EndFootnote,&sdhEnd);
		UT_ASSERT(bres);
	}
	else if(getContainerType() == FL_CONTAINER_ENDNOTE)
	{
		bres = m_pLayout->getDocument()->getNextStruxOfType(sdhStart,PTX_EndEndnote,&sdhEnd);
		UT_ASSERT(bres);
	}
	else if(getContainerType() == FL_CONTAINER_ANNOTATION)
	{
		bres = m_pLayout->getDocument()->getNextStruxOfType(sdhStart,PTX_EndAnnotation,&sdhEnd);
		UT_ASSERT(bres);
	}
	else
	{
		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
		return 0;
	}
	UT_ASSERT(bres && sdhEnd);
	PT_DocPosition endPos = m_pLayout->getDocument()->getStruxPosition(sdhEnd);
	UT_uint32 length = static_cast<UT_uint32>(endPos - startPos + 1); 
	return length;
}
void fl_ContainerLayout::add(fl_ContainerLayout* pL)
{
	if (m_pLastL)
	{
		UT_ASSERT(m_pLastL->getNext() == NULL);

		pL->setNext(NULL);
		pL->setPrev(m_pLastL);
		m_pLastL->setNext(pL);
		m_pLastL = pL;
	}
	else
	{
		UT_ASSERT(!m_pFirstL);
		UT_DEBUGMSG(("add: doing First = Last = NULL \n"));
		pL->setNext(NULL);
		pL->setPrev(NULL);
		m_pFirstL = pL;
		m_pLastL = m_pFirstL;
	}
	pL->setContainingLayout(this);
	if(pL->getContainerType() == FL_CONTAINER_BLOCK)
	{
		UT_ASSERT(getContainerType() != FL_CONTAINER_BLOCK);
		static_cast<fl_BlockLayout *>(pL)->setSectionLayout(static_cast<fl_SectionLayout *>(this));
	}
}
const char * fl_ContainerLayout::getContainerString(void)
{
	switch(getContainerType())
	{
	case FL_CONTAINER_BLOCK:
		return "FL_CONTAINER_BLOCK";
	case  FL_CONTAINER_DOCSECTION:
		return "FL_CONTAINER_DOCSECTION";
	case FL_CONTAINER_HDRFTR:
		return "FL_CONTAINER_HDRFTR";
	case FL_CONTAINER_SHADOW:
		return "FL_CONTAINER_SHADOW";
	case FL_CONTAINER_FOOTNOTE:
		return "FL_CONTAINER_FOOTNOTE";
	case FL_CONTAINER_ENDNOTE:
		return "FL_CONTAINER_ENDNOTE";
	case FL_CONTAINER_MARGINNOTE:
		return "FL_CONTAINER_MARGINNOTE";
	case FL_CONTAINER_TABLE:
		return "FL_CONTAINER_TABLE";
	case FL_CONTAINER_CELL:
		return "FL_CONTAINER_CELL";
	case FL_CONTAINER_FRAME:
		return "FL_CONTAINER_FRAME";
	case FL_CONTAINER_TOC:
		return "FL_CONTAINER_TOC";
	case FL_CONTAINER_ANNOTATION:
		return "FL_CONTAINER_ANNOTATION";
	case FL_CONTAINER_RDFANCHOR:
		return "FL_CONTAINER_RDFANCHOR";
	default:
		return "NOT_IMPLEMENTED";
	}
	return "NOT IMPLEMENTED";
}
fl_HdrFtrSectionLayout*	fl_ContainerLayout::getHdrFtrSectionLayout(void) const
{
	if(getContainerType() != FL_CONTAINER_SHADOW)
	{
		return NULL;
	}
	const fl_HdrFtrShadow * pHFS = static_cast<const fl_HdrFtrShadow * >(this);
	return pHFS->getHdrFtrSectionLayout();
}
void fl_ContainerLayout::setFirstContainer(fp_Container * pCon)
{
	if(pCon && getContainerType() == FL_CONTAINER_BLOCK)
	{
		UT_ASSERT(pCon->getContainerType() == FP_CONTAINER_LINE);
	}
	xxx_UT_DEBUGMSG(("Set FirstContainer of %x to %x \n",this,pCon));
	m_pFirstContainer = pCon;
}
fp_Run * fl_ContainerLayout::getFirstRun(void) const
{
	if(getContainerType() == FL_CONTAINER_BLOCK)
	{
		const fl_BlockLayout * pBL = static_cast<const fl_BlockLayout *>(this);
		return pBL->getFirstRun();
	}
	else if(getFirstLayout() == NULL)
	{
		return NULL;
	}
	return getFirstLayout()->getFirstRun();
}
/*!
 * This method appends all the text in the current layout to the supplied 
 * GrowBuf.
 */
void fl_ContainerLayout::appendTextToBuf(UT_GrowBuf & buf) const
{
	if(getContainerType() == FL_CONTAINER_BLOCK)
	{
		const fl_BlockLayout * pBL = static_cast<const fl_BlockLayout *>(this);
		pBL->appendTextToBuf(buf);
		return;
	}
	const fl_ContainerLayout * pCL = getFirstLayout();
	while(pCL)
	{
		pCL->appendTextToBuf(buf);
		pCL = pCL->getNext();
	}
}
/*!
 Get Container's position in document
 \param bActualContainerPos When true return block's position. When false
						return position of first run in block
 \return Position of Container (or first run in block)
 \fixme Split in two functions if called most often with FALSE
*/
UT_uint32 fl_ContainerLayout::getPosition(bool bActualBlockPos) const
{
	const fl_ContainerLayout * pL = this;
	if(!bActualBlockPos && (getContainerType() != FL_CONTAINER_TOC))
	{
		pL = static_cast<fl_ContainerLayout *>(getNextBlockInDocument());
		if(pL == NULL)
		{
		  PT_DocPosition pos = getDocLayout()->getDocument()->getStruxPosition(getStruxDocHandle());
		  return pos;
		}
		if(pL->getContainerType() == FL_CONTAINER_BLOCK)
		{
			const fl_BlockLayout * pBL = static_cast<const fl_BlockLayout *>(pL);
			return pBL->getPosition(bActualBlockPos);
		}
		return 0;
	}
	PT_DocPosition pos = getDocLayout()->getDocument()->getStruxPosition(getStruxDocHandle());
	return pos;
}
Exemplo n.º 9
0
const char * fp_ContainerObject::getContainerString(void)
{
	switch (getContainerType())
	{
	case 	FP_CONTAINER_RUN:
		return "FP_CONTAINER_RUN";
	case 	FP_CONTAINER_LINE:
		return "FP_CONTAINER_LINE";
	case	FP_CONTAINER_VERTICAL:
		return "FP_CONTAINER_VERTICAL";
	case 	FP_CONTAINER_ROW:
		return "FP_CONTAINER_ROW";
    case	FP_CONTAINER_TABLE:
		return "FP_CONTAINER_TABLE";
    case 	FP_CONTAINER_CELL:
		return "FP_CONTAINER_CELL";
	case 	FP_CONTAINER_COLUMN:
		return "FP_CONTAINER_COLUMN";
	case FP_CONTAINER_HDRFTR:
		return "FP_CONTAINER_HDRFTR";
	case FP_CONTAINER_ENDNOTE:
		return "FP_CONTAINER_ENDNOTE";
	case FP_CONTAINER_FOOTNOTE:
		return "FP_CONTAINER_FOOTNOTE";
	case FP_CONTAINER_ANNOTATION:
		return "FP_CONTAINER_ANNOTATION";
	case FP_CONTAINER_COLUMN_POSITIONED:
		return "FP_CONTAINER_COLUMN_POSITIONED";
	case FP_CONTAINER_COLUMN_SHADOW:
		return "FP_CONTAINER_COLUMN_SHADOW";
	case FP_CONTAINER_FRAME:
		return "FP_CONTAINER_FRAME";
	case FP_CONTAINER_TOC:
		return "FP_CONTAINER_TOC";
	default:
		return "unknown FP_CONTAINER object";
	}
}
/*!
 * Create a new containerLayout  and insert it into the linked list of
 * layouts held by this class.
 * Returns a pointer to the generated ContainerLayout class.
 */
fl_ContainerLayout * fl_ContainerLayout::insert(pf_Frag_Strux* sdh, fl_ContainerLayout * pPrev, PT_AttrPropIndex indexAP,fl_ContainerType iType)
{
	fl_ContainerLayout* pL=NULL;
	switch (iType)
	{
	case FL_CONTAINER_BLOCK:
		// we have a problem here -- the block needs to be in the list before the consturction is completed
		if(getContainerType() ==  FL_CONTAINER_HDRFTR)
		{
			pL = static_cast<fl_ContainerLayout *>(new fl_BlockLayout(sdh, pPrev, static_cast<fl_SectionLayout *>(this), indexAP,true));
		}
		else if ((pPrev!= NULL) && (pPrev->getContainerType() == FL_CONTAINER_TABLE))
		{
			pL = static_cast<fl_ContainerLayout *>(new fl_BlockLayout(sdh,pPrev, static_cast<fl_SectionLayout *>(pPrev->myContainingLayout()), indexAP));
		}
		else if ((pPrev!= NULL) && (pPrev->getContainerType() == FL_CONTAINER_ANNOTATION))
		{
			pL = static_cast<fl_ContainerLayout *>(new fl_BlockLayout(sdh,pPrev, static_cast<fl_SectionLayout *>(this), indexAP));
			fp_Container * pFirstC = pL->getFirstContainer();
			//
			// This sets indent for a annotation label.
			//
			if(pFirstC)
			  pFirstC->recalcMaxWidth(true);
		}
		else if ((pPrev!= NULL) && (pPrev->getContainerType() == FL_CONTAINER_RDFANCHOR))
		{
			pL = static_cast<fl_ContainerLayout *>(new fl_BlockLayout(sdh,pPrev, static_cast<fl_SectionLayout *>(this), indexAP));
		}
		else
		{
			pL = static_cast<fl_ContainerLayout *>(new fl_BlockLayout(sdh, static_cast<fl_BlockLayout *>(pPrev), static_cast<fl_SectionLayout *>(this), indexAP));
		}
		break;
	case FL_CONTAINER_TABLE:
		pL = static_cast<fl_ContainerLayout *>(new fl_TableLayout(getDocLayout(),sdh, indexAP, this));
		if(pPrev && (pPrev == this))
		{
		  fl_ContainerLayout * pOldFirst = pPrev->getFirstLayout();
		  pPrev->setFirstLayout(pL);
		  pL->setNext(pOldFirst);
		  if(pOldFirst)
		  {
		    pOldFirst->setPrev(pL);
		  }
		  if(pPrev->getLastLayout() == NULL)
		  {
		    pPrev->setLastLayout(pL);
		  }
		}
		else if (pPrev)
		{
			pPrev->_insertIntoList(pL);
		}
//
// Now put the Physical Container into the vertical container that contains it.
//
		{
			fp_TableContainer * pTab = static_cast<fp_TableContainer *>(static_cast<fl_TableLayout *>(pL)->getLastContainer());
			static_cast<fl_TableLayout *>(pL)->insertTableContainer(static_cast<fp_TableContainer *>(pTab));
		}
		if(getContainerType() == FL_CONTAINER_CELL)
		{
			fl_CellLayout * pCell = static_cast<fl_CellLayout *>(this);
			pCell->incNumNestedTables();
			fl_TableLayout * pTab = static_cast<fl_TableLayout *>(pCell->myContainingLayout());
			pTab->incNumNestedTables();
		}
		break;
	case FL_CONTAINER_CELL:
		pL = static_cast<fl_ContainerLayout *>(new fl_CellLayout(getDocLayout(),sdh, indexAP, this));
		if (pPrev)
		{
			pPrev->_insertIntoList(pL);
		}
		else
		{
			_insertFirst(pL);
		}
		break;
	case FL_CONTAINER_FRAME:
	{
		pL = static_cast<fl_ContainerLayout *>
		  (new fl_FrameLayout(getDocLayout(), 
				      sdh, indexAP, this));
		if (pPrev)
		{
			while(pPrev && pPrev->getContainerType() != FL_CONTAINER_BLOCK)
			{
				pPrev = pPrev->getPrev();
			}
//
// Add the frame to the list in te previous block.
//
			if(pPrev)
			{
				pPrev->_insertIntoList(pL);
				pPrev->addFrame(static_cast<fl_FrameLayout *>(pL));
			}
		}
		break;
	}
	case FL_CONTAINER_FOOTNOTE:
	{
		fl_DocSectionLayout * pDSL = getDocSectionLayout();
		pL = static_cast<fl_ContainerLayout *>(new fl_FootnoteLayout(getDocLayout(), 
					  pDSL, 
					  sdh, indexAP, this));
		if (pPrev)
			pPrev->_insertIntoList(pL);
		break;
	}
	case FL_CONTAINER_ANNOTATION:
	{
		fl_DocSectionLayout * pDSL = getDocSectionLayout();
		pL = static_cast<fl_ContainerLayout *>(new fl_AnnotationLayout(getDocLayout(), 
					  pDSL, 
					  sdh, indexAP, this));
		if (pPrev)
			pPrev->_insertIntoList(pL);
		break;
	}
	case FL_CONTAINER_TOC:
	{
		fl_DocSectionLayout * pDSL = getDocSectionLayout();
		pL = static_cast<fl_ContainerLayout *>(new fl_TOCLayout(getDocLayout(), 
					  pDSL, 
					  sdh, indexAP, this));
		if (pPrev)
			pPrev->_insertIntoList(pL);
		static_cast<fl_TOCLayout *>(pL)->getNewContainer(NULL);
		break;
	}
	case FL_CONTAINER_ENDNOTE:
	{
		fl_DocSectionLayout * pDSL = getDocSectionLayout();
		pL = static_cast<fl_ContainerLayout *>(new fl_EndnoteLayout(getDocLayout(), 
					  pDSL, 
					  sdh, indexAP, this));
		if (pPrev)
			pPrev->_insertIntoList(pL);
		break;
	}
	default:
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		break;
	}

	if (pL == NULL)
	{
		return pL;
	}

	if (!m_pLastL)
	{
		UT_ASSERT(!m_pFirstL);
		m_pFirstL = pL;
		m_pLastL = pL;
	}
	else if (m_pLastL == pPrev)
	{
		m_pLastL = pL;
	}
	else if (!pPrev)
	{
		m_pFirstL = pL;
	}
	if(getContainerType() == FL_CONTAINER_CELL)
	{
		static_cast<fl_TableLayout *>(myContainingLayout())->setDirty();
	}
	return pL;
}
fl_BlockLayout* fl_ContainerLayout::getNextBlockInDocument(void) const
{
	fl_ContainerLayout * pNext = getNext();
	if(getContainerType() != FL_CONTAINER_BLOCK)
	{
	  pNext = getFirstLayout();
	}
	fl_ContainerLayout * pOld = NULL;
	UT_uint32 depth = 0;
	next_is_null :
	if(pNext == NULL)
	{
		while((pNext == NULL) && ((pOld != NULL) || (depth == 0)))
	    {
			fl_ContainerLayout * pPrevOld = pOld;
			if(depth > 0)
			{
				pOld = pOld->myContainingLayout();
			}
			else
			{
				pOld = myContainingLayout();
			}
			depth++;
			if(pOld != NULL) // HdrFtr's have myContainingLayout == NULL
			{
				pNext = pOld->getNext();
			}
			if(pPrevOld == pOld)
			{
				pOld = NULL;
			}
		}
	}
	while(pNext)
	{
		pOld = pNext;
		if(pNext->getContainerType() == FL_CONTAINER_BLOCK)
		{
			return static_cast<fl_BlockLayout *>(pNext);
		}
		else if(pNext->getContainerType() == FL_CONTAINER_DOCSECTION)
		{
			pNext = pNext->getFirstLayout();
		}
		else if(pNext->getContainerType() == FL_CONTAINER_TABLE)
		{
			pNext = pNext->getFirstLayout();
		}
		else if(pNext->getContainerType() == FL_CONTAINER_FRAME)
		{
			if(pNext->getFirstLayout() == NULL)
			{
			     pNext = pNext->getNext();
			}
			else
			{
			     pNext = pNext->getFirstLayout();
			}
		}
		else if(pNext->getContainerType() == FL_CONTAINER_CELL)
		{
			pNext = pNext->getFirstLayout();
		}
		else if(pNext->getContainerType() == FL_CONTAINER_TOC)
		{
			pNext = pNext->getNext();
			if(pNext == NULL)
			{
				goto next_is_null;
			}
		}
		else if(pNext->getContainerType() == FL_CONTAINER_FOOTNOTE)
		{
			pNext = pNext->getNext();
			if(pNext == NULL)
			{
				goto next_is_null;
			}
		}
		else if(pNext->getContainerType() == FL_CONTAINER_ANNOTATION)
		{
			pNext = pNext->getNext();
			if(pNext == NULL)
			{
				goto next_is_null;
			}
		}
		else if(pNext->getContainerType() == FL_CONTAINER_RDFANCHOR)
		{
			pNext = pNext->getNext();
			if(pNext == NULL)
			{
				goto next_is_null;
			}
		}
		else if(pNext->getContainerType() == FL_CONTAINER_ENDNOTE)
		{
			pNext = pNext->getNext();
			if(pNext == NULL)
			{
				goto next_is_null;
			}
		}
		else
		{
			pNext = NULL;
			break;
		}
		if(pNext == NULL)
		{
				goto next_is_null;
		}
	}
	return NULL;
}
/*!
 * Return the nested List level of this structure.
 */
UT_sint32 fl_ContainerLayout::getLevelInList(void)
{
      fl_BlockLayout * pBList = NULL;
      if(getContainerType() == FL_CONTAINER_BLOCK)
      {
	   pBList = static_cast<fl_BlockLayout * >(this);
      }
      else
      {
	   pBList = getPrevBlockInDocument();
      }
      UT_sint32 iLevel = 0;
      bool bLoop = true;
      while(pBList && bLoop)
      {
	  while(pBList && !pBList->isListItem())
	  {
	       pBList = pBList->getPrevBlockInDocument();
	  }
	  if(pBList == NULL)
	  {
	       bLoop = false;
	       break;
	  }
	  const PP_AttrProp * pAP = NULL;
	  pBList->getAP(pAP);
	  const gchar * szLid=NULL;
	  UT_uint32 id=0;

	  if (!pAP || !pAP->getAttribute(PT_LISTID_ATTRIBUTE_NAME, szLid))
	       szLid = NULL;
	  if (szLid)
	  {
	       id = atoi(szLid);
		
	  }
	  else
	  {
		id = 0;
	  }
	  if(id == 0)
	  {
	        bLoop = false;
	        break;
	  }
	  PD_Document * pDoc = getDocLayout()->getDocument();
	  fl_AutoNum * pAuto = pDoc->getListByID( id);
	  if(pAuto->getLastItem() == pBList->getStruxDocHandle())
	  {
	        if(pAuto->getLastItem() == getStruxDocHandle())
		{
		     iLevel = pAuto->getLevel();
		     bLoop = false;
		     break;
		}
	        iLevel = pAuto->getLevel() -1;
		if(iLevel < 0)
		{
		      iLevel = 0;
		}
	  }
	  else
	  {
	        if(pBList == this)
	        { 
		      iLevel = pAuto->getLevel();
		}
		else
		{
		      iLevel = pAuto->getLevel() + 1;
		}
	  }
	  bLoop = false;
	  break;
      }
      return iLevel;
}
/*!
 * Remove a containerLayout class from the linked list held here.
 */
void fl_ContainerLayout::remove(fl_ContainerLayout * pL)
{
	UT_ASSERT(pL);
	UT_ASSERT(m_pFirstL);
	fl_ContainerLayout* prev = pL->getPrev(); // can be NULL

	if (prev)
	{
		prev->setNext(pL->getNext());
	}

	if (pL->getNext())
	{
		pL->getNext()->setPrev(prev);
		if(pL->getContainerType() == FL_CONTAINER_BLOCK)
		{
			UT_ASSERT(getContainerType() != FL_CONTAINER_BLOCK);
			static_cast<fl_BlockLayout *>(pL)->transferListFlags();
		}
		if (pL->getNext()->getContainerType() == FL_CONTAINER_BLOCK)
		{
			fl_BlockLayout* pBNext = static_cast<fl_BlockLayout *>(pL->getNext());
			if (pBNext->hasBorders())
			{
				pBNext->setLineHeightBlockWithBorders(1);
			}
		}
		if (prev && prev->getContainerType() == FL_CONTAINER_BLOCK)
		{
			fl_BlockLayout* pBPrev = static_cast<fl_BlockLayout *>(prev);
			if (pBPrev->hasBorders())
			{
				pBPrev->setLineHeightBlockWithBorders(-1);
			}
		}
	}

	if (pL == m_pFirstL)
	{
		m_pFirstL = m_pFirstL->getNext();
		if (!m_pFirstL)
		{
			m_pLastL = NULL;
		}
	}

	if (pL == m_pLastL)
	{
		m_pLastL = m_pLastL->getPrev();
		if (!m_pLastL)
		{
			m_pFirstL = NULL;
		}
	}
	if(getContainerType() != FL_CONTAINER_BLOCK)
	{
	  fl_SectionLayout * pSL = static_cast<fl_SectionLayout *>(this);
	  pSL->removeFromUpdate(pL);
	}
	pL->setNext(NULL);
	pL->setPrev(NULL);
	pL->setContainingLayout(NULL);
	if(pL->getContainerType() == FL_CONTAINER_BLOCK)
	{
		UT_ASSERT(getContainerType() != FL_CONTAINER_BLOCK);
		static_cast<fl_BlockLayout *>(pL)->setSectionLayout(NULL);
	}
}
Exemplo n.º 14
0
int ContainerImplementation::canAddObject(SceneObject* object, int containmentType, String& errorDescription) {
	//	if (locked)
	//	return TransferErrorCode::CONTAINERLOCKED;

	if ((object->isIntangibleObject() && getContainerType() != 3)
			|| (getContainerType() == 3 && !object->isIntangibleObject())) {
		errorDescription = "@container_error_message:container07"; // You cannot put that kind of item in that kind of container.

		return TransferErrorCode::INVALIDTYPE;
	}

	if (containmentType == -1) {
		if ((gameObjectType == SceneObjectType::WEARABLECONTAINER && object->getGameObjectType() == SceneObjectType::WEARABLECONTAINER)) {
			errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container.

			return TransferErrorCode::CANTNESTOBJECT;
		}

		if (object->isContainerObject() && getArrangementDescriptorSize() == 0) {
			errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container.

			return TransferErrorCode::CANTNESTOBJECT;
		}

		// Find out how much room we need
		int objectSize;

		if (object->isContainerObject())
			objectSize = object->getContainerObjectsSize() + 1;
		else
			objectSize = 1;

		// Return if there's not enough room in the container
		if (getContainerVolumeLimit() < getCountableObjectsRecursive() + objectSize) {
			errorDescription = "@container_error_message:container03"; // This container is full.

			return TransferErrorCode::CONTAINERFULL;
		}

		ManagedReference<SceneObject*> wearableParent = getParentRecursively(SceneObjectType::WEARABLECONTAINER);
		ManagedReference<SceneObject*> playerParent = getParentRecursively(SceneObjectType::PLAYERCREATURE);

		// If there's a wearable container parent, return if it doesn't have enough room
		if (wearableParent != NULL) {
			if (wearableParent->getContainerVolumeLimit() < wearableParent->getCountableObjectsRecursive() + objectSize) {
				errorDescription = "@container_error_message:container03"; // This container is full.

				return TransferErrorCode::CONTAINERFULL;
			}

			// It has room. Check if it's not equipped and on a player.
			ManagedReference<WearableContainerObject*> wearable = cast<WearableContainerObject*>(wearableParent.get());
			if (!wearable->isEquipped() && playerParent != NULL) {
				SceneObject* inventory = playerParent->getSlottedObject("inventory");
				SceneObject* bank = playerParent->getSlottedObject("bank");
				SceneObject* parentOfWearableParent = wearable->getParent().get();

				// Return if it's in a player inventory which doesn't have room
				if (parentOfWearableParent == inventory) {
					if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@error_message:inv_full"; // Your inventory is full.

						return TransferErrorCode::CONTAINERFULL;
					}
				// Return if it's in a player bank that doesn't have room
				} else if (parentOfWearableParent == bank) {
					if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@container_error_message:container03"; // This container is full.

						return TransferErrorCode::CONTAINERFULL;
					}
				}
			}
		} else {
			// There's no parent that's a wearable container. Check if this is
			if (gameObjectType == SceneObjectType::WEARABLECONTAINER) {
				WearableContainerObject* pack = cast<WearableContainerObject*>(_this.getReferenceUnsafeStaticCast());

				if (pack != NULL && !pack->isEquipped()) {
				// This is a wearable container, and it's not equipped.
					if (playerParent != NULL ) {
						SceneObject* inventory = playerParent->getSlottedObject("inventory");
						SceneObject* bank = playerParent->getSlottedObject("bank");
						SceneObject* thisParent = getParent().get();

						// Return if the container is in a player inventory without room
						if (thisParent == inventory) {
							if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
								errorDescription = "@error_message:inv_full"; // Your inventory is full.

								return TransferErrorCode::CONTAINERFULL;
							}
						// Return if it's in a player bank that doesn't have room
						} else if (thisParent == bank) {
							if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
								errorDescription = "@container_error_message:container03"; // This container is full.

								return TransferErrorCode::CONTAINERFULL;
							}
						}
					}
				}
			} else {
				// This is a non-wearable container.
				if (playerParent != NULL ) {
					SceneObject* inventory = playerParent->getSlottedObject("inventory");
					SceneObject* bank = playerParent->getSlottedObject("bank");
					SceneObject* thisParent = getParent().get();

					// Return if the container is in a player inventory without room
					if (thisParent == inventory) {
						if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
							errorDescription = "@error_message:inv_full"; // Your inventory is full.

							return TransferErrorCode::CONTAINERFULL;
						}
					// Return if it's in a player bank that doesn't have room
					} else if (thisParent == bank) {
						if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
							errorDescription = "@container_error_message:container03"; // This container is full.
								return TransferErrorCode::CONTAINERFULL;
						}
					}
				}
			}
		}

		// Check if the container is in a building or factory ingredient hopper
		if (playerParent == NULL) {
			ManagedReference<SceneObject*> rootParent = getRootParent();

			if (rootParent != NULL) {
				if (rootParent->isBuildingObject()) {
					BuildingObject* building = rootParent.castTo<BuildingObject*>();

					if (!building->isStaticBuilding() && (building->getCurrentNumberOfPlayerItems() + objectSize > building->getMaximumNumberOfPlayerItems())) {
						errorDescription = "@container_error_message:container13"; // This house has too many items in it

						return TransferErrorCode::TOOMANYITEMSINHOUSE;
					}
				} else if (rootParent->isFactory()) {
					FactoryObject* factory = rootParent.castTo<FactoryObject*>();
					SceneObject* hopper = factory->getSlottedObject("ingredient_hopper");

					if (hopper->getContainerVolumeLimit() < hopper->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@container_error_message:container03"; // This container is full.
							return TransferErrorCode::CONTAINERFULL;
					}
				}
			}
		}

		ManagedReference<SceneObject*> myParent = getParent();
		ManagedReference<SceneObject*> otherParent = object->getParent();

		if (myParent != NULL && otherParent != NULL) {
			if (otherParent->isCreatureObject()) {
				AiAgent* ai = dynamic_cast<AiAgent*>(otherParent.get());

				if (ai != NULL) {
					SceneObject* creatureInventory = ai->getSlottedObject("inventory");

					if (creatureInventory != NULL) {
						uint64 lootOwnerID = creatureInventory->getContainerPermissions()->getOwnerID();

						if (lootOwnerID != myParent->getObjectID()) {
							errorDescription = "@group:no_loot_permission";

							return TransferErrorCode::NOLOOTPERMISSION;
						}
					}

				}
			}
		}

	}

	return TangibleObjectImplementation::canAddObject(object, containmentType, errorDescription);
}