Exemplo n.º 1
0
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;
}
Exemplo n.º 3
0
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;
}