bool XAP_App::forgetFrame(XAP_Frame * pFrame)
{
	UT_return_val_if_fail(pFrame,false);

	// If this frame is the currently focussed frame write in NULL
	// until another frame appears

	if(pFrame == m_lastFocussedFrame )
	{
		m_lastFocussedFrame = static_cast<XAP_Frame *>(NULL);
	}

	if (pFrame->getViewNumber() > 0)
	{
		// locate vector of this frame's clones
		UT_GenericVector<XAP_Frame*>* pEntry = m_hashClones.pick(pFrame->getViewKey());
		UT_ASSERT(pEntry);

		if (pEntry)
		{
			UT_GenericVector<XAP_Frame*> * pvClones = pEntry;
			UT_return_val_if_fail(pvClones,false);

			// remove this frame from the vector
			UT_sint32 i = pvClones->findItem(pFrame);
			UT_ASSERT(i >= 0);

			if (i >= 0)
			{
				pvClones->deleteNthItem(i);
			}

			// see how many clones are left
			UT_uint32 count = pvClones->getItemCount();
			UT_ASSERT(count > 0);
			XAP_Frame * f = NULL;

			if (count == 1)
			{
				// remaining clone is now a singleton
				f = pvClones->getNthItem(count-1);
				UT_return_val_if_fail(f,false);

				f->setViewNumber(0);
				f->updateTitle();

				// remove this entry from hashtable
				m_hashClones.remove(f->getViewKey(), 
						    NULL);
				delete pvClones;
			}
			else
			{
				// notify remaining clones of their new view numbers
				for (UT_uint32 j=0; j<count; j++)
				{
					f = static_cast<XAP_Frame *>(pvClones->getNthItem(j));
					UT_continue_if_fail(f);

					f->setViewNumber(j+1);
					f->updateTitle();
				}
			}
		}
	}

	// remove this frame from our window list
	UT_sint32 ndx = m_vecFrames.findItem(pFrame);
	UT_ASSERT_HARMLESS(ndx >= 0);

	if (ndx >= 0)
	{
		m_vecFrames.deleteNthItem(ndx);
		notifyFrameCountChange();
	}

	notifyModelessDlgsCloseFrame(pFrame);

	// TODO do something here...

	return true;
}
bool XAP_App::rememberFrame(XAP_Frame * pFrame, XAP_Frame * pCloneOf)
{
	UT_ASSERT(pFrame);

	// add this frame to our window list
	m_vecFrames.addItem(pFrame);

	if(! m_lastFocussedFrame)
	    rememberFocussedFrame(pFrame);

	// TODO: error-check the following for mem failures
	if (pCloneOf)
	{
		// locate vector of this frame's clones
		UT_GenericVector<XAP_Frame*> * pEntry = m_hashClones.pick(pCloneOf->getViewKey());
		UT_GenericVector<XAP_Frame*> * pvClones = NULL;

		if (pEntry)
		{
			// hash table entry already exists
			pvClones = pEntry;

			if (!pvClones)
			{
				// nothing there, so create a new one
				pvClones = new UT_GenericVector<XAP_Frame*>();
				UT_return_val_if_fail(pvClones,false);

				pvClones->addItem(pCloneOf);

				// reuse this slot
				m_hashClones.set(pCloneOf->getViewKey(), pvClones);
			}
		}
		else
		{
			// create a new one
			pvClones = new UT_GenericVector<XAP_Frame*>();
			UT_return_val_if_fail(pvClones,false);

			pvClones->addItem(pCloneOf);

			// add it to the hash table
			m_hashClones.insert(pCloneOf->getViewKey(), pvClones);
		}

		pvClones->addItem(pFrame);

		// notify all clones of their new view numbers
		for (UT_sint32 j=0; j<pvClones->getItemCount(); j++)
		{
			XAP_Frame * f = pvClones->getNthItem(j);
			UT_continue_if_fail(f);

			f->setViewNumber(j+1);

			if (f != pFrame)
				f->updateTitle();
		}
	}
	
	// TODO do something here...
	notifyFrameCountChange();
	return true;
}