Ejemplo n.º 1
0
/*----------------------------------------------------------------------------------------------
	Set up the crawler to work on a given database connection.

	@param stuServerName - name of the database server
	@param stuDatabase - name of the database
	@param pstrmLog - pointer to the log stream (may be NULL)
	@param padvi3 - pointer to the progress report object (defaults to NULL)
----------------------------------------------------------------------------------------------*/
bool DbStringCrawler::Init(IOleDbEncap * pode, IStream *pstrmLog, IAdvInd3 * padvi3)
{
	m_qodeDb = pode;
	SmartBstr sbstrServer;
	StrUni stuServer;
	CheckHr(pode->get_Server(&sbstrServer));
	stuServer.Assign(sbstrServer.Chars(), sbstrServer.Length());
	SmartBstr sbstrDatabase;
	StrUni stuDatabase;
	CheckHr(pode->get_Database(&sbstrDatabase));
	stuDatabase.Assign(sbstrDatabase.Chars(), sbstrDatabase.Length());
	return Init(stuServer, stuDatabase, pstrmLog, padvi3);
}
Ejemplo n.º 2
0
void ViewTest1::TestGetDlgTagInfo()
{
	OLECHAR rgchGuid[9] = L"BF7056E0";
	SmartBstr sbstrAbbr;
	SmartBstr sbstrName;
	COLORREF clrFore;
	COLORREF clrBack;
	COLORREF clrUnder;
	int ivar;
	ComBool fHidden;

	// Sending NULL pointers
	HRESULT hr = m_qxvoTest->GetDlgTagInfo(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (SUCCEEDED(hr))
		Failure("Call to function GetDlgTagInfo(NULL...) should have returned an error");

	// Test for non-existent negative tag
	hr = m_qxvoTest->GetDlgTagInfo(-21, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if(!FAILED(hr))
		Failure("Function GetDlgTagInfo(-21, NULL...) accepted a non-existent tag setting");

	// Test referencing a non-existent positive tag
	hr = m_qxvoTest->GetDlgTagInfo(234, &fHidden, &clrFore, &clrBack, &clrUnder, &ivar,
		&sbstrAbbr, &sbstrName);
	if (!FAILED(hr))
		Failure("GetDlgTagInfo when passed a non-existent positive tag should have returned an "
			"error");

	CheckHr(m_qxvoTest->SetTagInfo(rgchGuid, 46, kosmAll, SmartBstr(L"BBBBB"), SmartBstr(L"YYYYY"),
		0x00000000, 0x00FF00FF, 0x0000FF00, 4, true));

	int inumtag;
	CheckHr(m_qxvoTest->get_CTags(&inumtag));

	// inumtag holds number of tags in overlay
	// (inumtag - 1) will reference the last tag, if no tags at all, will test for
	// non-existent tag
	CheckHr(m_qxvoTest->GetDlgTagInfo(inumtag-1, &fHidden, &clrFore, &clrBack, &clrUnder, &ivar,
		&sbstrAbbr, &sbstrName));
	if (fHidden != true || clrFore != 0x00000000 || clrBack != 0x00FF00FF
		|| clrUnder != 0x0000FF00 || ivar != 4 || wcscmp(sbstrAbbr.Chars(), L"BBBBB")
		|| wcscmp(sbstrName.Chars(), L"YYYYY"))
		Failure("Function GetDlgTagInfo returned wrong result after previous SetTagInfo "
			"function call");

	hr = m_qxvoTest->GetDlgTagInfo(inumtag-1, NULL, NULL, &clrBack, NULL, &ivar, NULL, NULL);
	if (SUCCEEDED(hr))
		Failure("GetDlgTagInfo(0, some invalid params) should have returned an error");
}
Ejemplo n.º 3
0
/*----------------------------------------------------------------------------------------------
	Paint Dll Client application in the middle of the client area.
----------------------------------------------------------------------------------------------*/
bool DcClientWnd::OnPaint(HDC hdcDef)
{
	Assert(!hdcDef);

	PAINTSTRUCT ps;
	HDC hdc = ::BeginPaint(m_hwnd, &ps);

	Rect rc;
	GetClientRect(rc);

	try
	{

		ISampleInterfacePtr qsi;
		qsi.CreateInstance(CLSID_SampleInterface);

		SmartBstr bstrText;
		CheckHr(qsi->get_HelloWorldString(&bstrText));
		StrApp staText(bstrText.Chars());

		::DrawText(hdc, staText.Chars(), -1, &rc, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
	}
	catch (...)
	{
		// Nothing much we can do...try this
		::DrawText(hdc, _T("Drawing failed!"), -1, &rc, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
	}

	::EndPaint(m_hwnd, &ps);
	return true;
}
Ejemplo n.º 4
0
/*----------------------------------------------------------------------------------------------
	Fix up the 'next' or 'basedOn' attributes in the styles, now that we have a complete
	list.
	Attribute:
		flid		- attribute to set
		hmhvostu	- map containing the values ofthe attribute
----------------------------------------------------------------------------------------------*/
void WpStylesheet::FixStyleReferenceAttrs(int flid, HashMap<HVO, StrUni> & hmhvostu)
{
	WpDaPtr wpda = dynamic_cast<WpDa *>(m_qsda.Ptr());

	//	Generate a list of all the style names.
	Vector<StrUni> vstuNames;
	int cst;
	CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cst));
	Assert(cst == m_vhcStyles.Size());
	for (int ist = 0; ist < cst; ist++)
	{
		SmartBstr sbstr;
		CheckHr(wpda->get_UnicodeProp(m_vhcStyles[ist].hvo, kflidStStyle_Name, &sbstr));
		vstuNames.Push(StrUni(sbstr.Chars()));
	}

	//	For each style, if it has a value in the map, find the corresponding style
	//	and set the attribute.
	for (int ist = 0; ist < cst; ist++)
	{
		HVO hvo = m_vhcStyles[ist].hvo;
		StrUni stuRef;
		if (hmhvostu.Retrieve(hvo, &stuRef))
		{
			for (int istTmp = 0; istTmp < cst; istTmp++)
			{
				if (vstuNames[istTmp] == stuRef)
				{
					CheckHr(wpda->CacheObjProp(hvo, flid, m_vhcStyles[istTmp].hvo));
					break;
				}
			}
		}
	}
}
Ejemplo n.º 5
0
/*----------------------------------------------------------------------------------------------
	Initialize the list of encodings from the writing system factory.
----------------------------------------------------------------------------------------------*/
void WpFormatWsDlg::InitEncList()
{
	int cws;
	ILgWritingSystemFactoryPtr qwsf;
	qwsf.CreateInstance(CLSID_LgWritingSystemFactory);	// Get the memory-based factory.
	CheckHr(qwsf->get_NumberOfWs(&cws));
	int * prgenc = NewObj int[cws];
	CheckHr(qwsf->GetWritingSystems(prgenc));
	int wsUser;
	CheckHr(qwsf->get_UserWs(&wsUser));

	for (int iws = 0; iws < cws; iws++)
	{
		if (prgenc[iws] == 0)
			continue;

		IWritingSystemPtr qws;
		CheckHr(qwsf->get_Engine(prgenc[iws], &qws));
		if (!qws)
			continue;

		//	Generate the name to use for the writing system.
		SmartBstr sbstr;
		CheckHr(qws->get_UiName(wsUser, &sbstr));
		if (!sbstr)
			continue;
		StrUni stu(sbstr.Chars());
		StrApp str = stu;

		m_vws.Push(prgenc[iws]);
		m_vstr.Push(str);
	}
	Assert(m_vws.Size() == m_vstr.Size());

	//	Sort the encodings by name.
	for (iws = 0; iws < m_vws.Size() - 1; iws++)
	{
		for (int iws2 = iws + 1; iws2 < m_vws.Size(); iws2++)
		{
			if (m_vstr[iws] > m_vstr[iws2])
			{
				StrApp strTmp = m_vstr[iws];
				int encTmp = m_vws[iws];
				m_vstr[iws] = m_vstr[iws2];
				m_vws[iws] = m_vws[iws2];
				m_vstr[iws2] = strTmp;
				m_vws[iws2] = encTmp;
			}
		}
		if (m_vws[iws] == m_wsInit)
			m_iwsInit = iws;
	}

	delete[] prgenc;
}
Ejemplo n.º 6
0
/*----------------------------------------------------------------------------------------------
	Draw to the given clip rectangle.
	@param hdc
	@param rcpClip the given clip rectangle

	TODO: use views code to display the field contents!
----------------------------------------------------------------------------------------------*/
void AfDeFeEdBoxBut::Draw(HDC hdc, const Rect & rcpClip)
{
	Assert(hdc);
	int ws;
	SmartBstr sbstr;
	if (m_qtss)
	{
		CheckHr(m_qtss->get_Text(&sbstr));
		int nVar;
		ITsTextPropsPtr qttp;
		CheckHr(m_qtss->get_PropertiesAt(0, &qttp));
		CheckHr(qttp->GetIntPropValues(ktptWs, &nVar, &ws));
		MakeCharProps(ws);
		CreateFont();
}

	AfGfx::FillSolidRect(hdc, rcpClip, m_chrp.clrBack);
	COLORREF clrBgOld = AfGfx::SetBkColor(hdc, m_chrp.clrBack);
	COLORREF clrFgOld = AfGfx::SetTextColor(hdc, m_chrp.clrFore);
	HFONT hfontOld = AfGdi::SelectObjectFont(hdc, m_hfont);
#if 1
	UINT uAlignPrev = ::GetTextAlign(hdc);
	if (m_fRtl)
	{
		::SetTextAlign(hdc, (uAlignPrev & ~(TA_CENTER|TA_LEFT)) | TA_RIGHT | TA_RTLREADING);
		::TextOutW(hdc, rcpClip.right - 19, rcpClip.top + 1, sbstr.Chars(), sbstr.Length());
	}
	else
	{
		::SetTextAlign(hdc, (uAlignPrev & ~(TA_CENTER|TA_RIGHT)) | TA_LEFT);
		::TextOutW(hdc, rcpClip.left + 2, rcpClip.top + 1, sbstr.Chars(), sbstr.Length());
	}
	::SetTextAlign(hdc, uAlignPrev);
#else
	::TextOutW(hdc, rcpClip.left + 2, rcpClip.top + 1, sbstr.Chars(), sbstr.Length());
#endif
	AfGdi::SelectObjectFont(hdc, hfontOld, AfGdi::OLD);
	AfGfx::SetBkColor(hdc, clrBgOld);
	AfGfx::SetTextColor(hdc, clrFgOld);
}
Ejemplo n.º 7
0
/*----------------------------------------------------------------------------------------------
	Change all the occurrences of the old styles names to the new names, and delete any
	obsolete names.
----------------------------------------------------------------------------------------------*/
bool FwDbMergeStyles::ProcessFormatting(ComVector<ITsTextProps> & vqttp,
	StrUni stuDelete)
{
	bool fAnyChanged = false;
	for (int ittp = 0; ittp < vqttp.Size(); ittp++)
	{
		SmartBstr sbstr;
		HRESULT hr;
		CheckHr(hr = vqttp[ittp]->GetStrPropValue(ktptNamedStyle, &sbstr));
		if (hr == S_OK && sbstr.Length() > 0)
		{
			ITsPropsBldrPtr qtpb = NULL;
			StrUni stuOld(sbstr.Chars());
			StrUni stuNew;
			if (Delete(stuOld))
			{
				CheckHr(vqttp[ittp]->GetBldr(&qtpb));
				if (stuDelete.Length() == 0)
				{
					// If the style name to delete is empty, we want to pass null
					// so that the named style string property is removed.
					CheckHr(qtpb->SetStrPropValue(ktptNamedStyle, NULL));
				}
				else
					CheckHr(qtpb->SetStrPropValue(ktptNamedStyle, stuDelete.Bstr()));

			}
			else if (Rename(stuOld, stuNew))
			{
				CheckHr(vqttp[ittp]->GetBldr(&qtpb));
				CheckHr(qtpb->SetStrPropValue(ktptNamedStyle, stuNew.Bstr()));
			}

			if (qtpb)
			{
				ITsTextPropsPtr qttpNew;
				CheckHr(qtpb->GetTextProps(&qttpNew));
				vqttp[ittp] = qttpNew;
				fAnyChanged = true;
			}
		}
	}

	return fAnyChanged;
}
Ejemplo n.º 8
0
/*----------------------------------------------------------------------------------------------
	Insert material as appropriate to display the specified object.
	This method has not yet been tested...maybe not even compiled?
----------------------------------------------------------------------------------------------*/
STDMETHODIMP VwBaseVc::DisplayEmbeddedObject(IVwEnv * pvwenv, HVO hvo)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pvwenv);
	// See if it is a CmPicture.
	ISilDataAccessPtr qsda;
	CheckHr(pvwenv->get_DataAccess(&qsda));
	int clsid;
	CheckHr(qsda->get_IntProp(hvo, kflidCmObject_Class, &clsid));
	if (clsid != kclidCmPicture)
		return S_OK; // don't know how to deal with it.
	StrUni stuRootDir = DirectoryFinder::FwRootDataDir();
	HVO hvoFile;
	CheckHr(qsda->get_ObjectProp(hvo, kflidCmPicture_PictureFile, &hvoFile));
	if (hvoFile == 0)
		return S_OK;
	SmartBstr sbstrFileName;
	CheckHr(qsda->get_UnicodeProp(hvoFile, kflidCmFile_InternalPath, &sbstrFileName));
	if (sbstrFileName.Length() == 0)
		return S_OK;
	StrUni stuPath;
	stuPath.Format(L"%s,%s,%s", stuRootDir.Chars(), L"\\", sbstrFileName.Chars());
	IPicturePtr qpic;
	try
	{
		IStreamPtr qstrm;
		FileStream::Create(stuPath, STGM_READ, &qstrm);
		STATSTG stg;
		CheckHr(qstrm->Stat(&stg, STATFLAG_NONAME));
		LONG cbdata = (LONG)stg.cbSize.QuadPart;
		CheckHr(::OleLoadPicture(qstrm, cbdata, FALSE, IID_IPicture, (LPVOID *)&qpic));
		CheckHr(pvwenv->AddPicture(qpic, ktagNotAnAttr, 0, 0));
	}
	catch (...)
	{
		return S_OK; // if anything goes wrong (e.g., file not found), just give up for now.
		// Todo: insert a 'file XXX not found string.
	}
	// Todo: also add the caption.

	END_COM_METHOD(g_fact, IID_IVwViewConstructor);
}
Ejemplo n.º 9
0
/*----------------------------------------------------------------------------------------------
	This method is called by CheckHr (with punk and iid null) or CheckExtHr, after confirming
	that hrErr is an error HRESULT.

	It first confirms that there is an error info object available. If punk and iid
	are supplied, it further checks that the error info object is relevant to that object and
	interface.

	If a relevant error object is available, and it indicates that a programming error has
	occurred, and its Description does not yet contain a stack dump, we add one if possible.
	Then we ThrowHr, with a special HelpId to indicate that HandleThrowable need not generate
	a new error object.

	If no relevant error object is available, we generate a stack dump and treat the problem
	as an internal error.
----------------------------------------------------------------------------------------------*/
void CheckHrCore(HRESULT hrErr)
{
	IErrorInfoPtr qerrinfo;
	::GetErrorInfo(0, &qerrinfo); // This clears the system wide error info
	if (!qerrinfo)
	{
		// We didn't have any (relevant) error info
		ThrowInternalError(hrErr);
	}

	SmartBstr sbstrDesc;
	qerrinfo->GetDescription(&sbstrDesc);

	// We have an error info object, and presume that it is relevant.
	// If it indicates a programming error, and doesn't already contain a
	// stack dump, try to add one.
	if (hrErr == E_INVALIDARG || hrErr == E_POINTER || hrErr == E_UNEXPECTED)
	{
		// If so look for stack dump type info.
		std::wstring strDesc = sbstrDesc;
		if (!wcsstr(strDesc.c_str(), ThrowableSd::MoreSep()))
		{
			// no stack there, so add one
			DumpStackHere("Error was detected by CheckHr here:\r\n");
			StrUni stuDescNew;
			stuDescNew.Format(L"%s%s%S", sbstrDesc.Chars(), ThrowableSd::MoreSep(),
				StackDumper::GetDump());
			sbstrDesc.Append(const_cast<OLECHAR *>(stuDescNew.Chars()));

			// Now modify the error info
			ICreateErrorInfoPtr qcerrinfo;
			if (SUCCEEDED(qerrinfo->QueryInterface(IID_ICreateErrorInfo, (LPVOID FAR*) &qcerrinfo)))
				qcerrinfo->SetDescription(sbstrDesc);
		}
	}
	// Throw an error indicating there is already a good error object in place.
	ThrowHr(hrErr, sbstrDesc.Bstr(), -1, qerrinfo);
}
Ejemplo n.º 10
0
/*----------------------------------------------------------------------------------------------
	Set the list of style objects to the (fake) styles attribute of StText.
	Called from the XML import routine.
----------------------------------------------------------------------------------------------*/
HRESULT WpStylesheet::AddLoadedStyles(HVO * rghvoNew, int chvo, int hvoNextStyle)
{
	int cst;
	CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cst));
	WpDaPtr wpda = dynamic_cast<WpDa *>(m_qsda.Ptr());
	// Note: we are clobbering any existing styles.
	HRESULT hr = wpda->CacheReplace(khvoText, kflidStText_Styles, 0, cst, rghvoNew, chvo);

	m_vhcStyles.Clear();
	bool fFoundNormal= false;
	for (int ihvo = 0; ihvo < chvo; ihvo++)
	{
		HvoClsid hc;
		hc.clsid = kclidStStyle;
		hc.hvo = rghvoNew[ihvo];
		m_vhcStyles.Push(hc);

		SmartBstr sbstrName;
		CheckHr(m_qsda->get_UnicodeProp(hc.hvo, kflidStStyle_Name, &sbstrName));
		StrUni stuName(sbstrName.Chars());
		if (stuName == g_pszwStyleNormal)
			fFoundNormal = true;
	}

	m_hvoNextStyle = max(m_hvoNextStyle, hvoNextStyle);

	if (!fFoundNormal)
		AddNormalParaStyle();

