/// <summary> /// This method is called by the ReversalEntriesText virtual handler when text may have changed in the /// property, in order to update the actual list of reversal entries appropriately. /// </summary> /// <param name="tssVal">The new string.</param> /// <param name="ws">The ws.</param> public void CommitReversalEntriesText(ITsString tssVal, int ws) { LexSenseReversalEntriesTextHandler vh = BaseVirtualHandler.GetInstalledHandler(m_cache, "LexSense", LexSenseReversalEntriesTextHandler.StandardFieldName) as LexSenseReversalEntriesTextHandler; Debug.Assert(vh != null, "The 'LexSenseReversalEntriesTextHandler' virtual handler has to be created at application startup now."); ITsString tssOld = vh.GetValue(m_hvo, ws); // The old and new values could be in another order, and this test won't catch that case. // That condition won't be fatal, however, so don't fret about it. if (tssOld.Equals(tssVal)) return; // no change has occurred string val = tssVal.Text; if (val == null) val = ""; // This will effectively cause any extant entries for the given 'ws' to be removed in the end. StringCollection formsColl = new StringCollection(); foreach (string form in val.Split(';')) { // These strings will be null, if there are two semi-colons together. // Or, it may be just whitespace, if it is '; ;'. if (form == null || form.Trim().Length == 0) continue; formsColl.Add(form.Trim()); } int[] senseEntries = ReversalEntriesRC.HvoArray; int originalSenseEntriesCount = senseEntries.Length; int indexId; DbOps.ReadOneIntFromCommand(m_cache, "SELECT id FROM ReversalIndex WHERE WritingSystem=?", ws, out indexId); ReversalIndex revIndex; if (indexId == 0) { // Create the missing reversal index instead of crashing. See LT-10186. ILgWritingSystem lgws = LgWritingSystem.CreateFromDBObject(m_cache, ws); IReversalIndex newIdx = m_cache.LangProject.LexDbOA.ReversalIndexesOC.Add(new ReversalIndex()); newIdx.WritingSystemRA = lgws; // Copy any and all alternatives from lgws.Name to newIdx.Name foreach (ILgWritingSystem lgwsLoop in m_cache.LanguageEncodings) { string lgsNameAlt = lgws.Name.GetAlternative(lgwsLoop.Hvo); if (lgsNameAlt != null && lgsNameAlt.Length > 0) newIdx.Name.SetAlternative(lgsNameAlt, lgws.Hvo); } revIndex = (ReversalIndex)newIdx; } else { revIndex = (ReversalIndex)CmObject.CreateFromDBObject(m_cache, indexId, false); } // We need the list of ReversalIndexEntries that this sense references, but which belong // to another reversal index. Those hvos, plus any entry hvos from the given 'ws' that are reused, // get put into 'survivingEntries'. Set<int> survivingEntries = new Set<int>(originalSenseEntriesCount + formsColl.Count); // 'entriesNeedingPropChangeBackRef' will hold the hvos of all ReversalIndexEntry objects that need to have // their 'ReferringSenses' virtual property (re)computed. // Any reversal index entry that gains or loses a reference will need this (re)computing. List<int> entriesNeedingPropChangeBackRef = new List<int>(originalSenseEntriesCount + formsColl.Count); foreach (int entryHvo in senseEntries) { // Use 'cheapo' FDO object maker, since it is supposed to all be in the cache already. ReversalIndexEntry rie = (ReversalIndexEntry)CmObject.CreateFromDBObject(m_cache, entryHvo, false); int wsIndex = 0; int hvoIndex = m_cache.GetOwnerOfObjectOfClass(rie.Hvo, ReversalIndex.kclsidReversalIndex); if (hvoIndex != 0) wsIndex = m_cache.GetIntProperty(hvoIndex, (int)ReversalIndex.ReversalIndexTags.kflidWritingSystem); if (wsIndex == ws) { string form = rie.LongName; if (formsColl.Contains(form)) { // Recycling an entry. survivingEntries.Add(rie.Hvo); formsColl.Remove(form); // Don't need to mess with it later on. } else { // It is being removed from the extant reference property, // so needs to recompute its back ref virtual handler. entriesNeedingPropChangeBackRef.Add(rie.Hvo); } } else { // These are all in some other ws, so they certainly must survive (cf. LT-3391). // Any entries that are reused will get added to this array later on. survivingEntries.Add(rie.Hvo); } } // Start Undoable section of code. m_cache.BeginUndoTask(Strings.ksUndoMakeRevEntries, Strings.ksRedoMakeRevEntries); ISilDataAccess sda = m_cache.MainCacheAccessor; IActionHandler acth = sda.GetActionHandler(); try { // add undo actions to reload the virtual handler and send prop changes to update displays if (acth != null) { List<PropChangedInfo> pciList = new List<PropChangedInfo>(); pciList.Add(new PropChangedInfo(m_hvo, vh.Tag, ws, 0, 0)); acth.AddAction(new PropChangedUndoAction(m_cache, true, PropChangeType.kpctNotifyAll, pciList)); acth.AddAction(new ReloadVirtualHandlerUndoAction(m_cache, true, vh, m_hvo, vh.Tag, ws)); } int cOldEntries = revIndex.EntriesOC.Count; foreach (string currentForm in formsColl) { int idRevEntry = revIndex.FindOrCreateReversalEntry(currentForm); entriesNeedingPropChangeBackRef.Add(idRevEntry); survivingEntries.Add(idRevEntry); } // Notify everyone, and his brother, about the changes done here. // PropChanged (1 of 3) Main: Replace main sense property with current set of entries. sda.Replace(m_hvo, (int)LexSense.LexSenseTags.kflidReversalEntries, 0, originalSenseEntriesCount, survivingEntries.ToArray(), survivingEntries.Count); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, m_hvo, (int)LexSense.LexSenseTags.kflidReversalEntries, 0, survivingEntries.Count, originalSenseEntriesCount); // remove entries from the index that are no longer valid foreach (int rieHvo in senseEntries) { if (!survivingEntries.Contains(rieHvo)) { // the entry is no longer a reversal entry for this sense ReversalIndexEntry rie = new ReversalIndexEntry(m_cache, rieHvo); if (rie.SenseIds.Count == 0) // the entry is longer a reversal entry for any sense revIndex.EntriesOC.Remove(rie); } } // PropChanged (2 of 3) Affected Entries: (Re)compute // on the virtual property of select reversal index entries. ReversalIndexEntry.ResetReferringSenses(m_cache, entriesNeedingPropChangeBackRef); // PropChanged (3 of 3) Index Entries: Simulate a complete replacement of the entries collection, // BUT only if new entries were added in this method. int cNewEntries = revIndex.EntriesOC.Count; if (cNewEntries > cOldEntries) { sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, indexId, (int)ReversalIndex.ReversalIndexTags.kflidEntries, 0, cNewEntries, cOldEntries); } // add redo actions to reload the virtual handler and send prop changes to update displays if (acth != null) { acth.AddAction(new ReloadVirtualHandlerUndoAction(m_cache, false, vh, m_hvo, vh.Tag, ws)); List<PropChangedInfo> pciList = new List<PropChangedInfo>(); pciList.Add(new PropChangedInfo(m_hvo, vh.Tag, ws, 0, 0)); acth.AddAction(new PropChangedUndoAction(m_cache, false, PropChangeType.kpctNotifyAll, pciList)); } } finally { if (acth != null && Marshal.IsComObject(acth)) Marshal.ReleaseComObject(acth); } // End undoable section of code. m_cache.EndUndoTask(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="SCTextEnum"/> class. /// </summary> /// <param name="settings">The import settings</param> /// <param name="domain">The source domain</param> /// <param name="startRef">first reference to retrieve</param> /// <param name="endRef">last reference to retrieve</param> /// <param name="encConverters">The encoding converters repository</param> /// ------------------------------------------------------------------------------------ public SCTextEnum(IScrImportSet settings, ImportDomain domain, BCVRef startRef, BCVRef endRef, IEncConverters encConverters) { m_settings = settings; m_domain = domain; m_startRef = new BCVRef(startRef); m_endRef = new BCVRef(endRef); m_mappingSet = m_settings.GetMappingSetForDomain(domain); // Gets the set of encoding converters m_encConverters = encConverters; // make a list of all of the begin and end markers for inline markers // Also build the map of encoding converters m_InlineBeginAndEndMarkers = new List<string>(); foreach (ImportMappingInfo mapping in m_settings.GetMappingListForDomain(domain)) { if (mapping.IsInline || m_settings.ImportTypeEnum == TypeOfImport.Paratext5) { m_InlineBeginAndEndMarkers.Add(mapping.BeginMarker); if (mapping.IsInline) m_InlineBeginAndEndMarkers.Add(mapping.EndMarker); } } m_InlineBeginAndEndMarkers.Sort(new StrLengthComparer(false)); // Build a list of all of the characters that inline markers start with Set<char> tempCharList = new Set<char>(); foreach (string marker in m_InlineBeginAndEndMarkers) tempCharList.Add(marker[0]); // Set ignores duplicates. m_InlineMarkerStartChars = tempCharList.ToArray(); // Get the import file source that will provide the files to import. m_importSource = settings.GetImportFiles(domain); m_importSourceEnum = m_importSource.GetEnumerator(); }
public void ToArrayTests2() { object[] starting = new object[3] { 1, 2, 3 }; Set<object> set = new Set<object>(starting); Assert.AreEqual(3, set.Count, "Set should have three items in it."); int[] ending = set.ToArray<int>(); Assert.AreEqual(3, ending.Length, "Set should have three items in it."); int i = 0; foreach (int startInt in starting) { Assert.AreEqual(startInt, ending[i++], "Set should have same three items in it."); } }
/// <summary> /// Check whether deleting these objects will be undoable. In any case, pops up a message /// asking the user whether to proceed. The type of message depends somewhat on the situation. /// </summary> /// <returns>true, if okay to continue with delete</returns> private bool CheckMultiDeleteConditionsAndReport(Set<int> idsToDelete, out bool fUndo) { int cOrphans = 0; if (m_expectedListItemsClassId == LexEntry.kclsidLexEntry || m_expectedListItemsClassId == LexSense.kclsidLexSense) { cOrphans = CmObject.CountOrphanedObjects(m_cache); } fUndo = cOrphans == 0; if (fUndo) { int iNextGroup = 0; DbOps.MakePartialIdList(ref iNextGroup, idsToDelete.ToArray()); fUndo = iNextGroup == idsToDelete.Count; } string sMsg = XMLViewsStrings.ksConfirmDeleteMultiMsg; string sTitle = XMLViewsStrings.ksConfirmDeleteMulti; if (!fUndo) { sMsg = XMLViewsStrings.ksCannotUndoTooManyDeleted; } return MessageBox.Show(this, sMsg, sTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK; }
protected void InsertSliceRange(int insertPosition, Set<Slice> slices) { List<Slice> indexableSlices = new List<Slice>(slices.ToArray()); for (int i = indexableSlices.Count - 1; i >= 0; --i) { InstallSlice(indexableSlices[i], insertPosition); } ResetTabIndices(insertPosition); }
public void FindSingleVertexGroup() { Set<int> s = new Set<int>(); for (int i=0; i<vertexCount; i++) { if (flag[i] != 0) { bool found = false; foreach (int j in adjVV[i]) if (flag[j] == flag[i]) { found = true; break; } if (!found) s.Add(i); } } int[] arr = s.ToArray(); Array.Sort(arr); this.singleVertexGroup = arr; }
private int GetBestAlt(int hvo, int tag, int wsPreferred, int wsDefault, int[] wsList) { Set<int> wsSet = new Set<int>(); if (wsPreferred != 0) wsSet.Add(wsPreferred); wsSet.AddRange(wsList); // We're not dealing with a real cache, so can't call something like this: //ws = LangProject.InterpretWsLabel(m_caches.MainCache, // LangProject.GetMagicWsNameFromId(ws), // m_caches.MainCache.DefaultAnalWs, // hvo, spec.StringFlid, null); int wsActual = 0; foreach (int ws1 in wsSet.ToArray()) { ITsString tssTest = m_caches.DataAccess.get_MultiStringAlt(hvo, tag, ws1); if (tssTest != null && tssTest.Length != 0) { wsActual = ws1; break; } } // Enhance JohnT: to be really picky here we should do like the real InterpretWsLabel // and fall back to default UI language, then English. // But we probably aren't even copying those alternatives to the sandbox cache. if (wsActual == 0) wsActual = wsDefault; return wsActual; }
/// <summary> /// This will remove the given hvosToRemove (if they exist in our sort items) and any items that refer to invalid objects. /// Reload the view if there were any changes, and adjust the CurrentIndex /// </summary> protected internal void RemoveUnwantedSortItems(List<int> hvosToRemove) { if (m_sortedObjects == null) return; // nothing to remove. bool fUpdatingListOrig = m_fUpdatingList; m_fUpdatingList = true; try { int currentIndex = CurrentIndex; int cOrigSortObjects = m_sortedObjects.Count; // Note: We start with a Set, since it can't have duplicates. // First remove the given hvos from our sort items. Set<int> unwantedIndices = new Set<int>(IndicesOfSortItems(hvosToRemove)); // then remove any remaining items that point to invalid objects. unwantedIndices.AddRange(IndicesOfInvalidSortItems()); // Put the now unique indices into a list, // so we can make sure they are processed in reverse order. List<int> sortedIndices = new List<int>(unwantedIndices.ToArray()); sortedIndices.Sort(); sortedIndices.Reverse(); foreach (int indexOfSortItem in sortedIndices) { if (indexOfSortItem >= 0) { m_sortedObjects.RemoveAt(indexOfSortItem); if (indexOfSortItem < currentIndex || SortedObjects.Count <= currentIndex) currentIndex--; } } if (m_sortedObjects.Count == 0) currentIndex = -1; else if (currentIndex >= m_sortedObjects.Count) currentIndex = m_sortedObjects.Count - 1; CurrentIndex = currentIndex; if (m_sortedObjects.Count != cOrigSortObjects) { SendPropChangedOnListChange(CurrentIndex, SortedObjects, ListChangedEventArgs.ListChangedActions.Normal); } } finally { m_fUpdatingList = fUpdatingListOrig; } }