/*---------------------------------------------------------------------------------------------- This attempts to place the cursor as defined in RecMainWnd m_vhvoPath, m_vflidPath, and m_ichCur. @param vhvo Vector of ids inside the field. @param vflid Vector of flids inside the field. @param ichCur Character offset in the final field for the cursor. ----------------------------------------------------------------------------------------------*/ void AfDeFeSt::RestoreCursor(Vector<HVO> & vhvo, Vector<int> & vflid, int ichCur) { // Store the current record/subrecord and field info. RecMainWnd * prmw = dynamic_cast<RecMainWnd *>(m_qadsc->MainWindow()); if (!prmw) return; CustViewDaPtr qcvd = prmw->MainDa(); AssertPtr(qcvd); IVwSelectionPtr qsel; if (m_qrootb) { // Get the index for the paragraph. // We are assuming at this point that we have something like // vhvo = 2007 (RnGenericRec), 2014 (StText), 2017 (StTxtPara) // vflid = 4006001, 14001 (StText_Paragraphs), 16002 (kflidStTxtPara_Contents) bool fFullSpec = vflid.Size() > 1 && vhvo.Size() > 2 && vflid[1] == kflidStText_Paragraphs; if (fFullSpec) { int ihvo; VwSelLevInfo rgvsli[1]; CheckHr(qcvd->GetObjIndex(vhvo[1], vflid[1], vhvo[2], &ihvo)); rgvsli[0].tag = kflidStText_Paragraphs; // Set up the index for the ids. rgvsli[0].cpropPrevious = 0; rgvsli[0].ihvo = ihvo; m_qrootb->MakeTextSelection( 0, // int ihvoRoot 1, // int cvlsi, rgvsli, // VwSelLevInfo * prgvsli kflidStTxtPara_Contents, // int tagTextProp, 0, // int cpropPrevious, ichCur, // int ichAnchor, ichCur, // int ichEnd, 0, // int ws, true, // ComBool fAssocPrev, -1, // int ihvoEnd, NULL, // ITsTextProps * pttpIns, true, // ComBool fInstall, &qsel); // IVwSelection ** ppsel } // If we didn't get a text selection, try getting a selection somewhere close. if (!qsel) { m_qrootb->MakeTextSelInObj( 0, // index of the one and only root object in this view 0, // the object we want is one level down NULL, // and here's how to find it there 0, NULL, // don't worry about the endpoint true, // select at the start of it true, // Find an editable field false, // and don't select a range. // Making this true, allows the whole record to scroll into view when we launch // a new window by clicking on a reference to an entry, but we don't get an insertion // point. Using false gives an insertion point, but the top of the record is typically // at the bottom of the screen, which isn't good. false, // don't select the whole object true, // but do install it as the current selection NULL); // and don't bother returning it to here. } } }
/*---------------------------------------------------------------------------------------------- Saves changes but keeps the editing window open. In this method we need to convert dummy items into real items if there are any people present. We also need to delete RnRoledPartic and convert the field into a dummy if all of the people have been deleted. Otherwise, there is no way for the user to get rid of RnRoledPartic. @return True if successful. ----------------------------------------------------------------------------------------------*/ bool RnDeFeRoleParts::SaveEdit() { // See if any items are present. int cpss; HVO hvopssl = m_vpssl[0]; ISilDataAccessPtr qsdaTemp; HRESULT hr = m_qvcd->QueryInterface(IID_ISilDataAccess, (void **)&qsdaTemp); if (FAILED(hr)) ThrowInternalError(E_INVALIDARG); CheckHr(qsdaTemp->get_VecSize(hvopssl, kflidPssIds, &cpss)); CustViewDaPtr qcvd; GetDataAccess(&qcvd); AssertPtr(qcvd); if (cpss > 1) // Don't count the dummy at the end. { if (m_hvoObj == khvoDummyRnRoledPartic) { // We have a dummy RnRoledParticipant with at least one item, so we need to // turn the dummy into a real object. HVO hvo; BeginChangesToLabel(); CheckHr(qcvd->MakeNewObject(kclidRnRoledPartic, m_hvoOwner, kflidRnEvent_Participants, -1, &hvo)); Assert(hvo); m_hvoObj = hvo; // If someone deleted the role we are interested in while we are displaying // this field, we can't set the object prop or we'll get an error from the // database. So before doing a save, make sure our role hasn't been deleted. if (m_pssRole) CheckHr(qcvd->SetObjProp(hvo, kflidRnRoledPartic_Role, m_pssRole)); SuperClass::SaveEdit(); CheckHr(qcvd->EndUndoTask()); // Need to notify this property after the participants were added in the superclass // for this to properly update document views. CheckHr(qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoOwner, kflidRnEvent_Participants, 1, 1, 0)); return true; } else { // We have a real RnRoledParticipant with at least one item, so handle it as usual. bool fDirty = m_fDirty; if (!SuperClass::SaveEdit()) return false; if (fDirty) { // Database triggers/procs do not update the entry, so we must do it here. qcvd->SetTimeStamp(m_hvoOwner); qcvd->CacheCurrTimeStamp(m_hvoOwner); } return true; } } else { if (m_hvoObj == khvoDummyRnRoledPartic) { // We have a dummy RnRoledParticipant without any people. Do nothing so the // field will go away when we move to the next record. return true; } else { // We have a real RnRoledParticipant with no items, so we need to change this // into a dummy RnRoledParticipant and remove it from the database. CustViewDaPtr qcvd; GetDataAccess(&qcvd); AssertPtr(qcvd); int ihvo; BeginChangesToLabel(); CheckHr(qcvd->GetObjIndex(m_hvoOwner, kflidRnEvent_Participants, m_hvoObj, &ihvo)); CheckHr(qcvd->DeleteObjOwner(m_hvoOwner, m_hvoObj, kflidRnEvent_Participants, ihvo)); CheckHr(qcvd->EndUndoTask()); m_hvoObj = khvoDummyRnRoledPartic; CheckHr(qcvd->PropChanged(m_qrootb, kpctNotifyAllButMe, m_hvoOwner, kflidRnEvent_Participants, 1, 0, 1)); return true; } } }