internal void Run(bool fMakeSelectionInNewFreeformAnnotation) { IVwSelection sel = null; if (m_site is InterlinDocChild) { sel = (m_site as InterlinDocChild).MakeSandboxSel(); } // If there's no sandbox selection, there may be one in the site itself, perhaps in another // free translation. if (sel == null) { sel = m_site.RootBox.Selection; } if (sel == null) { return; // Enhance JohnT: give an error, or disable the command. } int cvsli = sel.CLevels(false); cvsli--; // CLevels includes the string property itself, but AllTextSelInfo doesn't need it. // Out variables for AllTextSelInfo. int ihvoRoot; int tagTextProp; int cpropPrevious; int ichAnchor; int ichEnd; int ws; bool fAssocPrev; int ihvoEnd; ITsTextProps ttpBogus; // Main array of information retrived from sel that made combo. SelLevInfo[] rgvsli = SelLevInfo.AllTextSelInfo(sel, cvsli, out ihvoRoot, out tagTextProp, out cpropPrevious, out ichAnchor, out ichEnd, out ws, out fAssocPrev, out ihvoEnd, out ttpBogus); // Identify the segment. // This is important because although we are currently displaying just an StTxtPara, // eventually it might be part of a higher level structure. We want this to work // no matter how much higher level structure there is. int itagSegments = -1; for (int i = rgvsli.Length; --i >= 0;) { if (rgvsli[i].tag == m_vc.ktagParaSegments) { itagSegments = i; break; } } if (itagSegments == -1) { return; // Enhance JohnT: throw? disable command? Give an error? } int hvoSeg = rgvsli[itagSegments].hvo; if (m_fdoCache.IsDummyObject(hvoSeg)) { // we need to convert this into a real segment before proceeding. ICmBaseAnnotation cbaReal = CmBaseAnnotation.ConvertBaseAnnotationToReal(m_fdoCache, hvoSeg); hvoSeg = cbaReal != null ? cbaReal.Hvo : 0; rgvsli[itagSegments].hvo = hvoSeg; } ICmIndirectAnnotation ann = AddFreeformAnnotation(hvoSeg, m_hvoType); // If necessary (e.g., we just added a previously invisible FF annotation), // Reconstruct the root box. Otherwise, a simple PropChanged will do. if (m_fNeedReconstruct) { m_site.RootBox.Reconstruct(); // m_site.Invalidate(); // m_site.Update(); // necessary to get a lazy } if (!fMakeSelectionInNewFreeformAnnotation) { return; } // Now try to make a new selection in the FF we just made. // The elements of rgvsli from itagSegments onwards form a path to the segment. // In the segment we want the freeform propery, specifically the new one we just made. // We want to select at the start of it. SelLevInfo[] rgvsliNew = new SelLevInfo[rgvsli.Length - itagSegments + 1]; for (int i = 1; i < rgvsliNew.Length; i++) { rgvsliNew[i] = rgvsli[i + itagSegments - 1]; } // Work out how many freeforms are DISPLAYED before the (first occurrence of the) one we want to select. int ihvo = 0; Dictionary <int, List <int> > dict = m_vc.OrganizeFfAnnotations(hvoSeg); for (int i = m_choices.FirstFreeformIndex; i < m_choices.Count;) { int hvoAnnType = m_vc.SegDefnFromFfFlid(m_choices[i].Flid); List <int> annotations = null; if (dict.ContainsKey(hvoAnnType)) { annotations = dict[hvoAnnType]; } if (hvoAnnType == m_hvoType) { ihvo += annotations.IndexOf(ann.Hvo); break; // And that's where we want our selection!! } // Adjacent WSS of the same annotation count as only ONE object in the display. // So we advance i over as many items in m_choices as there are adjacent Wss // of the same flid. i += m_choices.AdjacentWssAtIndex(i).Length; // But each time we display this flid, we display ALL the objects, // so advance ihvo by the number of annotations of the type. int chvoAnn = annotations == null ? 0 : annotations.Count; ihvo += chvoAnn; } rgvsliNew[0].ihvo = ihvo; rgvsliNew[0].tag = m_vc.ktagSegFF; rgvsliNew[0].cpropPrevious = 0; m_site.RootBox.MakeTextSelInObj(0, rgvsliNew.Length, rgvsliNew, 0, null, true, true, false, false, true); }