Exemplo n.º 1
0
void fp_FrameContainer::setPage(fp_Page * pPage)
{
	if(pPage && (m_pPage != NULL) && m_pPage != pPage)
	{
		clearScreen();
		m_pPage->removeFrameContainer(this);
		getSectionLayout()->markAllRunsDirty();
		
		UT_GenericVector<fl_ContainerLayout *> AllLayouts;
		AllLayouts.clear();
		m_pPage->getAllLayouts(AllLayouts);
		UT_sint32 i = 0;
		for(i=0; i<AllLayouts.getItemCount(); i++)
		{
		      fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
		      pCL->collapse();
		      pCL->format();
	        }
		m_pPage->getOwningSection()->setNeedsSectionBreak(true,m_pPage);
		
	}
	m_pPage = pPage;
	if(pPage)
	{
		getFillType()->setParent(pPage->getFillType());
	}
	else
	{
		getFillType()->setParent(NULL);
	}
}
Exemplo n.º 2
0
void TCPAccountHandler::addBuddy(BuddyPtr pBuddy)
{
	UT_DEBUGMSG(("TCPAccountHandler::addBuddy()\n"));
	UT_return_if_fail(pBuddy);
	
	AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager();
	UT_return_if_fail(pManager);
	
	if (getProperty("allow-all") == "true")
	{
		const UT_GenericVector<AbiCollab *> pSessions = pManager->getSessions();
		for (UT_sint32 i = 0; i < pSessions.size(); i++)
		{
			AbiCollab* pSession = pSessions.getNthItem(i);
			UT_continue_if_fail(pSession);
			
			if (pSession->getAclAccount() != this)
				continue;
			
			pSession->appendAcl(pBuddy->getDescriptor(false).utf8_str());
		}
	}
	
	AccountHandler::addBuddy(pBuddy);
}
void ABI_Collab_Import::_enableUpdates(UT_GenericVector<AV_View *> vecViews, bool bIsGlob)
{
	if (bIsGlob)
	{
		// allow updates again
		m_pDoc->enableListUpdates();
		m_pDoc->updateDirtyLists();
		m_pDoc->setDontImmediatelyLayout(false);
		m_pDoc->endUserAtomicGlob();
	}
	m_pDoc->notifyPieceTableChangeEnd();
	
	bool bDone = false;
	for (UT_sint32 i = 0; i<vecViews.getItemCount(); i++)
	{
		FV_View * pView = static_cast<FV_View *>( vecViews.getNthItem(i));
		if(pView && !bDone && pView->shouldScreenUpdateOnGeneralUpdate())
		{
			m_pDoc->signalListeners(PD_SIGNAL_UPDATE_LAYOUT);
			bDone = true;
		}
		if(pView)
		{
			pView->fixInsertionPointCoords();
			pView->setActivityMask(true);
		}
	}
}
bool AP_CocoaToolbar_StyleCombo::repopulate(void)
{
	// repopulate the vector from the current document
    // If ithere is one present

	AD_Document * pAD_Doc = m_pFrame->getCurrentDoc();
	if(!pAD_Doc)
	{
		return false;
	}

	// clear anything that's already there
	m_vecContents.clear();

	m_pDocument = static_cast<PD_Document *>(pAD_Doc);

	UT_GenericVector<PD_Style*>* pStyles = NULL;
	m_pDocument->enumStyles(pStyles);
	UT_uint32 nStyles = pStyles->getItemCount();

	for (UT_uint32 k = 0; k < nStyles; k++)
	{
		const PD_Style * pStyle;
		pStyle = pStyles->getNthItem(k);
		if(pStyle) {
			m_vecContents.addItem(pStyle->getName());
		}
	}
	DELETEP(pStyles);

	return true;
}
bool XAP_App::updateClones(XAP_Frame * pFrame)
{
	UT_return_val_if_fail(pFrame,false);
	UT_ASSERT(pFrame->getViewNumber() > 0);

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

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

		UT_uint32 count = pvClones->getItemCount();
		UT_ASSERT(count > 0);
		XAP_Frame * f = NULL;

		for (UT_uint32 j=0; j<count; j++)
		{
			f = pvClones->getNthItem(j);
			UT_continue_if_fail(f);

			f->updateTitle();
		}
	}

	return true;
}
Exemplo n.º 6
0
/**
 * Write the <text:list-style> element.
 */
bool ODe_Style_List::write(GsfOutput* pODT,
                           const UT_UTF8String& rSpacesOffset) const {
                            
    UT_uint32 i, count;
    UT_UTF8String subElementSpacesOffset;
    UT_UTF8String output;
    UT_GenericVector<ODe_ListLevelStyle*>* pVector;
    bool ok;
    
    UT_UTF8String_sprintf(output, "%s<text:list-style style:name=\"%s\">\n",
                          rSpacesOffset.utf8_str(), m_name.utf8_str());
    ODe_writeUTF8String(pODT, output);
    
    subElementSpacesOffset = rSpacesOffset;
    subElementSpacesOffset += " ";
    
    pVector = m_levelStyles.enumerate();
    count = pVector->getItemCount();
    for (i=0; i<count; i++) {
        ok = (*pVector)[i]->write(pODT, subElementSpacesOffset);
        if (!ok) {
            return false;
        }
    }
    
    UT_UTF8String_sprintf(output, "%s</text:list-style>\n",
                          rSpacesOffset.utf8_str());
    ODe_writeUTF8String(pODT, output);
    
    return true;
}
Exemplo n.º 7
0
/**
 * Store the style in this automatic styles holder. As the specified
 * style get's stored here, this class takes care of freeing its memory later, so
 * you don't have to worry about freeing the memory of the stored style.
 * 
 * The style also get's it's unique name on this method.
 * 
 * After calling this method you may end up with your style pointer pointing to
 * a different style. It happens when there is already a stored style equivalent
 * to the one that you sent to be stored. The one that was passed is deleted.
 */
void ODe_AutomaticStyles::_storeStyle(ODe_Style_Style*& rpStyle,
                     UT_GenericStringMap<ODe_Style_Style*>& rStyles,
                     const char* pNamingPrefix) {
                        
    UT_GenericVector<ODe_Style_Style*>* pStyleVector;
    ODe_Style_Style* pStyle;
    bool isDuplicated;
    UT_uint32 i, count;
    
    pStyleVector = rStyles.enumerate();
    count = pStyleVector->getItemCount();
    
    for (i=0, isDuplicated=false; i<count && isDuplicated==false; i++) {
        
        pStyle = pStyleVector->getNthItem(i);
        if ( pStyle->isEquivalentTo(*rpStyle) ) {
            isDuplicated = true; // exit the loop
            delete rpStyle; // We don't want a duplicated style.
            rpStyle = pStyle;
        }
    }
    
    
    if (!isDuplicated) {
        // Let's name and store this style.
        UT_UTF8String styleName;
   
        UT_UTF8String_sprintf(styleName, "%s%d", pNamingPrefix, count+1);
        
        rpStyle->setStyleName(styleName);
        rStyles.insert(styleName.utf8_str(), rpStyle);
    }
}
void 
AP_UnixToolbar_StyleCombo::freeStyles() {

	UT_GenericVector<PangoFontDescription*> *pVec = m_mapStyles.enumerate();
	for (UT_sint32 i = 0; i < pVec->size(); i++) {
		pango_font_description_free(pVec->getNthItem(i));
	}
	delete pVec;
}
/**
 * Destructor
 */
ODe_DocumentData::~ODe_DocumentData() {
    UT_GenericVector<ODe_Style_MasterPage*>* pMasterPageVector;
    UT_uint32 count, i;
    
    pMasterPageVector = m_masterStyles.enumerate();
    count = pMasterPageVector->getItemCount();
    for (i=0; i<count; i++) {
        delete (*pMasterPageVector)[i];
    }    
    DELETEP(pMasterPageVector);
    
    if (m_pOfficeTextTemp != NULL) {
        ODe_gsf_output_close(m_pOfficeTextTemp);
    }
}
void ABI_Collab_Import::_disableUpdates(UT_GenericVector<AV_View *>& vecViews, bool bIsGlob)
{
	m_pDoc->getAllViews(&vecViews);

	for (UT_sint32 i=0; i < vecViews.getItemCount(); i++)
	{
		vecViews.getNthItem(i)->setActivityMask(false);
	}
	m_pDoc->notifyPieceTableChangeStart();
	
	if (bIsGlob)
	{
		// lock out all updates while processing the glob
		m_pDoc->disableListUpdates();
		m_pDoc->setDontImmediatelyLayout(true);
		m_pDoc->beginUserAtomicGlob();
	}
}
Exemplo n.º 11
0
/**
 * Writes <office:automatic-styles> element.
 */