#if 0
	// Old code for deleting only duplicates.

	int cstNew;
	CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cstNew));
	Assert(cstNew == cst + chvo);

	//	If there are any styles with duplicate names, delete the first
	//	(previously existing) one.

	Vector<int> vihvoDelete;
	Vector<StrUni> vstuStyleNames;
	for (ihvo = 0; ihvo < m_vhcStyles.Size(); ihvo++)
	{
		SmartBstr sbstrName;
		CheckHr(m_qsda->get_UnicodeProp(m_vhcStyles[ihvo].hvo, kflidStStyle_Name, &sbstrName));
		StrUni stu(sbstrName.Chars());
		vstuStyleNames.Push(stu);
	}
	Assert(vstuStyleNames.Size() == m_vhcStyles.Size());

	for (ihvo = 0; ihvo < vstuStyleNames.Size() - 1; ihvo++)
	{
		for (int ihvo2 = ihvo + 1; ihvo2 < vstuStyleNames.Size(); ihvo2++)
		{
			if (vstuStyleNames[ihvo] == vstuStyleNames[ihvo2])
			{
				vihvoDelete.Push(ihvo);
				break;
			}
		}
	}

	//	Delete the duplicates; do it backwards so the indices stay valid.
	for (int iihvo = vihvoDelete.Size(); --iihvo >= 0; )
	{
		HVO ihvoToDelete = vihvoDelete[iihvo];
		m_vhcStyles.Delete(ihvoToDelete);
		CheckHr(wpda->CacheReplace(khvoText, kflidStText_Styles, ihvoToDelete, ihvoToDelete+1,
			NULL, 0));
	}

	CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cstNew));
	Assert(cstNew == cst + chvo - vihvoDelete.Size());

