Example #1
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.
	}
}
Example #2
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;
}
Example #3
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)
}
Example #4
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;
}