void ODe_AutomaticStyles::write(GsfOutput* pContentStream) const {

    UT_GenericVector<ODe_Style_Style*>* pStyleVector;
    UT_GenericVector<ODe_Style_PageLayout*>* pPageLayoutVector;
    UT_GenericVector<ODe_Style_List*>* pListStyleVector;
    UT_uint32 i, count;
    UT_UTF8String spacesOffset = "  ";

    ODe_writeUTF8String(pContentStream, " <office:automatic-styles>\n");
    
#define ODE_WRITE_STYLES(styleMap) \
    pStyleVector = styleMap.enumerate(); \
    count = pStyleVector->getItemCount(); \
    for (i=0; i<count; i++) { \
        (*pStyleVector)[i]->write(pContentStream, spacesOffset); \
    } \
    DELETEP(pStyleVector);
    
    
    ODE_WRITE_STYLES (m_textStyles);
    ODE_WRITE_STYLES (m_paragraphStyles);
    ODE_WRITE_STYLES (m_sectionStyles);
    ODE_WRITE_STYLES (m_tableStyles);
    ODE_WRITE_STYLES (m_tableColumnStyles);
    ODE_WRITE_STYLES (m_tableRowStyles);
    ODE_WRITE_STYLES (m_tableCellStyles);
    ODE_WRITE_STYLES (m_graphicStyles);
    
#undef ODE_WRITE_STYLES
 
    pPageLayoutVector = m_pageLayouts.enumerate();
    count = pPageLayoutVector->getItemCount();
    for (i=0; i<count; i++) {
        (*pPageLayoutVector)[i]->write(pContentStream, spacesOffset);
    }
    
    pListStyleVector = m_listStyles.enumerate();
    count = pListStyleVector->getItemCount();
    for (i=0; i<count; i++) {
        (*pListStyleVector)[i]->write(pContentStream, spacesOffset);
    }
    
    ODe_writeUTF8String(pContentStream, " </office:automatic-styles>\n");
}
Exemplo n.º 12
0
/*!
 * Implements the signal() method of the Document listener class.
 */
bool AbiCollabService_Export::signal(UT_uint32 iSignal)
{
	if((iSignal == PD_SIGNAL_SAVEDOC) && m_pDoc->isDirty())
	{
		bool bSavedRemotely = ServiceAccountHandler::m_saveInterceptor.save(m_pDoc);
		if(bSavedRemotely)
		{
			UT_GenericVector<AV_View *> vecViews;
			m_pDoc->getAllViews(&vecViews);
			AV_View * pView = vecViews.getNthItem(0);
			XAP_Frame * pFrame = static_cast<XAP_Frame *> (pView->getParentData());
			if (pFrame->getViewNumber() > 0)
				XAP_App::getApp()->updateClones(pFrame);

		}
		return bSavedRemotely;
	}
	return true;
}
bool XAP_App::forgetClones(XAP_Frame * pFrame)
{
	UT_return_val_if_fail(pFrame,false);

	if (pFrame->getViewNumber() == 0)
	{
		return forgetFrame(pFrame);
	}

	UT_GenericVector<XAP_Frame*> vClones;
	getClones(&vClones, pFrame);
	
	for (UT_sint32 i = 0; i < vClones.getItemCount(); i++)
	{
		XAP_Frame * f = static_cast<XAP_Frame *>(vClones.getNthItem(i));
		forgetFrame(f);
	}

	return true;
}
Exemplo n.º 14
0
void XAP_populateComboBoxWithIndex(GtkComboBox * combo, 
								   const UT_GenericVector<const char*> & vec)
{
	GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo));
	GtkTreeIter iter;
	
	for(UT_sint32 i = 0; i < vec.getItemCount(); i++) {
		gtk_list_store_append(store, &iter);
		gtk_list_store_set(store, &iter, 0, vec[i], 1, i, -1);
	}
}
Exemplo n.º 15
0
bool fl_FrameLayout::doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc)
{
	UT_ASSERT(pcrxc->getType()==PX_ChangeRecord::PXT_ChangeStrux);
	fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
	UT_GenericVector<fl_ContainerLayout *> AllLayouts;
	AllLayouts.clear();
	fp_Page * pPage = NULL;
	UT_sint32 i = 0;
	if(pFrameC)
	{
	    pPage = pFrameC->getPage();
	    UT_return_val_if_fail(pPage, false);
	    pPage->getAllLayouts(AllLayouts);
	    for(i=0; i< AllLayouts.getItemCount();i++)
	    {
	         fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
		 pCL->collapse();
	    }
	}
	setAttrPropIndex(pcrxc->getIndexAP());
	collapse();
	lookupProperties();
	format();
	for(i=0; i< AllLayouts.getItemCount();i++)
	{
	    fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
	    pCL->format();
	    xxx_UT_DEBUGMSG(("Format block %x \n",pBL));
	    pCL->markAllRunsDirty();
	}
	getDocSectionLayout()->markAllRunsDirty();
	return true;
}
bool AP_CocoaToolbar_StyleCombo::populate(void)
{
	// clear anything that's already there
	m_vecContents.clear();

	// populate the vector

#if 1
	// HACK: for now, just hardwire it
	// NB if you change the case of the labels, it will stop working
	// unless you also change all the places where the style appears!
	m_vecContents.addItem("Normal");
	m_vecContents.addItem("Heading 1");
	m_vecContents.addItem("Heading 2");
	m_vecContents.addItem("Heading 3");
	m_vecContents.addItem("Plain Text");
	m_vecContents.addItem("Block Text");
#else
	// TODO: need a view/doc pointer to get this right
	// ALSO: will need to repopulate as new styles added
	// HYP:  only call this method from shared code? 

	UT_GenericVector<const PD_Styles*> pStyles = NULL;
	pDoc->enumStyles(pStyles);
	UT_uint32 nStyles = pStyles->getItemCount();

	for (UT_uint32 k = 0; k < nStyles; k++)
	{
		const PD_Style * pStyle;
		pStyle = pStyles->getNthItem(k);
		if(pStyle) {
			m_vecContents.addItem(pStyle->getName());
		}
	}
	DELETEP(pStyles);
#endif 

	return true;
}
bool fl_ContainerLayout::isOnScreen() const
{
	// we check if any of our containers is on screen
	// however, we will not call fp_Container::isOnScreen() to avoid
	// unnecessary overhead

	if(isCollapsed())
		return false;

	UT_return_val_if_fail(getDocLayout(),false);
	
	FV_View *pView = getDocLayout()->getView();

	bool bShowHidden = pView && pView->getShowPara();

	bool bHidden = ((m_eHidden == FP_HIDDEN_TEXT && !bShowHidden)
	              || m_eHidden == FP_HIDDEN_REVISION
		          || m_eHidden == FP_HIDDEN_REVISION_AND_TEXT);


	if(bHidden)
		return false;
	
	UT_GenericVector<UT_Rect*> vRect;
	UT_GenericVector<fp_Page*> vPages;

	pView->getVisibleDocumentPagesAndRectangles(vRect, vPages);

	UT_uint32 iCount = vPages.getItemCount();

	if(!iCount)
		return false;
	
	bool bRet = false;
	fp_Container * pC = getFirstContainer();

	if(!pC)
		return false;

	fp_Container *pCEnd = getLastContainer();

	while(pC)
	{
		fp_Page * pMyPage = pC->getPage();

		if(pMyPage)
		{
			for(UT_uint32 i = 0; i < iCount; i++)
			{
				fp_Page * pPage = vPages.getNthItem(i);

				if(pPage == pMyPage)
				{
					UT_Rect r;
					UT_Rect *pR = vRect.getNthItem(i);

					if(!pC->getPageRelativeOffsets(r))
						break;
				
					bRet = r.intersectsRect(pR);
					break;
				}
		
			}
		}

		if(bRet || pC == pCEnd)
			break;

		pC = static_cast<fp_Container*>(pC->getNext());
	}
	
	UT_VECTOR_PURGEALL(UT_Rect*,vRect);
	return bRet;
}
Exemplo n.º 18
0
bool fl_FrameLayout::doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)
{
	UT_UNUSED(pcrx);
	UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_DeleteStrux);
