/*---------------------------------------------------------------------------------------------- This is the main interesting method of displaying objects and fragments of them. Here a text is displayed by displaying its paragraphs; and a paragraph is displayed by invoking its style rule, making a paragraph, and displaying its contents. ----------------------------------------------------------------------------------------------*/ STDMETHODIMP TestStVc::Display(IVwEnv * pvwenv, HVO hvo, int frag) { try { switch(frag) { case kfrText: {// BLOCK for var skip warnings // We need to show something, since the current view code can't handle a property // containing no boxes. // Review JohnT: should we show an empty string or something? // Should we prevent the occurrence of texts with no paragraphs? int cpara = 0; ISilDataAccessPtr qsda; CheckHr(pvwenv->get_DataAccess(&qsda)); if (hvo) CheckHr(qsda->get_VecSize(hvo, kflidStText_Paragraphs, &cpara)); if (!cpara) { // Either we have no ST object at all, or it is empty of paragraphs. The // current view code can't handle either, so stick something in. ITsStrFactoryPtr qtsf; qtsf.CreateInstance(CLSID_TsStrFactory); ITsStringPtr qtssMissing; CheckHr(qtsf->MakeStringRgch(L"<no paragraphs>", 15, 0, &qtssMissing)); CheckHr(pvwenv->AddString(qtssMissing)); break; } CheckHr(pvwenv->AddObjVecItems(kflidStText_Paragraphs, this, kfrPara)); } break; case kfrPara: { // BLOCK // Invoke the paragraph's style rule if any ISilDataAccessPtr qsda; CheckHr(pvwenv->get_DataAccess(&qsda)); ITsTextPropsPtr qttp; CheckHr(qsda->get_UnknownProp(hvo, kflidStPara_StyleRules, IID_ITsTextProps, (void **) &qttp)); if (qttp) CheckHr(pvwenv->put_Props(qttp)); // And make the paragraph containing the paragraph contents. CheckHr(pvwenv->OpenParagraph()); CheckHr(pvwenv->AddStringProp(kflidStTxtPara_Contents)); CheckHr(pvwenv->CloseParagraph()); } break; } } catch (Throwable & thr) { return thr.Error(); } catch (...) { return WarnHr(E_FAIL); } return S_OK; }
/*---------------------------------------------------------------------------------------------- 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 AfDeFeSt::EndEdit(bool fForce) { if (m_qvcdMissing && !fForce) { ComBool fDirty; ISilDataAccessPtr qsdaTemp; CheckHr(m_qvcdMissing->QueryInterface(IID_ISilDataAccess, (void **)&qsdaTemp)); qsdaTemp->IsDirty(&fDirty); if (fDirty) { // The text got edited. So, make a real text and copy the relevant info. // First get the paragraph list HvoVec vhvoParas; int chvoParas; // If we already had a text, we will notify it of new paragraphs. bool fNotifyText = m_hvoText > 0; CheckHr(qsdaTemp->get_VecSize(m_hvoText, kflidStText_Paragraphs, &chvoParas)); int ihvo; // used twice for (ihvo = 0; ihvo < chvoParas; ihvo++) { HVO hvoPara; CheckHr(qsdaTemp->get_VecItem(m_hvoText, kflidStText_Paragraphs, ihvo, &hvoPara)); vhvoParas.Push(hvoPara); } // Actually, we may have had a real text...if so, skip this step if (m_hvoText < 0) { m_qcvd->MakeNewObject(kclidStText, m_hvoObj, m_flid, -2, &m_hvoText); } else { // Check if the record has been edited by someone else since we first loaded // the data. HRESULT hrTemp; if ((hrTemp = m_qcvd->CheckTimeStamp(m_hvoText)) != 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 it's original value. SuperClass::EndEdit(fForce); // REVIEW KenZ (PaulP): There may need to be a refresh call made here. // It's difficult to know, however, since I haven't tracked down when // this method actually gets called. m_fDirty = false; return; } } // Now make real paragraph objects and set their properties. for (ihvo = 0; ihvo < chvoParas; ihvo++) { HVO hvoPara = vhvoParas[ihvo]; ITsStringPtr qtss; ITsTextPropsPtr qttp; IUnknownPtr qunkTtp; CheckHr(qsdaTemp->get_UnknownProp(hvoPara, kflidStStyle_Rules, &qunkTtp)); CheckHr(qunkTtp->QueryInterface(IID_ITsTextProps, (void **) &qttp)); CheckHr(qsdaTemp->get_StringProp(hvoPara, kflidStTxtPara_Contents, &qtss)); CheckHr(m_qcvd->MakeNewObject(kclidStTxtPara, m_hvoText, kflidStText_Paragraphs, ihvo, &hvoPara)); if (qttp) CheckHr(m_qcvd->SetUnknown(hvoPara, kflidStPara_StyleRules, qttp)); CheckHr(m_qcvd->SetString(hvoPara, kflidStTxtPara_Contents, qtss)); } m_qvcdMissing.Clear(); // Update the root object to point at the real text we just made. int frag = kfrText; IVwViewConstructor * pvvc = m_qstvc; CheckHr(m_qrootb->putref_DataAccess(m_qcvd)); CheckHr(m_qrootb->SetRootObjects(&m_hvoText, &pvvc, &frag, GetLpInfo()->GetAfStylesheet(), 1)); m_qadsc->UpdateAllDEWindows(m_hvoObj, m_flid); if (fNotifyText) { CheckHr(m_qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoText, kflidStText_Paragraphs, 0, chvoParas, chvoParas)); } else { CheckHr(m_qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoObj, m_flid, 0, 1, 1)); } } } // Do this after the changes above, otherwise, our hwnd is no longer the child of a main // window, and we can't find the style sheet for the SetRootObjects call. SuperClass::EndEdit(fForce); m_fDirty = false; }