#endif

	return hr;
}
Ejemplo n.º 11
0
/*----------------------------------------------------------------------------------------------
	Set the values for the dialog controls based on the style styi.
	@param vwsProj Union of the current Vernacular and Analysis encodings for the project.
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::SetDialogValues(StyleInfo & styi, Vector<int> & vwsProj)
{
	// During SetDialogValues we never need to handle loss of focus in the name control,
	// because if anything needed to be done about updating that, it was done during
	// GetDialogValues, which is always called before SetDialogValues. We need to suppress it
	// because during this call the current style index and the current value of the control
	// may not agree: the purpose of this method is to update the control from the new style.
	// The normal loss-of-focus code is trying to synchronize in the opposite direction, and
	// can cause problems, for example, when we are disabling the control. For example:
	//  - Disabling the window causes it to lose focus if it previously had focus.
	//  - There is a kill focus event that tries to make the contents of the box agree with
	//		the name of the current style.
	//	- when this method is called, the old style is still the current one, so if we
	//		already changed the text in the box, we wind up trying to rename the old style
	//		to the name of the 'provided' style and produce a name conflict error.

	try
	{
		m_vwsProj = vwsProj;

		StrApp strDesc;
		m_fSuppressLossOfFocus = true;
		StrApp strName = styi.m_stuName;
		StrApp strTemp; // Temporary string.
		bool fProtectedStyle = m_pafsd->IsStyleProtected(styi.m_stuName);

		// Name edit box.
		::SetDlgItemText(m_hwnd, kctidFgEdName, strName.Chars());
		// Diable the control for styles originally provided by FieldWorks.
		::EnableWindow(m_hwndName, !fProtectedStyle);

		// Style type ltext.
		switch (styi.m_st)
		{
		case kstParagraph:
			strTemp.Load(kstidParagraph);
			break;
		case kstCharacter:
			strTemp.Load(kstidCharacter);
			break;
		default:
			Assert(false); // Should not happen.
		}
		::SetWindowText(m_hwndType, strTemp.Chars());

		// Update the "next" and "basedOn" comboboxes
		LoadNextStyleCombobox(styi);
		SetNextStyleComboboxValue(styi);
		LoadBasedOnStyleCombobox(styi);
		SetBasedOnStyleComboboxValue(styi);

		// ENHANCE LarryW(JohnT): When shortcut is implemented initialize the value instead.
		::EnableWindow(m_hwndShortcut, false); // Disables it.

		// **************************************
		m_vesi.Clear();
		strDesc = m_pafsd->GetNameOfStyle(styi.m_hvoBasedOn);
		strDesc.Append(" + ");

		ITsTextProps * pttp = styi.m_qttp;
		if (pttp)
		{
			StrApp strT;
			StrAppBuf strb; // a temp, used for making strings with units

			// Add default font info
			bool fFirstPart = true;
			SmartBstr sbstr;
			CheckHr(pttp->GetStrPropValue(ktptFontFamily, &sbstr));
			StrUni stuFont(sbstr.Chars());
			AppendDescPart(strDesc, FwStyledText::FontStringMarkupToUi(false, stuFont), fFirstPart);
			int val, var;
			CheckHr(pttp->GetIntPropValues(ktptFontSize, &var, &val));
			if (var != -1)
			{
				AfUtil::MakeMsrStr (val , knpt, &strb);
				AppendDescPart(strDesc, strb, fFirstPart);
			}
			CheckHr(pttp->GetIntPropValues(ktptBold, &var, &val));
			if (val == kttvForceOn || val == kttvInvert)
				AppendDescPart(strDesc, kstidBold, fFirstPart);
			CheckHr(pttp->GetIntPropValues(ktptItalic, &var, &val));
			if (val == kttvForceOn || val == kttvInvert)
				AppendDescPart(strDesc, kstidItalic, fFirstPart);
			CheckHr(pttp->GetIntPropValues(ktptSuperscript, &var, &val));
			if (val == kssvSuper)
				AppendDescPart(strDesc, kstidFfdSuperscript, fFirstPart);
			else if (val == kssvSub)
				AppendDescPart(strDesc, kstidFfdSubscript, fFirstPart);

			AppendTextIs(strDesc, (COLORREF)ReadValOrNinch(pttp, ktptForeColor),
				(COLORREF)ReadValOrNinch(pttp, ktptBackColor), fFirstPart);

			AppendUnderlineInfo(strDesc, (COLORREF)ReadValOrNinch(pttp, ktptUnderColor),
				ReadValOrNinch(pttp, ktptUnderline), fFirstPart);

			AppendOffsetInfo(strDesc, ReadValOrNinch(pttp, ktptOffset), fFirstPart);

			// Add info about other tabs
			int nDir = ReadValOrNinch(pttp, ktptRightToLeft);
			AddIf(strDesc, nDir == 0, kstidLeftToRight, fFirstPart);
			AddIf(strDesc, nDir == 1, kstidRightToLeft, fFirstPart);

			static const Keyval rgkeyvals[] =
			{
				{ktalLeading, kstidFpAlignLead},
				{ktalLeft, kstidFpAlignLeft},
				{ktalCenter, kstidFpAlignCenter},
				{ktalRight, kstidFpAlignRight},
				{ktalTrailing, kstidFpAlignTrail},
				{ktalJustify, kstidFpAlignJustify}, //TODO: support when in use.
				{0, 0}
			};
			AddFromList(strDesc, ReadValOrNinch(pttp, ktptAlign), rgkeyvals, fFirstPart);

			int nLeadIndent = ReadValOrNinch(pttp, ktptLeadingIndent);
			int nTrailIndent = ReadValOrNinch(pttp, ktptTrailingIndent);
			int nFirstIndent = ReadValOrNinch(pttp, ktptFirstIndent);
			if (nLeadIndent != knNinch || nTrailIndent != knNinch || nFirstIndent != knNinch)
			{
				AppendDescPart(strDesc, kstidIndentColon, fFirstPart);
				AppendMeasurement(strDesc, nLeadIndent, m_nMsrSys, kstidLeadingFmt);
				if (nFirstIndent != knNinch)
				{
					if (nFirstIndent < 0)
						AppendMeasurement(strDesc, -nFirstIndent, m_nMsrSys, kstidHangingFmt);
					else
						AppendMeasurement(strDesc, nFirstIndent, m_nMsrSys, kstidFirstLineFmt);
				}
				AppendMeasurement(strDesc, nTrailIndent, m_nMsrSys, kstidTrailingFmt);
			}
			// line spacing
			CheckHr(pttp->GetIntPropValues(ktptLineHeight, &var, &val));
			StrApp strSpacing;
			StrApp strFmt;
			if (var == ktpvMilliPoint)
			{
				if (val < 0)
					strFmt.Load(kstidFpLsExactFmt);
				else
					strFmt.Load(kstidFpLsAtLeastFmt);
				StrAppBuf strb;
				AfUtil::MakeMsrStr (val , knpt, &strb);
				strSpacing.Format(strFmt.Chars(), strb.Chars());
			}
			else if (var == ktpvRelative)
			{
				if (val >= kdenTextPropRel * 2)
					strSpacing.Load(kstidFpLsDouble);
				else if (val >= kdenTextPropRel * 3 / 2)
					strSpacing.Load(kstidFpLs15Lines);
				else
					strSpacing.Load(kstidFpLsSingle);
			}
			if (strSpacing.Length() != 0)
			{
				strFmt.Load(kstidLineSpacingFmt);
				strT.Format(strFmt.Chars(), strSpacing.Chars());
				AppendDescPart(strDesc, strT, fFirstPart);
			}

			int mpBefore = ReadValOrNinch(pttp, ktptSpaceBefore);
			int mpAfter = ReadValOrNinch(pttp, ktptSpaceAfter);
			if (mpBefore != knNinch || mpAfter != knNinch)
			{
				AppendDescPart(strDesc, kstidSpace, fFirstPart);
				AppendMeasurement(strDesc, mpBefore, knpt, kstidBeforeFmt);
				AppendMeasurement(strDesc, mpAfter, knpt, kstidAfterFmt);
			}

			int bulnum = ReadValOrNinch(pttp, ktptBulNumScheme);
			AddIf(strDesc, bulnum >= kvbnBulletBase && bulnum < kvbnBulletMax,
				kstidBulleted, fFirstPart);
			AddIf(strDesc, bulnum >= kvbnNumberBase && bulnum < kvbnNumberMax,
				kstidNumbered, fFirstPart);

			int mpBTop = ReadValOrNinch(pttp, ktptBorderTop);
			int mpBB = ReadValOrNinch(pttp, ktptBorderBottom);
			int mpBL = ReadValOrNinch(pttp, ktptBorderLeading);
			int mpBTr = ReadValOrNinch(pttp, ktptBorderTrailing);

			if (mpBTop != knNinch || mpBB != knNinch || mpBL != knNinch || mpBTr != knNinch)
			{
				AppendDescPart(strDesc, kstidBorderColon, fFirstPart);
				int clrBorder = ReadValOrNinch(pttp, ktptBorderColor);
				bool fFirstBorder = true;
				if (clrBorder != knNinch)
				{
					StrApp strClr;
					strClr.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrBorder)));
					strDesc.Append(strClr.Chars());
					fFirstBorder = false;
				}
				AppendBorderInfo(strDesc, mpBTop, kstidTopBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBB, kstidBottomBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBL, kstidLeadingBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBTr, kstidTrailingBdrFmt, fFirstBorder);
			}


			// Add info about writing-system overrides of font info.
			Vector<int> vwsSoFar;


			// Get the appropropriate writing system factory.
			ILgWritingSystemFactoryPtr qwsf;
			AssertPtr(m_pafsd);
			m_pafsd->GetLgWritingSystemFactory(&qwsf);
			AssertPtr(qwsf);
		//-		IWritingSystemPtr qws;

			// Each iteration of this loop processes information about one writing system.
			SmartBstr sbstrCharStyles;
			CheckHr(pttp->GetStrPropValue(kspWsStyle, &sbstrCharStyles));
			if (sbstrCharStyles.Length())
			{
				FwStyledText::DecodeFontPropsString(sbstrCharStyles, m_vesi, vwsSoFar);

				SmartBstr sbstrWs;
				StrApp strWs;
				int wsUser;
				CheckHr(qwsf->get_UserWs(&wsUser));
				SmartBstr sbstrAbbr;
				for (int iesi = 0; iesi < m_vesi.Size(); iesi++)
				{
					WsStyleInfo & esi = m_vesi[iesi];
					if (vwsSoFar[iesi] == 0)
						continue;		// Ignore writing system set to 0.
					fFirstPart = true;
					StrApp strT;
					StrApp strT2;
					strT.Format(_T("\n"));
					// Use the abbreviation in the user ws if it exists.
					// else try for an abbreviation in each ws in m_vwsProj in turn,
					// else use the ICU locale name as a last resort.
					IWritingSystemPtr qws;
					CheckHr(qwsf->GetStrFromWs(vwsSoFar[iesi], &sbstrWs));
					CheckHr(qwsf->get_Engine(sbstrWs, &qws));
					CheckHr(qws->get_Abbr(wsUser, &sbstrAbbr));
					if (sbstrAbbr.Length() == 0)
					{
						for (int iws = 0; iws < m_vwsProj.Size(); ++iws)
						{
							CheckHr(qws->get_Abbr(m_vwsProj[iws], &sbstrAbbr));
							if (sbstrAbbr.Length() != 0)
								break;
						}
					}
					if (sbstrAbbr.Length() == 0)
						strWs.Assign(sbstrWs.Chars(), sbstrWs.Length());
					else
						strWs.Assign(sbstrAbbr.Chars(), sbstrAbbr.Length());
					strT2.Format(_T("%s: "), strWs.Chars());
					if (strT2 == _T("___: "))
						strT2.Load(kctidFgUnknown);
					strT.Append(strT2);
					strDesc.Append (strT);
					AppendDescPart(strDesc,
						FwStyledText::FontStringMarkupToUi(false, esi.m_stuFontFamily),
						fFirstPart);
					if (esi.m_mpSize != knNinch)
					{
						AfUtil::MakeMsrStr (esi.m_mpSize , knpt, &strb);
						AppendDescPart(strDesc, strb, fFirstPart);
					}
					if (esi.m_fBold == kttvForceOn || esi.m_fBold == kttvInvert)
						AppendDescPart(strDesc, kstidBold, fFirstPart);
					if (esi.m_fItalic == kttvForceOn || esi.m_fItalic == kttvInvert)
						AppendDescPart(strDesc, kstidItalic, fFirstPart);
					if (esi.m_ssv == kssvSuper)
						AppendDescPart(strDesc, kstidFfdSuperscript, fFirstPart);
					else if (esi.m_ssv == kssvSub)
						AppendDescPart(strDesc, kstidFfdSubscript, fFirstPart);
					AppendTextIs(strDesc, esi.m_clrFore, esi.m_clrBack, fFirstPart);

					AppendUnderlineInfo(strDesc, esi.m_clrUnder, esi.m_unt, fFirstPart);

					AppendOffsetInfo(strDesc, esi.m_mpOffset, fFirstPart);
				} // 'for' loop
			}
		}
		::SetDlgItemText(m_hwnd, kctidFgDescription, strDesc.Chars());
// **************************************
	}
	catch(...)
	{
		m_fSuppressLossOfFocus = false;
		throw;
	}
	m_fSuppressLossOfFocus = false;
} //:> FmtGenDlg::SetDialogValues.
Ejemplo n.º 12
0
DEFINE_THIS_FILE

/*----------------------------------------------------------------------------------------------
	Write the given string, which encodes a group of writing-system styles, to WorldPad
	XML format.

	@param pstrm Pointer to an IStream for output.
	@param bstrWsStyles
	@param cchIndent Number of spaces to indent the XML output.

	This code must be kept in sync with FwStyledText::DecodeFontPropsString()!
----------------------------------------------------------------------------------------------*/
void FwXml::WriteWsStyles(IStream * pstrm, ILgWritingSystemFactory * pwsf, BSTR bstrWsStyles,
	int cchIndent)
{
	AssertPtr(pstrm);
	AssertPtr(pwsf);
	Assert(cchIndent >= 0);

	Vector<char> vchIndent;
	vchIndent.Resize(cchIndent + 1);	// new elements are zero initialized.
	memset(vchIndent.Begin(), ' ', cchIndent);
	Vector<WsStyleInfo> vesi;
	Vector<int> vws;
	FwStyledText::DecodeFontPropsString(bstrWsStyles, vesi, vws);
	if (vesi.Size())
	{
		FormatToStream(pstrm, "%s<WsStyles9999>%n", vchIndent.Begin());
		for (int iv = 0; iv < vesi.Size(); ++iv)
		{
			SmartBstr sbstrWs;
			CheckHr(pwsf->GetStrFromWs(vesi[iv].m_ws, &sbstrWs));
			if (!sbstrWs.Length())
			{
				// We don't want WorldPad writing invalid XML!
				// ThrowInternalError(E_INVALIDARG, "Writing system invalid for <WsProp ws>");
#if 99
				::MessageBoxA(NULL, "Writing system invalid for <WsProp ws>", "DEBUG!", MB_OK);
#endif
				::OutputDebugStringA("Writing system invalid for <WsProp ws>");
				continue;
			}
			FormatToStream(pstrm, "%s%s<WsProp ws=\"",
				vchIndent.Begin(), cchIndent ? "  " : "");
			WriteXmlUnicode(pstrm, sbstrWs.Chars(), sbstrWs.Length());
			FormatToStream(pstrm, "\"");
			if (vesi[iv].m_stuFontFamily.Length())
				FwXml::WriteStrTextProp(pstrm, ktptFontFamily, vesi[iv].m_stuFontFamily.Bstr());
			if (vesi[iv].m_stuFontVar.Length())
				FwXml::WriteStrTextProp(pstrm, ktptFontVariations,
					vesi[iv].m_stuFontVar.Bstr());
			if (vesi[iv].m_mpSize != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptFontSize, ktpvMilliPoint,
					vesi[iv].m_mpSize);
			if (vesi[iv].m_fBold != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptBold, ktpvEnum, vesi[iv].m_fBold);
			if (vesi[iv].m_fItalic != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptItalic, ktpvEnum, vesi[iv].m_fItalic);
			if (vesi[iv].m_ssv != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptSuperscript, ktpvEnum, vesi[iv].m_ssv);
			if (vesi[iv].m_clrFore != (COLORREF)knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptForeColor, ktpvDefault,
					vesi[iv].m_clrFore);
			if (vesi[iv].m_clrBack != (COLORREF)knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptBackColor, ktpvDefault,
					vesi[iv].m_clrBack);
			if (vesi[iv].m_clrUnder != (COLORREF)knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptUnderColor, ktpvDefault,
					vesi[iv].m_clrUnder);
			if (vesi[iv].m_unt != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptUnderline, ktpvEnum, vesi[iv].m_unt);
			if (vesi[iv].m_mpOffset != knNinch)
				FwXml::WriteIntTextProp(pstrm, pwsf, ktptOffset, ktpvMilliPoint,
					vesi[iv].m_mpOffset);
			FormatToStream(pstrm, " />%n");
		}
		FormatToStream(pstrm, "%s</WsStyles9999>%n", vchIndent.Begin());
	}
}
Ejemplo n.º 13
0
/*----------------------------------------------------------------------------------------------
	Renders the data described in a FORMATETC structure and transfers it through the STGMEDIUM
	structure.

	This is a standard COM IDataObject method.

	@param pfmte Pointer to a FORMATETC structure describing the desired data format.
	@param pmedium Pointer to a STGMEDIUM structure that defines the output medium.

	@return S_OK, DV_E_DVASPECT, DV_E_FORMATETC, DV_E_LINDEX, DV_E_TYMED, E_POINTER,
					E_UNEXPECTED, or E_NOTIMPL.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgTsDataObject::GetData(FORMATETC * pfmte, STGMEDIUM * pmedium)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pfmte);
	ChkComArgPtr(pmedium);
	AssertPtr(m_qtsswss.Ptr());
	if (pfmte->lindex != -1 && pfmte->lindex != 1)
		return DV_E_LINDEX;
	if (pfmte->dwAspect && pfmte->dwAspect != DVASPECT_CONTENT)
		return DV_E_DVASPECT;	// Invalid dwAspect value.

	if (pfmte->cfFormat == LgTsDataObject::s_cfTsString)
	{
		if (pfmte->tymed == TYMED_NULL)
		{
			pmedium->tymed = TYMED_NULL;
			pmedium->pstm = NULL;
			pmedium->pUnkForRelease = NULL;
			return S_OK;
		}
		if (pfmte->tymed & TYMED_ISTORAGE)
		{
			// Since we have no idea where to put the IStorage object, this particular request
			// is handled by GetDataHere instead.
			return E_NOTIMPL;
		}
		else
		{
			return DV_E_TYMED;
		}
	}
	else if (pfmte->cfFormat == CF_TEXT)
	{
		if (pfmte->tymed == TYMED_NULL)
		{
			pmedium->tymed = TYMED_NULL;
			pmedium->pstm = NULL;
			pmedium->pUnkForRelease = NULL;
			return S_OK;
		}
		if (pfmte->tymed & TYMED_HGLOBAL)
		{
			SmartBstr sbstr;
			CheckHr(m_qtsswss->get_Text(&sbstr));
			StrUni stu = sbstr.Chars();
			if (!StrUtil::NormalizeStrUni(stu, UNORM_NFC))
				ThrowInternalError(E_FAIL, "Normalize failure in StringDataObject::GetData.");
			StrAnsi sta(stu);
			pmedium->tymed = TYMED_HGLOBAL;
			pmedium->pUnkForRelease = NULL;
			pmedium->hGlobal = ::GlobalAlloc(GHND, (DWORD)(sta.Length() + 1));
			if (pmedium->hGlobal)
			{
				char * pszDst;
				pszDst = (char *)::GlobalLock(pmedium->hGlobal);
				strcpy_s(pszDst, sta.Length() + 1, sta.Chars());
				::GlobalUnlock(pmedium->hGlobal);
			}
			return S_OK;
		}
		if (!(pfmte->tymed & TYMED_HGLOBAL))
			return DV_E_TYMED;
		else
			return E_UNEXPECTED;
	}
	else if (pfmte->cfFormat == CF_OEMTEXT)
	{
		if (pfmte->tymed == TYMED_NULL)
		{
			pmedium->tymed = TYMED_NULL;
			pmedium->pstm = NULL;
			pmedium->pUnkForRelease = NULL;
			return S_OK;
		}
		if (pfmte->tymed & TYMED_HGLOBAL)
		{
			// REVIEW SteveMc: How does CF_OEMTEXT differ from CF_TEXT?
			SmartBstr sbstr;
			CheckHr(m_qtsswss->get_Text(&sbstr));
			StrUni stu = sbstr.Chars();
			if (!StrUtil::NormalizeStrUni(stu, UNORM_NFC))
				ThrowInternalError(E_FAIL, "Normalize failure in StringDataObject::GetData.");
			StrAnsi sta(stu);
			pmedium->tymed = TYMED_HGLOBAL;
			pmedium->pUnkForRelease = NULL;
			pmedium->hGlobal = ::GlobalAlloc(GHND, (DWORD)(sta.Length() + 1));
			if (pmedium->hGlobal)
			{
				char * pszDst;
				pszDst = (char *)::GlobalLock(pmedium->hGlobal);
				strcpy_s(pszDst, sta.Length() + 1, sta.Chars());
				::GlobalUnlock(pmedium->hGlobal);
			}
			return S_OK;
		}
		if (!(pfmte->tymed & TYMED_HGLOBAL))
			return DV_E_TYMED;
	}
	else if (pfmte->cfFormat == CF_UNICODETEXT)
	{
		if (pfmte->tymed == TYMED_NULL)
		{
			pmedium->tymed = TYMED_NULL;
			pmedium->pstm = NULL;
			pmedium->pUnkForRelease = NULL;
			return S_OK;
		}
		if (pfmte->tymed & TYMED_HGLOBAL)
		{
			SmartBstr sbstr;
			CheckHr(m_qtsswss->get_Text(&sbstr));
			StrUni stu = sbstr.Chars();
			if (!StrUtil::NormalizeStrUni(stu, UNORM_NFC))
				ThrowInternalError(E_FAIL, "Normalize failure in StringDataObject::GetData.");
			pmedium->tymed = TYMED_HGLOBAL;
			pmedium->pUnkForRelease = NULL;
			int cb = isizeof(wchar) * (stu.Length() + 1);
			pmedium->hGlobal = ::GlobalAlloc(GHND, (DWORD)cb);
			if (pmedium->hGlobal)
			{
				wchar * pszDst;
				pszDst = (wchar *)::GlobalLock(pmedium->hGlobal);
				memcpy(pszDst, stu.Chars(), cb);
				::GlobalUnlock(pmedium->hGlobal);
			}
			return S_OK;
		}
		if (!(pfmte->tymed & TYMED_HGLOBAL))
			return DV_E_TYMED;
		else
			return E_UNEXPECTED;
	}
	else
	{
		return DV_E_FORMATETC;
	}
	END_COM_METHOD(g_fact, IID_IDataObject);
}
Ejemplo n.º 14
0
void ViewTest1::TestSetTagInfo()
{
	// Trying to retrieve via get_ without a previous put_
	OLECHAR rgchGuid[9] = L"75F2376A";
	HVO hvo;
	SmartBstr sbstrAbbr;
	SmartBstr sbstrName;
	COLORREF clrFore;
	COLORREF clrBack;
	COLORREF clrUnder;
	int ivar;
	ComBool fHidden;

	HRESULT hr = m_qxvoTest->GetTagInfo(rgchGuid, &hvo, &sbstrAbbr, &sbstrName, &clrFore,
		&clrBack, &clrUnder, &ivar, &fHidden);
	if (!FAILED(hr))
		FailureFormat("Call to function GetTagInfo(invalid params...) should have failed. "
			"hr = %x", hr);

	// Sending NULL pointers for all params, only a few params, etc
	hr = m_qxvoTest->SetTagInfo(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (!FAILED(hr))
		Failure("Call to function SetTagInfo(NULL...) should have returned an error");

	hr = m_qxvoTest->SetTagInfo(NULL, 23, kosmAll, SmartBstr(L"AAAAA"), SmartBstr(L"ZZZZZ"),
		0x00000000, 0x00FF00FF, 0x0000FF00, 2, false);
	if (!FAILED(hr))
		Failure("Call to function SetTagInfo(NULL, valid params...) should have returned an "
			"error");

	hr = m_qxvoTest->GetTagInfo(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (!FAILED(hr))
		Failure("Call to function GetTagInfo(NULL...) should have returned an error");

	hr = m_qxvoTest->GetTagInfo(NULL, &hvo, &sbstrAbbr, &sbstrName, &clrFore, &clrBack,
		&clrUnder, &ivar, &fHidden);
	if (!FAILED(hr))
		Failure("Call to function GetTagInfo(NULL, valid params...) should have returned an "
			"error");

	hr = m_qxvoTest->GetTagInfo(rgchGuid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (!FAILED(hr))
		Failure("Call to function GetTagInfo(GUID, NULL...) should have returned an error");

	hr = m_qxvoTest->GetTagInfo(rgchGuid, NULL, NULL, &sbstrName, NULL, NULL, NULL, NULL,
		&fHidden);
	if (!FAILED(hr))
		Failure("Call to function GetTagInfo(GUID, some invalid params) should have returned an"
			" error");

	// Once set tag info is called, it stays recorded for the life of the test (if it does not
	// fail) The SmartBstr's added here are also used later in the test for the Sort function

	// Test to see if underline type has a range and that it is checked
	hr = m_qxvoTest->SetTagInfo(rgchGuid, 23, kosmAll, SmartBstr(L"AAAAA"), SmartBstr(L"ZZZZZ"),
		0x00000000, 0x00FF00FF, 0x0000FF00, -2342, false);
	if (!FAILED(hr))
		Failure("SetTagInfo with invalid underline type (-2342) should have returned an error");

	hr = m_qxvoTest->SetTagInfo(rgchGuid, 23, kosmAll, SmartBstr(L"AAAAA"), SmartBstr(L"ZZZZZ"),
		0x00000000, 0x00FF00FF, 0x0000FF00, 982347, false);
	if (!FAILED(hr))
		Failure("SetTagInfo with invalid underline type (982347) should have returned an "
			"error");

	// Comparing results of GetTagInfo after previous call to SetTagInfo
	// This is the first valid call to SetTagInfo. This will set one entry into the database at
	// element 0. Also subsequent calls to SetTagInfo with same GUID will replace data, not add
	hr = m_qxvoTest->SetTagInfo(rgchGuid, 23, kosmAll, SmartBstr(L"AAAAA"), SmartBstr(L"ZZZZZ"),
		0x00000000, 0x00FF00FF, 0x0000FF00, 2, false);
	if (FAILED(hr))
		FailureFormat("SetTagInfo function call failed. hr = %x", hr);

	CheckHr(m_qxvoTest->GetTagInfo(rgchGuid, &hvo, &sbstrAbbr, &sbstrName,
		&clrFore, &clrBack, &clrUnder, &ivar, &fHidden));
	if (hvo != 23 || wcscmp(sbstrAbbr.Chars(), L"AAAAA") ||
		wcscmp(sbstrName.Chars(), L"ZZZZZ") || clrFore != 0x00000000 ||
		clrBack != 0x00FF00FF || clrUnder != 0x0000FF00 || ivar != 2 ||	fHidden != false)
		Failure("Function GetTagInfo returned wrong result after previous SetTagInfo"
			" function call");

	// The above SetTagInfo should have set an entry (element 0) into the "database"
	// (what database?) Now try to retrieve via GetDbTagInfo as kind of follow up test
	CheckHr(m_qxvoTest->GetDbTagInfo(0, &hvo, &clrFore, &clrBack, &clrUnder, &ivar, &fHidden,
		rgchGuid));
	if (hvo != 23 || wcscmp(sbstrAbbr.Chars(), L"AAAAA") ||
		wcscmp(sbstrName.Chars(), L"ZZZZZ") || clrFore != 0x00000000 || clrBack != 0x00FF00FF ||
		clrUnder != 0x0000FF00 || ivar != 2 || fHidden != false)
		Failure("Function GetDbTagInfo returned wrong result after previous "
			"SetTagInfo function call");

	// Test with valid GUID but some invalid NULL params - again assuming that its an all
	// params are valid or else the function call should fail
	hr = m_qxvoTest->GetTagInfo(rgchGuid, NULL, NULL, &sbstrName, NULL, &clrBack, NULL, NULL,
		NULL);
	if (!FAILED(hr))
		Failure("GetTagInfo(rgchGuid, some invalid params) should have returned an error");
}
Ejemplo n.º 15
0
/*----------------------------------------------------------------------------------------------
	Write an integer-valued text property in XML format.

	@param pstrm Pointer to an IStream for output.
	@param tpt
	@param nVar
	@param nVal
----------------------------------------------------------------------------------------------*/
void FwXml::WriteIntTextProp(IStream * pstrm, ILgWritingSystemFactory * pwsf, int tpt, int nVar,
	int nVal)
{
	AssertPtr(pstrm);
	AssertPtr(pwsf);

	switch (tpt)
	{
	case ktptBackColor:
		FormatToStream(pstrm, " backcolor=\"%s\"", ColorName(nVal));
		break;
	case ktptBold:
		FormatToStream(pstrm, " bold=\"%s\"", ToggleValueName((byte)nVal));
		break;
	case ktptWs:
		if (nVal == 0)
		{
			Assert(nVar == 0);
		}
		else
		{
			SmartBstr sbstrWs;
			CheckHr(pwsf->GetStrFromWs(nVal, &sbstrWs));
			if (!sbstrWs.Length())
				ThrowInternalError(E_INVALIDARG, "Writing system invalid for <Run ws>");
			FormatToStream(pstrm, " ws=\"", nVal);
			WriteXmlUnicode(pstrm, sbstrWs.Chars(), sbstrWs.Length());
			FormatToStream(pstrm, "\"", nVal);
		}
		break;
	case ktptBaseWs:
		if (nVal == 0)
		{
			Assert(nVar == 0);
		}
		else
		{
			SmartBstr sbstrWs;
			CheckHr(pwsf->GetStrFromWs(nVal, &sbstrWs));
			if (!sbstrWs.Length())
				ThrowInternalError(E_INVALIDARG, "Writing system invalid for <Run wsBase>");
			FormatToStream(pstrm, " wsBase=\"", nVal);
			WriteXmlUnicode(pstrm, sbstrWs.Chars(), sbstrWs.Length());
			FormatToStream(pstrm, "\"", nVal);
		}
		break;
	case ktptFontSize:
		FormatToStream(pstrm, " fontsize=\"%d\"", nVal);
		if (nVar != ktpvDefault)
			FormatToStream(pstrm, " fontsizeUnit=\"%s\"", PropVarName(nVar));
		break;
	case ktptForeColor:
		FormatToStream(pstrm, " forecolor=\"%s\"", ColorName(nVal));
		break;
	case ktptItalic:
		FormatToStream(pstrm, " italic=\"%s\"", ToggleValueName((byte)nVal));
		break;
	case ktptOffset:
		FormatToStream(pstrm, " offset=\"%d\"", nVal);
		FormatToStream(pstrm, " offsetUnit=\"%s\"",	PropVarName(nVar));
		break;
	case ktptSuperscript:
		FormatToStream(pstrm, " superscript=\"%s\"", SuperscriptValName((byte)nVal));
		break;
	case ktptUnderColor:
		FormatToStream(pstrm, " undercolor=\"%s\"", ColorName(nVal));
		break;
	case ktptUnderline:
		FormatToStream(pstrm, " underline=\"%s\"", UnderlineTypeName((byte)nVal));
		break;
	case ktptSpellCheck:
		FormatToStream(pstrm, " spellcheck=\"%s\"", SpellingModeName((byte)nVal));
		break;

	//	Paragraph-level properties:

	case ktptAlign:
		FormatToStream(pstrm, " align=\"%s\"", AlignmentTypeName((byte)nVal));
		break;
	case ktptFirstIndent:
		FormatToStream(pstrm, " firstIndent=\"%d\"", nVal);
		break;
	case ktptLeadingIndent:
		FormatToStream(pstrm, " leadingIndent=\"%d\"", nVal);
		break;
	case ktptTrailingIndent:
		FormatToStream(pstrm, " trailingIndent=\"%d\"", nVal);
		break;
	case ktptSpaceBefore:
		FormatToStream(pstrm, " spaceBefore=\"%d\"", nVal);
		break;
	case ktptSpaceAfter:
		FormatToStream(pstrm, " spaceAfter=\"%d\"", nVal);
		break;
	case ktptTabDef:
		FormatToStream(pstrm, " tabDef=\"%d\"", nVal);
		break;
	case ktptLineHeight:
		FormatToStream(pstrm, " lineHeight=\"%d\"", abs(nVal));
		FormatToStream(pstrm, " lineHeightUnit=\"%s\"",	PropVarName(nVar));
		Assert(nVal >= 0 || nVar == ktpvMilliPoint);
		if (nVar == ktpvMilliPoint)
		{
			// negative means "exact" internally.  See FWC-20.
			FormatToStream(pstrm, " lineHeightType=\"%s\"", nVal < 0 ? "exact" : "atLeast");
		}
		break;
	case ktptParaColor:
		FormatToStream(pstrm, " paracolor=\"%s\"", ColorName(nVal));
		break;

	//	Properties from the views subsystem:

	case ktptRightToLeft:
		FormatToStream(pstrm, " rightToLeft=\"%d\"", nVal);
		break;
	case ktptPadLeading:
		FormatToStream(pstrm, " padLeading=\"%d\"", nVal);
		break;
	case ktptPadTrailing:
		FormatToStream(pstrm, " padTrailing=\"%d\"", nVal);
		break;
	// Not the other margins: they are duplicated by FirstIndent etc.
	case ktptMarginTop:
		FormatToStream(pstrm, " MarginTop=\"%d\"", nVal);
		break;
	case ktptPadTop:
		FormatToStream(pstrm, " padTop=\"%d\"", nVal);
		break;
	case ktptPadBottom:
		FormatToStream(pstrm, " padBottom=\"%d\"", nVal);
		break;

	case ktptBorderTop:
		FormatToStream(pstrm, " borderTop=\"%d\"", nVal);
		break;
	case ktptBorderBottom:
		FormatToStream(pstrm, " borderBottom=\"%d\"", nVal);
		break;
	case ktptBorderLeading:
		FormatToStream(pstrm, " borderLeading=\"%d\"", nVal);
		break;
	case ktptBorderTrailing:
		FormatToStream(pstrm, " borderTrailing=\"%d\"", nVal);
		break;
	case ktptBorderColor:
		FormatToStream(pstrm, " borderColor=\"%s\"", ColorName(nVal));
		break;

	case ktptBulNumScheme:
		FormatToStream(pstrm, " bulNumScheme=\"%d\"", nVal);
		break;
	case ktptBulNumStartAt:
		FormatToStream(pstrm, " bulNumStartAt=\"%d\"", nVal == INT_MIN ? 0 : nVal);
		break;

	case ktptDirectionDepth:
		FormatToStream(pstrm, " directionDepth=\"%d\"", nVal);
		break;
	case ktptKeepWithNext:
		FormatToStream(pstrm, " keepWithNext=\"%d\"", nVal);
		break;
	case ktptKeepTogether:
		FormatToStream(pstrm, " keepTogether=\"%d\"", nVal);
		break;
	case ktptHyphenate:
		FormatToStream(pstrm, " hyphenate=\"%d\"", nVal);
		break;
	case ktptWidowOrphanControl:
		FormatToStream(pstrm, " widowOrphan=\"%d\"", nVal);
		break;
	case ktptMaxLines:
		FormatToStream(pstrm, " maxLines=\"%d\"", nVal);
		break;
	case ktptCellBorderWidth:
		FormatToStream(pstrm, " cellBorderWidth=\"%d\"", nVal);
		break;
	case ktptCellSpacing:
		FormatToStream(pstrm, " cellSpacing=\"%d\"", nVal);
		break;
	case ktptCellPadding:
		FormatToStream(pstrm, " cellPadding=\"%d\"", nVal);
		break;
	case ktptEditable:
		FormatToStream(pstrm, " editable=\"%s\"", EditableName(nVal));
		break;
	case ktptSetRowDefaults:
		FormatToStream(pstrm, " setRowDefaults=\"%d\"", nVal);
		break;
	case ktptRelLineHeight:
		FormatToStream(pstrm, " relLineHeight=\"%d\"", nVal);
		break;
	case ktptTableRule:
		// Ignore this view-only property.
		break;
	default:
		break;
	}
}
Ejemplo n.º 16
0
/*----------------------------------------------------------------------------------------------
	Save data in the cache, to the database.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP VwRsOdbcDa::Save(SqlDb & sdb)
{
	BEGIN_COM_METHOD

	const kcchErrMsgBuf = 1024;
	const kcbFmtBufMax = 1024;
	const kcchMaxColNameSize = 200;

	SQLINTEGER cbColVal;
	SDWORD cbClassName;
	long cbHvo;
	SDWORD cbFieldName;
	SDWORD cbFlid;
	int cbFmtBufSize = kcbFmtBufMax;
	int cbFmtSpaceTaken;
	SDWORD cbType;
	SQLUSMALLINT cParamsProcessed = 0;
	HRESULT hr;
	FieldMetaDataMap fmdm;		//  REVIEW PaulP:  Would be nice to have this kept globally.
	FieldMetaDataRec fmdr;
	int nColVal;
	int nFlid;
	ITsStringPtr qtssColVal;
	RETCODE rc;
	byte * rgbFmt = NewObj byte[kcbFmtBufMax]; //[kcbFmtBufMax];
	SmartBstr sbstr;
	SQLCHAR sqlchSqlState[5];
	SQLCHAR sqlchMsgTxt[kcchErrMsgBuf];
	SQLINTEGER sqlnNativeErrPtr;
	SQLSMALLINT sqlnTextLength;
	SQLRETURN sqlr;
	SqlStatement sstmt;
	StrUni suColumnName;
	StrUni suFieldMetaDataSql;
	StrUni suSql;
	StrUni suTableName;
	wchar wchClassName[kcchMaxColNameSize];
	wchar wchFieldName[kcchMaxColNameSize];


	Assert(sdb.IsOpen());


	/*------------------------------------------------------------------------------------------
		If a pointer to a HashMap of field$ metadata information was not passed in as a
		parameter, create the HashMap.  The metaData includes all field names, field types,
		class names, and destination class name from the field$ and class$ tables.
		This information is needed since only store the "flid" value is stored in the cache
		(as the "tag") so when it comes time to do SQL "insert" and "update" statements,
		one need's to know what table and column needs to be affected.

		REVIEW PaulP:  Should really cache this information globally so that it does not have
		to be reloaded each time the view cache is saved.  The only time this info would have
		to be reloaded is when custom fields are added.  Perhaps we could have a table with
		a single record which indicates the last date/time a change to the database was made.
		This could be compared with the currently loaded date each time the cache is saved to
		see if there is a need to reload the field$ meta information.  Of course, if we
		require that only one user is allowed to be connected for a custom field addition,
		this would not be necessary.

		TOxDO PaulP:  Cleanup on any error exit, including db rollback.
						CheckSqlRc(SQLEndTran(SQL_HANDLE_DBC, sdb.Hdbc(), SQL_ROLLBACK));
	------------------------------------------------------------------------------------------*/
	try
	{
		//  Set up SQL statment to obtain meta data.
		suFieldMetaDataSql.Format(
			L"select f.Id FLID, Type, f.Name FLD_NAME,"
			L" c.Name CLS_NAME"
			L" from Field$ f"
			L" join Class$ c on c.id = f.Class"
			L" order by f.id");
		sstmt.Init(sdb);
		CheckSqlRc(SQLExecDirectW(sstmt.Hstmt(), \
			const_cast<wchar *>(suFieldMetaDataSql.Chars()), SQL_NTS));

		//  Bind Columns.
		rc = SQLSetStmtAttr(sstmt.Hstmt(), SQL_ATTR_PARAMS_PROCESSED_PTR, &cParamsProcessed, 0);
		CheckSqlRc(SQLBindCol(sstmt.Hstmt(), 1, SQL_C_SLONG, &nFlid, isizeof(int),
			&cbFlid));
		CheckSqlRc(SQLBindCol(sstmt.Hstmt(), 2, SQL_C_SLONG, &fmdr.m_iType,
			isizeof(fmdr.m_iType), &cbType));
		CheckSqlRc(SQLBindCol(sstmt.Hstmt(), 3, SQL_C_WCHAR, &wchFieldName,
			kcchMaxColNameSize, &cbFieldName));
		CheckSqlRc(SQLBindCol(sstmt.Hstmt(), 4, SQL_C_WCHAR, &wchClassName,
			kcchMaxColNameSize, &cbClassName));

		//  Put info from the columns into a FieldMetaDataRec record and insert
		//  this in the FieldMetaData HashMap.
		for (;;)
		{
			rc = SQLFetch(sstmt.Hstmt());
			if (rc != SQL_SUCCESS)
				break;
			// TOxDO PaulP:  Change this so it just gets a null terminated string!!!
			fmdr.m_suFieldName.Assign(wchFieldName, kcchMaxColNameSize);
			fmdr.m_suClassName.Assign(wchClassName, kcchMaxColNameSize);
			fmdm.Insert(nFlid, fmdr);
		}
		if (rc != SQL_NO_DATA)
		{
			//  REVIEW PaulP (SteveMc): Handle possible error message?
			ThrowHr(WarnHr(E_UNEXPECTED));
		}
		sstmt.Clear();
	}
	catch (...)
	{
		sstmt.Clear();
		delete rgbFmt;
		return E_UNEXPECTED;
	}


	/*------------------------------------------------------------------------------------------
		For every key in the "m_soprMods" ObjPropSet set (ie. all the object properties
		that have been updated), look up that key in the appropriate HashMap and form an SQL
		"update" statement according to the field$ "Type".

		This begins a single database transaction.  All the data in the application view cache
		must either be inserted/updated to the database successfully or the action should fail.
		This necessitates that the database connection is in manual-commit mode.

		REVIEW PaulP:  It is probably faster to collect all the properties for a given object
		type and update the table in the database all with one SQL statement but this will
		do for now until the OLE DB stuff is done.
	------------------------------------------------------------------------------------------*/
	try
	{
		ObjPropSet::iterator itops;
		for (itops = m_soprMods.Begin(); itops != m_soprMods.End(); ++itops)
		{
			//  Get the oprKey from the "update object property" Set.
			ObjPropRec & oprKey = itops.GetValue();

			//  Get the field$ metadata information based on the tag of that oprKey.
			fmdm.Retrieve(oprKey.m_tag, &fmdr);

			//  Initialize and form the SQL statment based on the field "type".
			sstmt.Init(sdb);
			switch (fmdr.m_iType)
			{
				case kcptNil:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;

				case kcptBoolean:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;

				case kcptInteger:
					//  Prepare the SQL statement.  (Uses parameters).
					suSql.Format(L"update %s set %s=? where id=?", fmdr.m_suClassName.Chars(),
						fmdr.m_suFieldName.Chars());
					rc = SQLPrepareW(sstmt.Hstmt(), const_cast<wchar *>(suSql.Chars()),
						SQL_NTS);

					//  Get the integer value from the appropriate HashMap.
					if (m_hmoprn.Retrieve(oprKey, &nColVal))
					{
						//  Bind integer value as the first parameter.
						if (nColVal)
						{
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_SLONG, SQL_INTEGER, 0, 0, &nColVal, 0, &cbColVal);
						}
						else
						{
							// REVIEW JohnT:  How do we indicate in the HashMap that the user
							//		wants to set an integer to NULL?
							cbColVal = SQL_NULL_DATA;
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_SLONG, SQL_INTEGER, 0, 0, NULL, 0, &cbColVal);
						}

						//  Bind the HVO (Id) as the second parameter.
						rc = SQLBindParameter(sstmt.Hstmt(), 2, SQL_PARAM_INPUT,
							SQL_C_SLONG, SQL_INTEGER, 0, 0, &(oprKey.m_hvo), 0, &cbHvo);
					}
					else
					{
						ThrowHr(WarnHr(E_UNEXPECTED));
					}
					break;


				case kcptNumeric:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptFloat:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptTime:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptGuid:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptImage:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptGenDate:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptBinary:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;


				case kcptString:
				case kcptBigString:

					//  Prepare the SQL statement.  (Uses parameters.)
					//  REVIEW PaulP:  Should I be hard-coding "_Fmt" in like this?
					suSql.Format(L"update %s set %s=?, %s_Fmt=? where id=?",
						fmdr.m_suClassName.Chars(), fmdr.m_suFieldName.Chars(),
						fmdr.m_suFieldName.Chars());
					rc = SQLPrepareW(sstmt.Hstmt(), const_cast<wchar *>(suSql.Chars()),
						SQL_NTS);

					if (m_hmoprtss.Retrieve(oprKey, qtssColVal))
					{
						//  Obtain a SmartBstr from the COM smart pointer that points
						//  to the TsString.
						CheckHr(qtssColVal->get_Text(&sbstr));
						if (sbstr.Length())
						{
							//  Copy format information of the TsString to byte array rgbFmt.
							hr = qtssColVal->SerializeFmtRgb(rgbFmt, cbFmtBufSize,
								&cbFmtSpaceTaken);
							if (hr != S_OK)
							{
								if (hr == S_FALSE)
								{
									//  If the supplied buffer is too small, try it again with
									//  the value that cbFmtSpaceTaken was set to.  If this
									//   fails, throw error.
									delete rgbFmt;
									rgbFmt = NewObj byte[cbFmtSpaceTaken];
									cbFmtBufSize = cbFmtSpaceTaken;
									CheckHr(qtssColVal->SerializeFmtRgb(rgbFmt, cbFmtBufSize,
										&cbFmtSpaceTaken));
								}
								else
								{
									ThrowHr(WarnHr(E_UNEXPECTED));
								}
							}

							//  Bind the text and format parts of the string to the parameters.
							SQLINTEGER cbTextPart = sbstr.Length() * 2;
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_WCHAR, SQL_WVARCHAR, cbTextPart, 0,
								const_cast<wchar *>(sbstr.Chars()), cbTextPart, &cbTextPart);
							SQLINTEGER cbFmtPart = cbFmtSpaceTaken;
							rc = SQLBindParameter(sstmt.Hstmt(), 2, SQL_PARAM_INPUT,
								SQL_C_BINARY, SQL_VARBINARY, cbFmtPart, 0, rgbFmt, cbFmtPart,
								&cbFmtPart);
						}
						else
						{
							//  Since the string had no length, bind NULL to the parameters.
							SQLINTEGER cbTextPart = SQL_NULL_DATA;
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_WCHAR, SQL_WVARCHAR, 1, 0, NULL, 0, &cbTextPart);
							//  REVIEW PaulP:  Should we set the Fmt info to NULL for NULL
							//     strings or should we use the Fmt info returned from the
							//     TsString?
							SQLINTEGER cbFmtPart = SQL_NULL_DATA;
							rc = SQLBindParameter(sstmt.Hstmt(), 2, SQL_PARAM_INPUT,
								SQL_C_BINARY, SQL_VARBINARY, 1, 0, NULL, 0, &cbFmtPart);
						}
					}
					else
					{
						ThrowHr(WarnHr(E_UNEXPECTED));
					}

					//  Bind the HVO (ie. Id) value.
					rc = SQLBindParameter(sstmt.Hstmt(), 3, SQL_PARAM_INPUT, SQL_C_SLONG,
						SQL_INTEGER, 0, 0, &(oprKey.m_hvo), 0, &cbHvo);
					break;


				case kcptBigUnicode:
				case kcptUnicode:

					//  Prepare the SQL statement.  (Uses parameters.)
					suSql.Format(L"update %s set %s=? where id=?", fmdr.m_suClassName.Chars(),
						fmdr.m_suFieldName.Chars());
					rc = SQLPrepareW(sstmt.Hstmt(), const_cast<wchar *>(suSql.Chars()),
						SQL_NTS);

					if (m_hmoprtss.Retrieve(oprKey, qtssColVal))
					{
						//  Obtain a SmartBstr from the COM smart pointer that
						//  points to a TsString.
						CheckHr(qtssColVal->get_Text(&sbstr));
						if (sbstr.Length())
						{
							//  Bind the string parameter.
							SQLINTEGER cbTextPart = sbstr.Length() * 2;
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_WCHAR, SQL_WVARCHAR, cbTextPart, 0,
								const_cast<wchar *>(sbstr.Chars()), cbTextPart, &cbTextPart);
						}
						else
						{
							//  If the string had no length, bind NULL to the parameter.
							SQLINTEGER cbTextPart = SQL_NULL_DATA;
							rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
								SQL_C_WCHAR, SQL_WVARCHAR, 1, 0, NULL, 0, &cbTextPart);
						}
					}
					else
					{
						ThrowHr(WarnHr(E_UNEXPECTED));
					}

					//  Bind the HVO (ie. Id) value.
					rc = SQLBindParameter(sstmt.Hstmt(), 2, SQL_PARAM_INPUT, SQL_C_SLONG,
						SQL_INTEGER, 0, 0, &(oprKey.m_hvo), 0, &cbHvo);
					break;

				case kcptOwningAtom:
					//  Update owning field.
					//  Update Owner$ object of CmObject.
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptReferenceAtom:
					//  This is basically the same as the Integer case except we obtain the
					//  value from the m_hmoprobj HashMap rather than the m_hmoprn HashMap.
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptOwningCollection:
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptReferenceCollection:
					//  Affect the joiner table.
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptOwningSequence:
					//  Need to update.
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				case kcptReferenceSequence:
					//  Affect the joiner table.
					ThrowHr(WarnHr(E_NOTIMPL));
					break;
				default:
					ThrowHr(WarnHr(E_UNEXPECTED));
					break;
			}

			//  Execute the SQL update command.
			//rc = SQLSetStmtAttr(sstmt.Hstmt(), SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
			rc = SQLExecute(sstmt.Hstmt());
			if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO)
			{
				//  TOxDO PaulP:  Error information can be obtained from sqlchMsgTxt.
				sqlr = SQLGetDiagRec(SQL_HANDLE_STMT, sstmt.Hstmt(), 1, sqlchSqlState,
					&sqlnNativeErrPtr, sqlchMsgTxt, kcchErrMsgBuf, &sqlnTextLength);
				ThrowHr(WarnHr(E_UNEXPECTED));
			}
			sstmt.Clear();
		}


		/*--------------------------------------------------------------------------------------
			Go through the m_soperMods ObjPropSet set and update columns in the MultiX tables.
		--------------------------------------------------------------------------------------*/
		ObjPropEncSet::iterator itopes;
		for (itopes = m_soperMods.Begin(); itopes != m_soperMods.End(); ++itopes)
		{
			//  Get the operKey from the "update MSA" Set.
			ObjPropEncRec & operKey = itopes.GetValue();

			//  Get the field$ metadata information based on the tag of that operKey.
			fmdm.Retrieve(operKey.m_tag, &fmdr);

			//  Initialize and form the SQL statment.
			sstmt.Init(sdb);
			if (m_hmopertss.Retrieve(operKey, qtssColVal))
			{
				//  Obtain a SmartBstr from the COM smart pointer that points to the TsString.
				CheckHr(qtssColVal->get_Text(&sbstr));
				if (sbstr.Length())
				{
					//  Get the format of the TsString
					hr = qtssColVal->SerializeFmtRgb(rgbFmt, cbFmtBufSize, &cbFmtSpaceTaken);
					if (hr != S_OK)
					{
						if (hr == S_FALSE)
						{
							//  If the supplied buffer is too small, try it again with the value
							//  that cbFmtSpaceTaken was set to.  If this fails, signal error.
							delete rgbFmt;
							rgbFmt = NewObj byte[cbFmtSpaceTaken];
							cbFmtBufSize = cbFmtSpaceTaken;
							CheckHr(qtssColVal->SerializeFmtRgb(rgbFmt, cbFmtBufSize,
								&cbFmtSpaceTaken));
						}
						else
						{
							ThrowHr(WarnHr(E_UNEXPECTED));
						}
					}

					//  Execute stored procedure to set MSA value.
					//  REVIEW PaulP:  This technique isn't going to work for custom fields
					//		since there will likely not be any "Set" stored procedure.
					suSql.Format(L"exec Set_%s_%s %d, %d, ?, ?", fmdr.m_suClassName.Chars(),
						fmdr.m_suFieldName.Chars(), operKey.m_hvo, operKey.m_ws);
					rc = SQLPrepareW(sstmt.Hstmt(), const_cast<wchar *>(suSql.Chars()),
						SQL_NTS);

					//  Bind the text and format parts of the string to the parameters.
					SQLINTEGER cbTextPart = sbstr.Length() * 2;
					rc = SQLBindParameter(sstmt.Hstmt(), 1, SQL_PARAM_INPUT,
						SQL_C_WCHAR, SQL_WVARCHAR, cbTextPart, 0,
						const_cast<wchar *>(sbstr.Chars()), cbTextPart, &cbTextPart);

					SQLINTEGER cbFmtPart = cbFmtSpaceTaken;
					rc = SQLBindParameter(sstmt.Hstmt(), 2, SQL_PARAM_INPUT, SQL_C_BINARY,
					SQL_VARBINARY, cbFmtPart, 0, rgbFmt, cbFmtPart, &cbFmtPart);
				}
				else
				{
					//  REVIEW PaulP:  This technique isn't going to work for custom fields
					//		since there will likely not be any "Set" stored procedure.
					suSql.Format(L"exec Set_%s_%s %d, %d, NULL, NULL",
						fmdr.m_suClassName.Chars(), fmdr.m_suFieldName.Chars(), operKey.m_hvo,
						operKey.m_ws);
					rc = SQLPrepareW(sstmt.Hstmt(), const_cast<wchar *>(suSql.Chars()),
						SQL_NTS);
				}

				//  Execute the SQL update command.
				//rc = SQLSetStmtAttr(sstmt.Hstmt(), SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
				rc = SQLExecute(sstmt.Hstmt());
				if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO)
				{
					//  TOxDO PaulP:  Error information can be obtained from sqlchMsgTxt.
					sqlr = SQLGetDiagRec(SQL_HANDLE_STMT, sstmt.Hstmt(), 1, sqlchSqlState,
						&sqlnNativeErrPtr, sqlchMsgTxt, kcchErrMsgBuf, &sqlnTextLength);
					ThrowHr(WarnHr(E_UNEXPECTED));
				}
				sstmt.Clear();
			}
			else
			{
				ThrowHr(WarnHr(E_UNEXPECTED));
			}
		}


		/*--------------------------------------------------------------------------------------
			Commit the database transaction.
			REVIEW PaulP:  The DataSource MUST be in manual commit mode.
		--------------------------------------------------------------------------------------*/
		CheckSqlRc(SQLEndTran(SQL_HANDLE_DBC, sdb.Hdbc(), SQL_COMMIT));

	}
	catch (...)
	{
		sstmt.Clear();
		delete rgbFmt;
		CheckSqlRc(SQLEndTran(SQL_HANDLE_DBC, sdb.Hdbc(), SQL_ROLLBACK));
		return E_UNEXPECTED;
	}


	/*------------------------------------------------------------------------------------------
		Clear the two Sets containing records of modified properties and MBA's.
	------------------------------------------------------------------------------------------*/
	m_soprMods.Clear();
	m_soperMods.Clear();
	delete rgbFmt; // REVIEW: Shouldn't this be delete[]?

	return S_OK;

	END_COM_METHOD(g_fact, IID_IVwCacheDa);
}
Ejemplo n.º 17
0
/*----------------------------------------------------------------------------------------------
	Check to see if the edit box has valid data.  if so return true.  If not then put up a
	message to the user, then return false.
----------------------------------------------------------------------------------------------*/
bool CleDeFeString::IsOkToClose(bool fWarn)
{
	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(m_qadsc->MainWindow());
	Assert(pcmw);

	IVwSelectionPtr qvwsel;
	CheckHr(m_qrootb->get_Selection(&qvwsel));
	if (qvwsel)
	{
		ComBool fOk;
		CheckHr(qvwsel->Commit(&fOk));
	}

	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	StrUni stuNew;

	const OLECHAR * prgwch;
	int cch;
	ITsStringPtr qtss;
	CustViewDaPtr qcvd;

	GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	int ws = m_qsvc->WritingSystems()[0];

	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, ws, &qtss));
	Assert(qtss);
	qtss->LockText(&prgwch, &cch);
	qtss->UnlockText(prgwch);

	// Trim leading and trailing space characters.
	UnicodeString ust(prgwch, cch);
	ust.trim();
	stuNew.Assign(ust.getBuffer(), ust.length());

	//  Obtain pointer to IOleDbEncap interface.
	IOleDbEncapPtr qode;
	IOleDbCommandPtr qodc;
	StrUni stuSql;
	ComBool fIsNull;
	ComBool fMoreRows;
	AssertPtr(m_qadsc->MainWindow());
	AfLpInfo * plpi = m_qadsc->MainWindow()->GetLpInfo();
	AssertPtr(plpi);
	AfDbInfo * pdbi = plpi->GetDbInfo();
	AssertPtr(pdbi);
	pdbi->GetDbAccess(&qode);
	AssertPtr(qode);
	CheckHr(qode->CreateCommand(&qodc));
	int cpii = qpli->GetCount();

	if ((m_flid == kflidCmPossibility_Name) || (m_flid == kflidCmPossibility_Abbreviation))
	{
		// Make sure it does not have a ":" or a " - " in the string
		int ich = stuNew.FindStr(L":");
		StrUni stuTmp;
		bool fFixed = false;
		while (ich > 0)
		{
			stuNew.Replace(ich,ich + 1,"-");
			fFixed = true;
			ich = stuNew.FindStr(L":");
		}
		ich = stuNew.FindStr(L" - ");
		while (ich > 0)
		{
			stuNew.Replace(ich,ich + 3,"-");
			fFixed = true;
			ich = stuNew.FindStr(L" - ");
		}
		if (fFixed)
		{
			if (fWarn)
			{
				ITsStrFactoryPtr qtsf;
				qtsf.CreateInstance(CLSID_TsStrFactory);
				qtsf->MakeStringRgch(stuNew.Chars(), stuNew.Length(), pcmw->UserWs(), &qtss);
				CheckHr(qcvd->SetMultiStringAlt(m_hvoObj, m_flid, ws, qtss));
				CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
				StrApp strMsg(kstidFixedStr);
				StrApp strTitle(kstidFixedStrTitle);
				::MessageBox(m_hwnd, strMsg.Chars(), strTitle.Chars(),
					MB_OK | MB_ICONINFORMATION);
			}
			return false;
		}
	}

	if (qpli->GetAllowDup())
		return true;

	ILgWritingSystemFactoryPtr qwsf;
	pdbi->GetLgWritingSystemFactory(&qwsf);
	AssertPtr(qwsf);
	switch (m_flid)
	{
		case kflidCmPossibility_Name:
		{
			for (int ipii = 0; ipii < cpii; ipii++)
			{
				if (ipii == ipss)
					continue;
				PossItemInfo * ppii = qpli->GetPssFromIndex(ipii);
				AssertPtr(ppii);
				StrUni stu;
				ppii->GetName(stu, kpntName);
				if (stu == stuNew)
				{
					stuSql.Format(L"select ws from CmPossibility_Name "
						L"where obj = %d and ws = %d",
						ppii->GetPssId(), ws);
					CheckHr(qode->CreateCommand(&qodc));
					CheckHr(qodc->ExecCommand(stuSql.Bstr(), knSqlStmtSelectWithOneRowset));
					CheckHr(qodc->GetRowset(0));
					CheckHr(qodc->NextRow(&fMoreRows));

					if (fMoreRows)
					{
						if (fWarn)
						{
							// this name already exists
							IWritingSystemPtr qws;
							CheckHr(qwsf->get_EngineOrNull(ws, &qws));
							AssertPtr(qws);
							SmartBstr sbstr;
							qws->get_Name(ws, &sbstr);

							StrUni stu(kstidDupItemName);
							StrUni stuMsg;
							stuMsg.Format(stu,sbstr.Chars());
							StrApp str(stuMsg);
							StrApp strTitle(kstidDupItemTitle);
							::MessageBox(m_hwnd, str.Chars(), strTitle.Chars(),
								MB_OK | MB_ICONINFORMATION);
						}
						return false;
					}
				}
			}
			break;
		}
		case kflidCmPossibility_Abbreviation:
		{
			for (int ipii = 0; ipii < cpii; ipii++)
			{
				if (ipii == ipss)
					continue;
				PossItemInfo * ppii = qpli->GetPssFromIndex(ipii);
				AssertPtr(ppii);
				StrUni stu;
				ppii->GetName(stu, kpntAbbreviation);
				if (stu == stuNew)
				{
					stuSql.Format(L"select ws from CmPossibility_Abbreviation "
						L"where obj = %d and ws = %d",
						ppii->GetPssId(), ws);
					CheckHr(qode->CreateCommand(&qodc));
					CheckHr(qodc->ExecCommand(stuSql.Bstr(), knSqlStmtSelectWithOneRowset));
					CheckHr(qodc->GetRowset(0));
					CheckHr(qodc->NextRow(&fMoreRows));

					if (fMoreRows)
					{
						if (fWarn)
						{
							// this abbreviation already exists
							IWritingSystemPtr qws;
							CheckHr(qwsf->get_EngineOrNull(ws, &qws));
							AssertPtr(qws);
							SmartBstr sbstr;
							qws->get_Name(ws, &sbstr);

							StrUni stu(kstidDupItemAbbr);
							StrUni stuMsg;
							stuMsg.Format(stu,sbstr.Chars());
							StrApp str(stuMsg);
							StrApp strTitle(kstidDupItemTitle);
							::MessageBox(m_hwnd, str.Chars(), strTitle.Chars(),
								MB_OK | MB_ICONINFORMATION);
						}
						return false;
					}
				}
			}
			break;
		}
	}
	return true;
}