#if 0
	fp_FrameContainer * pFrameC = getFirstContainer();
	if(pFrameC && pFrameC->getPage())
	{
		pFrameC->getPage()->markDirtyOverlappingRuns(pFrameC);
	}
#endif
	fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
	UT_GenericVector<fl_BlockLayout *> vecBlocks;
	pFrameC->getBlocksAroundFrame(vecBlocks);
	UT_sint32 i = 0;
	for(i=0; i< vecBlocks.getItemCount();i++)
	{
	  fl_BlockLayout * pBL = vecBlocks.getNthItem(i);
	  pBL->collapse();
	  xxx_UT_DEBUGMSG(("Collapse block %x \n",pBL));
	}

//
// Remove all remaining structures
//
	collapse();
//	UT_ASSERT(pcrx->getStruxType()== PTX_SectionFrame);
//
	fl_ContainerLayout * pCL = getPrev();
	myContainingLayout()->remove(this);
	UT_DEBUGMSG(("Unlinking frame Layout %p \n",this));
//
// Remove from the list of frames in the previous block
//
	while(pCL && pCL->getContainerType() != FL_CONTAINER_BLOCK)
	{
		pCL = pCL->getPrev();
	}
	if(pCL == NULL)
	{
		UT_DEBUGMSG(("No BlockLayout before this frame! \n"));
		return false;
	}
	fl_BlockLayout * pBL = static_cast<fl_BlockLayout *>(pCL);
	bool bFound = false;
	for(i=0; i<pBL->getNumFrames() && !bFound;i++)
	{
	  fl_FrameLayout * pF = pBL->getNthFrameLayout(i);
	  if(pF == this)
	  {
	    bFound = true;
	  }
	}
	if(bFound)
	{
	  pBL->removeFrame(this);
	}
	else
	{
	  UT_DEBUGMSG(("Whoops! not Frame found. Try ahead \n"));
	  pCL = this;
	  while(pCL && pCL->getContainerType() != FL_CONTAINER_BLOCK)
	  {
	    pCL = pCL->getNext();
	  }
	  if(pCL == NULL)
	  {
	    UT_DEBUGMSG(("No BlockLayout before this frame! \n"));
	    return false;
	  }
	  pBL = static_cast<fl_BlockLayout *>(pCL);
	  pBL->removeFrame(this);
	}
	for(i=0; i< vecBlocks.getItemCount();i++)
	{
	  pBL = vecBlocks.getNthItem(i);
	  pBL->format();
	  xxx_UT_DEBUGMSG(("format block %x \n",pBL));
	}

	delete this;			// TODO whoa!  this construct is VERY dangerous.

	return true;
}
Exemplo n.º 19
0
void AbiCollabSessionManager::setDocumentHandles(BuddyPtr pBuddy, const UT_GenericVector<DocHandle*>& vDocHandles)
{
	UT_DEBUGMSG(("Setting document handles for buddy %s\n", pBuddy->getDescriptor().utf8_str()));
	UT_return_if_fail(pBuddy);

	// create a copy of the current document handles, which
	// we'll use to determine which document handles do not exist anymore
	std::vector<DocHandle*> oldDocHandles(pBuddy->getDocHandles());

	for (UT_sint32 i = 0; i < vDocHandles.size(); i++)
	{
		DocHandle* pDocHandle = vDocHandles.getNthItem(i);
		UT_continue_if_fail(pDocHandle);

		// sanity checking
		UT_UTF8String sId = pDocHandle->getSessionId();
		UT_continue_if_fail(sId.size() > 0);
	
		// construct a nice document name
		UT_UTF8String sDocumentName = pDocHandle->getName();
		if (sDocumentName.size() == 0)
		{
			// this document has no name yet; give it an untitled name
			const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet();
			std::string sUntitled;
			pSS->getValueUTF8(XAP_STRING_ID_UntitledDocument, sUntitled);
			UT_UTF8String_sprintf(sDocumentName, sUntitled.c_str(), 0);

			// TODO: as should append a number here, but at the moment
			// XAP_Frame::m_iUntitled is not accessible from here
		}
		
		// check to see if we already have a document handle with this ID
		DocHandle* pCurDocHandle = pBuddy->getDocHandle(sId);
		if (!pCurDocHandle)
		{
			// Ok, all set. Get the buddy from the AccountHandler, and assign 
			// the document handle to the buddy
			DocHandle * pNewDocHandle = new DocHandle(sId, sDocumentName);

			pBuddy->addDocHandle(pNewDocHandle);
			UT_DEBUGMSG(("Added DocHandle (%s) to buddy (%s)\n", sId.utf8_str(), pBuddy->getDescription().utf8_str()));
						
			// signal that a buddy has a new session
			AccountBuddyAddDocumentEvent event(pNewDocHandle);
			signal(event, pBuddy);
		}
		else
		{
			UT_DEBUGMSG(("Found an existing DocHandle (%s) for buddy (%s)\n", sId.utf8_str(), pBuddy->getDescription().utf8_str()));
			
			// we already have a handle for this document, remove it from the old document handles copy
			for (std::vector<DocHandle*>::iterator it = oldDocHandles.begin(); it != oldDocHandles.end(); it++)
			{
				DocHandle* pOldDocHandle = *it;
				if (pCurDocHandle == pOldDocHandle)
				{
					oldDocHandles.erase(it);
					break;
				}
			}
		}
	}
	
	// every document that is still in the old document handles list does not 
	// exist anymore, so let's delete it
	std::vector<DocHandle*>::iterator it = oldDocHandles.begin();
	while (it != oldDocHandles.end())
	{
		DocHandle* pDocHandle = *it;
		UT_continue_if_fail(pDocHandle);

		// TODO: when we are a part of this session, then handle that properly
	
		UT_DEBUGMSG(("Purging existing DocHandle (%s) for buddy (%s)\n", pDocHandle->getSessionId().utf8_str(), pBuddy->getDescription().utf8_str()));
		UT_UTF8String pDestroyedSessionId = pDocHandle->getSessionId();
		pBuddy->destroyDocHandle(pDestroyedSessionId);
		CloseSessionEvent event(pDestroyedSessionId);
		signal(event, pBuddy);

		it = oldDocHandles.erase(it);
	}
}
Exemplo n.º 20
0
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */


#include "tf_test.h"
#include "ut_vector.h"



