コード例 #1
0
/*----------------------------------------------------------------------------------------------
	Finish initialization.
----------------------------------------------------------------------------------------------*/
void AfDeFeSt::Init(CustViewDa * pcvd, HVO hvoText)
{
	AssertPtr(pcvd);
	Assert(m_hvoObj); // Initialize should have been called prior to this.
	AssertPtr(m_qadsc);

	// Get the current default writing system for this field and convert any magic number.
	AfLpInfo * plpi = GetLpInfo();
	AssertPtr(plpi);
	m_qcvd = pcvd;
	m_hvoText = hvoText;
	ILgWritingSystemFactoryPtr qwsf;
	plpi->GetDbInfo()->GetLgWritingSystemFactory(&qwsf);
	m_qstvc.Attach(NewObj StVc(m_qfsp->m_stuSty.Chars(), m_ws, m_chrp.clrBack, qwsf));
}
コード例 #2
0
/*----------------------------------------------------------------------------------------------
	The Ok button in the list chooser has been hit. Process the results from the list chooser.
	@param pplc Pointer to the dialog box being closed.
	----------------------------------------------------------------------------------------------*/
void AfDeFeCliRef::ChooserApplied(PossChsrDlg * pplc)
{
	// Get the output values.
	StrUni stu;
	ITsStringPtr qtss;
	ITsStrFactoryPtr qtsf;
	HVO pssId;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	pplc->GetDialogValues(pssId);
	m_pss = pssId;
	m_fRecurse = true;
	if (pssId)
	{
		PossListInfoPtr qpli;
		AfLpInfo * plpi = GetLpInfo();
		AssertPtr(plpi);
		plpi->LoadPossList(m_hvoPssl, m_wsMagic, &qpli);
		AssertPtr(qpli);
		int ipss = qpli->GetIndexFromId(pssId);
		PossItemInfo * ppii = qpli->GetPssFromIndex(ipss);
		if (m_fHier)
			ppii->GetHierName(qpli, stu, m_pnt);
		else
			ppii->GetName(stu, m_pnt);
		int ws = ppii->GetWs();
		qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss);
		m_qtss = qtss;
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)qtss.Ptr());
	}
	else
	{
		m_qtss = NULL;
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, NULL);
	}
	// I (KenZ) don't fully understand this. But if a user enters the chooser, and opens a
	// list editor from there and adds a new item, closes the list editor, checks the new
	// item in the chooser, selects OK, then moves to the next record without moving from
	// the field, the added item is lost. We get ksyncPossList and ksyncAddPss sync messages
	// from the list editor, but for some reason we are getting an extra ksyncPossList
	// message after this method completes. That extra message is calling ListChanged which
	// calls UpdateField, which reloads our temporary cache from the main cache and wipes out
	// the change we just made. So until we can do something better, we'll save the changes
	// here to make sure the UpdateField doesn't wipe out our change.
	SaveEdit();
	::InvalidateRect(m_hwnd, NULL, true);
}
コード例 #3
0
/*----------------------------------------------------------------------------------------------
	This method checks for duplicates in list names.  If the given name exists then return true.

	@param pszName name to check to see if it exists.
	@return True if name already exists.
----------------------------------------------------------------------------------------------*/
bool ListsPropDlg::CheckName(const achar * pszName)
{
	AfMainWnd * pafw = MainWindow();
	AssertPtr(pafw);
	AfLpInfo * plpi = pafw->GetLpInfo();
	AssertPtr(plpi);
	Vector<HVO> & vhvo = plpi->GetPsslIds();

	AfDbInfoPtr qdbi = plpi->GetDbInfo();
	AssertPtr(qdbi);
	IOleDbEncapPtr qode;
	qdbi->GetDbAccess(&qode);

	StrAnsi sta;
	int i;
	StrUni stuIds;
	int cv = vhvo.Size();
	Assert(cv);

	ComBool fIsNull;
	ComBool fMoreRows;
	ULONG cbSpaceTaken;
	IOleDbCommandPtr qodc;

	const int kcchBuffer = MAX_PATH;
	OLECHAR rgchName[kcchBuffer];
	HVO hvo;
	StrUni stu;
	for (i = 0; i < cv; ++i)
	{
		hvo = vhvo[i];
		stu.Format(L"exec GetOrderedMultiTxt '%d', %d",
			hvo, kflidCmMajorObject_Name);
		CheckHr(qode->CreateCommand(&qodc));
		CheckHr(qodc->ExecCommand(stu.Bstr(), knSqlStmtStoredProcedure));
		CheckHr(qodc->GetRowset(0));
		CheckHr(qodc->NextRow(&fMoreRows));
		Assert(fMoreRows); // This proc should always return something.
		CheckHr(qodc->GetColValue(1, reinterpret_cast <BYTE *>(rgchName),
			kcchBuffer * isizeof(OLECHAR), &cbSpaceTaken, &fIsNull, 2));
		sta = rgchName;
		if (hvo != m_hvoObj && sta.Equals(pszName))
			return false;
	}
	return true;
}
コード例 #4
0
ファイル: TssEdit.cpp プロジェクト: FieldDB/FieldWorks
/*----------------------------------------------------------------------------------------------
	Make the root box.
----------------------------------------------------------------------------------------------*/
void TssEdit::MakeRoot(IVwGraphics * pvg, ILgWritingSystemFactory * pwsf, IVwRootBox ** pprootb)
{
	AssertPtr(pvg);
	AssertPtrN(pwsf);
	AssertPtr(pprootb);

	*pprootb = NULL;

	IVwRootBoxPtr qrootb;
	qrootb.CreateInstance(CLSID_VwRootBox);
	CheckHr(qrootb->SetSite(this));
	HVO hvo = khvoString;
	int frag = kfrString;

	// Set up a new view constructor.
	ComBool fRTL = FALSE;
	IWritingSystemPtr qws;
	Assert(pwsf == m_qwsf.Ptr());
	CheckHr(pwsf->get_EngineOrNull(m_wsBase, &qws));
	if (qws)
		CheckHr(qws->get_RightToLeft(&fRTL));
	TssEditVcPtr qtevc;
	qtevc.Attach(NewObj TssEditVc(this, m_nEditable, m_fShowTags, fRTL));

	CheckHr(m_qcda->putref_WritingSystemFactory(pwsf));
	CheckHr(qrootb->putref_DataAccess(m_qcda));

	AfMainWnd * pafw = MainWindow();
	AssertPtrN(pafw);
	AfStylesheet * pss = NULL;
	AfLpInfo * plpi = pafw->GetLpInfo();
	if (plpi)
	{
		pss = plpi->GetAfStylesheet();
		// This allows it to receive updates to style defns.
		pafw->RegisterRootBox(qrootb);
	}
	IVwViewConstructor * pvvc = qtevc;
	CheckHr(qrootb->SetRootObjects(&hvo, &pvvc, &frag, pss, 1));

	*pprootb = qrootb.Detach();
}
コード例 #5
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::BeginEdit(HWND hwnd, Rect & rc, int dxpCursor, bool fTopCursor)
{
	SuperClass::BeginEdit(hwnd, rc, dxpCursor, fTopCursor);

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(m_qadsc->MainWindow());
	Assert(pcmw);
	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	PossItemInfo * ppii = qpli->GetPssFromIndex(ipss);
	AssertPtr(ppii);

	// Save the primary string for comparison.
	AfLpInfo * plpi = pcmw->GetLpInfo();
	AssertPtr(plpi);
	CustViewDaPtr qcvd = pcmw->MainDa();
	AssertPtr(qcvd);
	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, plpi->ActualWs(qpli->GetWs()), &m_qtssOld));

	switch(m_flid)
	{
		case kflidCmPossibility_Name:
		{
			StrUni stu;
			ppii->GetName(stu, kpntName);
			StrUni stuNewItem(kstidNewItem);
			if (stu.Left(stuNewItem.Length()) == stuNewItem)
				m_qrootb->MakeSimpleSel(true, true, true, true, NULL);
			break;
		}
		case kflidCmPossibility_Abbreviation:
		{
			StrUni stu;
			ppii->GetName(stu, kpntAbbreviation);
			StrUni stuNew(kstidNew);
			if (stu.Left(stuNew.Length()) == stuNew)
				m_qrootb->MakeSimpleSel(true, true, true, true, NULL);
			break;
		}
	}
	return true;
}
コード例 #6
0
/*----------------------------------------------------------------------------------------------
	Fill in the string with the given "Date Created" or "Date Modified" value.

	@param flid Field id for either "DateCreated" or "DateModified".
	@param strb Reference to the output string.
----------------------------------------------------------------------------------------------*/
void GeneralPropDlgTab::GetDateString(int flid, StrAppBuf & strb)
{
	strb.Clear();
	try
	{
		AfLpInfo * plpi = m_ppropd->GetLangProjInfo();
		AssertPtr(plpi);
		CustViewDaPtr qcvd;
		plpi->GetDataAccess(&qcvd);
		AssertPtr(qcvd);
		int64 ntim = 0;
		SilTime tim;
		SYSTEMTIME stim;
		achar rgchDate[50]; // Tuesday, August 15, 2000		mardi 15 août 2000
		achar rgchTime[50]; // 10:17:09 PM					22:20:08
		int cch;
		HVO hvo = m_ppropd->GetObjId();
		HRESULT hr;
		CheckHr(hr = qcvd->get_TimeProp(hvo, flid, &ntim));
		if (hr == S_FALSE && !ntim)
		{
			int clid = MAKECLIDFROMFLID(flid);
			AfDbInfo * pdbi = plpi->GetDbInfo();
			AssertPtr(pdbi);
			IOleDbEncapPtr qode;
			pdbi->GetDbAccess(&qode);
			AssertPtr(qode);
			IFwMetaDataCachePtr qmdc;
			pdbi->GetFwMetaDataCache(&qmdc);
			AssertPtr(qmdc);
			SmartBstr sbstrField;
			CheckHr(qmdc->GetFieldName(flid, &sbstrField));
			IOleDbCommandPtr qodc;
			CheckHr(qode->CreateCommand(&qodc));
			StrUni stu;
			ComBool fIsNull;
			ComBool fMoreRows;
			ULONG cbSpaceTaken;

			SmartBstr sbstrClass;
			CheckHr(qmdc->GetClassName(clid, &sbstrClass));
			// Note that we need the view, not just the class table proper, in case the
			// attribute is defined on a superclass (such as CmMajorObject).
			stu.Format(L"select [%b] from [%b_] where [Id] = %d",
				sbstrField.Bstr(), sbstrClass.Bstr(), hvo);
			CheckHr(qodc->ExecCommand(stu.Bstr(), knSqlStmtSelectWithOneRowset));
			CheckHr(qodc->GetRowset(0));
			CheckHr(qodc->NextRow(&fMoreRows));
			if (fMoreRows)
			{
				DBTIMESTAMP dbtim;
				CheckHr(qodc->GetColValue(1, reinterpret_cast <BYTE *>(&dbtim),
					sizeof(DBTIMESTAMP), &cbSpaceTaken, &fIsNull, 0));
				if (!fIsNull)
				{
					stim.wYear = (unsigned short)dbtim.year;
					stim.wMonth = (unsigned short)dbtim.month;
					stim.wDayOfWeek = 0;
					stim.wDay = (unsigned short)dbtim.day;
					stim.wHour = (unsigned short)dbtim.hour;
					stim.wMinute = (unsigned short)dbtim.minute;
					stim.wSecond = (unsigned short)dbtim.second;
					stim.wMilliseconds = (unsigned short)(dbtim.fraction/1000000);
					cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL,
						rgchDate, 50);
					rgchDate[cch] = 0;
					cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &stim, NULL,
						rgchTime, 50);
					rgchTime[cch] = 0;
					strb.Format(_T("%s %s"), rgchDate, rgchTime);
				}
			}

		}
		else if (ntim)
		{
			tim = ntim;
			// Convert the date to a system date.
			// Then format it to a time based on the current user locale.
			stim.wYear = (unsigned short)tim.Year();
			stim.wMonth = (unsigned short)tim.Month();
			stim.wDayOfWeek = (unsigned short)tim.WeekDay();
			stim.wDay = (unsigned short)tim.Date();
			stim.wHour = (unsigned short)tim.Hour();
			stim.wMinute = (unsigned short)tim.Minute();
			stim.wSecond = (unsigned short)tim.Second();
			stim.wMilliseconds = (unsigned short)tim.MilliSecond();
			cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL, rgchDate,
				50);
			rgchDate[cch] = 0;
			cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &stim, NULL, rgchTime, 50);
			rgchTime[cch] = 0;
			strb.Format(_T("%s %s"), rgchDate, rgchTime);
		}
	}
	catch (...)	// Was empty.
	{
		throw;	// For now we have nothing to add, so pass it on up.
	}
}
コード例 #7
0
/*----------------------------------------------------------------------------------------------
	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 pvwenv Pointer to the view environment.
	@param hvo The id of the object we are displaying.
	@param frag Identifies the part of the view we are currently displaying.
	@return HRESULT indicating success (S_OK), or failure (E_FAIL).
----------------------------------------------------------------------------------------------*/
STDMETHODIMP CleRecVc::Display(IVwEnv * pvwenv, HVO hvo, int frag)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pvwenv);

	Assert(false);  // Is this needed for poss lists?

	switch (frag)
	{
	case kfrRefName:
	case kfrListName:
		{
			SmartBstr bstrClass = L"UnLoaded";
			ITsStringPtr qtss;
			ITsStringPtr qtssTitle;

			// Make sure data is loaded.
			LoadDataFor(pvwenv, hvo, frag);
			AfMainWnd * pafw = AfApp::Papp()->GetCurMainWnd();
			AssertPtr(pafw);
			AfLpInfo * plpi = pafw->GetLpInfo();
			AssertPtr(plpi);
			AfDbInfo * pdbi = plpi->GetDbInfo();
			AssertPtr(pdbi);

#define HYPERLINK_CHANGE
#ifdef HYPERLINK_CHANGE
			// Update the string with the new object.
			GUID uid;
			if (!pdbi->GetGuidFromId(hvo, uid))
				ReturnHr(E_FAIL);

			StrUni stuData;
			OLECHAR * prgchData;
			// Make large enough for a guid plus the type character at the start.
			stuData.SetSize(isizeof(GUID) / isizeof(OLECHAR) + 1, &prgchData);
			*prgchData = kodtNameGuidHot;
			memmove(prgchData + 1, &uid, isizeof(uid));

			ITsPropsFactoryPtr qtpf;
			ITsPropsBldrPtr qtpb;
			ITsTextPropsPtr qttp;
			ITsStrFactoryPtr qtsf;

			qtpf.CreateInstance(CLSID_TsPropsFactory);
			CheckHr(qtpf->GetPropsBldr(&qtpb));
			CheckHr(qtpb->SetIntPropValues(ktptWs, ktpvDefault, pdbi->UserWs()));
			CheckHr(qtpb->SetStrPropValue(ktptObjData, stuData.Bstr()));
			CheckHr(qtpb->GetTextProps(&qttp));
			qtsf.CreateInstance(CLSID_TsStrFactory);
			OLECHAR chObj = kchObject;
			CheckHr(qtsf->MakeStringWithPropsRgch(&chObj, 1, qttp, &qtss));

			CheckHr(pvwenv->OpenSpan());
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
			int flid = kflidRnGenericRec_Title;
			CheckHr(pvwenv->NoteDependency(&hvo, &flid, 1));
			CheckHr(pvwenv->AddString(qtss)); // The class name.
			CheckHr(pvwenv->CloseSpan());
#else // !HYPERLINK_CHANGE
			int clid;
			HVO hvoOwn;
			int64 ntim;
			int ws = pdbi->UserWs();
			ISilDataAccessPtr qsda;
			CheckHr(pvwenv->get_DataAccess(&qsda));
			AssertPtr(qsda);
			CheckHr(qsda->get_IntProp(hvo, kflidCmObject_Class, &clid));
			CheckHr(qsda->get_ObjectProp(hvo, kflidCmObject_Owner, &hvoOwn));
			// REVIEW KenZ(RandyR) Whey are DN flids in this app?
			CheckHr(qsda->get_TimeProp(hvo, kflidRnGenericRec_DateCreated, &ntim));
			CheckHr(qsda->get_StringProp(hvo, kflidRnGenericRec_Title, &qtssTitle));

			int stid;
			// Sharon! Not needed?
//			if (clid == kclidRnEvent)
//			{
//				if (plpi->GetRnId() == hvoOwn)
//					stid = kstidEvent;
//				else
//					stid = kstidSubevent;
//			}
//			else if (clid == kclidRnAnalysis)
//			{
//				if (plpi->GetRnId() == hvoOwn)
//					stid = kstidAnalysis;
//				else
//					stid = kstidSubanalysis;
//			}
			StrUni stu(stid);
			StrUni stuSep(kstidSpHyphenSp);
			ITsStrFactoryPtr qtsf;
			qtsf.CreateInstance(CLSID_TsStrFactory);
			CheckHr(qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss));

			CheckHr(pvwenv->OpenSpan());
			CheckHr(pvwenv->AddString(qtss)); // The class name.
			CheckHr(qtsf->MakeStringRgch(stuSep.Chars(), stuSep.Length(), ws, &qtss));
			CheckHr(pvwenv->AddString(qtss)); // The separator
			//CheckHr(pvwenv->AddString(qtssTitle)); // The title.
			// The following gives the title of the owning object instead of the ref.
			CheckHr(pvwenv->AddStringProp(kflidRnGenericRec_Title, this)); // The title.
			CheckHr(pvwenv->AddString(qtss)); // The separator
			// 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.
				char rgchDate[50]; // Tuesday, August 15, 2000		mardi 15 août 2000
				::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stim, NULL, rgchDate, 50);
				stu = rgchDate;
				CheckHr(qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss));
				CheckHr(pvwenv->AddString(qtss)); // The date.
			}
			CheckHr(pvwenv->CloseSpan());
