/*! Do not use this function inside loops, used the other enumStyles() instead !!! */ bool pt_PieceTable::enumStyles(UT_uint32 k, const char ** pszName, const PD_Style ** ppStyle) const { // return the kth style. UT_uint32 kLimit = m_hashStyles.size(); if (k >= kLimit) return false; UT_GenericVector<PD_Style*> * vStyle = m_hashStyles.enumerate() ; //vStyle->qsort(compareStyleNames); PD_Style * pStyle = vStyle->getNthItem(k); UT_return_val_if_fail (pStyle,false); if (ppStyle) { *ppStyle = pStyle; } if (pszName) { *pszName = pStyle->getName(); } UT_ASSERT_HARMLESS(*pszName); delete vStyle; return true; }
static const gchar * s_evalProperty (const PP_Property * pProp, const PP_AttrProp * pAttrProp, const PD_Document * pDoc, bool bExpandStyles) { const gchar * szValue = NULL; if (pAttrProp->getProperty (pProp->getName(), szValue)) { return szValue; } if (!bExpandStyles) return NULL; PD_Style * pStyle = _getStyle (pAttrProp, pDoc); int i = 0; while (pStyle && (i < pp_BASEDON_DEPTH_LIMIT)) { if (pStyle->getProperty (pProp->getName (), szValue)) { return szValue; } pStyle = pStyle->getBasedOn (); i++; } return NULL; }
/*! \fn bool PP_AttrProp::explodeStyle(const PD_Document * pDoc, bool bOverwrite) \brief This function transfers attributes and properties defined in style into the AP. \param bOverwrite indicates what happens if the property/attribute is already present. If false \ (default) the style definition is ignored; if true the style value overrides the present value. */ bool PP_AttrProp::explodeStyle(const PD_Document * pDoc, bool bOverwrite) { UT_return_val_if_fail(pDoc,false); // expand style if present const gchar * pszStyle = NULL; if(getAttribute(PT_STYLE_ATTRIBUTE_NAME, pszStyle)) { PD_Style * pStyle = NULL; if(pszStyle && (strcmp(pszStyle, "None") != 0) && pDoc->getStyle(pszStyle,&pStyle)) { UT_Vector vAttrs; UT_Vector vProps; UT_sint32 i; pStyle->getAllAttributes(&vAttrs, 100); pStyle->getAllProperties(&vProps, 100); for(i = 0; i < vProps.getItemCount(); i += 2) { const gchar * pName = (const gchar *)vProps.getNthItem(i); const gchar * pValue = (const gchar *)vProps.getNthItem(i+1); const gchar * p; bool bSet = bOverwrite || !getProperty(pName, p); if(bSet) setProperty(pName, pValue); } // attributes are more complicated, because there are some style attributes that must // not be transferred to the generic AP for(i = 0; i < vAttrs.getItemCount(); i += 2) { const gchar * pName = (const gchar *)vAttrs.getNthItem(i); if(!pName || !strcmp(pName, "type") || !strcmp(pName, "name") || !strcmp(pName, "basedon") || !strcmp(pName, "followedby") || !strcmp(pName, "props")) { continue; } const gchar * pValue = (const gchar *)vAttrs.getNthItem(i+1); const gchar * p; bool bSet = bOverwrite || !getAttribute(pName, p); if(bSet) setAttribute(pName, pValue); } } } return true; }
bool pt_PieceTable::appendStyle(const gchar ** attributes) { // this function can only be called while loading the document. //UT_ASSERT(m_pts==PTS_Loading); // first, store the attributes and properties and get an index to them. PT_AttrPropIndex indexAP; if (!m_varset.storeAP(attributes,&indexAP)) return false; // verify unique name UT_ASSERT_HARMLESS(sizeof(char) == sizeof(gchar)); const char * szName = UT_getAttribute(PT_NAME_ATTRIBUTE_NAME, attributes); if (!szName || !*szName) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return true; // silently ignore unnamed styles } UT_DEBUGMSG(("STYLE: Appending style %s \n",szName)); PD_Style * pStyle = NULL; if (getStyle(szName,&pStyle) == true) { // duplicate name UT_return_val_if_fail (pStyle, false); if (pStyle->isUserDefined()) { // already loaded, ignore redefinition UT_DEBUGMSG(("appendStyle[%s]: duplicate definition ignored\n", szName)); return true; } // override builtin definition return pStyle->setIndexAP(indexAP); } else { // this is a new name pStyle = new PD_Style(this, indexAP, szName); UT_DEBUGMSG(("STYLE: Creating new style %s saving in hash \n",szName)); // // TODO: Learn how to use Dom's AbiObject instead of this hack. // Rob asks, as AbiObject is no more, is this still a hack? // if (pStyle) m_hashStyles.insert(szName,pStyle); return true; } }
bool pt_PieceTable::removeStyle (const gchar * szName) { UT_return_val_if_fail (szName, false); UT_ASSERT_HARMLESS(sizeof(char) == sizeof(gchar)); UT_DEBUGMSG(("DOM: remove the style, maybe recode the hash-table\n")); PD_Style * pStyle; if (getStyle(szName,&pStyle)) { if (!pStyle->isUserDefined()) return false; // can't destroy a builtin style delete pStyle; m_hashStyles.remove (szName, NULL); return true; } return false; }
UT_Error IE_Exp_OpenXML_Listener::addDocumentStyles() { UT_Error err = UT_OK; const PP_AttrProp * pAP = NULL; const gchar* styleName = NULL; const gchar* basedOn = NULL; const gchar* followedBy = NULL; const gchar* propertyName = NULL; const gchar* propertyValue = NULL; PT_AttrPropIndex api = pdoc->getAttrPropIndex(); bool bHaveProp = pdoc->getAttrProp(api, &pAP); if(!bHaveProp || !pAP) return UT_OK; const PD_Style* pStyle = NULL; size_t styleCount = pdoc->getStyleCount(); size_t k; for(k=0; k<styleCount; k++) { if(!pdoc->enumStyles(k, &styleName, &pStyle)) continue; if(!pStyle) continue; OXML_Style* style = new OXML_Style(styleName, styleName); OXML_SharedStyle shared_style(style); PD_Style* basedOnStyle = pStyle->getBasedOn(); if(basedOnStyle) { basedOn = basedOnStyle->getName(); style->setBasedOn(basedOn); } PD_Style* followedByStyle = pStyle->getFollowedBy(); if(followedByStyle) { followedBy = followedByStyle->getName(); style->setFollowedBy(followedBy); } err = document->addStyle(shared_style); if(err != UT_OK) return err; size_t propCount = pStyle->getPropertyCount(); size_t i; for(i=0; i<propCount; i++) { if(!pStyle->getNthProperty(i, propertyName, propertyValue)) continue; err = style->setProperty(propertyName, propertyValue); if(err != UT_OK) { UT_DEBUGMSG(("FRT:ERROR, Setting Document Style Property %s=%s failed\n", propertyName, propertyValue)); return err; } } } return UT_OK; }
BOOL AP_Win32Dialog_Styles::_onInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) { XAP_Win32App * app = static_cast<XAP_Win32App *> (m_pApp); UT_return_val_if_fail (app,0); const XAP_StringSet * pSS = m_pApp->getStringSet(); WCHAR szTemp[20]; GetWindowTextW(hWnd, szTemp, 20 ); m_hDlg=hWnd; // Regular dialog box if( lstrcmpW(szTemp, L"Styles") == 0 ) { setDialogTitle (pSS->getValue(AP_STRING_ID_DLG_Styles_StylesTitle)); // localize controls _DS(STYLES_TOP_TEXT_LIST, DLG_Styles_List); _DS(STYLES_TOP_TEXT_PARAGRAPH_PREVIEW, DLG_Styles_ParaPrev); _DS(STYLES_TOP_TEXT_CHARACTER_PREVIEW, DLG_Styles_CharPrev); _DS(STYLES_TOP_TEXT_DESCRIPTION, DLG_Styles_Description); _DS(STYLES_TOP_BUTTON_DELETE, DLG_Styles_Delete); _DS(STYLES_TOP_BUTTON_MODIFY, DLG_Styles_Modify); _DS(STYLES_TOP_BUTTON_NEW, DLG_Styles_New); _DS(STYLES_TOP_TEXT_AVAILABLE, DLG_Styles_Available); // "Available Styles" GROUPBOX _DSX(STYLES_TOP_BUTTON_APPLY, DLG_Apply); _DSX(STYLES_TOP_BUTTON_CLOSE, DLG_Close); // Set the list combo. _win32Dialog.addItemToCombo(AP_RID_DIALOG_STYLES_TOP_COMBO_LIST, pSS->getValue (AP_STRING_ID_DLG_Styles_LBL_InUse)); _win32Dialog.addItemToCombo(AP_RID_DIALOG_STYLES_TOP_COMBO_LIST, pSS->getValue(AP_STRING_ID_DLG_Styles_LBL_All)); _win32Dialog.addItemToCombo(AP_RID_DIALOG_STYLES_TOP_COMBO_LIST, pSS->getValue(AP_STRING_ID_DLG_Styles_LBL_UserDefined)); _win32Dialog.selectComboItem(AP_RID_DIALOG_STYLES_TOP_COMBO_LIST, (int)m_whichType); // Create a preview windows. HWND hwndChild = GetDlgItem(hWnd, AP_RID_DIALOG_STYLES_TOP_TEXT_PARAGRAPH_PREVIEW); m_pParaPreviewWidget = new XAP_Win32PreviewWidget(static_cast<XAP_Win32App *>(m_pApp), hwndChild, 0); UT_uint32 w,h; m_pParaPreviewWidget->getWindowSize(&w,&h); _createParaPreviewFromGC(m_pParaPreviewWidget->getGraphics(), w, h); m_pParaPreviewWidget->setPreview(m_pParaPreview); hwndChild = GetDlgItem(hWnd, AP_RID_DIALOG_STYLES_TOP_TEXT_CHARACTER_PREVIEW); m_pCharPreviewWidget = new XAP_Win32PreviewWidget(static_cast<XAP_Win32App *>(m_pApp), hwndChild, 0); m_pCharPreviewWidget->getWindowSize(&w,&h); _createCharPreviewFromGC(m_pCharPreviewWidget->getGraphics(), w, h); m_pCharPreviewWidget->setPreview(m_pCharPreview); _populateWindowData(); } // This is either the new or Modify sub dialog of styles else { _win32DialogNewModify.setHandle(hWnd); // Localize the controls Labels etc... setWindowText(hWnd, pSS->getValue( (m_bisNewStyle) ? AP_STRING_ID_DLG_Styles_NewTitle : AP_STRING_ID_DLG_Styles_ModifyTitle )); #define _DS(c,s) setDlgItemText(hWnd, AP_RID_DIALOG_##c,pSS->getValue(AP_STRING_ID_##s)) #define _DSX(c,s) setDlgItemText(hWnd, AP_RID_DIALOG_##c,pSS->getValue(XAP_STRING_ID_##s)) _DS(STYLES_NEWMODIFY_LBL_NAME, DLG_Styles_ModifyName); _DS(STYLES_NEWMODIFY_LBL_BASEDON, DLG_Styles_ModifyBasedOn); _DS(STYLES_NEWMODIFY_LBL_TYPE, DLG_Styles_ModifyType); _DS(STYLES_NEWMODIFY_LBL_FOLLOWPARA, DLG_Styles_ModifyFollowing); _DS(STYLES_NEWMODIFY_LBL_REMOVE, DLG_Styles_RemoveLab); _DS(STYLES_NEWMODIFY_GBX_PREVIEW, DLG_Styles_ModifyPreview); _DS(STYLES_NEWMODIFY_GBX_DESC, DLG_Styles_ModifyDescription); _DS(STYLES_NEWMODIFY_BTN_REMOVE, DLG_Styles_RemoveButton); _DS(STYLES_NEWMODIFY_BTN_SHORTCUT, DLG_Styles_ModifyShortCut); _DSX(STYLES_NEWMODIFY_BTN_OK, DLG_OK); _DSX(STYLES_NEWMODIFY_BTN_CANCEL, DLG_Cancel); #undef _DSX #undef _DS // Changes basic controls based upon either New or Modify Dialog _win32DialogNewModify.showControl( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_TYPE , (m_bisNewStyle) ? SW_HIDE : SW_SHOW ); _win32DialogNewModify.showControl( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_TYPE , (m_bisNewStyle) ? SW_SHOW : SW_HIDE ); // Initialize the controls with appropriate data size_t nStyles = getDoc()->getStyleCount(); const char * name = NULL; const char * pLocalised = NULL; const PD_Style * pcStyle = NULL; int nIndex; UT_Win32LocaleString str; UT_UTF8String utf8; UT_GenericVector<PD_Style*> * pStyles = NULL; getDoc()->enumStyles(pStyles); UT_return_val_if_fail( pStyles, FALSE ); for (UT_uint32 i = 0; i < nStyles; i++) { pcStyle = pStyles->getNthItem(i); UT_return_val_if_fail( pcStyle, FALSE ); name = pcStyle->getName(); pt_PieceTable::s_getLocalisedStyleName(name, utf8); pLocalised = utf8.utf8_str(); nIndex = _win32DialogNewModify.addItemToCombo(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, pLocalised); _win32DialogNewModify.setComboDataItem(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, nIndex, i); nIndex = _win32DialogNewModify.addItemToCombo(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, pLocalised); _win32DialogNewModify.setComboDataItem(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, nIndex, i); } delete pStyles; // Strings (not styles names) const char* pDefCurrent = pSS->getValue(AP_STRING_ID_DLG_Styles_DefCurrent); const char* pDefNone = pSS->getValue(AP_STRING_ID_DLG_Styles_DefNone); nIndex = _win32DialogNewModify.addItemToCombo( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, pDefCurrent ); _win32DialogNewModify.setComboDataItem(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, nIndex, (DWORD)-1); nIndex = _win32DialogNewModify.addItemToCombo( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, pDefNone); _win32DialogNewModify.setComboDataItem(AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, nIndex, (DWORD)-1); if( m_bisNewStyle ) { const char* p = pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyParagraph); _win32DialogNewModify.addItemToCombo( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_TYPE, p ); p = pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyCharacter); _win32DialogNewModify.addItemToCombo( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_TYPE, p); // Set the Default syltes: none, default current UT_sint32 result; str.fromUTF8(pSS->getValue(AP_STRING_ID_DLG_Styles_DefNone)); result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, CB_FINDSTRING, -1, (LPARAM) str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, result ); str.fromUTF8(pSS->getValue(AP_STRING_ID_DLG_Styles_DefCurrent)); result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, CB_FINDSTRING, -1, (LPARAM) str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, result ); str.fromUTF8(pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyParagraph)); result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_TYPE, CB_FINDSTRING, -1, (LPARAM) str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_TYPE, result ); eventBasedOn(); eventFollowedBy(); eventStyleType(); fillVecFromCurrentPoint(); } else { const char * szCurrentStyle = NULL; const char * szBasedOn = NULL; const char * szFollowedBy = NULL; const char * pLocalised = NULL; PD_Style * pStyle = NULL; PD_Style * pBasedOnStyle = NULL; PD_Style * pFollowedByStyle = NULL; szCurrentStyle = m_selectedStyle.c_str(); pt_PieceTable::s_getLocalisedStyleName(szCurrentStyle, utf8); pLocalised = utf8.utf8_str(); _win32DialogNewModify.setControlText( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_NAME, pLocalised); if(szCurrentStyle) getDoc()->getStyle(szCurrentStyle,&pStyle); if(!pStyle) { XAP_Frame * pFrame = getFrame(); pFrame->showMessageBox( pSS->getValue(AP_STRING_ID_DLG_Styles_ErrNoStyle), XAP_Dialog_MessageBox::b_O, XAP_Dialog_MessageBox::a_OK); m_answer = AP_Dialog_Styles::a_CANCEL; return false; } // // Valid style get the Based On and followed by values // pBasedOnStyle = pStyle->getBasedOn(); pFollowedByStyle = pStyle->getFollowedBy(); size_t nStyles = getDoc()->getStyleCount(); const char * name = NULL; const PD_Style * pcStyle = NULL; UT_GenericVector<PD_Style*> * pStyles = NULL; getDoc()->enumStyles(pStyles); UT_return_val_if_fail( pStyles, FALSE ); for (UT_uint32 i = 0; i < nStyles; i++) { pcStyle = pStyles->getNthItem(i); UT_return_val_if_fail( pcStyle, FALSE ); name = pcStyle->getName(); if(pBasedOnStyle && pcStyle == pBasedOnStyle) { szBasedOn = name; } if(pFollowedByStyle && pcStyle == pFollowedByStyle) { szFollowedBy = name; } } delete pStyles; if(pBasedOnStyle != NULL) { pt_PieceTable::s_getLocalisedStyleName(szBasedOn, utf8); pLocalised = utf8.utf8_str(); str = AP_Win32App::s_fromUTF8ToWinLocale(pLocalised); UT_uint32 result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, CB_FINDSTRING, -1, (LPARAM)str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, result ); } else { // Not a style name str.fromUTF8(pSS->getValue(AP_STRING_ID_DLG_Styles_DefNone)); UT_uint32 result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, CB_FINDSTRING, -1, (LPARAM) str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_BASEDON, result ); } if(pFollowedByStyle != NULL) { pt_PieceTable::s_getLocalisedStyleName(szFollowedBy, utf8); pLocalised = utf8.utf8_str(); str = AP_Win32App::s_fromUTF8ToWinLocale(pLocalised); UT_uint32 result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, CB_FINDSTRING, -1, (LPARAM)str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, result ); } else { pt_PieceTable::s_getLocalisedStyleName(pSS->getValue(AP_STRING_ID_DLG_Styles_DefCurrent), utf8); pLocalised = utf8.utf8_str(); str = AP_Win32App::s_fromUTF8ToWinLocale(pLocalised); UT_uint32 result = SendDlgItemMessageW(hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, CB_FINDSTRING, -1, (LPARAM) str.c_str()); _win32DialogNewModify.selectComboItem( AP_RID_DIALOG_STYLES_NEWMODIFY_CBX_FOLLOWPARA, result ); } if(strstr(getAttsVal("type"),"P") != 0) { _win32DialogNewModify.setControlText( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_TYPE, pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyParagraph) ); } else { _win32DialogNewModify.setControlText( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_TYPE, pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyCharacter) ); } // Disable for editing top controls in Modify Dialog _win32DialogNewModify.enableControl( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_NAME, false ); _win32DialogNewModify.enableControl( AP_RID_DIALOG_STYLES_NEWMODIFY_EBX_TYPE, false ); fillVecWithProps(szCurrentStyle,true); } // Generate the Preview class HWND hwndChild = GetDlgItem( hWnd, AP_RID_DIALOG_STYLES_NEWMODIFY_CTL_PREVIEW ); m_pAbiPreviewWidget = new XAP_Win32PreviewWidget(static_cast<XAP_Win32App *>(m_pApp), hwndChild, 0); UT_uint32 w,h; m_pAbiPreviewWidget->getWindowSize(&w,&h); _createAbiPreviewFromGC(m_pAbiPreviewWidget->getGraphics(), w, h); _populateAbiPreview(m_bisNewStyle); m_pAbiPreviewWidget->setPreview(m_pAbiPreview); rebuildDeleteProps(); _populatePreviews(true); } XAP_Win32DialogHelper::s_centerDialog(hWnd); return 1; // 1 == we did not call SetFocus() }
bool pt_PieceTable::_realChangeSpanFmt(PTChangeFmt ptc, PT_DocPosition dpos1, PT_DocPosition dpos2, const gchar ** attributes, const gchar ** properties, bool bRevisionDelete) { // apply a span-level formatting change to the given region. UT_return_val_if_fail (m_pts==PTS_Editing,false); _tweakFieldSpan(dpos1,dpos2); // // Deal with case of exactly selecting the endOfFootnote // pf_Frag * pfEndDum = m_fragments.findFirstFragBeforePos(dpos2); if(isEndFootnote(pfEndDum)) { if(dpos2 > dpos1) { dpos2--; } } // // Deal with addStyle // bool bApplyStyle = (PTC_AddStyle == ptc); const gchar ** sProps = NULL; const gchar ** lProps = properties; if(bApplyStyle) { // // OK for styles we expand out all defined properties including BasedOn styles // Then we use these to eliminate any specfic properties in the current strux // Then properties in the current strux will resolve to those defined in the // style (they exist there) to specifc values in strux (if not overridden by // the style) then finally to default value. // const gchar * szStyle = UT_getAttribute(PT_STYLE_ATTRIBUTE_NAME,attributes); PD_Style * pStyle = NULL; UT_return_val_if_fail (szStyle,false); getDocument()->getStyle(szStyle,&pStyle); UT_return_val_if_fail (pStyle,false); UT_Vector vProps; // // Get the vector of properties // pStyle->getAllProperties(&vProps,0); // // Finally make the const gchar * array of properties // UT_uint32 countp = vProps.getItemCount() + 1; sProps = (const gchar **) UT_calloc(countp, sizeof(gchar *)); countp--; UT_uint32 i; for(i=0; i<countp; i++) { sProps[i] = (const gchar *) vProps.getNthItem(i); } sProps[i] = NULL; lProps = sProps; } if (dpos1 == dpos2) // if length of change is zero, then we have a toggle format. { UT_uint32 startUndoPos = m_history.getUndoPos(); bool bRes = _insertFmtMarkFragWithNotify(ptc,dpos1,attributes,lProps); UT_uint32 endUndoPos = m_history.getUndoPos(); // Won't be a persistant change if it's just a toggle PX_ChangeRecord *pcr=0; m_history.getUndo(&pcr,true); if (pcr && (startUndoPos != endUndoPos) ) { UT_DEBUGMSG(("Setting persistance of change to false\n")); pcr->setPersistance(false); m_history.setSavePosition(m_history.getSavePosition()+1); } if(bApplyStyle) { FREEP(sProps); } return bRes; } UT_return_val_if_fail (dpos1 < dpos2,false); bool bHaveAttributes, bHaveProperties; bHaveAttributes = (attributes && *attributes); bHaveProperties = (lProps && *lProps); pf_Frag * pf_First; pf_Frag * pf_End; PT_BlockOffset fragOffset_First; PT_BlockOffset fragOffset_End; bool bFound; bFound = getFragsFromPositions(dpos1,dpos2,&pf_First,&fragOffset_First,&pf_End,&fragOffset_End); UT_return_val_if_fail (bFound, false); #if 0 { pf_Frag * pf1, * pf2; PT_BlockOffset fo1, fo2; bool bFound1 = getFragFromPosition(dpos1,&pf1,&fo1); bool bFound2 = getFragFromPosition(dpos2,&pf2,&fo2); UT_return_val_if_fail (bFound1 && bFound2, false); UT_return_val_if_fail ((pf1==pf_First) && (fragOffset_First==fo1), false); UT_return_val_if_fail ((pf2==pf_End) && (fragOffset_End==fo2), false); } #endif // see if the amount of text to be changed is completely // contained within a single fragment. if so, we have a // simple change. otherwise, we need to set up a multi-step // change -- it may not actually take more than one step, // but it is too complicated to tell at this point, so we // assume it will and don't worry about it. // // we are in a simple change if the beginning and end are // within the same fragment. // NOTE: if we call beginMultiStepGlob() we ***MUST*** call // NOTE: endMultiStepGlob() before we return -- otherwise, // NOTE: the undo/redo won't be properly bracketed. bool bSimple = (pf_First == pf_End); if (!bSimple) beginMultiStepGlob(); pf_Frag_Strux * pfsContainer = NULL; pf_Frag * pfNewEnd; UT_uint32 fragOffsetNewEnd; UT_uint32 length = dpos2 - dpos1; while (length != 0) { // FIXME: Special check to support a FmtMark at the end of the // document. This is necessary because FmtMarks don't have a // length... See bug 452. if (0 == length && (!pf_First || pf_Frag::PFT_FmtMark != pf_First->getType())) break; UT_return_val_if_fail (dpos1+length==dpos2, false); UT_uint32 lengthInFrag = pf_First->getLength() - fragOffset_First; UT_uint32 lengthThisStep = UT_MIN(lengthInFrag, length); switch (pf_First->getType()) { case pf_Frag::PFT_EndOfDoc: default: UT_DEBUGMSG(("fragment type: %d\n",pf_First->getType())); UT_ASSERT_HARMLESS(0); if(bApplyStyle) { FREEP(sProps); } return false; case pf_Frag::PFT_Strux: { // we are only applying span-level changes, so we ignore strux. // but we still need to update our loop indices. pfNewEnd = pf_First->getNext(); fragOffsetNewEnd = 0; pfsContainer = static_cast<pf_Frag_Strux *> (pf_First); bool bFoundStrux = false; if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux, false); } } break; case pf_Frag::PFT_Text: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeSpanWithNotify(ptc,static_cast<pf_Frag_Text *>(pf_First), fragOffset_First,dpos1,lengthThisStep, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd,bRevisionDelete); UT_return_val_if_fail (bResult,false); } break; case pf_Frag::PFT_Object: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeObjectWithNotify(ptc,static_cast<pf_Frag_Object *>(pf_First), fragOffset_First,dpos1,lengthThisStep, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd,false); UT_return_val_if_fail (bResult,false); } break; case pf_Frag::PFT_FmtMark: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeFmtMarkWithNotify(ptc,static_cast<pf_Frag_FmtMark *>(pf_First), dpos1, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd); UT_return_val_if_fail (bResult,false); } break; } dpos1 += lengthThisStep; length -= lengthThisStep; // since _fmtChange{Span,FmtMark,...}WithNotify(), can delete pf_First, mess with the // fragment list, and does some aggressive coalescing of // fragments, we cannot just do a pf_First->getNext() here. // to advance to the next fragment, we use the *NewEnd variables // that each of the cases routines gave us. pf_First = pfNewEnd; if (!pf_First) length = 0; fragOffset_First = fragOffsetNewEnd; } if(bApplyStyle) { FREEP(sProps); } if (!bSimple) endMultiStepGlob(); return true; }
/*! * Take a packet, interpret it's contents and apply the implied operations on the document. */ bool ABI_Collab_Import::_import(const SessionPacket& packet, UT_sint32 iImportAdjustment, BuddyPtr pCollaborator, bool inGlob) { UT_DEBUGMSG(("ABI_Collab_Import::_import() - packet class type: %d, iImportAdjustment: %d\n", packet.getClassType(), iImportAdjustment)); UT_return_val_if_fail(pCollaborator, false); switch (packet.getClassType()) { case PCT_GlobSessionPacket: { const GlobSessionPacket* gp = static_cast<const GlobSessionPacket*>(&packet); UT_return_val_if_fail(gp->getPackets().size() > 0, false); // store the last seen revision from this collaborator (it is immediately used by the export) m_remoteRevs[pCollaborator] = gp->getRev(); for (UT_uint32 j = 0; j < gp->getPackets().size(); j++) { SessionPacket* pGlobPacket = gp->getPackets()[j]; if (pGlobPacket) { bool res = _import(*pGlobPacket, iImportAdjustment, pCollaborator, true); // yay for recursion :) if (!res) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } } return true; } case PCT_SignalSessionPacket: { const SignalSessionPacket* sp = static_cast<const SignalSessionPacket*>(&packet); m_pDoc->signalListeners(sp->getSignalType()); return true; } case PCT_RevertSessionPacket: { const RevertSessionPacket* rrp = static_cast<const RevertSessionPacket*>(&packet); UT_DEBUGMSG(("Revert packet seen on import for rev: %d\n", rrp->getRev())); if (m_iAlreadyRevertedRevs.size() == 0 || m_iAlreadyRevertedRevs.front() != rrp->getRev()) { UT_DEBUGMSG(("Incoming revert for revision %d, which we didn't detect locally (m_iAlreadyRevertedRev: %d)!\n", rrp->getRev(), m_iAlreadyRevertedRevs.front())); UT_DEBUGMSG(("DOCUMENT OUT OF SYNC DETECTED!!!!\n")); UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return false; } m_iAlreadyRevertedRevs.pop_front(); return true; } case PCT_RevertAckSessionPacket: { UT_DEBUGMSG(("RevertAck packet seen on import for rev: %d\n", static_cast<const RevertAckSessionPacket*>(&packet)->getRev())); // remove this collaborator from our revert ack list; he can play again... for (std::vector<std::pair<BuddyPtr, UT_sint32> >::iterator it = m_revertSet.begin(); it != m_revertSet.end(); it++) { if ((*it).first == pCollaborator) { UT_DEBUGMSG(("Found collaborator %s on our revert ack list with rev %d! Removing him from the list...\n", (*it).first->getDescription().utf8_str(), (*it).second)); UT_ASSERT_HARMLESS((*it).second == static_cast<const RevertAckSessionPacket*>(&packet)->getRev()); m_revertSet.erase(it); return true; } } UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } default: // silly C++ can't switch on ranges if (packet.getClassType() >= _PCT_FirstChangeRecord && packet.getClassType() <= _PCT_LastChangeRecord) { const ChangeRecordSessionPacket* crp = static_cast<const ChangeRecordSessionPacket*>(&packet); UT_DEBUGMSG(("It's safe to import this packet\n")); UT_DEBUGMSG(("For CR number %d requested point %d adjustment %d \n", crp->getRev(), crp->getPos(), iImportAdjustment)); PT_DocPosition pos = static_cast<PT_DocPosition>(crp->getPos() + iImportAdjustment); UT_ASSERT(pos <= getEndOfDoc()); if (!inGlob) { // store the last seen revision from this collaborator (it is immediately used by the export) // NOTE: if this changerecord is part of a glob, then we don't do this; we'll have // already set the revision of the glob itself as the last seen one m_remoteRevs[pCollaborator] = crp->getRev(); } // todo: remove these temp vars PT_DocPosition iPos2 = 0; // process the packet switch(crp->getPXType()) { case PX_ChangeRecord::PXT_GlobMarker: { UT_DEBUGMSG(("Found GLOB marker (ignoring)\n")); return true; } case PX_ChangeRecord::PXT_InsertSpan: { const InsertSpan_ChangeRecordSessionPacket* icrsp = static_cast<const InsertSpan_ChangeRecordSessionPacket*>( crp ); UT_UCS4String UCSChars = const_cast<UT_UTF8String&>(icrsp->m_sText).ucs4_str(); // ugly, ucs4_str should be const func! PP_AttrProp attrProp; attrProp.setAttributes(const_cast<const gchar**>(icrsp->getAtts())); attrProp.setProperties(const_cast<const gchar**>(icrsp->getProps())); m_pDoc->insertSpan(pos,UCSChars.ucs4_str(),UCSChars.length(), &attrProp); break; } case PX_ChangeRecord::PXT_DeleteSpan: { iPos2 = pos + crp->getLength(); PP_AttrProp *p_AttrProp_Before = NULL; UT_uint32 icnt = 0; m_pDoc->deleteSpan(pos,iPos2,p_AttrProp_Before,icnt,true); break; } case PX_ChangeRecord::PXT_ChangeSpan: { const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp ); gchar** szAtts = pcrsp->getAtts(); gchar** szProps = pcrsp->getProps(); iPos2 = pos + pcrsp->getLength(); if((szProps == NULL) && (szAtts == NULL)) { // // This happens if we remove all formats // we have to handle this seperately // // Get style of containing block // pf_Frag_Strux* sdh = NULL; m_pDoc->getStruxOfTypeFromPosition(pos,PTX_Block,&sdh); if(!sdh) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } PD_Style * pStyle = m_pDoc->getStyleFromSDH(sdh); if(!pStyle) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } const gchar * szName = pStyle->getName(); const gchar * atts[3] = {PT_STYLE_ATTRIBUTE_NAME,szName,NULL}; m_pDoc->changeSpanFmt(PTC_SetExactly, pos, iPos2, atts, const_cast<const gchar**>( szProps ) ); } else { m_pDoc->changeSpanFmt(PTC_SetExactly, pos, iPos2, const_cast<const gchar**>(szAtts), const_cast<const gchar**>( szProps ) ); } break; } case PX_ChangeRecord::PXT_InsertStrux: { const ChangeStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const ChangeStrux_ChangeRecordSessionPacket*>( crp ); PTStruxType pts = pcrsp->m_eStruxType; gchar** szAtts = pcrsp->getAtts(); gchar** szProps = pcrsp->getProps(); if((szProps != NULL) || (szAtts != NULL)) { m_pDoc->insertStrux( pos, pts, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ) ); } else { m_pDoc->insertStrux(pos, pts); } break; } case PX_ChangeRecord::PXT_DeleteStrux: { const DeleteStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const DeleteStrux_ChangeRecordSessionPacket*>( crp ); PTStruxType pts = pcrsp->m_eStruxType; m_pDoc->deleteStrux(pos,pts,true); break; } case PX_ChangeRecord::PXT_ChangeStrux: { const ChangeStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const ChangeStrux_ChangeRecordSessionPacket*>( crp ); PTStruxType pts = pcrsp->m_eStruxType; gchar** szAtts = pcrsp->getAtts(); gchar** szProps = pcrsp->getProps(); UT_return_val_if_fail(szProps != NULL || szAtts != NULL, false); UT_DEBUGMSG(("Executing ChangeStrux pos= %d \n",pos)); m_pDoc->changeStruxFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ), pts); // TODO: this mask is waaaay to generic XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); if (pFrame) { FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView()); if (pView) pView->notifyListeners(AV_CHG_TYPING | AV_CHG_FMTCHAR | AV_CHG_FMTBLOCK | AV_CHG_PAGECOUNT | AV_CHG_FMTSTYLE ); } break; } case PX_ChangeRecord::PXT_InsertObject: { const Object_ChangeRecordSessionPacket* ocrsp = static_cast<const Object_ChangeRecordSessionPacket*>( crp ); PTObjectType pto = ocrsp->getObjectType(); gchar** szAtts = ocrsp->getAtts(); gchar** szProps = ocrsp->getProps(); if((szProps == NULL) && (szAtts == NULL)) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } m_pDoc->insertObject(pos, pto, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ) ); break; } case PX_ChangeRecord::PXT_DeleteObject: { iPos2 = pos + 1; PP_AttrProp *p_AttrProp_Before = NULL; UT_uint32 icnt = 0; m_pDoc->deleteSpan(pos, iPos2, p_AttrProp_Before, icnt, true); break; } case PX_ChangeRecord::PXT_ChangeObject: { const Object_ChangeRecordSessionPacket* ccrsp = static_cast<const Object_ChangeRecordSessionPacket*>( crp ); //PTObjectType pto = ccrsp->m_eObjectType; gchar** szAtts = ccrsp->getAtts(); gchar** szProps = ccrsp->getProps(); if ((szProps == NULL) && (szAtts == NULL)) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos + 1, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps )); break; } case PX_ChangeRecord::PXT_ChangeDocRDF: { // down cast crp to get dcrp const RDF_ChangeRecordSessionPacket* dcrp = static_cast<const RDF_ChangeRecordSessionPacket*>( crp ); gchar** szAtts = dcrp->getAtts(); gchar** szProps = dcrp->getProps(); if ((szProps == NULL) && (szAtts == NULL)) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } { // update the local document RDF to remove // szAtts RDF and then add the szProps RDF m_pDoc->getDocumentRDF()->handleCollabEvent( szAtts, szProps ); } break; } case PX_ChangeRecord::PXT_InsertFmtMark: { const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp ); gchar** szAtts = pcrsp->getAtts(); gchar** szProps = pcrsp->getProps(); if((szProps == NULL) && (szAtts == NULL)) { // nothing to do here, please move along // NOTE: why does this happen anyway? // This happens when for example when sending over tables: UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } return m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps )); } case PX_ChangeRecord::PXT_DeleteFmtMark: { return m_pDoc->deleteFmtMark(pos); } case PX_ChangeRecord::PXT_ChangeFmtMark: { const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp ); gchar** szAtts = pcrsp->getAtts(); gchar** szProps = pcrsp->getProps(); if ((szProps == NULL) && (szAtts == NULL)) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return false; } return m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps )); } case PX_ChangeRecord::PXT_ChangePoint: { UT_DEBUGMSG(("Change Point CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true, 0); } case PX_ChangeRecord::PXT_ListUpdate: { UT_DEBUGMSG(("ListUpdate CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0); } case PX_ChangeRecord::PXT_StopList: { UT_DEBUGMSG(("StopList CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0); } case PX_ChangeRecord::PXT_UpdateField: { UT_DEBUGMSG(("UpdateFiled CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0); } case PX_ChangeRecord::PXT_RemoveList: { UT_DEBUGMSG(("RemoveList CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0); } case PX_ChangeRecord::PXT_UpdateLayout: { UT_DEBUGMSG(("UpdateLayout CR \n")); return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0); } case PX_ChangeRecord::PXT_CreateDataItem: { const Data_ChangeRecordSessionPacket* dp = static_cast<const Data_ChangeRecordSessionPacket*>( crp ); const char * szNameV = g_strdup(dp->getAttribute(PT_DATAITEM_ATTRIBUTE_NAME)); PD_DataItemHandle pHandle = NULL; std::string sToken = dp->m_bTokenSet ? dp->m_sToken : ""; UT_ByteBuf * pBuf= new UT_ByteBuf(); UT_DEBUGMSG(("PXT_CreateDataItem: append image buffer @ 0x%p, %lu bytes, sToken %s\n", &dp->m_vecData[0], (long unsigned)dp->m_vecData.size(), sToken.c_str())); pBuf->append(reinterpret_cast<const UT_Byte *>( &dp->m_vecData[0] ), dp->m_vecData.size() ); bool res = m_pDoc->createDataItem(szNameV,false,pBuf,sToken,&pHandle); delete pBuf; return res; } case PX_ChangeRecord::PXT_ChangeDocProp: { UT_DEBUGMSG(("ChangeDocProp CR \n")); const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp ); // // Assemble the Attributes for different properties // const gchar** szAtts = const_cast<const gchar **>(pcrsp->getAtts()); const gchar** szProps = const_cast<const gchar **>(pcrsp->getProps()); // // Now direct the document to make the changes // return m_pDoc->changeDocPropeties(szAtts,szProps); } default: { UT_DEBUGMSG(("Unimplemented crp->getPXType(): %d\n", crp->getPXType())); UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); break; } } return true; } else { UT_DEBUGMSG(("ABI_Collab_Import::import called with unhandled packet class type: %d!\n", packet.getClassType())); return false; } break; } return false; }
bool AP_UnixDialog_Styles::_populateModify(void) { const XAP_StringSet * pSS = m_pApp->getStringSet(); // // Don't do any callback while setting up stuff here. // setModifySignalBlocked(true); setModifyDescription( m_curStyleDesc.c_str()); // // Get Style name and put in in the text entry // const char * szCurrentStyle = NULL; UT_UTF8String s; if(!isNew()) { szCurrentStyle= getCurrentStyle(); if(!szCurrentStyle) { // TODO: change me to use a real messagebox pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_ErrNoStyle,s); messageBoxOK( s.utf8_str()); m_answer = AP_Dialog_Styles::a_CANCEL; return false; } gtk_entry_set_text (GTK_ENTRY(m_wStyleNameEntry), getCurrentStyle()); gtk_editable_set_editable(GTK_EDITABLE(m_wStyleNameEntry),FALSE ); } else { gtk_editable_set_editable(GTK_EDITABLE(m_wStyleNameEntry),TRUE ); } // // Next interogate the current style and find the based on and followed by // Styles // const char * szBasedOn = NULL; const char * szFollowedBy = NULL; PD_Style * pBasedOnStyle = NULL; PD_Style * pFollowedByStyle = NULL; if(!isNew()) { PD_Style * pStyle = NULL; if(szCurrentStyle) getDoc()->getStyle(szCurrentStyle,&pStyle); if(!pStyle) { // TODO: do a real error dialog pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_ErrStyleNot,s); messageBoxOK( s.utf8_str()); m_answer = AP_Dialog_Styles::a_CANCEL; return false; } // // Valid style get the Based On and followed by values // pBasedOnStyle = pStyle->getBasedOn(); pFollowedByStyle = pStyle->getFollowedBy(); } // // Next make a glists of all styles and attach them to the BasedOn and FollowedBy // UT_GenericVector<PD_Style*> * pStyles = NULL; getDoc()->enumStyles(pStyles); UT_sint32 nStyles = pStyles->getItemCount(); for (UT_sint32 i = 0; i < nStyles; i++) { const PD_Style * pcStyle = pStyles->getNthItem(i); const char * name = pcStyle->getName(); if(pBasedOnStyle && pcStyle == pBasedOnStyle) { szBasedOn = name; } if(pFollowedByStyle && pcStyle == pFollowedByStyle) szFollowedBy = name; if(szCurrentStyle && strcmp(name,szCurrentStyle) != 0) m_gbasedOnStyles.push_back(name); else if(szCurrentStyle == NULL) m_gbasedOnStyles.push_back(name); m_gfollowedByStyles.push_back(name); } DELETEP(pStyles); m_gfollowedByStyles.sort(); m_gfollowedByStyles.push_back(pSS->getValue(AP_STRING_ID_DLG_Styles_DefCurrent)); m_gbasedOnStyles.sort(); m_gbasedOnStyles.push_back(pSS->getValue(AP_STRING_ID_DLG_Styles_DefNone)); m_gStyleType.push_back(pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyParagraph)); m_gStyleType.push_back(pSS->getValue(AP_STRING_ID_DLG_Styles_ModifyCharacter)); // // Set the popdown list // setComboContent(GTK_COMBO_BOX_TEXT(m_wBasedOnCombo),m_gbasedOnStyles); setComboContent(GTK_COMBO_BOX_TEXT(m_wFollowingCombo),m_gfollowedByStyles); if(isNew()) { setComboContent(GTK_COMBO_BOX_TEXT(m_wStyleTypeCombo),m_gStyleType); } // // OK here we set intial values for the basedOn and followedBy // if(!isNew()) { if(pBasedOnStyle != NULL) gtk_entry_set_text (GTK_ENTRY(m_wBasedOnEntry),szBasedOn); else { pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_DefNone,s); gtk_entry_set_text (GTK_ENTRY(m_wBasedOnEntry), s.utf8_str()); } if(pFollowedByStyle != NULL) gtk_entry_set_text (GTK_ENTRY(m_wFollowingEntry),szFollowedBy); else { pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_DefCurrent,s); gtk_entry_set_text (GTK_ENTRY(m_wFollowingEntry), s.utf8_str()); } const char * pszType = getAttsVal(PT_TYPE_ATTRIBUTE_NAME); if(pszType && strstr(pszType,"P") != 0) { pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_ModifyParagraph,s); gtk_entry_set_text (GTK_ENTRY(m_wStyleTypeEntry),s.utf8_str()); } else { pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_ModifyCharacter,s); gtk_entry_set_text (GTK_ENTRY(m_wStyleTypeEntry),s.utf8_str()); } } else { // // Hardwire defaults for "new" // pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_DefNone,s); gtk_entry_set_text (GTK_ENTRY(m_wBasedOnEntry), s.utf8_str()); pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_DefCurrent,s); gtk_entry_set_text (GTK_ENTRY(m_wFollowingEntry), s.utf8_str()); pSS->getValueUTF8(AP_STRING_ID_DLG_Styles_ModifyParagraph,s); gtk_entry_set_text (GTK_ENTRY(m_wStyleTypeEntry),s.utf8_str()); } gtk_editable_set_editable(GTK_EDITABLE(m_wFollowingEntry),FALSE ); gtk_editable_set_editable(GTK_EDITABLE(m_wBasedOnEntry),FALSE ); gtk_editable_set_editable(GTK_EDITABLE(m_wStyleTypeEntry),FALSE ); // // Set these in our attributes vector // event_basedOn(); event_followedBy(); event_styleType(); if(isNew()) { fillVecFromCurrentPoint(); } else { fillVecWithProps(szCurrentStyle,true); } // // Allow callback's now. // setModifySignalBlocked(false); // // Now set the list of properties which can be deleted. // rebuildDeleteProps(); gtk_entry_set_text(GTK_ENTRY(m_wDeletePropEntry),""); return true; }
void AP_UnixDialog_Styles::event_ModifyClicked(void) { PD_Style * pStyle = NULL; const char * szCurrentStyle = getCurrentStyle (); m_sNewStyleName = szCurrentStyle; if(szCurrentStyle) getDoc()->getStyle(szCurrentStyle, &pStyle); if (!pStyle) { // TODO: error message - nothing selected return; } // // Allow built-ins to be modified // #if 0 if (!pStyle->isUserDefined ()) { // can't change builtin, error message const XAP_StringSet * pSS = m_pApp->getStringSet(); UT_UTF8String s; pSS->getValueUTF8 (AP_STRING_ID_DLG_Styles_ErrStyleBuiltin,s); const gchar * msg = s.utf8_str(); getFrame()->showMessageBox (static_cast<const char *>(msg), XAP_Dialog_MessageBox::b_O, XAP_Dialog_MessageBox::a_OK); return; } #endif #if HIDE_MAIN_DIALOG // // Hide the old window // gtk_widget_hide(m_windowMain); #endif // // fill the data structures needed for the Modify dialog // setIsNew(false); modifyRunModal(); if(m_answer == AP_Dialog_Styles::a_OK) { applyModifiedStyleToDoc(); getDoc()->updateDocForStyleChange(getCurrentStyle(),true); getDoc()->signalListeners(PD_SIGNAL_UPDATE_LAYOUT); } else { // // Do other stuff // } // // Restore the values in the main dialog // #if HIDE_MAIN_DIALOG // // Reveal main window again // gtk_widget_show( m_windowMain); #endif }
const PP_PropertyType * PP_evalPropertyType(const gchar * pszName, const PP_AttrProp * pSpanAttrProp, const PP_AttrProp * pBlockAttrProp, const PP_AttrProp * pSectionAttrProp, tProperty_type Type, const PD_Document * pDoc, bool bExpandStyles) { // find the value for the given property // by evaluating it in the contexts given. // use the CSS inheritance as necessary. if (!pszName || !*pszName) { UT_DEBUGMSG(("PP_evalProperty: null property given\n")); return NULL; } const PP_PropertyType * p_property; const PP_Property * pProp = PP_lookupProperty(pszName); if (!pProp) { UT_DEBUGMSG(("PP_evalProperty: unknown property \'%s\'\n",pszName)); return NULL; } PD_Style * pStyle = NULL; // TODO: make lookup more efficient by tagging each property with scope (block, char, section) // see if the property is on the Span item. if (pSpanAttrProp) { p_property = pSpanAttrProp->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; if (bExpandStyles) { pStyle = _getStyle(pSpanAttrProp, pDoc); int i = 0; while (pStyle && (i < pp_BASEDON_DEPTH_LIMIT)) { p_property = pStyle->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; pStyle = pStyle->getBasedOn(); i++; } } } // otherwise, see if we can inherit it from the containing block or the section. if (!pSpanAttrProp || pProp->canInherit()) { if (pBlockAttrProp) { p_property = pBlockAttrProp->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; if (bExpandStyles) { pStyle = _getStyle(pBlockAttrProp, pDoc); int i = 0; while (pStyle && (i < pp_BASEDON_DEPTH_LIMIT)) { p_property = pStyle->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; pStyle = pStyle->getBasedOn(); i++; } } } if (!pBlockAttrProp || pProp->canInherit()) { if (pSectionAttrProp) { p_property = pSectionAttrProp->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; } } } if (pDoc->getStyle("Normal", &pStyle)) { // next to last resort -- check for this property in the Normal style p_property = pStyle->getPropertyType(pProp->getName(), Type); if(p_property) return p_property; } // if no inheritance allowed for it or there is no // value set in containing block or section, we return // the default value for this property. return pProp->getInitialType(Type); }
const gchar * PP_evalProperty (const gchar * pszName, const PP_AttrProp * pSpanAttrProp, const PP_AttrProp * pBlockAttrProp, const PP_AttrProp * pSectionAttrProp, const PD_Document * pDoc, bool bExpandStyles) { // find the value for the given property // by evaluating it in the contexts given. // use the CSS inheritance as necessary. if (!pszName || !*pszName) { UT_DEBUGMSG(("PP_evalProperty: null property given\n")); return NULL; } if (pDoc == 0) bExpandStyles = false; const PP_Property * pProp = PP_lookupProperty(pszName); if (!pProp) { UT_DEBUGMSG(("PP_evalProperty: unknown property \'%s\'\n",pszName)); return NULL; } /* Not all properties can have a value of inherit, but we're not validating here. * This is not to be confused with automatic inheritance - the difference is whether * to take the default value (for when no value is specified). */ bool bInherit = false; // see if the property is on the Span item. const gchar * szValue = NULL; // TODO: ?? make lookup more efficient by tagging each property with scope (block, char, section) if (pSpanAttrProp) { szValue = s_evalProperty (pProp, pSpanAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { bInherit = false; if (pBlockAttrProp) { szValue = s_evalProperty (pProp, pBlockAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { bInherit = false; if (pSectionAttrProp) { szValue = s_evalProperty (pProp, pSectionAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { const PP_AttrProp * pDocAP = pDoc->getAttrProp (); if (pDocAP) pDocAP->getProperty (pszName, szValue); } } } } } } else if (pBlockAttrProp) { szValue = s_evalProperty (pProp, pBlockAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { bInherit = false; if (pSectionAttrProp) { szValue = s_evalProperty (pProp, pSectionAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { const PP_AttrProp * pDocAP = pDoc->getAttrProp (); if (pDocAP) pDocAP->getProperty (pszName, szValue); } } } } else if (pSectionAttrProp) { szValue = s_evalProperty (pProp, pSectionAttrProp, pDoc, bExpandStyles); if (szValue) if (strcmp (szValue, "inherit") == 0) { szValue = NULL; bInherit = true; } if ((szValue == NULL) && (bInherit || pProp->canInherit ())) { const PP_AttrProp * pDocAP = pDoc->getAttrProp (); if (pDocAP) pDocAP->getProperty (pszName, szValue); } } else { const PP_AttrProp * pDocAP = pDoc->getAttrProp (); if (pDocAP) { pDocAP->getProperty (pszName, szValue); // dom-dir requires special treatment at document level if(szValue && strcmp(pszName, "dom-dir") == 0) { if( strcmp(szValue, "logical-ltr") == 0 || strcmp(szValue, "logical-rtl") == 0) szValue += 8; } } } if (szValue) if (strcmp (szValue, "inherit") == 0) // shouldn't happen, but doesn't hurt to check szValue = NULL; if (szValue == NULL) if (bExpandStyles) { PD_Style * pStyle = 0; if (pDoc->getStyle ("Normal", &pStyle)) { /* next to last resort -- check for this property in the Normal style */ pStyle->getProperty (pszName, szValue); if (szValue) if (strcmp (szValue, "inherit") == 0) szValue = NULL; } } if(szValue == NULL && pDoc && (bInherit || pProp->canInherit ())) { // see if the doc has a value for this prop const PP_AttrProp * pAP = pDoc->getAttrProp(); if(pAP) { pAP->getProperty(pszName, szValue); } } if (szValue == NULL) szValue = pProp->getInitial (); // which may itself be NULL, but that is a bad thing - FIXME!! return szValue; }