TFTEST_MAIN("UT_GenericVector basics")
{
	UT_GenericVector<const char *> v;

	TFPASS(v.getItemCount() == 0);
	v.addItem("foo");
	TFPASS(v.getItemCount() == 1);
	v.addItem("bar");
	TFPASS(v.getItemCount() == 2);
	v.addItem("baz");
	TFPASS(v.getItemCount() == 3);

	TFPASS(strcmp(v[1], "bar") == 0);
	TFPASS(strcmp(v.getNthItem(2), "baz") == 0);

	TFPASS(strcmp(v.getFirstItem(), "foo") == 0);
	TFPASS(strcmp(v.getLastItem(), "baz") == 0);
	TFPASS(strcmp(v.back(), "baz") == 0);
Exemplo n.º 21
0
/*!
 * This method Does the stuff requested on the "action" button, "Apply" in the
 * Modeless dialog and "OK" in the Modal dialog.
 * Read comments with for all the stuff that can happen.
 */
void AP_Dialog_Lists::Apply(void)
{
	gchar szStart[20];
	if(!isModal() && (!isPageLists() || m_bFoldingLevelChanged))
	{
//
// OK fold up the text according the level specified.
//
	        m_bFoldingLevelChanged = false;
		fl_AutoNum * pAuto = getBlock()->getAutoNum();
		const gchar * props[5] = {"text-folded",NULL,"text-folded-id",NULL,NULL};
		UT_UTF8String sStr = UT_UTF8String_sprintf("%d",getCurrentFold());
		props[1] = sStr.utf8_str();
		UT_uint32 ID = 0;
		if(!pAuto)
		{
		        ID = getView()->getDocument()->getUID(UT_UniqueId::List);
		}
		else
		{
		        ID = pAuto->getID();
		}
		UT_UTF8String sID = UT_UTF8String_sprintf("%d",ID);
		props[3] = sID.utf8_str();
		PT_DocPosition posLow = 0;
		PT_DocPosition posHigh = 0;
		if(getView()->isSelectionEmpty() && pAuto)
		{
		      PL_StruxDocHandle sdhLow = pAuto->getFirstItem();
		      PL_StruxDocHandle sdhHigh = pAuto->getLastItemInHeiracy();
		      posLow = getView()->getDocument()->getStruxPosition(sdhLow)+1;
		      posHigh = getView()->getDocument()->getStruxPosition(sdhHigh)+1;
		}
		else
		{
		      posLow = getView()->getPoint();
		      posHigh = getView()->getSelectionAnchor();
		      if(posLow > posHigh)
		      {
			  PT_DocPosition posTemp = posLow;
			  posLow = posHigh;
			  posHigh = posTemp;
		      }
		}
		getView()->setCollapsedRange(posLow,posHigh,props);
		return;
	}

/*!
 *
 * OK this is failsafe code incase the user has changed the font but wants a
 * bullet list anyway. We don't let then!
 */
	if(m_NewListType == BULLETED_LIST || m_NewListType == IMPLIES_LIST)
	{
		m_pszFont = "Symbol";
	}
	else if(m_NewListType > DASHED_LIST && m_NewListType < OTHER_NUMBERED_LISTS)
	{
		m_pszFont = _getDingbatsFontName();
	}

/*!
 * Just to make things even more confusing this method is also used in a Modal
 * mannor by the styles dialog. This method is called when the users clicks "OK"
 * on the modal dialog. When that happens we fill an output vector with all the
 * properties currently defined.
 */
	if(isModal())
	{
//
// Fill out output vector with gchar * strings to be accessed via the calling
// function.
//
		if(m_OutProps.getItemCount() > 0)
			m_OutProps.clear();
		sprintf(szStart,"%d",m_iStartValue);
		m_OutProps.addItem((void *) "start-value");
		m_Output[0] = (gchar *) szStart;
		m_OutProps.addItem((void *) m_Output[0].c_str());
		m_OutProps.addItem((void *) "list-style");
		m_Output[1] = getBlock()->getListStyleString(m_NewListType);
		m_OutProps.addItem((void *) m_Output[1].c_str());
		m_OutProps.addItem((void *) "list-delim");
		m_OutProps.addItem((void *)  m_pszDelim.c_str());
		m_OutProps.addItem((void *) "list-decimal");
		m_OutProps.addItem((void *) m_pszDecimal.c_str());
		m_OutProps.addItem((void *) "field-font");
		m_OutProps.addItem((void *) m_pszFont.c_str());
		m_OutProps.addItem((void *) "margin-left");
		m_Output[2] =	UT_convertInchesToDimensionString(DIM_IN, m_fAlign, 0);
		m_OutProps.addItem((void *) m_Output[2].c_str());

		m_OutProps.addItem((void *) "text-indent");
		m_Output[3] = UT_convertInchesToDimensionString(DIM_IN, m_fIndent, 0);
		m_OutProps.addItem((void *) m_Output[3].c_str());
		m_Answer = a_OK;
		return;
	}
/*!
 * If the "Apply to current" radio buton is chosen we have two options.
 * 1. If "No list" is chosen we stop the current list at on this block.
 * 2. Otherwise we change the current list to the type requested here.
 * This piece of code changes the list style at the current point to the
 * Style requested by the user.
 */
	UT_GenericVector<fl_BlockLayout*> vBlock;
	UT_uint32 i = 0;
	getView()->getBlocksInSelection(&vBlock);
	UT_uint32 count = vBlock.getItemCount();
	getView()->cmdUnselectSelection();
	if(m_bApplyToCurrent == true && m_isListAtPoint == true &&  m_NewListType != NOT_A_LIST)
	{
		getView()->getDocument()->beginUserAtomicGlob();
		getView()->changeListStyle(getAutoNum(),m_NewListType,m_iStartValue,
                                   m_pszDelim.c_str(), m_pszDecimal.c_str(), 
                                   m_pszFont.c_str(),m_fAlign,m_fIndent);
		if(getAutoNum() != NULL)
		{
			getAutoNum()->update(0);
		}
		getView()->getDocument()->endUserAtomicGlob();
		clearDirty();
		getView()->updateLayout();
		getView()->setPoint(getView()->getPoint());
		getView()->ensureInsertionPointOnScreen();
		return;
	}
/*!
 * This code stops the list at the current point.
 */
	if ( m_isListAtPoint == true &&  m_NewListType == NOT_A_LIST)
	{
		getView()->getDocument()->beginUserAtomicGlob();
		for(i=0;i < count; i++)
		{
			fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i);
			if(pBlock->isListItem() == true)
			{
				getView()->getDocument()->StopList(pBlock->getStruxDocHandle());
			}
		}
		getView()->getDocument()->endUserAtomicGlob();
		clearDirty();
		getView()->updateLayout();
		getView()->setPoint(getView()->getPoint());
		getView()->ensureInsertionPointOnScreen();
		return;
	}
/*!
 * Start new list. 4 Possibilities.
 * 1. If there is a list at the current point and the user choose no list, stop
 *    the list the current point.
 *
 * 2. start a new list with the properties given if there is not a
 * list at the current point.
 *
 * 3. Start a sublist at the current point if a list already exists there and
 *    contains two or more items.
 *
 * 4. Change the list to the requested value if a list already eists but only
 *    has one item in it.
 */
	if(m_bStartNewList == true)
	{
		getView()->getDocument()->beginUserAtomicGlob();
		for(i=0;i < count; i++)
		{
			fl_BlockLayout * pBlock2 = (fl_BlockLayout *) vBlock.getNthItem(i);
			if(pBlock2->isListItem() == true && m_NewListType == NOT_A_LIST)
			{
//
// This stops the current list.
//
				if(pBlock2->isListItem() == true)
				{
					getView()->getDocument()->StopList(pBlock2->getStruxDocHandle());
				}
			}
			else if ( pBlock2->isListItem() == false && m_NewListType != NOT_A_LIST )
			{
//
// This starts the new list
//
				pBlock2->getDocument()->disableListUpdates();
				if(i == 0)
				{
					pBlock2->StartList(m_NewListType,m_iStartValue,
                                       m_pszDelim.c_str(), m_pszDecimal.c_str(),
                                       m_pszFont.c_str(), m_fAlign, 
                                       m_fIndent, 0, 1);
					pBlock2->getDocument()->enableListUpdates();
					pBlock2->getDocument()->updateDirtyLists();
				}
				else
				{
					fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i);
					fl_BlockLayout * rBlock = (fl_BlockLayout *) pBlock->getPrev();
					if(rBlock != NULL)
					{
						pBlock->resumeList(rBlock);
						pBlock->getDocument()->enableListUpdates();
					}
				}

			}
			else if( pBlock2->getAutoNum() && (pBlock2->getAutoNum()->getNumLabels() > 1) && m_NewListType != NOT_A_LIST )
			{
//
// This starts a sublist.
//
				UT_uint32 curlevel = pBlock2->getLevel();
				UT_uint32 currID = pBlock2->getAutoNum()->getID();
				curlevel++;
				pBlock2->getDocument()->disableListUpdates();
//
// Need to update m_fAlign and m_fIndent to reflect the higher level of indentation.
//
				if(i == 0)
				{
					m_fAlign = m_fAlign + (float) LIST_DEFAULT_INDENT;
					pBlock2->StartList(m_NewListType,m_iStartValue,
                                       m_pszDelim.c_str(), m_pszDecimal.c_str(),
                                       m_pszFont.c_str(), m_fAlign, m_fIndent, 
                                       currID,curlevel);
					pBlock2->getDocument()->enableListUpdates();
					pBlock2->getDocument()->updateDirtyLists();
				}
				else
				{
					fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i);
					fl_BlockLayout * rBlock = (fl_BlockLayout *) pBlock->getPrev();
					if(rBlock != NULL)
					{
						pBlock->resumeList(rBlock);
						pBlock->getDocument()->enableListUpdates();
						pBlock->getDocument()->updateDirtyLists();
					}
				}
			}
			else if( pBlock2->getAutoNum() && (pBlock2->getAutoNum()->getNumLabels() <= 1) && m_NewListType != NOT_A_LIST )
			{
//
// The list at the current point only has one item which is the current paragraph.
// We can't share an sdh amongst two autonum's so we can't start a sublist.
// We'll change the list style instead.
//
				getView()->changeListStyle(pBlock2->getAutoNum(),
                                           m_NewListType, m_iStartValue,
                                           m_pszDelim.c_str(), 
                                           m_pszDecimal.c_str(), 
                                           m_pszFont.c_str(), m_fAlign,
                                           m_fIndent);
				if(pBlock2->getAutoNum() != NULL)
				{
					pBlock2->getAutoNum()->update(0);
				}

			}
		}
		clearDirty();
		getView()->updateLayout();
		getView()->setPoint(getView()->getPoint());
		getView()->updateScreen(true);
		getView()->notifyListeners(AV_CHG_MOTION | AV_CHG_HDRFTR);
		getView()->getDocument()->endUserAtomicGlob();
		getView()->ensureInsertionPointOnScreen();
		return;
	}