#endif // HYPERLINK_CHANGE

			break;
		}
	}

	return S_OK;

	END_COM_METHOD(g_fact2, IID_IVwViewConstructor)
}
コード例 #8
0
/*----------------------------------------------------------------------------------------------
	Called by the framework to initialize the dialog. All one-time initialization should be
	done here (that is, all controls have been created and have valid hwnd's, but they
	need initial values.)

	See ${AfDialog#FWndProc}
	@param hwndCtrl (not used)
	@param lp (not used)
	@return true if Successful
----------------------------------------------------------------------------------------------*/
bool RnTlsOptDlg::OnInitDlg(HWND hwndCtrl, LPARAM lp)
{
	m_qrmw = dynamic_cast<RecMainWnd *>(MainWindow());
	AfMdiClientWndPtr qmdic = m_qrmw->GetMdiClientWnd();
	AssertPtr(qmdic);
	// Cancel the dialog if we aren't allowed to make changes.
	AfClientRecWndPtr qafcrw = dynamic_cast<AfClientRecWnd *>(qmdic->GetCurChild());
	// This might not exist yet if the filter doesn't match anything during startup.
	if (qafcrw && !qafcrw->IsOkToChange())
	{
		SuperClass::OnCancel();
		return true;
	}

	Assert(m_cTabs == 6); // Ensure that the number of dialogs is what we expect.
	m_hwndTab = GetDlgItem(m_hwnd, kcidTlsOptDlgTab);

	AfLpInfo * plpi = m_qrmw->GetLpInfo();
	AssertPtr(plpi);

	// Setup m_vuvs
	plpi->GetDbInfo()->GetCopyUserViewSpecs(&m_vuvs);
	SetVuvsCopy();

	AfViewBarShell * pvwbrs = m_qrmw->GetViewBarShell();
	AssertPtr(pvwbrs);

	// CAUTION! The order these are inserted is important since we use constant indexes to
	// access them (e.g., kidlgGeneral).
	AfDialogViewPtr qadv;
	qadv.Attach(NewObj TlsOptDlgCst(this));
	m_vdlgv.Push(qadv);
	qadv.Attach(NewObj TlsOptDlgVw(this));
	m_vdlgv.Push(qadv);
	qadv.Attach(NewObj FwFilterDlg(this));
	m_vdlgv.Push(qadv);
	qadv.Attach(NewObj TlsOptDlgSort(this));
	m_vdlgv.Push(qadv);
	qadv.Attach(NewObj TlsOptDlgOvr(this));
	m_vdlgv.Push(qadv);
	qadv.Attach(NewObj TlsOptDlgGen(this));
	m_vdlgv.Push(qadv);

	// Initialize the object classes that we can create in this dialog.
	TlsObject to;
	to.m_clsid = kclidRnEvent;
	to.m_nLevel = 0;
	to.m_strName.Load(kstidEventEntry);
	m_vto.Push(to);
	to.m_clsid = kclidRnAnalysis;
	to.m_nLevel = 0;
	to.m_strName.Load(kstidAnalEntry);
	m_vto.Push(to);

	// Initialize the Custom Define In vector.
	to.m_clsid = kclidRnEvent;
	to.m_nLevel = 0;
	to.m_strName.Load(kstidEventEntry);
	to.m_strClsName = "RnEvent";
	m_vcdi.Push(to);
	to.m_clsid = kclidRnAnalysis;
	to.m_nLevel = 0;
	to.m_strName.Load(kstidAnalEntry);
	to.m_strClsName = "RnAnalysis";
	m_vcdi.Push(to);
	to.m_clsid = kclidRnGenericRec;
	to.m_nLevel = 1000; // Level 1000 means ALL Entries
	to.m_strName.Load(kstidTlsOptCstAllEnt);
	to.m_strClsName = "RnGenericRec";
	m_vcdi.Push(to);
	m_iDefaultCstDfn = m_vcdi.Size() - 1;

	// If we don't get a reasonable values from GetCurClsLevel, we just default to 0 for the
	// index.
	m_ivto = 0;
	for (int ivto = 0; ivto < m_vto.Size(); ++ivto)
	{
		if (m_vto[ivto].m_clsid == m_tgv.clsid
			&& m_vto[ivto].m_nLevel == m_tgv.nLevel)
		{
			m_ivto = ivto;
			break;
		}
	}

	// Initialize the master view types supported by this dialog.
	TlsView tv;
	tv.m_vwt = kvwtBrowse;
	tv.m_fMaster = false;
	m_vtv.Push(tv);
	tv.m_vwt = kvwtDE;
	tv.m_fMaster = true;
	m_vtv.Push(tv);
	tv.m_vwt = kvwtDoc;
	tv.m_fMaster = false;
	m_vtv.Push(tv);

	// Update the General tab.
	TlsOptDlgGen * ptodg = dynamic_cast<TlsOptDlgGen *>(m_vdlgv[kidlgGeneral].Ptr());
	AssertPtr(ptodg);
	ptodg->SetDialogValues(m_vuvs, &m_siwndClientDel);

	// Update the Custom Fields tab.
	TlsOptDlgCst * ptodc = dynamic_cast<TlsOptDlgCst *>(m_vdlgv[kidlgCustom].Ptr());
	AssertPtr(ptodc);
	ptodc->SetDialogValues(m_vuvs, &m_siwndClientDel, &m_siCustFldDel);

	int iv1;

	// Update the Views tab.
	TlsOptDlgVw * ptodv = dynamic_cast<TlsOptDlgVw *>(m_vdlgv[kidlgViews].Ptr());
	AssertPtr(ptodv);
	if (m_tgv.itabInitial == kidlgViews && m_tgv.iv1 >= 0)
	{
		iv1 = m_tgv.iv1;
	}
	else
	{
		// Use the current view that is selected.
		Set<int> sisel;
		pvwbrs->GetSelection(m_qrmw->GetViewbarListIndex(kvbltView), sisel);
		if (sisel.Size())
			iv1 = *sisel.Begin();
		else
		{
			iv1 = -1;
			Assert(!qafcrw);
		}
	}
	if (iv1 >= 0)
		ptodv->SetDialogValues(m_vuvs, &m_siwndClientDel, iv1);

	// Update the Filters tab.
	FwFilterDlg * pfltdlg = dynamic_cast<FwFilterDlg *>(m_vdlgv[kidlgFilters].Ptr());
	AssertPtr(pfltdlg);
	if (m_tgv.itabInitial == kidlgFilters && m_tgv.iv1 >= 0)
	{
		iv1 = m_tgv.iv1;
	}
	else
	{
		// Use the current filter that is selected.
		Set<int> sisel;
		pvwbrs->GetSelection(m_qrmw->GetViewbarListIndex(kvbltFilter), sisel);
		if (sisel.Size())
			iv1 = *sisel.Begin() - 1; // Subtract one for the No Filter item.
		else
		{
			iv1 = -1;
			Assert(!qafcrw);
		}
	}
	pfltdlg->SetDialogValues(m_qrmw, Max(0, iv1));

	// Update the Sort Methods tab.
	TlsOptDlgSort * psrtdlg = dynamic_cast<TlsOptDlgSort *>(m_vdlgv[kidlgSortMethods].Ptr());
	AssertPtr(psrtdlg);
	if (m_tgv.itabInitial == kidlgSortMethods && m_tgv.iv1 >= 0)
	{
		iv1 = m_tgv.iv1;
	}
	else
	{
		// Use the current sort method that is selected.
		Set<int> sisel;
		pvwbrs->GetSelection(m_qrmw->GetViewbarListIndex(kvbltSort), sisel);
		if (sisel.Size())
			iv1 = *sisel.Begin() - 1; // Subtract one for the No sort item.
		else
		{
			iv1 = -1;
			Assert(!qafcrw);
		}
	}
	psrtdlg->SetDialogValues(m_qrmw, Max(0, iv1));

	// Update the Overlays tab.
	TlsOptDlgOvr * ptodo = dynamic_cast<TlsOptDlgOvr *>(m_vdlgv[kidlgOverlays].Ptr());
	AssertPtr(ptodo);
	if (m_tgv.itabInitial == kidlgOverlays && m_tgv.iv1 >= 0)
	{
		iv1 = m_tgv.iv1;
	}
	else
	{
		// Use the first overlay that is selected.
		Set<int> sisel;
		pvwbrs->GetSelection(m_qrmw->GetViewbarListIndex(kvbltOverlay), sisel);
		if (sisel.Size())
			iv1 = *sisel.Begin() - 1; // Subtract one for the No Overlay item.
		else
		{
			iv1 = -1;
			Assert(!qafcrw);
		}
	}
	ptodo->SetDialogValues(plpi, Max(0, iv1),
		(m_tgv.itabInitial == kidlgOverlays && m_tgv.iv2 >= 0) ? m_tgv.iv2 : 0);

	// WARNING: If this ever gets changed to anything but a fixed length buffer, make sure
	// ti.pszText is set after loading each string, since the memory pointed to by strb
	// could be different each time.
	StrAppBuf strb;
	TCITEM ti;
	ti.mask = TCIF_TEXT;
	ti.pszText = const_cast<achar *>(strb.Chars());

	// Add a tab to the tab control for each dialog view.
	strb.Load(kstidTlsOptCust);
	TabCtrl_InsertItem(m_hwndTab, kidlgCustom, &ti);
	strb.Load(kstidTlsOptView);
	TabCtrl_InsertItem(m_hwndTab, kidlgViews, &ti);
	strb.Load(kstidTlsOptFltr);
	TabCtrl_InsertItem(m_hwndTab, kidlgFilters, &ti);
	strb.Load(kstidTlsOptSort);
	TabCtrl_InsertItem(m_hwndTab, kidlgSortMethods, &ti);
	strb.Load(kstidTlsOptOvr);
	TabCtrl_InsertItem(m_hwndTab, kidlgOverlays, &ti);
	strb.Load(kstidTlsOptGen);
	TabCtrl_InsertItem(m_hwndTab, kidlgGeneral, &ti);

	// This section must be after at least one tab gets added to the tab control.
	RECT rcTab;
	::GetWindowRect(m_hwndTab, &rcTab);
	TabCtrl_AdjustRect(m_hwndTab, false, &rcTab);
	POINT pt = { rcTab.left, rcTab.top };
	::ScreenToClient(m_hwnd, &pt);
	m_dxsClient = pt.x;
	m_dysClient = pt.y;

	// Subclass the Help button.
	AfButtonPtr qbtn;
	qbtn.Create();
	qbtn->SubclassButton(m_hwnd, kctidHelp, kbtHelp, NULL, 0);

	ShowChildDlg(m_tgv.itabInitial);
	m_siwndClientDel.Clear();
	m_siCustFldDel.Clear();

	AfApp::Papp()->EnableMainWindows(false);

	SetFocus(::GetDlgItem(m_hwnd, kcidTlsOptDlgTab));
	return SuperClass::OnInitDlg(hwndCtrl, lp);
}
コード例 #9
0
/*----------------------------------------------------------------------------------------------
	The edit box changed. We need to validate what was done.
	@param pedit
	@return
----------------------------------------------------------------------------------------------*/
bool AfDeFeCliRef::OnChange(AfDeFeEdBoxBut::DeEdit * pedit)
{
	if (m_fRecurse)
	{
		m_fRecurse = false;
		return true;
	}
	if (!m_hwnd)
		return true; // We aren't completely set up yet, so ignore this.

	// Get the characters from the edit box.
	ITsStringPtr qtss;
	::SendMessage(m_hwnd, FW_EM_GETTEXT, 0, (LPARAM)&qtss);

	int ichMin;
	int ichLim;
	::SendMessage(m_hwnd, EM_GETSEL, (WPARAM)&ichMin, (LPARAM)&ichLim);

	int cchTyped; // number of characters in the typed string
	// JohnT: use a StrUni rather than an StrUniBuf, because some user sometime will accidentally
	// paste something long here, and performance here is not critical.
	StrUni stuTyped;
	OLECHAR * pchBuf;
	qtss->get_Length(&cchTyped);

	if (cchTyped > kcchPossNameAbbrMax)
	{
		if (ichMin == cchTyped)
			ichMin = kcchPossNameAbbrMax;
		if (ichLim == cchTyped)
			ichLim = kcchPossNameAbbrMax;
		cchTyped = kcchPossNameAbbrMax;
		m_fRecurse = true; // Stop the recursion caused by the next instruction.
		// Note: This recursively calls this procedure.
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)qtss.Ptr());
		::SendMessage(m_hwnd, EM_SETSEL, ichMin, ichMin);
	}

	stuTyped.SetSize(cchTyped, &pchBuf);
	qtss->FetchChars(0, cchTyped, pchBuf);

