/// <summary> /// If hvoWordform is the hvo of a capitalized wordform which has no useful information, /// delete it. It is considered useless if /// - it has no occurrences /// - it has no anlyses /// - it doesn't have known incorrect spelling status. /// Note that the argument may be some other kind of object (typically a WfiAnalysis or WfiGloss). /// If so do nothing. /// </summary> public static void DeleteRedundantCapitalizedWordform(FdoCache cache, int hvoWordform) { if (cache.GetClassOfObject(hvoWordform) != WfiWordform.kclsidWfiWordform) return; if (cache.GetVectorProperty(hvoWordform, OccurrencesFlid(cache), true).Length != 0) return; if (cache.IsValidObject(hvoWordform)) { // If it's real it might have analyses etc. WfiWordform wf = (WfiWordform) CmObject.CreateFromDBObject(cache, hvoWordform); if (wf.AnalysesOC.Count > 0) return; // Arguably we should keep it for known correct spelling status. However, if it's ever been // confirmed as an analysis, even temporarily, it will have that. if (wf.SpellingStatus == (int)SpellingStatusStates.incorrect) return; } foreach (int ws in cache.LangProject.CurVernWssRS.HvoArray) { CaseFunctions cf = new CaseFunctions(cache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(ws).IcuLocale); string text = cache.GetMultiStringAlt(hvoWordform, (int) WfiWordformTags.kflidForm, ws).Text; if (!String.IsNullOrEmpty(text) && cf.StringCase(text) == StringCaseStatus.allLower) return; } cache.DeleteObject(hvoWordform); }
/// <summary> /// Delete the objects which are the ids in the Set. /// </summary> public static void DeleteObjects(Set<int> idsToDel, FdoCache cache, bool fRequiresFullRefreshOfViewInUndoRedo, VwClearInfoAction vwClearInfoAction, bool fUndo, ProgressState state) { Set<int> realIdsToDel = new Set<int>(); foreach (int hvo in idsToDel) { if (cache.IsDummyObject(hvo)) continue; // don't try removing dummy object from cache. otherwise, you can't undo it. realIdsToDel.Add(hvo); } if (realIdsToDel.Count == 0) return; if (fUndo && realIdsToDel.Count == 1 && fRequiresFullRefreshOfViewInUndoRedo || cache.DatabaseAccessor == null) { // Just one object...more efficient to to it directly, also, it lets many // tests pass that would otherwise need a real database. foreach (int hvo in realIdsToDel) { cache.DeleteObject(hvo); } } else { IActionHandler acth = cache.ActionHandlerAccessor; if (acth == null) fUndo = false; // May be null if we are currently suppressing Subtasks int iMin = 0; int[] ids = realIdsToDel.ToArray(); int step = 50; if (state != null) { // 600 4-digit ids, 500 5-digit ids, 428 6-digit ids, 375 7-digit ids int cChunks = (ids.Length / 450) + 1; step = 60 / cChunks; if (step == 0) step = 1; } while (iMin < ids.Length) { int iLim = iMin; string hvoList = CmObject.MakePartialIdList(ref iLim, ids); ObjectGroupUndoItem item; if (iMin > 0 || iLim < ids.Length) { Set<int> idsDel = new Set<int>(iLim - iMin); for (int i = iMin; i < iLim; ++i) idsDel.Add(ids[i]); item = new ObjectGroupUndoItem(idsDel, hvoList, cache, fRequiresFullRefreshOfViewInUndoRedo, fUndo); } else { item = new ObjectGroupUndoItem(realIdsToDel, hvoList, cache, fRequiresFullRefreshOfViewInUndoRedo, fUndo); } item.DoIt(vwClearInfoAction); if (fUndo) acth.AddAction(item); if (state != null) { int percent = state.PercentDone + step; state.PercentDone = percent; state.Breath(); } iMin = iLim; } } }