/*!
 * OK Attach the block at this point to the previous list of the same margin.
 */
	if(m_bResumeList == true &&  m_isListAtPoint != true )
	{
		getView()->getDocument()->beginUserAtomicGlob();
		for(i=0;i < count; i++)
		{
			fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i);
			fl_BlockLayout * rBlock = pBlock->getPreviousListOfSameMargin();
			if(rBlock != NULL)
			{
				pBlock->resumeList(rBlock);
				pBlock->getDocument()->enableListUpdates();
				pBlock->getDocument()->updateDirtyLists();
			}
		}
		getView()->getDocument()->endUserAtomicGlob();
	}
	getView()->updateLayout();
	getView()->setPoint(getView()->getPoint());
	getView()->updateScreen(true);
	getView()->notifyListeners(AV_CHG_MOTION | AV_CHG_HDRFTR);
	getView()->ensureInsertionPointOnScreen();
	clearDirty();
}
Exemplo n.º 22
0
/*!
 * Fill the supplied vector with a list of the blocks whose lines are affected
 * by the Frame.
 */ 
void fp_FrameContainer::getBlocksAroundFrame(UT_GenericVector<fl_BlockLayout *> & vecBlocks)
{
  fp_Page * pPage = getPage();
  if(pPage == NULL)
  {
    return;
  }
  UT_sint32 iColLeader = 0;
  fp_Column * pCol = NULL;
  fl_BlockLayout * pCurBlock = NULL;
  fp_Line * pCurLine = NULL;
  fp_Container * pCurCon = NULL;
  if(pPage->countColumnLeaders() == 0)
  {
      UT_sint32 iPage = getPreferedPageNo();
      if(iPage >0)
          setPreferedPageNo(iPage-1);
      return;
  }
  for(iColLeader = 0; iColLeader < pPage->countColumnLeaders(); iColLeader++)
  {
      pCol = pPage->getNthColumnLeader(iColLeader);
      while(pCol)
      {
          UT_sint32 i = 0;
          UT_sint32 iYCol = pCol->getY(); // Vertical position relative to page.
          for(i=0; i< pCol->countCons(); i++)
          {
              pCurCon = static_cast<fp_Container *>(pCol->getNthCon(i));
              if(pCurCon->getContainerType() == FP_CONTAINER_LINE)
              {
                  pCurLine = static_cast<fp_Line *>(pCurCon);
                  UT_sint32 iYLine = iYCol + pCurLine->getY();
                  xxx_UT_DEBUGMSG(("iYLine %d FullY %d FullHeight %d \n",iYLine,getFullY(),getFullHeight()));
                  if((iYLine + pCurLine->getHeight() > getFullY()) && (iYLine < (getFullY() + getFullHeight())))
                  {
                      //
                      // Line overlaps frame in Height. Add it's block to the vector.
                      //
                      if(pCurLine->getBlock() != pCurBlock)
                      {
                          pCurBlock = pCurLine->getBlock();
                          vecBlocks.addItem(pCurBlock);
                          xxx_UT_DEBUGMSG(("Add Block %x to vector \n",pCurBlock));
                      }
                  }
              }
          }
          pCol = pCol->getFollower();
      }
  }
  if(vecBlocks.getItemCount() == 0)
  {
      pCol = pPage->getNthColumnLeader(0);
      fp_Container * pCon = pCol->getFirstContainer();
      fl_BlockLayout * pB = NULL;
      if(pCon && pCon->getContainerType() == FP_CONTAINER_LINE)
      {
          pB = static_cast<fp_Line *>(pCon)->getBlock();
      }
      else if(pCon)
      {
          fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(pCon->getSectionLayout());
          pB = pCL->getNextBlockInDocument();
      }
      if(pB != NULL)
          vecBlocks.addItem(pB);
  }

}
Exemplo n.º 23
0
void AP_UnixDialog_Styles::_populateCList(void)
{
	const PD_Style * pStyle;
	const gchar * name = NULL;

	size_t nStyles = getDoc()->getStyleCount();
	xxx_UT_DEBUGMSG(("DOM: we have %d styles\n", nStyles));
	
	if (m_listStyles == NULL) {
		m_listStyles = gtk_list_store_new (1, G_TYPE_STRING);
		GtkTreeModel *sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (m_listStyles));
		gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0, GTK_SORT_ASCENDING);
		gtk_tree_view_set_model (GTK_TREE_VIEW(m_tvStyles), sort);
		g_object_unref (G_OBJECT (sort));
		g_object_unref (G_OBJECT (m_listStyles));
	} else {
		gtk_list_store_clear (m_listStyles);
	}
	
	GtkTreeViewColumn *column = gtk_tree_view_get_column (GTK_TREE_VIEW(m_tvStyles), 0);
	if (!column) 
	{
		column = gtk_tree_view_column_new_with_attributes ("Style", gtk_cell_renderer_text_new (), "text", 0, NULL);
		gtk_tree_view_append_column(GTK_TREE_VIEW(m_tvStyles), column);
	}

	GtkTreeIter iter;
	GtkTreeIter *pHighlightIter = NULL;
	UT_GenericVector<PD_Style*> *pStyles = NULL;
	getDoc()->enumStyles(pStyles);
	for (UT_uint32 i = 0; i < nStyles; i++)
	{
		pStyle = pStyles->getNthItem(i);

		// style has been deleted probably
		if (!pStyle)
			continue;

		name = pStyle->getName();

		if ((m_whichType == ALL_STYLES) || 
			(m_whichType == USED_STYLES && pStyle->isUsed()) ||
			(m_whichType == USER_STYLES && pStyle->isUserDefined()) ||
			(!strcmp(m_sNewStyleName.utf8_str(), name))) /* show newly created style anyways */
		{
			gtk_list_store_append(m_listStyles, &iter);
			gtk_list_store_set(m_listStyles, &iter, 0, name, -1);
			
			if (!strcmp(m_sNewStyleName.utf8_str(), name)) {
				pHighlightIter = gtk_tree_iter_copy(&iter);
			}
		}
	}
	DELETEP(pStyles);

	GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_tvStyles));
	if (pHighlightIter) {
		// select new/modified
		gtk_tree_selection_select_iter(selection, pHighlightIter);
		gtk_tree_iter_free(pHighlightIter);
	}
	else {
		// select first
		GtkTreePath *path = gtk_tree_path_new_from_string("0");
		gtk_tree_selection_select_path(selection, path);
		gtk_tree_path_free(path);
	}
	
	// selection "changed" doesn't fire here, so hack manually
	s_tvStyles_selection_changed (selection, (gpointer)(this));
}
bool ODe_DocumentData::writeStylesXML(GsfOutfile* pOdt) const {
    GsfOutput* pStylesStream;
    UT_GenericVector<ODe_Style_MasterPage*>* pMasterPageVector;    
    bool ok;
    UT_uint32 count, i;
    
    pStylesStream = gsf_outfile_new_child (pOdt, "styles.xml", FALSE);
    
    const char * const preamble [] = {
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
    "\n",
    "<office:document-styles"
    " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\""
    " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\""
    " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\""
    " xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\""
    " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\""
    " xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\""
    " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
    " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
    " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\""
    " xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\""
    " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\""
    " xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\""
    " xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\""
    " xmlns:math=\"http://www.w3.org/1998/Math/MathML\""
    " xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\""
    " xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\""
    " xmlns:ooo=\"http://openoffice.org/2004/office\""
    " xmlns:ooow=\"http://openoffice.org/2004/writer\""
    " xmlns:oooc=\"http://openoffice.org/2004/calc\""
    " xmlns:dom=\"http://www.w3.org/2001/xml-events\""
    " office:version=\"1.1\">\n"};
    
    ODe_writeToStream(pStylesStream, preamble, G_N_ELEMENTS(preamble));
    
    m_stylesXMLFontDecls.write(pStylesStream);
    
    m_styles.write(pStylesStream);
    m_stylesAutoStyles.write(pStylesStream);
    
    ODe_writeUTF8String(pStylesStream, " <office:master-styles>\n");
    
    pMasterPageVector = m_masterStyles.enumerate();
    count = pMasterPageVector->getItemCount();
    for (i=0; i<count; i++) {
        ok = (*pMasterPageVector)[i]->write(pStylesStream);
        
        if (!ok) {
            return false;
        }
    }    
    
    ODe_writeUTF8String(pStylesStream, " </office:master-styles>\n");
    
    ODe_writeUTF8String(pStylesStream, "</office:document-styles>");
    
    ODe_gsf_output_close(pStylesStream);
    
    return true;
}
/**
 * Do all necessary work after having read the AbiWord document.
 */