#ifdef DEBUG_THIS_FILE
	StrAnsi sta;
	sta.Format("AfDeFeCliRef::OnChange:  pedit->m_ch=%d; ichMin=%d; ichLim=%d; pedit->m_cchMatched=%d; cchTyped=%d.\n",
										 pedit->m_ch,    ichMin,    ichLim,    pedit->m_cchMatched,    cchTyped);
	OutputDebugString(sta.Chars());
#endif

	bool fTypeAhead = false; // allow type ahead only when adding characters at end of current item
							// or backspacing at end of current item.
	bool fNeedCompare;
	if (pedit->m_ch == 0) // (see kcidEditPaste special code)
	{
		// If we pasted something, force a compare.
		fNeedCompare = true;
	}
	else if (ichMin == pedit->m_cchMatched + 1 && pedit->m_ch != VK_BACK && pedit->m_ch != VK_DELETE)
	{
		// Need to compare if we typed a character and we are one greater than last match.
		fNeedCompare = true;
		if (cchTyped == ichMin)
		{
			fTypeAhead = true;
#ifdef DEBUG_THIS_FILE
			sta.Format("OnChange: 1 - setting fTypeAhead to true.\n");
			OutputDebugString(sta.Chars());
#endif
		}
	}
	else if (ichMin > pedit->m_cchMatched)
	{
		// Don't compare any other time we are past the last match.
		fNeedCompare = false;
	}
