/*---------------------------------------------------------------------------------------------- Set the text of the control to be equal to ptss. If ptss is NULL, the edit box is cleared. Message: FW_EM_SETTEXT. ----------------------------------------------------------------------------------------------*/ void TssEdit::SetText(ITsString * ptss) { AssertPtrN(ptss); // NULL can be used to clear string. Assert(m_qcda); ITsStringPtr qtss = ptss; if (!ptss) { ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); CheckHr(qtsf->MakeStringRgch(L"", 0, m_wsBase, &qtss)); } ITsStringPtr qtssOld; CheckHr(m_qcda->get_StringProp(khvoString, ktagString, &qtssOld)); int cchOld; CheckHr(qtssOld->get_Length(&cchOld)); CheckHr(m_qcda->CacheStringProp(khvoString, ktagString, qtss)); int cchNew; CheckHr(qtss->get_Length(&cchNew)); // Pretend the whole length has been deleted and the whole new inserted. CheckHr(m_qcda->PropChanged(NULL, kpctNotifyAll, khvoString, ktagString, 0, cchNew, cchOld)); OnUpdate(); ::UpdateWindow(m_hwnd); OnChange(); }
/*---------------------------------------------------------------------------------------------- Close the current editor, saving changes that were made. hwnd is the editor hwnd. @param fForce True if we want to force the editor closed without making any validity checks or saving any changes. ----------------------------------------------------------------------------------------------*/ void AfDeFeCliRef::EndEdit(bool fForce) { if (!fForce) { if (!m_pss) { // The user added a new item. ITsStringPtr qtss; int cch; StrUni stu; // Name/Abbr string entered by user. OLECHAR * pchBuf; // Get the characters from the edit box. ::SendMessage(m_hwnd, FW_EM_GETTEXT, 0, (LPARAM)&qtss); qtss->get_Length(&cch); stu.SetSize(cch, &pchBuf); qtss->FetchChars(0, cch, pchBuf); if (cch) { // If a non-null string is present, create a new item. m_fSaving = true; // Disable updates while adding a new item. // The user created a new item, so add it to the possibility list. m_pss = CreatePss(m_hvoPssl, stu.Chars(), m_pnt, m_fHier); Assert(m_pss); // What should we do if we have an error? m_fSaving = false; } } } // When we close the edit window, the squiggley will automatically be removed. SuperClass::EndEdit(fForce); }
/*---------------------------------------------------------------------------------------------- Save the text to a file. ----------------------------------------------------------------------------------------------*/ bool WpDa::SaveToFile(StrAnsi staFileName) { IStreamPtr qstrm; FileStream::Create(staFileName.Chars(), kfstgmWrite | kfstgmCreate, &qstrm); // FileStream::Create("c:\\output.txt", kfstgmWrite | kfstgmCreate, &qstrm); ULONG cbWritten; // Write byte-order mark. byte b = 0xFF; CheckHr(qstrm->Write(&b, 1, &cbWritten)); b = 0xFE; CheckHr(qstrm->Write(&b, 1, &cbWritten)); int ctss; CheckHr(get_VecSize(1, kflidStText_Paragraphs, &ctss)); for (int itss = 0; itss < ctss; itss++) { ITsStringPtr qtss; CheckHr(get_StringProp(itss + 2, kflidStTxtPara_Contents, &qtss)); BSTR bstr = NULL; int cchw; CheckHr(qtss->get_Length(&cchw)); qtss->GetChars(0, cchw, &bstr); // Write the string to the file. if (cchw > 0) { Assert(bstr); CheckHr(qstrm->Write(bstr, cchw * isizeof(wchar), &cbWritten)); } if (itss < ctss - 1) { // CRLF--little-endian b = 13; CheckHr(qstrm->Write(&b, 1, &cbWritten)); b = 0; CheckHr(qstrm->Write(&b, 1, &cbWritten)); b = 10; CheckHr(qstrm->Write(&b, 1, &cbWritten)); b = 0; CheckHr(qstrm->Write(&b, 1, &cbWritten)); } ReleaseBstr(bstr); } return true; }
/*---------------------------------------------------------------------------------------------- Return true if the text buffer is empty--that is, containing only one empty string. ----------------------------------------------------------------------------------------------*/ bool WpDa::IsEmpty() { int ctss; CheckHr(get_VecSize(1, kflidStText_Paragraphs, &ctss)); if (ctss == 0) return true; if (ctss > 1) return false; ITsStringPtr qtss; CheckHr(get_StringProp(2, kflidStTxtPara_Contents, &qtss)); int cchw; CheckHr(qtss->get_Length(&cchw)); return (cchw == 0); }
/*---------------------------------------------------------------------------------------------- Display TsString in the control (may be explicitly called when created by ATL, because in this case TssEdit::Create() will not be called) ----------------------------------------------------------------------------------------------*/ void TssEdit::PostCreate(ITsString * ptss) { AssertPtrN(ptss); if (ptss) { int cch; ITsStringPtr qtss = ptss; CheckHr(qtss->get_Length(&cch)); // Treat as inserting all the characters, since the cache previously had nothing. CheckHr(m_qcda->PropChanged(NULL, kpctNotifyAll, khvoString, ktagString, 0, cch, 0)); OnUpdate(); ::UpdateWindow(m_hwnd); OnChange(); } }
/*---------------------------------------------------------------------------------------------- Check the requirments of the FldSpec, and verify that data in the field meets the requirement. It returns: kFTReqNotReq if the all requirements are met. kFTReqWs if data is missing, but it is encouraged. kFTReqReq if data is missing, but it is required. ----------------------------------------------------------------------------------------------*/ FldReq AfDeFeSt::HasRequiredData() { if (m_qfsp->m_fRequired == kFTReqNotReq) return kFTReqNotReq; CustViewDaPtr qcvd; GetDataAccess(&qcvd); AssertPtr(qcvd); bool fEmpty = true; ITsStringPtr qtss; int cch = 0; HVO hvoPara; int iPara; if (!m_hvoText) goto LExit; int cPara; CheckHr(qcvd->get_VecSize(m_hvoText, kflidStText_Paragraphs, &cPara)); if (!cPara) goto LExit; // Make sure at least some paragraph has data. for (iPara = 0; iPara < cPara; ++iPara) { CheckHr(qcvd->get_VecItem(m_hvoText, kflidStText_Paragraphs, iPara, &hvoPara)); // At some point we may need to handle something other than StTxtPara. CheckHr(qcvd->get_StringProp(hvoPara, kflidStTxtPara_Contents, &qtss)); if (qtss) CheckHr(qtss->get_Length(&cch)); if (cch) break; // Have a valid string } fEmpty = iPara == cPara; LExit: if (fEmpty) return m_qfsp->m_fRequired; else return kFTReqNotReq; }
/*---------------------------------------------------------------------------------------------- Selects a range of characters. Message: EM_SETSEL. ----------------------------------------------------------------------------------------------*/ void TssEdit::SetSel(int ichAnchor, int ichEnd) { Assert(m_qrootb); int cch = 0; ITsStringPtr qtss; CheckHr(m_qcda->get_StringProp(khvoString, ktagString, &qtss)); if (qtss) CheckHr(qtss->get_Length(&cch)); if (ichAnchor < 0) ichAnchor = cch; if (ichEnd < 0) ichEnd = cch; if (ichAnchor > cch) ichAnchor = cch; // This can happen; apparently when a tab brings the focus to this window, Windows passes // a large number rather than -1 to set the end of the range. if (ichEnd > cch) ichEnd = cch; CheckHr(m_qrootb->MakeTextSelection(0, 0, NULL, ktagString, 0, ichAnchor, ichEnd, 0, true, -1, NULL, true, NULL)); }
/*---------------------------------------------------------------------------------------------- Load the data needed to display this view. In this case, we need to load the class, owner (so we can tell whether it is a subitem), the title, and create date. If all of these are already in the cache, don't reload it. @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::LoadDataFor(IVwEnv * pvwenv, HVO hvo, int frag) { BEGIN_COM_METHOD; ChkComArgPtr(pvwenv); Assert(false); // TODO: rework StrUni stuSql; ISilDataAccessPtr qsda; CheckHr(pvwenv->get_DataAccess(&qsda)); bool fLoaded = false; int clid; CheckHr(qsda->get_IntProp(hvo, kflidCmObject_Class, &clid)); if (clid) { HVO hvoOwn; CheckHr(qsda->get_ObjectProp(hvo, kflidCmObject_Owner, &hvoOwn)); if (hvoOwn) { int64 tim; // REVIEW KenZ(RandyR) Whey are DN flids in this app? CheckHr(qsda->get_TimeProp(hvo, kflidRnGenericRec_DateCreated, &tim)); if (tim) { ITsStringPtr qtss; CheckHr(qsda->get_StringProp(hvo, kflidRnGenericRec_Title, &qtss)); if (qtss) { int cch; CheckHr(qtss->get_Length(&cch)); if (cch) fLoaded = true; } } } } if (!fLoaded) { // If any field is missing from the cache, load everything. IDbColSpecPtr qdcs; IVwOleDbDaPtr qda; CheckHr(qsda->QueryInterface(IID_IVwOleDbDa, (void**)&qda)); stuSql.Format(L"select id, Class$, Owner$, DateCreated, Title, Title_Fmt " L"from RnGenericRec_ " L"where id = %d", hvo); qdcs.CreateInstance(CLSID_DbColSpec); CheckHr(qdcs->Push(koctBaseId, 0, 0, 0)); CheckHr(qdcs->Push(koctInt, 1, kflidCmObject_Class, 0)); CheckHr(qdcs->Push(koctObj, 1, kflidCmObject_Owner, 0)); // REVIEW KenZ(RandyR) Whey are DN flids in this app? CheckHr(qdcs->Push(koctTime, 1, kflidRnGenericRec_DateCreated, 0)); CheckHr(qdcs->Push(koctString, 1, kflidRnGenericRec_Title, 0)); CheckHr(qdcs->Push(koctFmt, 1, kflidRnGenericRec_Title, 0)); AfMainWnd * pafw = AfApp::Papp()->GetCurMainWnd(); AssertPtr(pafw); AfStatusBar * pstbr = pafw->GetStatusBarWnd(); AssertPtr(pstbr); bool fProgBar = pstbr->IsProgressBarActive(); if (!fProgBar) { StrApp strMsg(kstidStBar_LoadingData); pstbr->StartProgressBar(strMsg.Chars(), 0, 70, 1); } // Execute the query and store results in the cache. CheckHr(qda->Load(stuSql.Bstr(), qdcs, hvo, 0, pstbr, NULL)); if (!fProgBar) pstbr->EndProgressBar(); } return S_OK; END_COM_METHOD(g_fact2, IID_IVwViewConstructor) }
/*---------------------------------------------------------------------------------------------- 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; }
/*---------------------------------------------------------------------------------------------- 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; }