bool ODe_DocumentData::doPostListeningWork() {
    
    UT_GenericVector<ODe_Style_Style*>* pStylesVector;
    UT_GenericVector<ODe_Style_List*>* pListStyles;
    UT_GenericVector<ODe_ListLevelStyle*>* pListLevelStyles;
    UT_uint32 i, j, count, count2;
    
    ////
    // Build the <office:font-face-decls> element for the Styles XML file.
    
    pStylesVector = m_stylesAutoStyles.getParagraphStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    pStylesVector = m_stylesAutoStyles.getTextStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    pStylesVector = m_styles.getParagraphStylesEnumeration();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    pStylesVector = m_styles.getTextStylesEnumeration();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    ////
    // Build the <office:font-face-decls> element for the Content XML file.
    
    pStylesVector = m_contentAutoStyles.getParagraphStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    pStylesVector = m_contentAutoStyles.getTextStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        m_contentXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() );
    }
    
    pListStyles = m_contentAutoStyles.getListStyles();
    count = pListStyles->getItemCount();
    for (i=0; i<count; i++) {
        pListLevelStyles = pListStyles->getNthItem(i)->getListLevelStyles();
        count2 = pListLevelStyles->getItemCount();
        for (j=0; j<count2; j++) {
            m_contentXMLFontDecls.addFont((*pListLevelStyles)[j]->getFontName());
        }
    }
    
    ////
    // Build/expand the <style:default-style> paragraph elements for the Styles
    // XML file based on the existence of AbiWord's default-tab-interval 
    // property in any of the automatic or normal styles.
    // 
    pStylesVector = m_contentAutoStyles.getParagraphStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        handleDefaultTabInterval((*pStylesVector)[i]);
    }

    pStylesVector = m_stylesAutoStyles.getTextStyles();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        handleDefaultTabInterval((*pStylesVector)[i]);
    }

    pStylesVector = m_styles.getParagraphStylesEnumeration();
    count = pStylesVector->getItemCount();
    for (i=0; i<count; i++) {
        handleDefaultTabInterval((*pStylesVector)[i]);
    }
    
    return true;
}
Exemplo n.º 26
0
AbiCollab* AbiCollabSessionManager::startSession(PD_Document* pDoc, UT_UTF8String& sSessionId, 
			AccountHandler* pAclAccount, bool bLocallyOwned, XAP_Frame* pFrame, 
			const UT_UTF8String& masterDescriptor)
{
	UT_DEBUGMSG(("Starting collaboration session for document with id %s, master descriptor: %s\n",
			pDoc->getDocUUIDString(), masterDescriptor.utf8_str()));
	UT_return_val_if_fail(pDoc, NULL);
	UT_return_val_if_fail(pAclAccount, NULL);

	if (sSessionId == "")
	{
		XAP_App* pApp = XAP_App::getApp();	
		UT_UUID* pUUID = pApp->getUUIDGenerator()->createUUID();
		pUUID->toString(sSessionId);
	}

	if (masterDescriptor != "")
	{
		// search for a buddy descriptor in the authors list that matches this 
		// descriptor, and make that the active author; if such an author does
		// not exist, then search for an author with no abicollab property set 
		// at all, and give it this buddy descriptor (ie, we assume that it is 
		// "us", even though it might not always be a valid assumption).

		int iAuthorId = -1;
		UT_GenericVector<pp_Author*> authors = pDoc->getAuthors();
		pp_Author* pEmptyAuthor = NULL;
		UT_DEBUGMSG(("Scanning %d authors to see if we recognize this master buddy\n", authors.getItemCount()));
		for (UT_sint32 i = 0; i < authors.getItemCount(); i++)
		{
			pp_Author* pAuthor = authors.getNthItem(i);
			UT_continue_if_fail(pAuthor);

			const gchar* szDescriptor = NULL;
			pAuthor->getProperty("abicollab-descriptor", szDescriptor);
			if (!szDescriptor)
			{
				if (!pEmptyAuthor && !pAuthor->getAttrProp()->hasProperties())
					pEmptyAuthor = pAuthor;
				continue;
			}

			if (masterDescriptor != szDescriptor)
				continue;

			// yay, we already editted this document ourselves!
			iAuthorId = pAuthor->getAuthorInt();
			pDoc->setMyAuthorInt(iAuthorId);
			UT_DEBUGMSG(("Found our own author object with descriptior %s, id %d!\n", masterDescriptor.utf8_str(), iAuthorId));
			break;
		}

		if (iAuthorId == -1)
		{
			if (pEmptyAuthor)
			{
				// reuse this author object and make it our own
				iAuthorId = pEmptyAuthor->getAuthorInt();
				PP_AttrProp * pPA = pEmptyAuthor->getAttrProp();
				pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str());
				pDoc->setMyAuthorInt(iAuthorId);
				pDoc->sendChangeAuthorCR(pEmptyAuthor);
				UT_DEBUGMSG(("Reusing empty author object with id %d, setting descriptor to %s!\n", iAuthorId, masterDescriptor.utf8_str()));
			}
			else
			{
				UT_DEBUGMSG(("No suitable author found in the document for descriptor %s\n", masterDescriptor.utf8_str()));
				
				iAuthorId = pDoc->findFirstFreeAuthorInt();
				pp_Author * pA = pDoc->addAuthor(iAuthorId);
				pDoc->setMyAuthorInt(iAuthorId);
				PP_AttrProp * pPA = pA->getAttrProp();
				pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str());
				pDoc->sendAddAuthorCR(pA);
				UT_DEBUGMSG(("Added a new author to the documument with descriptor %s, id %d\n", masterDescriptor.utf8_str(), iAuthorId));
			}
		}
	}
	
	UT_DEBUGMSG(("Creating a new collaboration session with UUID: %s\n", sSessionId.utf8_str()));

	UT_return_val_if_fail(_setupFrame(&pFrame, pDoc), NULL);
	AbiCollab* pAbiCollab = new AbiCollab(pDoc, sSessionId, pAclAccount, bLocallyOwned);
	m_vecSessions.push_back(pAbiCollab);
	
	// notify all people we are sharing a new document
	// FIXME: since we only allow a session to be shared on 1 account, we should
	// only notify the buddies on that account, instead of notifying the buddies
	// on all accounts.
	StartSessionEvent event;
	event.setBroadcast(true);
	signal(event);
	
	return pAbiCollab;
}
/*!
 * Massage the byte buffer into an array of strings that can be loaded by 
 * gdk-pixbuf
 */
