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); }
bool AP_Dialog_Paragraph::setDialogData(const gchar ** pProps) { UT_return_val_if_fail (pProps, false); // NOTICE : When setting values, this function always calls // NOTICE : _set[thing]ItemValue() with the bToggleDirty flag // NOTICE : set to false, because these are the "un-dirty" // NOTICE : values. if (pProps[0]) { const gchar * sz; sz = UT_getAttribute("text-align", pProps); if (sz) { tAlignState t = align_LEFT; if (strcmp(sz, "center") == 0) t = align_CENTERED; else if (strcmp(sz, "right") == 0) t = align_RIGHT; else if (strcmp(sz, "justify") == 0) t = align_JUSTIFIED; else if (strcmp(sz, "left") == 0) t = align_LEFT; else UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _setMenuItemValue(id_MENU_ALIGNMENT, t, op_INIT); } sz = UT_getAttribute("dom-dir", pProps); if (sz) { tCheckState t = check_FALSE; if (strcmp(sz, "ltr") == 0) t = check_FALSE; else if (strcmp(sz, "rtl") == 0) t = check_TRUE; else UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _setCheckItemValue(id_CHECK_DOMDIRECTION, t, op_INIT); } sz = UT_getAttribute("margin-left", pProps); if (sz) _setSpinItemValue(id_SPIN_LEFT_INDENT, sz, op_INIT); sz = UT_getAttribute("margin-right", pProps); if (sz) _setSpinItemValue(id_SPIN_RIGHT_INDENT, sz, op_INIT); sz = UT_getAttribute("text-indent", pProps); if (sz) { // NOTE : Calling UT_convertDimensionless() _discards_ all // NOTE : unit system information. IFF all units are // NOTE : consistent among all paragraph properties will // NOTE : the comparisons be valid. For now this should be // NOTE : valid. if (UT_convertDimensionless(sz) > (double) 0) { // if text-indent is greater than margin-left, we have a "first line" case _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_FIRSTLINE, op_INIT); } else if (UT_convertDimensionless(sz) < (double) 0) { // if text-indent is less than margin-left, we have a "hanging" case _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_HANGING, op_INIT); } else { // they're equal then there's nothing special about them _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_NONE, op_INIT); } // set the value regardless; dialog will enable/disable field // if spacing is "NONE". Must flip the sign (strip minus) // to give illusion of Word's definitions of indent/margin. const gchar * newSz = sz; if (sz[0] == '-') newSz++; _setSpinItemValue(id_SPIN_SPECIAL_INDENT, newSz, op_INIT); } sz = UT_getAttribute("line-height", pProps); if (sz) { UT_uint32 nLen = strlen(sz); if (nLen > 0) { const char * pPlusFound = strrchr(sz, '+'); if (pPlusFound && *(pPlusFound + 1) == 0) { _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_ATLEAST, op_INIT); // need to strip off that plus int posPlus = pPlusFound - (char*) sz; UT_return_val_if_fail (posPlus>=0, false); UT_return_val_if_fail (posPlus<100, false); char pTmp[100]; strcpy(pTmp, sz); pTmp[posPlus] = 0; _setSpinItemValue(id_SPIN_SPECIAL_SPACING, (gchar*)pTmp, op_INIT); } else { if(UT_hasDimensionComponent(sz)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_EXACTLY, op_INIT); //see Bug 10086 for fabs() usage else if((strcmp("1.0", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 1.0) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_SINGLE, op_INIT); else if((strcmp("1.5", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 1.5) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_ONEANDHALF, op_INIT); else if((strcmp("2.0", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 2.0) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_DOUBLE, op_INIT); else _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_MULTIPLE, op_INIT); // set the spin contents regardless of menu content; platforms will // enable or disable the spin item for varying states of menu _setSpinItemValue(id_SPIN_SPECIAL_SPACING, sz, op_INIT); } } } sz = UT_getAttribute("margin-top", pProps); if (sz) _setSpinItemValue(id_SPIN_BEFORE_SPACING, sz, op_INIT); sz = UT_getAttribute("margin-bottom", pProps); if (sz) _setSpinItemValue(id_SPIN_AFTER_SPACING, sz, op_INIT); { // NOTE : "orphans" and "widows" hold a number specifying the number // NOTE : of lines to consider an orphaned or widowed piece of text. // NOTE : If they're both 0 they're off. If either is greater than // NOTE : 0, then some form of control is in effect. If the property // NOTE : is not set, they're indeterminate (e.g. because we're setting // NOTE : properties for text with multiple "orphans" values), or because // NOTE : the block has no value for orphans/widows here. bool bNoOrphans = false; bool bNoWidows = false; double orphans = 0, widows = 0; sz = UT_getAttribute("orphans", pProps); if (sz) orphans = UT_convertDimensionless(sz); else bNoOrphans = true; sz = UT_getAttribute("widows", pProps); if (sz) widows = UT_convertDimensionless(sz); else bNoWidows = true; if (bNoOrphans && bNoWidows) _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_INDETERMINATE, op_INIT); else if (orphans > 0 || widows > 0) _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_FALSE, op_INIT); } sz = UT_getAttribute("keep-together", pProps); if (sz) { if (strcmp(sz, "yes") == 0) _setCheckItemValue(id_CHECK_KEEP_LINES, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_KEEP_LINES, check_FALSE, op_INIT); } else _setCheckItemValue(id_CHECK_KEEP_LINES, check_INDETERMINATE, op_INIT); sz = UT_getAttribute("keep-with-next", pProps); if (sz) { if (strcmp(sz, "yes") == 0) _setCheckItemValue(id_CHECK_KEEP_NEXT, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_KEEP_NEXT, check_FALSE, op_INIT); } else _setCheckItemValue(id_CHECK_KEEP_NEXT, check_INDETERMINATE, op_INIT); // these are not like the others, they set fields on this, not dialogData. sz = UT_getAttribute("page-margin-left", pProps); if (sz) { m_pageLeftMargin = g_strdup(sz); } else { m_pageLeftMargin = g_strdup(PP_lookupProperty("page-margin-left")->getInitial()); } sz = UT_getAttribute("page-margin-right", pProps); if (sz) { m_pageRightMargin = g_strdup(sz); } else { m_pageRightMargin = g_strdup(PP_lookupProperty("page-margin-right")->getInitial()); } // TODO : add these to PP_Property (pp_Property.cpp) !!! // TODO : and to FV_View::getBlockFormat (or else they won't come in) /* m_pageBreakBefore; m_suppressLineNumbers; m_noHyphenate; */ } return true; }
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; }