//	else if ((cchTyped == ichMin) && (ichMin == ichLim) && (pedit->m_ch != kscDelForward))
	else if ((cchTyped == ichMin) && (ichMin == ichLim) && (pedit->m_ch != 46))
	{
		// Need to compare if we typed a character and we are at the end of the item
		// Need to compare if we delete the last character in the non-type-ahead string
		fNeedCompare = true;
		fTypeAhead = true;
#ifdef DEBUG_THIS_FILE
		sta.Format("OnChange:  kscDelForward=%d.\n");
		OutputDebugString(sta.Chars());
		sta.Format("OnChange: 2 - setting fTypeAhead to true.\n");
		OutputDebugString(sta.Chars());
#endif
	}
	else
	{
		// Always compare if we are not past the last match.
		fNeedCompare = true;
	}

	int cch;

	// Since the edit box deletes the selection on backspace, we need to use
	// some extra logic to make backspace actually move the selection back.
	if (pedit->m_cchMatched && pedit->m_ch == VK_BACK && m_pss)
	{
		// If we had a previous match and we got a backspace, we always decrement the matched
		// characters and start looking at that point.
		cch = --pedit->m_cchMatched;
	}
	else
	{
		// Otherwise we start looking at the cursor location.
		cch = ichMin;
	}

	AfLpInfo * plpi = GetLpInfo();
	AssertPtr(plpi);

	PossListInfoPtr qpli;
	plpi->LoadPossList(m_hvoPssl, m_wsMagic, &qpli);
	AssertPtr(qpli);

	PossItemInfo * ppii = NULL;
	ComBool fExactMatch = false;

	fNeedCompare = true;

	if (cchTyped == 0)
	{
		// If nothing to match, get the first item in the possibility list. If we are
		// already at that item, remove the item. If we are already cleared, do nothing.
		if (!m_pss)
			return true;
		// If everything is highlighted, we want to clear the item with Del or Bsp.
		// But when we are backspacing, if there is only one character left and we backspace
		// over that, we want to switch to the first item in the list.
		ppii = qpli->GetPssFromIndex(0);
		if (ichMin != 1)
		{
			m_pss = 0;
			m_qtss = NULL;
			pedit->m_cchMatched = 0; // Keep cursor at beginning of item.
			m_fRecurse = true;
			::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)m_qtss.Ptr());
			return true;
		}
	}
	else if (fNeedCompare)
	{
		// Try to find an item that matches what the user typed in the possibility list.
		StrUni stuMatch(stuTyped);
/////		stuMatch.Replace(cch, stuMatch.Length(), L"");// Delete chars to right of cursor.
		Locale loc = GetLpInfo()->GetLocale(m_ws);
		if (m_fHier)
		{
			ppii = qpli->FindPssHier(stuMatch.Chars(), loc, m_pnt, fExactMatch);
		}
		else
		{
			ppii = qpli->FindPss(stuMatch.Chars(), loc, m_pnt);
		}

		if (ppii)
		{
			// found a match that starts with stuTyped
			int ipssTemp;

			// TODO TimP:  check for hierarchy.  If stuTyped contains hierarchy,

			// Was the match exact (rather than just starting with stuTyped) ?
			if (fExactMatch) // May have matched in the FindPssHier() call above.
			{
#ifdef DEBUG_THIS_FILE
				sta.Format("OnChange:  Exact match (hier).\n");
				OutputDebugString(sta.Chars());
#endif
			}
			else
			{
				fExactMatch = ! qpli->PossUniqueName(-1, stuTyped, m_pnt, ipssTemp);
				if (fExactMatch)
				{
#ifdef DEBUG_THIS_FILE
					sta.Format("OnChange:  Exact match.\n");
					OutputDebugString(sta.Chars());
#endif
					// in case FindPss() above matches "ABC" but "AB" is also in list.
					ppii = qpli->GetPssFromIndex(ipssTemp);
				}
				else
				{
#ifdef DEBUG_THIS_FILE
					sta.Format("OnChange:  Not exact match.\n");
					OutputDebugString(sta.Chars());
#endif
				}
			}
		}
	}
	else
		ppii = NULL;

	StrUni stuFound;
	int ws = m_ws;
	if (ppii && (fTypeAhead || fExactMatch))
	{
		// If found, process the new item.
		int pss = ppii->GetPssId();
		m_pss = pss;
		if (m_fHier)
			ppii->GetHierName(qpli, stuFound, m_pnt);
		else
			ppii->GetName(stuFound, m_pnt);
		ws = ppii->GetWs();

		// If the last character was a delimiter, we need to set cch accordingly.
		if (m_fHier && (stuTyped.Length() > 0) && (pedit->m_ch != VK_BACK) &&
			(stuTyped.GetAt(stuTyped.Length() - 1) == kchHierDelim))
		{
			// Need to set cch to the position of the last delimiter.
			cch = stuFound.FindCh(kchHierDelim, cch - 1) + 1;
		}

		pedit->m_cchMatched = cch;
	}
	else
	{
		// Something illegal was typed. Assume they are adding a new item.
		if (pedit->m_cchMatched + 1 == cch && pedit->m_ch != VK_BACK)
			::MessageBeep(MB_ICONEXCLAMATION); // Beep on the first unmatched character.
		// Underline the string with a red squiggly.
		ITsIncStrBldrPtr qtisb;
		qtisb.CreateInstance(CLSID_TsIncStrBldr);
		qtisb->SetIntPropValues(ktptWs, ktpvDefault, m_ws);
		CheckHr(qtisb->SetIntPropValues(ktptUnderColor, ktpvDefault, kclrRed));
		CheckHr(qtisb->SetIntPropValues(ktptUnderline, ktpvEnum, kuntSquiggle));
		qtisb->AppendRgch(stuTyped.Chars(), stuTyped.Length());
		qtisb->GetString(&m_qtss);
		m_fRecurse = true; // Stop the recursion caused by the next instruction.
		// Note: This recursively calls this procedure.
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)m_qtss.Ptr());
		::SendMessage(m_hwnd, EM_SETSEL, ichMin, ichMin);
		m_pss = 0; // We no longer have a matched HVO.
		return true;
	}

	// Update the edit box text and selection.
	ITsStrFactoryPtr qtsf;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	qtsf->MakeStringRgch(stuFound.Chars(), stuFound.Length(), ws, &qtss);
	m_qtss = qtss;