GdkPixbuf * IE_ImpGraphic_GdkPixbuf::_loadXPM(UT_ByteBuf * pBB)
{
	GdkPixbuf * pixbuf = NULL;
	const char * pBC = reinterpret_cast<const char *>(pBB->getPointer(0));

	UT_GenericVector<char*> vecStr;
	UT_sint32 k =0;
	UT_sint32 iBase =0;

	//
	// Find dimension line to start with.
	//
	UT_sint32 length = static_cast<UT_sint32>(pBB->getLength());
	for(k =0; (*(pBC+k) != '"') &&( k < length); k++)
		;

	if(k >= length)
	{
		return NULL;
	}

	k++;
	iBase = k;
	for(; (*(pBC+k) != '"') && (k < length); k++)
		;
	if(k >= length)
	{
		return NULL;
	}

	char * sz = NULL;
	UT_sint32 kLen = k-iBase+1;
	sz = static_cast<char *>(UT_calloc(kLen,sizeof(char)));
	UT_sint32 i =0;

	for(i=0; i< (kLen -1); i++)
	{
		*(sz+i) = *(pBC+iBase+i);
	}
	*(sz+i) = 0;
	vecStr.addItem(sz);

	//
	// Now loop through all the lines until we get to "}" outside the
	// '"'
	while((*(pBC+k) != '}')  && (k < length) )
	{
		k++;

		//
		// Load a single string of data into our vector.
		// 
		if(*(pBC+k) =='"')
		{
			//
			// Start of a line
			//
			k++;
			iBase = k;
			for(; (*(pBC+k) != '"') && (k < length); k++) 
			{
			}
			if(k >= length)
			{
				return NULL;
			}
			sz = NULL;
			kLen = k-iBase+1;
			sz = static_cast<char *>(UT_calloc(kLen,sizeof(char)));
			for(i=0; i<(kLen -1); i++)
			{
				*(sz+i) = *(pBC+iBase+i);
			}
			*(sz +i) = 0;
			vecStr.addItem(sz);
		}
	}

	if(k >= length)
	{
		for(i=0; i< vecStr.getItemCount(); i++)
		{
			char * psz = vecStr.getNthItem(i);
			FREEP(psz);
		}
		return NULL;
	}

	const char ** pszStr = static_cast<const char **>(UT_calloc(vecStr.getItemCount(),sizeof(char *)));
	for(i=0; i< vecStr.getItemCount(); i++)
		pszStr[i] = vecStr.getNthItem(i);
	pixbuf = gdk_pixbuf_new_from_xpm_data(pszStr);
	DELETEP(pszStr);
	return pixbuf;
}
// returns true if the import can continue, false otherwise
bool ABI_Collab_Import::_handleCollision(UT_sint32 iIncomingRev, UT_sint32 iLocalRev, BuddyPtr pCollaborator)
{
	UT_DEBUGMSG(("_handleCollision() - incoming rev %d collides against local rev %d!!!\n", iIncomingRev, iLocalRev));
	UT_return_val_if_fail(pCollaborator, false);

	if (m_pAbiCollab->isLocallyControlled())
	{
		UT_DEBUGMSG(("We're controlling this session, refusing this changerecord from %s!\n", pCollaborator->getDescription().utf8_str()));
		// add this collaborator to our revert ack list, so we can ignore his packets
		// until we get an acknoledgement that he has reverted his local, colliding changes
		m_revertSet.push_back(std::make_pair(pCollaborator, iIncomingRev));
		// send the revert command to the collaborator
		RevertSessionPacket rsp(m_pAbiCollab->getSessionId(), m_pDoc->getOrigDocUUIDString(), iIncomingRev);
		m_pAbiCollab->push(&rsp, pCollaborator);
		return false;
	}
	else
	{
		UT_DEBUGMSG(("We're NOT controlling this session, reverting local changes and accepting changerecord!\n"));

		ABI_Collab_Export* pExport = m_pAbiCollab->getExport();
		UT_return_val_if_fail(pExport, false);

		UT_GenericVector<ChangeAdjust *>* pAdjusts = pExport->getAdjusts();
		UT_return_val_if_fail(pAdjusts, false);
		
		m_pAbiCollab->setIsReverting(true); // mask all changes in the exporter

		// undo our cool local changes, and nuke our exported packet list as well up to (and including) iLocalRev
		for (UT_sint32 i = pAdjusts->getItemCount() - 1; i >= 0; i--)
		{
			ChangeAdjust* pChange = pAdjusts->getNthItem(i);
			if (pChange)
			{
				if (pChange->getLocalRev() >= iLocalRev)
				{
					if (strcmp(m_pDoc->getOrigDocUUIDString(), pChange->getRemoteDocUUID().utf8_str()) == 0)
					{
						UT_DEBUGMSG(("UNDO-ING AND NUKING LOCAL CHANGE: EXPORT POSITION %d, pChange->m_iCRNumber: %d!\n", i, pChange->getLocalRev()));

						// undo the change locally
						m_pDoc->undoCmd(1);

						// fix up the positions on the change stack
						for (UT_sint32 j = i+1; j < pAdjusts->getItemCount(); j++)
						{
							ChangeAdjust* pC = pAdjusts->getNthItem(j);
							if (pC)
							{
								UT_DEBUGMSG(("Looking at fixing up the position of change pos %d\n", j));
								if (pChange->getLocalPos() < pC->getLocalPos())
								{
									UT_DEBUGMSG(("Adjusting change pos %d from m_iDocPos: %d to m_iDocPos: %d\n", j, pC->getLocalPos(), pC->getLocalPos() - pChange->getLocalAdjust()));
									pC->setLocalPos(pC->getLocalPos() - pChange->getLocalAdjust());
								}
								else
                                {
									UT_DEBUGMSG(("No need to adjust change pos %d\n", j));
                                }
							}
							else
                            {
								UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
                            }
						}
						
						// kill off the item
						pAdjusts->deleteNthItem(i);
						delete pChange;
					}
					else
                    {
						UT_DEBUGMSG(("Skipping undo of remote change\n"));
                    }
				}
				else
					break;
			}
			else
            {
				UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
            }
		}

		m_pAbiCollab->setIsReverting(false); // unmask all changes in the exporter

		UT_DEBUGMSG(("Pre-Acknowledging revert of revision %d\n", iLocalRev));
		// send the revert acknowledgement command to the session owner
		RevertAckSessionPacket rasp(m_pAbiCollab->getSessionId(), m_pDoc->getOrigDocUUIDString(), iLocalRev);
		m_pAbiCollab->push(&rasp, pCollaborator);

		m_iAlreadyRevertedRevs.push_back(iLocalRev);	
		
		return true;
	}
}
void AccountHandler::_handlePacket(Packet* packet, BuddyPtr buddy)
{
	// packet and buddy must always be set
	UT_return_if_fail(packet);
	UT_return_if_fail(buddy);
	
	// as must the session manager
	AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager();
	UT_return_if_fail(pManager);
	
	// manager didn't handle it, see what we can do
	switch (packet->getClassType()) 
	{			
		case PCT_JoinSessionRequestEvent:
		{
			JoinSessionRequestEvent* jse = static_cast<JoinSessionRequestEvent*>(packet);
			
			// lookup session
			AbiCollab* pSession = pManager->getSessionFromSessionId(jse->getSessionId());
			UT_return_if_fail(pSession);

            // check if this buddy is allowed to access this document
            // TODO: this should be done for every session packet, not just join session packets
            if (!hasAccess(pSession->getAcl(), buddy))
            {
                // we should only reach this point if someone is brute forcing trying
                // out session IDs while not being on the ACL. Ban this uses.
                UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
                return;
            }
		
			// lookup exporter
			ABI_Collab_Export* pExport = pSession->getExport();
			UT_return_if_fail(pExport);
			
			// lookup adjusts
			const UT_GenericVector<ChangeAdjust *>* pExpAdjusts = pExport->getAdjusts();
			UT_return_if_fail(pExpAdjusts);
		
			PD_Document* pDoc = pSession->getDocument();

			// add this author to the document if we don't recognize him
			UT_sint32 iAuthorId = -1;
			UT_UTF8String buddyDescriptor = buddy->getDescriptor();
			UT_GenericVector<pp_Author*> authors = pDoc->getAuthors();
			UT_DEBUGMSG(("Scanning %d authors to see if we recognize this buddy\n", authors.getItemCount()));
			for (UT_sint32 i = 0; i < authors.getItemCount(); i++)
			{
				pp_Author* pAuthor = authors.getNthItem(i);
				UT_continue_if_fail(pAuthor);

				const gchar* szDescriptor = NULL;
				pAuthor->getProperty("abicollab-descriptor", szDescriptor);
				if (!szDescriptor)
					continue;

				if (buddyDescriptor != szDescriptor)
					continue;

				// yay, we know this author!
				iAuthorId = pAuthor->getAuthorInt();
				UT_DEBUGMSG(("Found known author with descriptior %s, id %d!\n", buddyDescriptor.utf8_str(), iAuthorId));
				break;
			}
			
			if (iAuthorId == -1)
			{
				// we don't know this author yet, create a new author object for him
				iAuthorId = pDoc->findFirstFreeAuthorInt();
				pp_Author * pA = pDoc->addAuthor(iAuthorId);
				PP_AttrProp * pPA = pA->getAttrProp();
				pPA->setProperty("abicollab-descriptor", buddyDescriptor.utf8_str());
				pDoc->sendAddAuthorCR(pA);
				UT_DEBUGMSG(("Added a new author to the documument with descriptor %s, id %d\n", buddyDescriptor.utf8_str(), iAuthorId));
			}
			
			// serialize entire document into string
			JoinSessionRequestResponseEvent jsre(jse->getSessionId(), iAuthorId);
			if (AbiCollabSessionManager::serializeDocument(pDoc, jsre.m_sZABW, false /* no base64 */) == UT_OK)
			{
				// set more document properties
				jsre.m_iRev = pDoc->getCRNumber();
				jsre.m_sDocumentId = pDoc->getDocUUIDString();
				if (pDoc->getFilename())
					jsre.m_sDocumentName = UT_go_basename_from_uri(pDoc->getFilename());
				
				// send to buddy!
				send(&jsre, buddy);
				
				// add this buddy to the collaboration session
				pSession->addCollaborator(buddy);
			}
			break;
		}
		
		case PCT_JoinSessionRequestResponseEvent:
		{
			JoinSessionRequestResponseEvent* jsre = static_cast<JoinSessionRequestResponseEvent*>( packet );
			PD_Document* pDoc = 0;
			if (AbiCollabSessionManager::deserializeDocument(&pDoc, jsre->m_sZABW, false) == UT_OK)
			{
				if (pDoc)
				{
					// NOTE: we could adopt the same document name here, but i'd
					// rather not at the moment - MARCM
					pDoc->forceDirty();
					if (jsre->m_sDocumentName.size() > 0)
					{
						gchar* fname = g_strdup(jsre->m_sDocumentName.utf8_str());
						pDoc->setFilename(fname);
					}
					// The default ownership when joining is FALSE, as that seems 
					// to make sense for the generic case. The person sharing the 
					// document by default owns the document (and is thus allowed
					// to modify the ACL).
					pManager->joinSession(jsre->getSessionId(), pDoc, jsre->m_sDocumentId, jsre->m_iRev, jsre->getAuthorId(), buddy, this, false, NULL);
				}
				else 
				{
					UT_DEBUGMSG(("AccountHandler::_handlePacket() - deserializing document failed!\n"));
				}
			}
			break;
		}
		
		case PCT_GetSessionsEvent:
		{
			GetSessionsResponseEvent gsre;
			const UT_GenericVector<AbiCollab *> sessions = pManager->getSessions();
			for (UT_sint32 i = 0; i < sessions.getItemCount(); i++)
			{
				AbiCollab* pSession = sessions.getNthItem(i);
				if (pSession && pSession->isLocallyControlled())
				{
                    // check if the buddy has access to this session
                    if (!hasAccess(pSession->getAcl(), buddy))
                    {
                        UT_DEBUGMSG(("Buddy %s denied access to session %s by ALC\n", buddy->getDescriptor(true).utf8_str(), pSession->getSessionId().utf8_str()));
                        continue;
                    }

					const PD_Document * pDoc = pSession->getDocument();
                    UT_continue_if_fail(pDoc);

                    // determine name
					UT_UTF8String documentBaseName;
					if (pDoc->getFilename())
						documentBaseName = UT_go_basename_from_uri(pDoc->getFilename());
					// set session info
					gsre.m_Sessions[ pSession->getSessionId() ] = documentBaseName;
				}
			}
			send(&gsre, buddy);
			break;
		}
		
		case PCT_GetSessionsResponseEvent:
		{
			GetSessionsResponseEvent* gsre = static_cast<GetSessionsResponseEvent*>( packet );
			UT_GenericVector<DocHandle*> vDocHandles;
			for (std::map<UT_UTF8String,UT_UTF8String>::iterator it=gsre->m_Sessions.begin(); it!=gsre->m_Sessions.end(); ++it) {
				DocHandle* pDocHandle = new DocHandle((*it).first, (*it).second);
				vDocHandles.addItem(pDocHandle);
			}
			pManager->setDocumentHandles(buddy, vDocHandles);
			break;
		}
		
		default:
		{
			UT_DEBUGMSG(("Unhandled packet class: 0x%x\n", packet->getClassType()));
			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
			break;
		}
	}
}
Exemplo n.º 30
0
bool pt_PieceTable::_realInsertObject(PT_DocPosition dpos,
									PTObjectType pto,
									const gchar ** attributes,
									const gchar ** properties )
{

	// dpos == 1 seems to be generally bad. - plam
	// I'm curious about how often it happens.  Please mail me if it does!
	UT_ASSERT_HARMLESS(dpos > 1);

	// TODO currently we force the caller to pass in the attr/prop.
	// TODO this is probably a good thing for Images, but might be
	// TODO bogus for things like Fields.

	UT_return_val_if_fail (m_pts==PTS_Editing,false);

	// store the attributes and properties and get an index to them.
	UT_UTF8String sProps;
	UT_sint32 i = 0;
	sProps.clear();
	if(properties != NULL)
	{
	    for(i=0;(properties[i] != NULL);i+=2)
	    {
		UT_DEBUGMSG(("Object: szProps = |%s| \n",properties[i]));
		sProps +=properties[i];
		sProps += ":";
		sProps += properties[i+1];
		if(properties[i+2] != NULL)
		{
		    sProps += ";";
		}
	    }
	}
	UT_GenericVector<const gchar*>  Atts;
	Atts.clear();
	if(attributes)
	{
		for(i=0; attributes[i] != 0; i++)
		{
		    Atts.addItem(attributes[i]);
		}
	}
	if(sProps.size() > 0)
	{
	    Atts.addItem("props");
	    Atts.addItem(sProps.utf8_str());
	}
	PT_AttrPropIndex indexAP;
	if (!m_varset.storeAP(&Atts,&indexAP))
		return false;

	// get the fragment at the given document position.

	pf_Frag * pf = NULL;
	PT_BlockOffset fragOffset = 0;
	bool bFound = getFragFromPosition(dpos,&pf,&fragOffset);
	UT_return_val_if_fail (bFound,false);

	pf_Frag_Strux * pfs = NULL;
	bool bFoundStrux = _getStruxFromFrag(pf,&pfs);
	UT_return_val_if_fail (bFoundStrux,false);
	if(isEndFootnote((pf_Frag *) pfs))
	{
		bFoundStrux = _getStruxFromFragSkip((pf_Frag *)pfs,&pfs);
	}
	UT_return_val_if_fail (bFoundStrux,false);
	PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pf) + fragOffset;
    pf_Frag_Object * pfo = NULL;
	if (!_insertObject(pf,fragOffset,pto,indexAP,pfo))
		return false;

	// create a change record, add it to the history, and notify
	// anyone listening.

	PX_ChangeRecord_Object * pcr
		= new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_InsertObject,
									 dpos,indexAP,pfo->getXID(),pto,blockOffset,
                                     pfo->getField(),reinterpret_cast<PL_ObjectHandle>(pfo));
	UT_return_val_if_fail (pcr,false);

	m_history.addChangeRecord(pcr);
	m_pDocument->notifyListeners(pfs,pcr);

	return true;
}