/*----------------------------------------------------------------------------------------------
	Generate the sort key as a BSTR
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgUnicodeCollater::get_SortKey(BSTR bstrValue, LgCollatingOptions colopt,
	BSTR * pbstrKey)
{
	BEGIN_COM_METHOD
	ChkComBstrArg(bstrValue);
	ChkComOutPtr(pbstrKey);

	HRESULT hr;
	int cchw;
	*pbstrKey = NULL;
	// Passing 0 and null just produces a length
	IgnoreHr(hr = SortKeyRgch(bstrValue, BstrLen(bstrValue), colopt, 0, NULL, &cchw));
	if (FAILED(hr))
		return hr;

	BSTR bstrOut;
	bstrOut = SysAllocStringLen(NULL, cchw);
	if (!bstrOut)
		return E_OUTOFMEMORY;
	IgnoreHr(hr = SortKeyRgch(bstrValue, BstrLen(bstrValue), colopt, cchw, bstrOut, &cchw));
	if (FAILED(hr))
	{
		SysFreeString(bstrOut);
		return hr;
	}
	*pbstrKey = bstrOut;
	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
Exemple #2
0
/*----------------------------------------------------------------------------------------------
 Sets the name of the class that this is a virtual property of. Normally set by
 whatever creates the handler. The cache does not call this, so it may be
 left unimplemented if there is a more convenient way to initialize the
 property.
---------------------------------------------------------------------------------------------*/
STDMETHODIMP VwBaseVirtualHandler::put_ClassName(BSTR bstr)
{
    BEGIN_COM_METHOD;
    ChkComBstrArg(bstr)
    m_stuClass.Assign(bstr, BstrLen(bstr));
    END_COM_METHOD(g_fact, IID_IVwVirtualHandler);
}
Exemple #3
0
/*----------------------------------------------------------------------------------------------
	Perform whatever action is appropriate when the use clicks on a hot link
----------------------------------------------------------------------------------------------*/
STDMETHODIMP VwBaseVc::DoHotLinkAction(BSTR bstrData, ISilDataAccess * psda)
{
	BEGIN_COM_METHOD;
	ChkComArgPtrN(ptss);

	if (BstrLen(bstrData) > 0 && bstrData[0] == kodtExternalPathName)
	{
		StrAppBuf strbFile(bstrData + 1);
		if (::UrlIs(strbFile.Chars(), URLIS_URL))
		{
			// If it's a URL launch whatever it means.
			::ShellExecute(NULL, L"open", strbFile.Chars(), NULL, NULL, SW_SHOWNORMAL);
			return S_OK;
		}
		if (AfApp::Papp())
		{
			AfMainWnd * pafw = AfApp::Papp()->GetCurMainWnd();
			if (pafw && pafw->GetLpInfo())
				pafw->GetLpInfo()->MapExternalLink(strbFile);

			AfApp::LaunchHL(NULL, _T("open"), strbFile.Chars(), NULL, NULL, SW_SHOW);
		}
	}

	return S_OK;

	END_COM_METHOD(g_fact, IID_IVwViewConstructor);
}
/*----------------------------------------------------------------------------------------------
	Create a property with the given writing system, old writing system, and named style (ktptNamedStyle).
	Note that ktptCharStyle (which this used to use) is effectively obsolete.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP TsPropsFact::MakeProps(BSTR bstr, int ws, int ows, ITsTextProps ** ppttp)
{
	BEGIN_COM_METHOD;
	ChkComBstrArgN(bstr);
	ChkComOutPtr(ppttp);
	if ((uint)ws > kwsLim)
		ThrowInternalError(E_INVALIDARG, "Magic writing system invalid in string");

	return MakePropsRgch(bstr, BstrLen(bstr), ws, ows, ppttp);

	END_COM_METHOD(g_factPropsFact, IID_ITsPropsFactory);
}
/*----------------------------------------------------------------------------------------------
	Do a direct string comparison.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgUnicodeCollater::Compare(BSTR bstrValue1, BSTR bstrValue2,
	LgCollatingOptions colopt, int * pnVal)
{
	BEGIN_COM_METHOD
	ChkComBstrArg(bstrValue1);
	ChkComBstrArg(bstrValue2);
	ChkComOutPtr(pnVal);

	HRESULT hr;

	int cchw1;
	int cchw2;

	IgnoreHr(hr = SortKeyRgch(bstrValue1, BstrLen(bstrValue1), colopt, 0, NULL, &cchw1));
	if (FAILED(hr))
		return hr;
	IgnoreHr(hr = SortKeyRgch(bstrValue2, BstrLen(bstrValue2), colopt, 0, NULL, &cchw2));
	if (FAILED(hr))
		return hr;

	OLECHAR * pchKey1 = (OLECHAR *) _alloca(cchw1 * isizeof(OLECHAR));
	OLECHAR * pchKey2 = (OLECHAR *) _alloca(cchw2 * isizeof(OLECHAR));

	IgnoreHr(hr = SortKeyRgch(bstrValue1, BstrLen(bstrValue1), colopt, cchw1, pchKey1, &cchw1));
	if (FAILED(hr))
		return hr;
	IgnoreHr(hr = SortKeyRgch(bstrValue2, BstrLen(bstrValue2), colopt, cchw2, pchKey2, &cchw2));
	if (FAILED(hr))
		return hr;
	int nVal = u_strncmp(pchKey1, pchKey2, min(cchw1, cchw2));
	if (!nVal)
	{
		// equal as far as length of shortest key
		if (BstrLen(bstrValue1) < BstrLen(bstrValue2))
			nVal = -1;
		else if (BstrLen(bstrValue1) > BstrLen(bstrValue2))
			nVal = 1;
	}
	*pnVal = nVal;
	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
Exemple #6
0
/*----------------------------------------------------------------------------------------------
	Generate the sort key as a byte *
----------------------------------------------------------------------------------------------*/
byte * LgIcuCollator::GetSortKey(BSTR bstrValue, byte* prgbKey, int32_t* pcbKey)
{
	byte * pbKey;
	int32_t crgbKey = *pcbKey;
	EnsureCollator();
	*pcbKey = m_pCollator->getSortKey(bstrValue, BstrLen(bstrValue),
		prgbKey, crgbKey);
	if (*pcbKey > crgbKey)
	{
		// sort key is too long, the caller has to pass us a bigger buffer.
		pbKey = NULL;
	}
	else
	{
		// sort key is less than 1024 bytes
		pbKey = prgbKey;
	}

	return pbKey;
}
Exemple #7
0
// Get the display name of the locale represented by this enumerator.
// The display name will be in the selected locale if it is non-empty;
// pass null or an empty string to get the system default locale.
STDMETHODIMP LgIcuLocaleEnumerator::get_DisplayName(int iloc, BSTR bstrLocaleName,
	BSTR * pbstrName)
{
	BEGIN_COM_METHOD
	ChkComOutPtr(pbstrName);
	ChkComBstrArgN(bstrLocaleName);
	if (iloc >= m_clocale)
		ThrowHr(WarnHr(E_INVALIDARG));
	UnicodeString ust;
	if (BstrLen(bstrLocaleName) == 0)
		m_prgLocales[iloc].getDisplayName(ust);
	else
	{
		StrAnsi staLocaleName(bstrLocaleName);
		Locale loc = Locale::createFromName(staLocaleName.Chars());
		m_prgLocales[iloc].getDisplayName(loc, ust);
	}

	*pbstrName = UnicodeStringToBstr(ust);
	END_COM_METHOD(g_factLocEnum, IID_ILgIcuLocaleEnumerator);

}
Exemple #8
0
/*----------------------------------------------------------------------------------------------
	Set the system keyboard and TSF language.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgTextServices::SetKeyboard(int lcid, BSTR bstrKeymanKbd, int * pnActiveLangId,
	BSTR * pbstrActiveKeymanKbd, ComBool * pfSelectLangPending)
{
	BEGIN_COM_METHOD;
	ChkComBstrArgN(bstrKeymanKbd);
	ChkComArgPtr(pnActiveLangId);
	ChkComArgPtr(pbstrActiveKeymanKbd);
	ChkComArgPtr(pfSelectLangPending);

	HRESULT hr;
	int nLangId = LANGIDFROMLCID(lcid);

	bool fDoingKeyman = BstrLen(bstrKeymanKbd) > 0;
	bool fSetInputLang = false;
#ifdef ENABLE_TSF
	if (IsKeyboardDifferent(bstrKeymanKbd, *pbstrActiveKeymanKbd) ||
		(LANGID)nLangId != (LANGID)*pnActiveLangId)
	{
		fSetInputLang = SetKeyboard_TSF(fDoingKeyman, lcid, pnActiveLangId);
	}
#endif /*ENABLE_TSF*/

	if (fDoingKeyman)
	{
		hr = SetKeyboard_Keyman(lcid, bstrKeymanKbd, pbstrActiveKeymanKbd, pfSelectLangPending);
	}
	else // no keyman keyboard wanted.
	{
		if (!fSetInputLang)
			SetKeyboard_Windows(lcid);

		TurnOffKeymanKbd(pbstrActiveKeymanKbd);
		*pfSelectLangPending = true;
	}

	END_COM_METHOD(g_fact, IID_ILgTextServices);
}
Exemple #9
0
/*----------------------------------------------------------------------------------------------
	Return the text string that gets shown to the user when this object needs to be displayed.
	This is the method for displaying the name of a single reference. This view shows the
	name for an RnGenericRec consisting of the type of record, hyphen, title, hyphen,
	creation date. "Subevent - Fishing for pirana - 3/22/2001"

	@param pguid Pointer to a database object's assigned GUID.
	@param pptss Address of a pointer to an ITsString COM object used for returning the text
					string.

	@return S_OK, E_POINTER, or E_FAIL.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP CleRecVc::GetStrForGuid(BSTR bstrGuid, ITsString ** pptss)
{
	Assert(false);  // rework

	BEGIN_COM_METHOD;
	ChkComBstrArg(bstrGuid);
	ChkComOutPtr(pptss);

	if (BstrLen(bstrGuid) != 8)
		ReturnHr(E_INVALIDARG);

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(AfApp::Papp()->GetCurMainWnd());
	AssertPtr(pcmw);
	CleLpInfo * plpi = dynamic_cast<CleLpInfo *>(pcmw->GetLpInfo());
	AssertPtr(plpi);

	HVO hvo = plpi->GetDbInfo()->GetIdFromGuid((GUID *)bstrGuid);

	CustViewDaPtr qcvd;
	plpi->GetDataAccess(&qcvd);
	AssertPtr(qcvd);
	int clid;
	HVO hvoOwn;
	int64 ntim;
	ITsStringPtr qtssTitle;
	CheckHr(qcvd->get_IntProp(hvo, kflidCmObject_Class, &clid));
	CheckHr(qcvd->get_ObjectProp(hvo, kflidCmObject_Owner, &hvoOwn));
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
	CheckHr(qcvd->get_TimeProp(hvo, kflidRnGenericRec_DateCreated, &ntim));
	CheckHr(qcvd->get_StringProp(hvo, kflidRnGenericRec_Title, &qtssTitle));

	int stid;
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
	if (clid == kclidRnEvent)
	{
		if (pcmw->GetRootObj() == hvoOwn)
			stid = kstidEvent;
		else
			stid = kstidSubevent;
	}
	else if (clid == kclidRnAnalysis)
	{
		if (pcmw->GetRootObj() == hvoOwn)
			stid = kstidAnalysis;
		else
			stid = kstidSubanalysis;
	}
	StrUni stu(stid);
	StrUni stuSep(kstidSpHyphenSp);

	ITsStrFactoryPtr qtsf;
	ITsIncStrBldrPtr qtisb;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	CheckHr(qtsf->GetIncBldr(&qtisb));
	CheckHr(qtisb->Append(stu.Bstr()));

	CheckHr(qtisb->Append(stuSep.Bstr()));
	CheckHr(qtisb->AppendTsString(qtssTitle)); // The title.
	CheckHr(qtisb->Append(stuSep.Bstr()));
	// Leave the date blank if a date doesn't exist.
	if (ntim)
	{
		// Convert the date to a system date.
		SilTime tim = ntim;
		SYSTEMTIME stim;
		stim.wYear = (unsigned short) tim.Year();
		stim.wMonth = (unsigned short) tim.Month();
		stim.wDay = (unsigned short) tim.Date();

		// Then format it to a time based on the current user locale.
		achar rgchDate[50]; // Tuesday, August 15, 2000		mardi 15 août 2000
		::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL, rgchDate, 50);
		stu = rgchDate;
		CheckHr(qtisb->Append(stu.Bstr()));
	}
	CheckHr(qtisb->GetString(pptss));

	return S_OK;

	END_COM_METHOD(g_fact2, IID_IVwViewConstructor)
}
Exemple #10
0
/*----------------------------------------------------------------------------------------------
	Set a keyman keyboard
----------------------------------------------------------------------------------------------*/
HRESULT SetKeyboard_Keyman(int lcid, BSTR bstrKeymanKbd, BSTR * pbstrActiveKeymanKbd,
	ComBool * pfSelectLangPending)
{
#ifdef Tracing_KeybdSelection
	StrAnsi sta;
	sta.Format("LgTextServices::SetKeyboard(%d) [setting Keyman kbd]%n", lcid);
	::OutputDebugStringA(sta.Chars());
#endif
	int nLangId = LANGIDFROMLCID(lcid);
	HRESULT hr = S_OK;
	ILgKeymanHandlerPtr qkh;
	qkh.CreateInstance(CLSID_LgKeymanHandler);
	// Tell Keyman about the particular keyboard (but only if it changed).
	if (IsKeyboardDifferent(bstrKeymanKbd, *pbstrActiveKeymanKbd))
	{
		// Activate the particular layout we want.
		// John Durdin says this next step is necessary.
		//::ActivateKeyboardLayout(::GetKeyboardLayout(0), 0);
		// JohnT: discovered that if we've never set a keyboard before, the current one
		// won't be right, but forcing the right langid into the low word seems to help.
		// Keyman always uses the US English keyboard, which is the magic number we're
		// stuffing into the high word.
		HKL hklDesired = (HKL)(0x04090000 | (nLangId & 0xffff));
#ifdef Tracing_KeybdSelection
		StrAnsi sta;
		sta.Format("LgTextServices::SetKeyboard(%d) - "
			"::ActivateKeyboardLayout(%d [%x], 0) for keyman setup\n",
			lcid, hklDesired, hklDesired);
		::OutputDebugStringA(sta.Chars());
#endif
		::ActivateKeyboardLayout(hklDesired, 0);

		try
		{
			CheckHr(qkh->put_ActiveKeyboardName(bstrKeymanKbd));
#ifdef TRACING_KEYMAN
			StrUni stuMsg;
			stuMsg.Format(L"%b is now the active Keyman keyboard.\n",
				bstrKeymanKbd);
			::OutputDebugStringW(stuMsg.Chars());
#endif
			if (*pbstrActiveKeymanKbd)
				::SysFreeString(*pbstrActiveKeymanKbd);
			CopyBstr(pbstrActiveKeymanKbd, bstrKeymanKbd);
			*pfSelectLangPending = true;
		}
		catch (Throwable& thr)
		{
			hr = thr.Result();
#ifdef TRACING_KEYMAN
			StrAnsi staMsg;
			staMsg.Format("Cannot make %B the active Keyman keyboard!?\n",
				bstrKeymanKbd);
			::OutputDebugStringA(staMsg.Chars());
#endif
			if (BstrLen(*pbstrActiveKeymanKbd))
			{
				// We failed, so ensure it's turned off.
				TurnOffKeymanKbd(pbstrActiveKeymanKbd);
				*pfSelectLangPending = true;
			}
		}
	}
	return hr;
}
Exemple #11
0
/*----------------------------------------------------------------------------------------------
Replace
	The default implementation just replaces characters from ichMin to ichLim with
	those from bstrInput, then set *pichModMin to ichMin, and *pichModLim and
	*pichIP both to ichMin + BstrLen(bstrInput).

	 Arguments:
		bstrInput				what user typed
		pttpInput          		text properties desired for new text
		ptsbOld        			original, unedited text, gets modified
		ichMin,	ichLim			range in original to replace
		pichModMin, pichModLim  range in output text affected
		pichIP                  position of IP in modified string

----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgInputMethodEditor::Replace(BSTR bstrInput, ITsTextProps * pttpInput,
		ITsStrBldr * ptsbOld, int ichMin, int ichLim, int * pichModMin, int * pichModLim,
		int * pichIP)
{
	BEGIN_COM_METHOD;
	ChkComBstrArgN(bstrInput);
	ChkComArgPtrN(pttpInput);
	ChkComArgPtr(ptsbOld);
	ChkComOutPtr(pichModMin);
	ChkComOutPtr(pichModLim);
	ChkComOutPtr(pichIP);

	int cCh;
	SmartBstr sbstr;
	CheckHr(ptsbOld->get_Length(&cCh));
	if (ichMin < 0 || ichLim > cCh || ichMin > ichLim)
	{
		*pichModMin = 0;
		*pichModLim = 0;
		*pichIP = 0;
		ThrowHr(WarnHr(E_INVALIDARG));
	}

	// Check to make sure the ichMin is not between a surrognte pair.
	do
	{
		if (0 < ichMin)
		{
			CheckHr(ptsbOld->GetChars(ichMin, ichMin + 1, &sbstr));
			if (sbstr[0] < 0xDC00 || sbstr[0] > 0xDFFF)
				break;
		}
		else
		{
			break;
		}
	} while (--ichMin > 0);

	// Check to make sure the ichLim is not between a surrgante pair.
	do
	{
		if (cCh > ichLim)
		{
			CheckHr(ptsbOld->GetChars(ichLim, ichLim + 1, &sbstr));
			if (sbstr[0] < 0xDC00 || sbstr[0] > 0xDFFF)
				break;
		}
		else
		{
			break;
		}
	} while (++ichLim < cCh);

	// Now, do the real work

	CheckHr(ptsbOld->Replace(ichMin, ichLim, bstrInput, pttpInput));
	*pichModMin = ichMin;
	*pichModLim = ichMin + BstrLen(bstrInput);
	*pichIP = ichMin + BstrLen(bstrInput);

	END_COM_METHOD(g_fact, IID_ILgFontManager);
}
Exemple #12
0
/*----------------------------------------------------------------------------------------------
	Initialize the engine. This must be called before any oher methods of the interface.
	How the data is used is implementation dependent. The UniscribeRenderer does not
	use it at all. The Graphite renderer uses font name, bold, and italic settings
	to initialize itself with the proper font tables. For Graphite, bstrData contains
	(optionally) default settings for any font features.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwGrEngine::InitRenderer(IVwGraphics * pvg, BSTR bstrData)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pvg);
	ChkComBstrArgN(bstrData);

	// Make sure we can create a Graphite font.
	try
	{
		HDC hdc;
		IVwGraphicsWin32Ptr qvg32;
		CheckHr(pvg->QueryInterface(IID_IVwGraphicsWin32, (void **)&qvg32));
		CheckHr(qvg32->GetDeviceContext(&hdc));
		//FwGrGraphics gg(pvg);
		//gg.GetDeviceContext(&hdc);

		// Remember the font face name.
		LgCharRenderProps chrp;
		pvg->get_FontCharProperties(&chrp);
		memcpy(m_szFaceName, chrp.szFaceName, isizeof(m_szFaceName));

		// Make sure there is a cached font object.
		WinFont * pfontOld = m_pfont;
		m_pfont = new FwWinFont(hdc);
		m_fontSize = gr::GrEngine::RoundFloat(m_pfont->ascent() + m_pfont->descent());

		// Instead a code below, a FontException will be thrown.
		//FontErrorCode ferr = m_pfont->isValidForGraphite();
		//HRESULT hr;
		//std::wstring stuMsgBogus = FontLoadErrorDescription(ferr, 0, 0, &hr);

		// Delete this after creating the new one, so that if there happens to be only one
		// the font cache doesn't get destroyed and recreated!
		delete pfontOld;

		// Store the default feature values, which may be different from the font.
		m_cfeatWDefaults = ParseFeatureString((gr::utf16*)bstrData, BstrLen(bstrData), m_rgfsetDefaults);

		// This is kind of a kludge. The m_pfont may be kind of temporary, because the caller may delete
		// the graphics object and the DC. So call something to get set the FontFace set up while the
		// Font is still valid, so we can at least have access to some basic information from the engine.
		// Ideally we should probably create the WinFont with a private device context.
		int nTemp;
		this->get_ScriptDirection(&nTemp);

		return S_OK;
	}
	catch (FontException & fexptn)
	{
		// There was an error in initializing the font.
		FontErrorCode ferr = fexptn.errorCode;
		//int nVersion = fexptn.version;
		//int nSubVersion = fexptn.subVersion;
		HRESULT hr;
		std::wstring stuMsgBogus = FontLoadErrorDescription(ferr, 0, 0, &hr);
		return hr;
	}
	catch (...)
	{
		return kresUnexpected;
	}

	END_COM_METHOD(g_fact, IID_IRenderEngine);
}