#ifdef DEBUG_THIS_FILE
	sta.Format("AfDeFeCliRef::OnChange:  pedit->m_cchMatched=%d; stuFound.Length()=%d; ichMin=%d; ichLim=%d.\n",
										 pedit->m_cchMatched,    stuFound.Length(),    ichMin,    ichLim);
	OutputDebugString(sta.Chars());
#endif

	m_fRecurse = true; // Shortcut the recursion caused by the next instruction.
	if (fTypeAhead)
	{
		// Note: This recursively calls this procedure.
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)qtss.Ptr());
		::SendMessage(m_hwnd, EM_SETSEL, pedit->m_cchMatched, stuFound.Length());
#ifdef DEBUG_THIS_FILE
	sta.Format("AfDeFeCliRef::OnChange:  type ahead.\n");
	OutputDebugString(sta.Chars());
#endif
	}
	else
	{
		// Note: This recursively calls this procedure.
		::SendMessage(m_hwnd, FW_EM_SETTEXT, 0, (LPARAM)qtss.Ptr());
		::SendMessage(m_hwnd, EM_SETSEL, ichMin, ichMin);
#ifdef DEBUG_THIS_FILE
	sta.Format("AfDeFeCliRef::OnChange:  NOT type ahead.\n");
	OutputDebugString(sta.Chars());
#endif
	}

	return true;
}
コード例 #10
0
/*----------------------------------------------------------------------------------------------
	Close the current editor, saving changes that were made.  This also updates the the cache
	if the name or abbr fields were edited, this then causing the treebar to be updated.
	@param fForce True if we want to force the editor closed without making any
		validity checks or saving any changes.
----------------------------------------------------------------------------------------------*/
void CleDeFeString::EndEdit(bool fForce)
{
	if (fForce)
	{
		SuperClass::EndEdit(fForce);
		return;
	}

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(MainWindow());
	Assert(pcmw);

	PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
	int ipss = qpli->GetIndexFromId(m_hvoObj);
	if (ipss < 0)
	{
		SuperClass::EndEdit(fForce); // Closing an old editor after an item was removed.
		return;
	}
	PossItemInfo * ppii = qpli->GetPssFromIndex(ipss);
	AssertPtr(ppii);
	StrUni stu;

	const OLECHAR * prgwch;
	int cch;
	ITsStringPtr qtss;
	AssertPtr(m_qadsc->MainWindow());
	AfLpInfo * plpi = m_qadsc->MainWindow()->GetLpInfo();
	AssertPtr(plpi);
	AfDbInfo * pdbi;
	pdbi = plpi->GetDbInfo();
	AssertPtr(pdbi);
	int wsMagic = qpli->GetWs();
	int ws = plpi->ActualWs(wsMagic);

	// At this point, all strings in a PossList cache are assumed to have the same writing system.
	// However, if that writing system is missing, a non-null string from a different writing system is
	// loaded. Thus if FRN is the writing system for the PossList cache, we can't tell from the
	// cache whether the string we are getting is FRN or ENG, or some other writing system. When
	// we display strings in this editor, we show actual strings for each writing system shown.
	// Suppose we are showing FRN and ENG, but FRN is missing. If a person edits the ENG
	// string that is showing, the user would expect the tree to reflect this change, since
	// FRN is still missing. However we can't do this at this point because we don't know
	// which writing system is actually being substituted in the tree. It could actually be a GER
	// string because there also wasn't an ENG string. So until we cache encodings with each
	// string, the best we can do is only modify the PossList cache if the string for the
	// primary writing system changed. In that case, we now have a FRN string, so it should show
	// in the tree as well.
	CustViewDaPtr qcvd = pcmw->MainDa();
	AssertPtr(qcvd);

	// Get the current primary string.
	CheckHr(qcvd->get_MultiStringAlt(m_hvoObj, m_flid, ws, &qtss));
	if (qtss)
	{
		qtss->LockText(&prgwch, &cch);
		qtss->UnlockText(prgwch);
	}

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

	// We don't expect to use this for anything except name or abbr.
	Assert(m_flid == kflidCmPossibility_Name || m_flid == kflidCmPossibility_Abbreviation);
	// We don't allow long strings.
	if (stu.Length() > kcchPossNameAbbrMax) // Need constant here and the line below.
	{
		::MessageBeep(MB_ICONEXCLAMATION); // Beep if we truncated the length.
		stu.Replace(kcchPossNameAbbrMax, stu.Length(), L"");
	}

	ITsStrFactoryPtr qtsf;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	qtsf->MakeStringRgch(stu.Chars(), stu.Length(), ws, &qtss);

	// If we changed the length, store the trimmed string.
	if (cch != stu.Length())
	{
		// Check if the record has been edited by someone else since we first loaded the data.
		HRESULT hrTemp;
		if ((hrTemp = qcvd->CheckTimeStamp(m_hvoObj)) != S_OK)
		{
			// If it was changed and the user does not want to overwrite it, perform a refresh
			// so the displayed field will revert to its original value.
			CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
			return;
		}

		// Update the value in the cache and refresh views.
		CheckHr(qcvd->SetMultiStringAlt(m_hvoObj, m_flid, ws, qtss));
		CheckHr(qcvd->PropChanged(NULL, kpctNotifyAll, m_hvoObj, m_flid, 0, 1, 1));
	}

	SuperClass::EndEdit(fForce);

	// See if the primary string has changed.
	ComBool fEqual;
	CheckHr(qtss->Equals(m_qtssOld, &fEqual));
	if (fEqual)
		return; // No change was made, so we don't need to do anything else.

	// A change was made.
	if (m_flid != kflidCmPossibility_Name && m_flid != kflidCmPossibility_Abbreviation)
		return; // Nothing more to do if it isn't a name or abbreviation.

	// We've changed the primary name or abbreviation, so update the PossList cache.
	ppii->SetName(stu, m_flid == kflidCmPossibility_Name ? kpntName : kpntAbbreviation);

	if (qpli->GetIsSorted())
	{
		// The list is sorted, so we need to move the item to its new location.
		if (qpli->PutInSortedPosition(m_hvoObj, false))
		{
			int ihvo;
			pcmw->LoadData();
			HvoClsidVec & vhc = pcmw->Records();
			for (ihvo = vhc.Size(); --ihvo >= 0; )
			{
				if (vhc[ihvo].hvo == m_hvoObj)
					break;
			}
			Assert(ihvo >= 0); // Should have found item.
			pcmw->SetCurRecIndex(ihvo);
		}
	}
	// We can't do a sync in this method that opens new editors, so just flag
	// that it needs to be done.
	// We need to sync if either name or abbreviation has changed. Even though we may only
	// be showing one or the other in our lists, there may be overlays or something else
	// showing the other, so to be safe, we need to do a sync if either changed.
	dynamic_cast<CleDeSplitChild *>(m_qadsc.Ptr())->SetNeedSync(true);
}
コード例 #11
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;
}
コード例 #12
0
/*----------------------------------------------------------------------------------------------
	Add a field editor for a given field at the location and indent specified.

	@param hvoRoot Id of the root object that holds the fields we want to display.
	@param clid Class of the root object.
	@param nLev Level (main/sub) of the root object in the window.
	@param pfsp The FldSpec that defines this field.
	@param pcvd Pointer to the CustViewDa specifying what fields to display.
	@param idfe Index where the new fields are to be inserted. On return it contains
		an index to the field following any inserted fields.
	@param nInd Indent of the fields to be added.
	@param fAlwaysVisible If true, show field regardless of pbsp->m_eVisibility
----------------------------------------------------------------------------------------------*/
void CleDeSplitChild::AddField(HVO hvoRoot, int clid, int nLev, FldSpec * pfsp,
	CustViewDa * pcvd, int & idfe, int nInd, bool fAlwaysVisible)
{
	AssertPtr(pcvd);
	AssertPtr(pfsp);

	bool fCheckMissingData = fAlwaysVisible ? false : pfsp->m_eVisibility == kFTVisIfData;

	// If the user never wants to see this field, skip it.
	if (pfsp->m_eVisibility == kFTVisNever)
		return;

	ITsStringPtr qtss;

	AfLpInfo * plpi = pcvd->GetLpInfo();
	AssertPtr(plpi);

	AfStatusBarPtr qstbr = MainWindow()->GetStatusBarWnd();
	Assert(qstbr);

	switch(pfsp->m_ft)
	{
	case kftEnum:
		{
			AfDeFeComboBox * pdecb = NewObj AfDeFeComboBox();
			ITsStrFactoryPtr qtsf;
			qtsf.CreateInstance(CLSID_TsStrFactory);
			int itss;
			CheckHr(pcvd->get_IntProp(hvoRoot, pfsp->m_flid, &itss));
			pdecb->Initialize(hvoRoot, pfsp->m_flid, nInd, pfsp->m_qtssLabel,
				pfsp->m_qtssHelp, this, pfsp);
			pdecb->Init(pfsp->m_pnt);
			ComVector<ITsString> * pvtss;
			pvtss = pdecb->GetVec();
			int stid;
			switch (pfsp->m_flid)
			{
			case kflidCmPerson_Gender:
				stid = kstidEnumGender;
				break;
#ifdef ADD_LEXTEXT_LISTS
			case kflidCmAnnotationDefn_AllowsComment: // Fall through.
			case kflidCmAnnotationDefn_AllowsFeatureStructure: // Fall through.
			case kflidCmAnnotationDefn_AllowsInstanceOf: // Fall through.
			case kflidCmAnnotationDefn_UserCanCreate: // Fall through.
			case kflidCmAnnotationDefn_CanCreateOrphan: // Fall through.
			case kflidCmAnnotationDefn_PromptUser: // Fall through.
			case kflidCmAnnotationDefn_CopyCutPastable: // Fall through.
			case kflidCmAnnotationDefn_ZeroWidth: // Fall through.
			case kflidCmAnnotationDefn_Multi: // Fall through.
#endif
			case kflidMoInflAffixSlot_Optional: // Fall through.
			case kflidCmPerson_IsResearcher:
				stid = kstidEnumNoYes;
				if (itss)
					itss = 1;
				break;
			default:
				Assert(false); // A list must be provided above.
				break;
			}
			StrUni stuEnum(stid);
			const wchar * pszEnum = stuEnum.Chars();
			const wchar * pszEnumLim = stuEnum.Chars() + stuEnum.Length();
			while (pszEnum < pszEnumLim)
			{
				const wchar * pszEnumNl = wcschr(pszEnum, '\n');
				if (!pszEnumNl)
					pszEnumNl = pszEnumLim;

				AfDbInfo * pdbi = plpi->GetDbInfo();
				AssertPtr(pdbi);
				int wsUser = pdbi->UserWs();

				qtsf->MakeStringRgch(pszEnum, pszEnumNl - pszEnum, wsUser,
					&qtss);
				pvtss->Push(qtss);
				pszEnum = pszEnumNl + 1;
			}
			pdecb->SetIndex(itss);
			m_vdfe.Insert(idfe++, pdecb);
		}
		return;

	case kftMsa:	// Fall through.
	case kftMta:
		{
			Vector<int> vwsT;
			Vector<int> & vws = vwsT;

			// We need a special editor for name and address to catch changes to update the
			// tree views.
			if ((pfsp->m_flid == kflidCmPossibility_Name) ||
				(pfsp->m_flid == kflidCmPossibility_Abbreviation))
			{
				CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(MainWindow());
				Assert(pcmw);
		//		PossListInfoPtr qpli = pcmw->GetPossListInfoPtr();
				int wsPL= pcmw->GetWsPssl();
				switch (wsPL)
				{
				case kwsAnals:
					vws = plpi->AnalWss();
					break;
				case kwsVerns:
					vws = plpi->VernWss();
					break;
				case kwsAnal:
					vwsT.Push(plpi->AnalWs());
					break;
				case kwsVern:
					vwsT.Push(plpi->VernWs());
					break;
				case kwsAnalVerns:
					vws = plpi->AnalVernWss();
					break;
				case kwsVernAnals:
					vws = plpi->VernAnalWss();
					break;
				default:
					vwsT.Push(wsPL);
					break;
				}

				if (fCheckMissingData)
				{
					ITsStringPtr qtss;
					int iws;
					for (iws = vws.Size(); --iws >= 0; )
					{
						CheckHr(pcvd->get_MultiStringAlt(hvoRoot, pfsp->m_flid, vws[iws],
							&qtss));
						int cch;
						CheckHr(qtss->get_Length(&cch));
						if (cch)
							break;
					}
					if (iws < 0)
						return; // All writing systems are empty.
				}
				// An extra ref cnt is created here which is eventually assigned to the vector.
				CleDeFeStringPtr qdfs = NewObj CleDeFeString;
				qdfs->Initialize(hvoRoot, pfsp->m_flid, nInd, pfsp->m_qtssLabel,
					pfsp->m_qtssHelp, this, pfsp);

				if (pfsp->m_ft == kftMta)
					qdfs->Init(&vws, ktptSemiEditable);
				else
					qdfs->Init(&vws, ktptIsEditable);

				m_vdfe.Insert(idfe++, qdfs);
			}
			else
			{
				switch (pfsp->m_ws)
				{
				case kwsAnals:
					vws = plpi->AnalWss();
					break;
				case kwsVerns:
					vws = plpi->VernWss();
					break;
				case kwsAnal:
					vwsT.Push(plpi->AnalWs());
					break;
				case kwsVern:
					vwsT.Push(plpi->VernWs());
					break;
				case kwsAnalVerns:
					vwsT = plpi->AnalVernWss();
					break;
				case kwsVernAnals:
					vwsT = plpi->VernAnalWss();
					break;
				default:
					vwsT.Push(pfsp->m_ws);
					Assert(pfsp->m_ws);
					break;
				}

				if (fCheckMissingData)
				{
					ITsStringPtr qtss;
					int iws;
					for (iws = vws.Size(); --iws >= 0; )
					{
						CheckHr(pcvd->get_MultiStringAlt(hvoRoot, pfsp->m_flid, vws[iws],
							&qtss));
						int cch;
						CheckHr(qtss->get_Length(&cch));
						if (cch)
							break;
					}
					if (iws < 0)
						return; // All writing systems are empty.
				}
				// An extra ref cnt is created here which is eventually assigned to the vector.
				AfDeFeStringPtr qdfs = NewObj AfDeFeString;
				qdfs->Initialize(hvoRoot, pfsp->m_flid, nInd, pfsp->m_qtssLabel,
					pfsp->m_qtssHelp, this, pfsp);

				if (pfsp->m_ft == kftMta)
					qdfs->Init(&vws, ktptSemiEditable);
				else
					qdfs->Init(&vws, ktptIsEditable);

				m_vdfe.Insert(idfe++, qdfs);
			}

		}
		return;
	case kftExpandable:	// Fall through.
	case kftSubItems:
		return;

	case kftObjRefAtomic:	// Fall through.
	case kftObjRefSeq:
		{
			bool fMultiRefs;
			if (pfsp->m_ft == kftObjRefAtomic)
			{
				HVO hvoRef;
				CheckHr(pcvd->get_ObjectProp(hvoRoot, pfsp->m_flid, &hvoRef));
				fMultiRefs = false;
				if (fCheckMissingData && !hvoRef)
					return;
			}
			else
			{
				fMultiRefs = true;
				if (fCheckMissingData) // otherwise no need to check
				{
					int chvo;
					CheckHr(pcvd->get_VecSize(hvoRoot, pfsp->m_flid, &chvo));
					if (!chvo)
						return;
				}
			}
			AfDeFeRefs * pdfr = NewObj AfDeFeRefs;
			pdfr->Initialize(hvoRoot, pfsp->m_flid, nInd, pfsp->m_qtssLabel,
				pfsp->m_qtssHelp, this, pfsp);
			switch (pfsp->m_flid)
			{
			default:
				// Standard kftObjRefAtomic & kftObjRefSeq fields are all handled in the superclass.
				SuperClass::AddField(hvoRoot, clid, nLev, pfsp, pcvd, idfe, nInd, fAlwaysVisible);
				return;
			}
			m_vdfe.Insert(idfe++, pdfr);
		}
		return;
	}
	qstbr->StepProgressBar(10);

	// Standard fields are all handled in the superclass.
	SuperClass::AddField(hvoRoot, clid, nLev, pfsp, pcvd, idfe, nInd, fAlwaysVisible);
	return;
}