/// <summary> /// Despite being public where the other SetDlgInfo is internal, this is a "special-case" /// initialization method not used in Flex, but in TE, where there is not a pre-existing mediator /// for each main window. This initializer obtains the configuration parameters and sets up a /// suitable mediator. In doing so it duplicates knowledge from various places: /// 1. Along with the code that initializes xWindow and various other places, it 'knows' where /// to find the configuration node for the respeller dialog. /// 2. It duplicates some of the logic in FwXWindow.InitMediatorValues and RestoreProperties, /// knowing the LocalSettingsId and how to use it to restore mediator properties, and what items /// must be in the mediator. Also logic in xWindow for restoring global settings. /// 3. It knows how to initialize a number of virtual properties normally created as part of /// FLEx's startup code. /// 4. It knows how to set up the string table that Flex uses. /// 5. It knows how to initialize the Flex part inventories. /// </summary> public bool SetDlgInfo(IWfiWordform wf, Form parent, IApp app) { if (wf == null) throw new ArgumentNullException("wf"); if (parent == null) throw new ArgumentNullException("parent"); if (app == null) throw new ArgumentNullException("app"); using (var dlg = new ProgressDialogWorkingOn()) { dlg.Owner = parent; dlg.Text = MEStrings.ksFindingOccurrences; dlg.WorkingOnText = MEStrings.ksSearchingOccurrences; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(ActiveForm); dlg.Update(); dlg.BringToFront(); //var progressState = new MilestoneProgressState(dlg.ProgressDisplayer); try { m_cache = wf.Cache; m_srcwfiWordform = wf; // Get the parameter node. var path = Path.Combine(FwDirectoryFinder.GetCodeSubDirectory( Path.Combine(FwUtils.ksFlexAppName, Path.Combine("Configuration", "Words"))), "areaConfiguration.xml"); var doc = XWindow.LoadConfigurationWithIncludes(path, true); var paramNode = doc.DocumentElement.SelectSingleNode("listeners/listener[@class=\"SIL.FieldWorks.XWorks.MorphologyEditor.RespellerDlgListener\"]/parameters"); Debug.Assert(paramNode != null); // Initialize a mediator. var mediator = new Mediator(); m_fDisposeMediator = true; // Copied from FwXWindow.InitMediatorValues mediator.PropertyTable.LocalSettingsId = "local"; mediator.PropertyTable.SetProperty("cache", m_cache); mediator.PropertyTable.SetPropertyPersistence("cache", false); string userPath = DirectoryFinder.UserAppDataFolder(app.ApplicationName); Directory.CreateDirectory(userPath); mediator.PropertyTable.UserSettingDirectory = userPath; //// Enhance JohnT: possibly these three lines (also copied) are not needed. //mediator.PropertyTable.SetProperty("DocumentName", GetMainWindowCaption(cache)); //mediator.PropertyTable.SetPropertyPersistence("DocumentName", false); mediator.PathVariables["{DISTFILES}"] = FwDirectoryFinder.CodeDirectory; mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.GlobalSettingsId); mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.LocalSettingsId); //progressState.SetMilestone(); // Set this AFTER the restore! Otherwise it goes away! mediator.PropertyTable.SetProperty("window", dlg.Owner); mediator.PropertyTable.SetPropertyPersistence("window", false); string directoryContainingConfiguration = Path.Combine(FwDirectoryFinder.FlexFolder, "Configuration"); StringTable table = new StringTable(directoryContainingConfiguration); mediator.StringTbl = table; mediator.FeedbackInfoProvider = (IFeedbackInfoProvider)app; //progressState.SetMilestone(); //progressState.SetMilestone(); LayoutCache.InitializePartInventories(m_cache.ProjectId.Name, app, m_cache.ProjectId.ProjectFolder); //progressState.SetMilestone(); // Get all the scripture texts. // Review: should we include IText ones too? // NB: The ownership check is designed to exclude archived drafts. // The second half collects footnotes and the title of the book. var stTextRepos = m_cache.ServiceLocator.GetInstance<IStTextRepository>(); var unarchivedScriptureTexts = m_cache.LangProject.TranslatedScriptureOA.StTexts.ToList(); //progressState.SetMilestone(); // Build concordance info, including the occurrence list for our wordform. ProgressState state = new ProgressState(dlg.ProgressDisplayer); // This is an ugly way of getting the state to the RespellingSda method mediator.PropertyTable.SetProperty("SpellingPrepState", state); mediator.PropertyTable.SetPropertyPersistence("SpellingPrepState", false); NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => { int done = 0; int total = unarchivedScriptureTexts.Count; foreach (var txt in unarchivedScriptureTexts) { done++; foreach (IStTxtPara para in txt.ParagraphsOS) { if (para.ParseIsCurrent) continue; ParagraphParser.ParseParagraph(para, true); } state.PercentDone = 50*done/total; state.Breath(); } }); // Make sure we will include all of Scripture in the occurrences list. InterestingTextList.SetScriptureTextsInPropertyTable(mediator.PropertyTable, unarchivedScriptureTexts); return SetDlgInfoPrivate(mediator, paramNode); } finally { dlg.Close(); } } }
/// <summary> /// Determine the contents for each of the paragraphs to be changed, applying the /// changes immediately if so requested. /// </summary> private void ComputeParaChanges(bool fMakeChangeNow, ProgressDialogWorkingOn progress) { // Build the new strings for each foreach (var info1 in m_changedParas.Values) info1.MakeNewContents(fMakeChangeNow, progress); }
/// <summary> /// Parse the given lists of files and create a wordset from them. /// </summary> /// <param name="paths"></param> /// <remarks>This is marked internal so that unit tests can call it</remarks> internal void CreateWordsetFromFiles(string[] paths) { CheckDisposed(); using (ProgressDialogWorkingOn dlg = new ProgressDialogWorkingOn()) { string sWordSetName = GetWordSetName(paths); IWfiWordSet wordSet = WfiWordSet.Create(m_cache, sWordSetName, GetWordSetDescription(paths)); dlg.Owner = FindForm(); dlg.Icon = dlg.Owner.Icon; dlg.Minimum = 0; dlg.Maximum = paths.Length; dlg.Text = String.Format(ParserUIStrings.ksLoadingFilesForWordSetX, sWordSetName); dlg.Show(); dlg.BringToFront(); using (WordImporter importer = new WordImporter(m_cache)) { foreach (string path in paths) { UpdateProgress(path, dlg); importer.PopulateWordset(path, wordSet); } } dlg.Close(); } }
/// <summary> /// Core of the DoIt method, may be called with or without progress dialog. /// </summary> /// <param name="dlg"></param> private void CoreDoIt(ProgressDialogWorkingOn dlg) { // While we do the changes which we can much more efficiently Undo/Redo in this action, // we don't want the various changes we make generating masses of SqlUndoActions. IActionHandler handler = m_cache.ActionHandlerAccessor; m_cache.MainCacheAccessor.SetActionHandler(null); m_hvoNewWf = WfiWordform.FindOrCreateWordform(m_cache, m_newSpelling, m_vernWs, true); try { foreach (KeyValuePair<int, ParaChangeInfo> pair in m_changedParas) { UpdateOffsets(pair.Key, pair.Value); // Review JohnT: should we do the PropChanged, or not?? If not, we should force // a Refresh when the dialog closes. if (!pair.Value.OldContents.Equals(pair.Value.NewContents)) pair.Value.SetString(m_cache, pair.Value.NewContents, true); UpdateProgress(dlg); } UpdateInstanceOf(m_hvoNewWf, dlg); } finally { m_cache.MainCacheAccessor.SetActionHandler(handler); } if (dlg != null) dlg.WorkingOnText = MEStrings.ksDealingAnalyses; m_cache.BeginUndoTask(string.Format(MEStrings.ksUndoChangeSpelling, m_oldSpelling, m_newSpelling), string.Format(MEStrings.ksRedoChangeSpelling, m_oldSpelling, m_newSpelling)); m_cache.ActionHandlerAccessor.AddAction(this); UpdateProgress(dlg); // The destination wordform really exists and should be marked correct. IWfiWordform wf = WfiWordform.CreateFromDBObject(m_cache, m_hvoNewWf); m_oldOccurrencesNewWf = wf.OccurrencesInTexts.ToArray(); m_fWasNewSpellingCorrect = wf.SpellingStatus == (int)SpellingStatusStates.correct; wf.SpellingStatus = (int)SpellingStatusStates.correct; EnchantHelper.SetSpellingStatus(m_newSpelling, m_vernWs, m_cache.LanguageWritingSystemFactoryAccessor, true); UpdateProgress(dlg); m_hvoOldWf = WfiWordform.FindOrCreateWordform(m_cache, m_oldSpelling, m_vernWs, true); IWfiWordform wfOld = WfiWordform.CreateFromDBObject(m_cache, m_hvoOldWf); m_oldOccurrencesOldWf = wfOld.OccurrencesInTexts.ToArray(); m_fWasOldSpellingCorrect = wfOld.SpellingStatus == (int)SpellingStatusStates.correct; UpdateProgress(dlg); // Compute new occurrence lists, save and cache Set<int> changes = new Set<int>(); foreach (ParaChangeInfo info in m_changedParas.Values) changes.AddRange(info.Changes); if (AllChanged) { m_newOccurrencesOldWf = new int[0]; // no remaining occurrences } else { // Only some changed, need to figure m_newOccurrences List<int> newOccurrencesOldWf = new List<int>(); foreach (int hvo in m_oldOccurrencesOldWf) if (!changes.Contains(hvo)) newOccurrencesOldWf.Add(hvo); m_newOccurrencesOldWf = newOccurrencesOldWf.ToArray(); } UpdateProgress(dlg); List<int> newOccurrences = new List<int>(m_oldOccurrencesNewWf.Length + changes.Count); newOccurrences.AddRange(m_oldOccurrencesNewWf); foreach (int hvo in changes) { if (m_cache.IsDummyObject(hvo)) // if this is a dummy annotation, make sure we update the owner m_cache.VwCacheDaAccessor.CacheObjProp(hvo, (int)CmObjectFields.kflidCmObject_Owner, m_hvoNewWf); newOccurrences.Add(hvo); } m_newOccurrencesNewWf = newOccurrences.ToArray(); int vhId = BaseVirtualHandler.GetInstalledHandlerTag(m_cache, "WfiWordform", "OccurrencesInTexts"); m_cache.VwCacheDaAccessor.CacheVecProp(m_hvoOldWf, vhId, m_newOccurrencesOldWf, m_newOccurrencesOldWf.Length); m_cache.VwCacheDaAccessor.CacheVecProp(m_hvoNewWf, vhId, m_newOccurrencesNewWf, m_newOccurrencesNewWf.Length); SendCountVirtualPropChanged(m_hvoNewWf); SendCountVirtualPropChanged(m_hvoOldWf); UpdateProgress(dlg); // Deal with analyses. if (CopyAnalyses) { foreach (WfiAnalysis analysis in wfOld.AnalysesOC) { // Only copy approved analyses. if (analysis.GetAgentOpinion(m_cache.LangProject.DefaultUserAgent) != Opinions.approves) continue; IWfiAnalysis newAnalysis = wf.AnalysesOC.Add(new WfiAnalysis()); foreach (WfiGloss gloss in analysis.MeaningsOC) { IWfiGloss newGloss = newAnalysis.MeaningsOC.Add(new WfiGloss()); newGloss.Form.CopyAlternatives(gloss.Form); } foreach (WfiMorphBundle bundle in analysis.MorphBundlesOS) { IWfiMorphBundle newBundle = newAnalysis.MorphBundlesOS.Append(new WfiMorphBundle()); newBundle.Form.CopyAlternatives(bundle.Form); newBundle.SenseRA = bundle.SenseRA; newBundle.MorphRA = bundle.MorphRA; newBundle.MsaRA = bundle.MsaRA; } } } UpdateProgress(dlg); if (AllChanged) { wfOld.SpellingStatus = (int)SpellingStatusStates.incorrect; EnchantHelper.SetSpellingStatus(m_oldSpelling, m_vernWs, m_cache.LanguageWritingSystemFactoryAccessor, false); if (UpdateLexicalEntries) { foreach (WfiAnalysis wa in wfOld.AnalysesOC) { if (wa.MorphBundlesOS.Count == 1) { } } } if (!KeepAnalyses) { // Remove multi-morpheme anals in src wf. List<IWfiAnalysis> goners = new List<IWfiAnalysis>(); foreach (IWfiAnalysis goner in wfOld.AnalysesOC) { if (goner.MorphBundlesOS.Count > 1) goners.Add(goner); } foreach (IWfiAnalysis goner in goners) { goner.DeleteUnderlyingObject(); // This will shift twfic pointers up to wordform, if needed. } goners.Clear(); } if (UpdateLexicalEntries) { // Change LE allo on single morpheme anals. foreach (IWfiAnalysis update in wfOld.AnalysesOC) { if (update.MorphBundlesOS.Count == 1) { IWfiMorphBundle mb = update.MorphBundlesOS[0]; TsStringAccessor tsa = mb.Form.GetAlternative(m_vernWs); string srcForm = tsa.Text; if (srcForm != null) { // Change morph bundle form. mb.Form.SetAlternative(m_newSpelling, m_vernWs); } IMoForm mf = mb.MorphRA; if (mf != null) { mf.Form.SetAlternative(m_newSpelling, m_vernWs); } } } } // Move remaining anals from src wf to new wf. // This changes the owners of the remaining ones, // since it is an owning property. wf.AnalysesOC.Add(wfOld.AnalysesOC.HvoArray); SendAnalysisVirtualPropChanged(m_hvoNewWf); SendAnalysisVirtualPropChanged(m_hvoOldWf); UpdateProgress(dlg); } m_cache.EndUndoTask(); }
internal static void UpdateProgress(ProgressDialogWorkingOn dlg) { if (dlg == null) return; dlg.PerformStep(); dlg.Update(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Figure what the new contents needs to be. (Also sets OldContents.) Maybe even set /// the contents. /// </summary> /// <param name="fMakeChangeNow">if set to <c>true</c> make the actual change now; /// otherwise, just figure out what the new contents will be.</param> /// ------------------------------------------------------------------------------------ public void MakeNewContents(bool fMakeChangeNow, ProgressDialogWorkingOn progress) { RespellingSda sda = m_action.RespellSda; m_oldContents = RespellUndoAction.AnnotationTargetString(m_hvoTarget, m_flid, m_ws, sda); ITsStrBldr bldr = m_oldContents.GetBldr(); m_changes.Sort((left, right) => sda.get_IntProp(left, ConcDecorator.kflidBeginOffset).CompareTo( sda.get_IntProp(right, ConcDecorator.kflidBeginOffset))); for (int i = m_changes.Count - 1; i >= 0; i--) { int ichMin = sda.get_IntProp(m_changes[i], ConcDecorator.kflidBeginOffset); int ichLim = sda.get_IntProp(m_changes[i], ConcDecorator.kflidEndOffset); string replacement = Replacement(m_action.OldOccurrence(m_changes[i])); bldr.Replace(ichMin, ichLim, replacement, null); if (fMakeChangeNow) { ITsString tssNew = bldr.GetString(); if (!m_oldContents.Equals(tssNew)) { if (m_ws == 0) sda.SetString(m_hvoTarget, m_flid, tssNew); else sda.SetMultiStringAlt(m_hvoTarget, m_flid, m_ws, tssNew); } } } RespellUndoAction.UpdateProgress(progress); m_newContents = bldr.GetString(); }
private string ApplyTransform(string sInputFile, XmlNode node, ProgressDialogWorkingOn dlg) { string sProgressPrompt = XmlUtils.GetManditoryAttributeValue(node, "progressPrompt"); UpdateProgress(sProgressPrompt, dlg); string sXslt = XmlUtils.GetManditoryAttributeValue(node, "file"); string sOutputFile = Path.Combine(m_outputDirectory, Cache.DatabaseName + sXslt + "Result." + GetExtensionFromNode(node)); XmlUtils.XSLParameter[] parameterList = CreateParameterList(node); if (parameterList != null) { foreach (XmlUtils.XSLParameter param in parameterList) { if (param.Name == "prmVernacularFontSize") { param.Value = GetNormalStyleFontSize(Cache.LangProject.DefaultVernacularWritingSystem); } if (param.Name == "prmGlossFontSize") { param.Value = GetNormalStyleFontSize(Cache.LangProject.DefaultAnalysisWritingSystem); } } } SIL.Utils.XmlUtils.TransformFileToFile(Path.Combine(TransformPath, sXslt), parameterList, sInputFile, sOutputFile); return sOutputFile; }
private void SetNewOccurrencesOfWordforms(ProgressDialogWorkingOn progress) { Set<int> changes = new Set<int>(); foreach (ParaChangeInfo info in m_changedParas.Values) { changes.AddRange(info.Changes); } if (AllChanged) { m_newOccurrencesOldWf = new int[0]; // no remaining occurrences } else { // Only some changed, need to figure m_newOccurrences List<int> newOccurrencesOldWf = new List<int>(); foreach (int hvo in OldOccurrencesOfOldWordform) { //The offsets of our occurrences have almost certainly changed. //Update them so that the respelling dialog view will appear correct. var occur = RespellSda.OccurrenceFromHvo(hvo) as LocatedAnalysisOccurrence; if (occur != null) { occur.ResetSegmentOffsets(); } if (!changes.Contains(hvo)) { newOccurrencesOldWf.Add(hvo); } } m_newOccurrencesOldWf = newOccurrencesOldWf.ToArray(); } UpdateProgress(progress); List<int> newOccurrences = new List<int>(m_oldOccurrencesNewWf.Length + changes.Count); newOccurrences.AddRange(m_oldOccurrencesNewWf); newOccurrences.AddRange(changes); m_newOccurrencesNewWf = newOccurrences.ToArray(); RespellSda.ReplaceOccurrences(OldWordform, m_newOccurrencesOldWf); RespellSda.ReplaceOccurrences(NewWordform, m_newOccurrencesNewWf); SendCountVirtualPropChanged(NewWordform); SendCountVirtualPropChanged(OldWordform); }
private ProgressDialogWorkingOn InitProgressDialog() { ProgressDialogWorkingOn dlg = new ProgressDialogWorkingOn(); dlg.Owner = this.FindForm(); dlg.Icon = dlg.Owner.Icon; dlg.Minimum = 0; dlg.Maximum = m_cPrompts + m_cTransforms; dlg.Text = m_sProgressDialogTitle; dlg.Show(); return dlg; }
public void PerformRetrieval(out string sFxtOutputPath, ProgressDialogWorkingOn dlg) { CheckDisposed(); string sPrompt = XmlUtils.GetOptionalAttributeValue(m_fxtNode, "progressPrompt"); if (sPrompt != null) UpdateProgress(sPrompt, dlg); string sFxt = XmlUtils.GetManditoryAttributeValue(m_fxtNode, "file"); string sFxtPath = Path.Combine(DirectoryFinder.FWCodeDirectory, Path.Combine(@"Language Explorer\Configuration\Grammar\FXTs", sFxt)); m_fxtDumper = new XDumper(Cache); sFxtOutputPath = Path.Combine(m_outputDirectory, Cache.DatabaseName + sFxt + "Result.xml"); m_fxtDumper.Go(Cache.LangProject as CmObject, sFxtPath, File.CreateText(sFxtOutputPath)); }
/// <summary> /// Despite being public where the other SetDlgInfo is internal, this is a "special-case" /// initialization method not used in Flex, but in TE, where there is not a pre-existing mediator /// for each main window. This initializer obtains the configuration parameters and sets up a /// suitable mediator. In doing so it duplicates knowledge from various places: /// 1. Along with the code that initializes xWindow and various other places, it 'knows' where /// to find the configuration node for the respeller dialog. /// 2. It duplicates some of the logic in FwXWindow.InitMediatorValues and RestoreProperties, /// knowing the LocalSettingsId and how to use it to restore mediator properties, and what items /// must be in the mediator. Also logic in xWindow for restoring global settings. /// 3. It knows how to initialize a number of virtual properties normally created as part of /// FLEx's startup code. /// 4. It knows how to set up the string table that Flex uses. /// 5. It knows how to initialize the Flex part inventories. /// </summary> /// <returns></returns> public bool SetDlgInfo(IWfiWordform wf) { using (ProgressDialogWorkingOn dlg = new ProgressDialogWorkingOn()) { if (FwApp.App != null) dlg.Owner = FwApp.App.ActiveMainWindow; else dlg.Owner = Form.ActiveForm; if (dlg.Owner != null) // I think it's only null when debugging? But play safe. dlg.Icon = dlg.Owner.Icon; dlg.Text = MEStrings.ksFindingOccurrences; dlg.WorkingOnText = MEStrings.ksSearchingOccurrences; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(Form.ActiveForm); dlg.Update(); dlg.BringToFront(); MilestoneProgressState progressState = new MilestoneProgressState(dlg.ProgressDisplayer); try { //progressState.AddMilestone(1.0f); //progressState.AddMilestone(1.0f); //progressState.AddMilestone(1.0f); //progressState.AddMilestone(4.0f); //progressState.AddMilestone(2.0f); FdoCache cache = wf.Cache; m_srcwfiWordform = wf; // Get the parameter node. string path = Path.Combine(DirectoryFinder.GetFWCodeSubDirectory(@"Language Explorer\Configuration\Words"), "areaConfiguration.xml"); XmlDocument doc = XmlUtils.LoadConfigurationWithIncludes(path, true); XmlNode paramNode = doc.DocumentElement.SelectSingleNode("listeners/listener[@class=\"SIL.FieldWorks.XWorks.MorphologyEditor.RespellerDlgListener\"]/parameters"); Debug.Assert(paramNode != null); // Initialize a mediator. Mediator mediator = new Mediator(); // Copied from FwXWindow.InitMediatorValues mediator.PropertyTable.LocalSettingsId = cache.DatabaseName; mediator.PropertyTable.SetProperty("cache", cache); mediator.PropertyTable.SetPropertyPersistence("cache", false); //// Enhance JohnT: possibly these three lines (also copied) are not needed. //mediator.PropertyTable.SetProperty("DocumentName", GetMainWindowCaption(cache)); //mediator.PropertyTable.SetPropertyPersistence("DocumentName", false); mediator.PathVariables["{DISTFILES}"] = DirectoryFinder.FWCodeDirectory; mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.GlobalSettingsId); mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.LocalSettingsId); //progressState.SetMilestone(); // Set this AFTER the restore! Otherwise it goes away! mediator.PropertyTable.SetProperty("window", dlg.Owner); mediator.PropertyTable.SetPropertyPersistence("window", false); string directoryContainingConfiguration = DirectoryFinder.GetFWCodeSubDirectory(@"Language Explorer\Configuration"); StringTable table = new SIL.Utils.StringTable(directoryContainingConfiguration); mediator.StringTbl = table; //progressState.SetMilestone(); EnsureVirtuals(cache); //progressState.SetMilestone(); SIL.FieldWorks.Common.Controls.LayoutCache.InitializePartInventories(cache.DatabaseName); //progressState.SetMilestone(); // Get all the scripture texts. // Review: should we include IText ones too? // Note that the ownership check is designed to exclude archived drafts. // The second half collects footnotes and the title of the book. string sql = "select st.id from StText_ st " + "join ScrSection_ ss on st.Owner$ = ss.id " + "join ScrBook_ sb on ss.Owner$ = sb.id " + "join Scripture s on sb.Owner$ = s.id " + "union " + "select st.id from StText_ st " + "join ScrBook_ sb on st.Owner$ = sb.id " + "join Scripture s on sb.Owner$ = s.id"; int[] texts = DbOps.ReadIntArrayFromCommand(cache, sql, null); //progressState.SetMilestone(); // Build concordance info, including the occurrence list for our wordform. // Enhance: possibly we could create the Wfics only for this wordform? try { cache.EnableBulkLoadingIfPossible(true); ParagraphParser.ConcordTexts(cache, texts, progressState); } finally { cache.EnableBulkLoadingIfPossible(false); } m_cache = cache; GetCaptionWfics(texts, wf); return SetDlgInfo1(mediator, paramNode); } finally { dlg.Close(); } } }
/// <summary> /// This version is used inside FLEx when the friendly tool is not active. So, we need to /// build the concordance, but on FLEx's list, and we can assume all the parts and layouts /// are loaded. /// </summary> /// <param name="wf"></param> /// <returns></returns> public bool SetDlgInfo2(IWfiWordform wf, Mediator mediator, XmlNode configurationParams) { using (ProgressDialogWorkingOn dlg = new ProgressDialogWorkingOn()) { dlg.Owner = Form.ActiveForm; if (dlg.Owner != null) // I think it's only null when debugging? But play safe. dlg.Icon = dlg.Owner.Icon; dlg.Text = MEStrings.ksFindingOccurrences; dlg.WorkingOnText = MEStrings.ksSearchingOccurrences; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(Form.ActiveForm); dlg.Update(); dlg.BringToFront(); MilestoneProgressState progressState = new MilestoneProgressState(dlg.ProgressDisplayer); try { //progressState.AddMilestone(1.0f); //progressState.AddMilestone(1.0f); //progressState.AddMilestone(1.0f); //progressState.AddMilestone(4.0f); //progressState.AddMilestone(2.0f); FdoCache cache = wf.Cache; m_srcwfiWordform = wf; ConcordanceWordsVirtualHandler handler = cache.VwCacheDaAccessor.GetVirtualHandlerId( WordformInventory.ConcordanceWordformsFlid(cache)) as ConcordanceWordsVirtualHandler; handler.Progress = progressState; // We don't use this value here, we just want it to get computed with our progress // state active. cache.GetVectorSize(cache.LangProject.WordformInventoryOA.Hvo, handler.Tag); handler.Progress = null; m_cache = cache; return SetDlgInfo1(mediator, configurationParams); } finally { dlg.Close(); } } }
private static void UpdateProgress(ProgressDialogWorkingOn dlg) { if (dlg != null) { dlg.PerformStep(); dlg.Update(); } }
/// <summary> /// Actually make the change indicated in the action (execute the original command, /// from the Apply button in the dialog). /// </summary> public void DoIt(Mediator mediator) { if (m_changes.Count == 0) return; BuildChangedParasInfo(); if (m_changedParas.Count < 10) { CoreDoIt(null, mediator); } else { using (var dlg = new ProgressDialogWorkingOn()) { dlg.Owner = Form.ActiveForm; dlg.Icon = dlg.Owner.Icon; dlg.Minimum = 0; // 2x accounts for two main loops; extra 10 very roughly accounts for final cleanup. dlg.Maximum = m_changedParas.Count * 2 + 10; dlg.Text = MEStrings.ksChangingSpelling; dlg.WorkingOnText = MEStrings.ksChangingSpelling; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(); dlg.BringToFront(); CoreDoIt(dlg, mediator); dlg.Close(); } } }
/// <summary> /// Parse the given lists of files and create a wordset from them. /// </summary> /// <param name="paths"></param> /// <remarks>This is marked internal so that unit tests can call it</remarks> internal void CreateWordsetFromFiles(string[] paths) { CheckDisposed(); using (ProgressDialogWorkingOn dlg = new ProgressDialogWorkingOn()) { m_cache.DomainDataByFlid.BeginUndoTask("Import Word Set", "Import Word Set"); string sWordSetName = GetWordSetName(paths); var wordSet = m_cache.ServiceLocator.GetInstance<IWfiWordSetFactory>().Create(); m_cache.LangProject.MorphologicalDataOA.TestSetsOC.Add(wordSet); wordSet.Name.SetAnalysisDefaultWritingSystem(sWordSetName); wordSet.Description.SetAnalysisDefaultWritingSystem(GetWordSetDescription(paths)); dlg.Owner = FindForm(); dlg.Icon = dlg.Owner.Icon; dlg.Minimum = 0; dlg.Maximum = paths.Length; dlg.Text = String.Format(ParserUIStrings.ksLoadingFilesForWordSetX, sWordSetName); dlg.Show(); dlg.BringToFront(); WordImporter importer = new WordImporter(m_cache); foreach (string path in paths) { UpdateProgress(path, dlg); importer.PopulateWordset(path, wordSet); } m_cache.DomainDataByFlid.EndUndoTask(); dlg.Close(); } }
/// <summary> /// Core of the DoIt method, may be called with or without progress dialog. /// </summary> private void CoreDoIt(ProgressDialogWorkingOn progress, Mediator mediator) { var specialMdc = m_specialSda.MetaDataCache; int flidOccurrences = specialMdc.GetFieldId2(WfiWordformTags.kClassId, "Occurrences", false); using (UndoableUnitOfWorkHelper uuow = new UndoableUnitOfWorkHelper(m_cache.ActionHandlerAccessor, String.Format(MEStrings.ksUndoChangeSpelling, m_oldSpelling, NewSpelling), String.Format(MEStrings.ksRedoChangeSpelling, m_oldSpelling, NewSpelling))) { IWfiWordform wfOld = FindOrCreateWordform(m_oldSpelling, m_vernWs); var originalOccurencesInTexts = wfOld.OccurrencesInTexts.ToList(); // At all levels. IWfiWordform wfNew = FindOrCreateWordform(NewSpelling, m_vernWs); SetOldOccurrencesOfWordforms(flidOccurrences, wfOld, wfNew); UpdateProgress(progress); // It's important to do this BEFORE we update the changed paragraphs. As we update the analysis to point // at the new wordform and update the text, it may happen that AnalysisAdjuster sees the only occurrence // of the (new) wordform go away, if the text is being changed to an other-case form. If we haven't set // the spelling status first, the wordform may get deleted before we ever record its spelling status. // This way, having a known spelling status will prevent the deletion. SetSpellingStatus(wfNew); ComputeParaChanges(true, progress); if (progress != null) progress.WorkingOnText = MEStrings.ksDealingAnalyses; UpdateProgress(progress); // Compute new occurrence lists, save and cache SetNewOccurrencesOfWordforms(progress); UpdateProgress(progress); // Deal with analyses. if (wfOld.IsValidObject && CopyAnalyses) { // Note: "originalOccurencesInTexts" may have fewer segments, after the call, as they can be removed. CopyAnalysesToNewWordform(originalOccurencesInTexts, wfOld, wfNew); } UpdateProgress(progress); if (AllChanged) { SpellingHelper.SetSpellingStatus(m_oldSpelling, m_vernWs, m_cache.LanguageWritingSystemFactoryAccessor, false); if (wfOld.IsValidObject) { ProcessAnalysesAndLexEntries(progress, wfOld, wfNew); } UpdateProgress(progress); } // Only mess with shifting if it was only a case diff in wf, but no changes were made in paragraphs. // Regular spelling changes will trigger re-tokenization of para, otherwise if (PreserveCase) { // Move pointers in segments to new WF, if the segment references the original WF. foreach (var segment in originalOccurencesInTexts) { if (!m_changedParas.ContainsKey(segment.Owner.Hvo)) continue; // Skip shifting it for items that were not checked var wfIdx = segment.AnalysesRS.IndexOf(wfOld); while (wfIdx > -1) { segment.AnalysesRS.RemoveAt(wfIdx); segment.AnalysesRS.Insert(wfIdx, wfNew); wfIdx = segment.AnalysesRS.IndexOf(wfOld); } } } // The timing of this is rather crucial. During the work above, we may (if this is invoked from a // wordform concordance) detect that the current occurrence is no longer valid (since we change the spelling // and that wordform no longer occurs in that position). This leads to reloading the list and broadcasting // a RecordNavigation message, as we switch the selection to the first item. However, before we reload the // list, we need to process ItemDataModified, because that figures out what the new list items are. If // it doesn't happen before we reload the list, we will put a bunch of invalid occurrences back into it. // Things to downhill from there as we try to select an invalid one. // OTOH, we can't figure out the new item data for the wordforms until the work above updates the occurrences! // The right solution is to wait until we have updated the instances, then send ItemDataModified // to update the ConcDecorator state, then close the UOW which triggers other PropChanged effects. // We have to use SendMessage so the ConcDecorator gets that updated before the Clerk using it // tries to re-read the list. if (wfOld.CanDelete) { wfOld.Delete(); } else { mediator.SendMessage("ItemDataModified", wfOld); } mediator.SendMessage("ItemDataModified", wfNew); uuow.RollBack = false; } }
public void PerformRetrieval(out string outputPath, ProgressDialogWorkingOn dlg) { CheckDisposed(); string sPrompt = XmlUtils.GetOptionalAttributeValue(m_retrieverNode, "progressPrompt"); if (sPrompt != null) UpdateProgress(sPrompt, dlg); outputPath = Path.Combine(m_outputDirectory, Cache.ProjectId.Name + "RetrieverResult.xml"); m_retriever.Retrieve(outputPath, Cache.LanguageProject); }
private void ProcessAnalysesAndLexEntries(ProgressDialogWorkingOn progress, IWfiWordform wfOld, IWfiWordform wfNew) { wfOld.SpellingStatus = (int)SpellingStatusStates.incorrect; //if (UpdateLexicalEntries) //{ // foreach (IWfiAnalysis wa in wfOld.AnalysesOC) // { // if (wa.MorphBundlesOS.Count == 1) // { // } // } //} if (!KeepAnalyses) { // Remove multi-morpheme anals in src wf. List<IWfiAnalysis> goners = new List<IWfiAnalysis>(); foreach (IWfiAnalysis goner in wfOld.AnalysesOC) { if (goner.MorphBundlesOS.Count > 1) { goners.Add(goner); } } foreach (IWfiAnalysis goner in goners) { IWfiWordform wf = goner.OwnerOfClass<IWfiWordform>(); wf.AnalysesOC.Remove(goner); } goners.Clear(); } if (UpdateLexicalEntries) { // Change LE allo on single morpheme anals. foreach (IWfiAnalysis update in wfOld.AnalysesOC) { if (update.MorphBundlesOS.Count != 1) continue; // Skip any with zero or more than one. IWfiMorphBundle mb = update.MorphBundlesOS[0]; ITsString tss = mb.Form.get_String(m_vernWs); string srcForm = tss.Text; if (srcForm != null) { // Change morph bundle form. mb.Form.set_String(m_vernWs, NewSpelling); } IMoForm mf = mb.MorphRA; if (mf != null) { mf.Form.set_String(m_vernWs, NewSpelling); } } } // Move remaining anals from src wf to new wf. // This changes the owners of the remaining ones, // since it is an owning property. var analyses = new List<IWfiAnalysis>(); analyses.AddRange(wfOld.AnalysesOC); foreach (var anal in analyses) wfNew.AnalysesOC.Add(anal); }
private string ApplyTransform(string inputFile, XmlNode node, ProgressDialogWorkingOn dlg) { string progressPrompt = XmlUtils.GetManditoryAttributeValue(node, "progressPrompt"); UpdateProgress(progressPrompt, dlg); string stylesheetName = XmlUtils.GetManditoryAttributeValue(node, "stylesheetName"); string stylesheetAssembly = XmlUtils.GetManditoryAttributeValue(node, "stylesheetAssembly"); string outputFile = Path.Combine(m_outputDirectory, Cache.ProjectId.Name + stylesheetName + "Result." + GetExtensionFromNode(node)); XsltArgumentList argumentList = CreateParameterList(node); IWritingSystemContainer wsContainer = Cache.ServiceLocator.WritingSystems; if (argumentList.GetParam("prmVernacularFontSize", "") != null) { argumentList.RemoveParam("prmVernacularFontSize", ""); argumentList.AddParam("prmVernacularFontSize", "", GetNormalStyleFontSize(wsContainer.DefaultVernacularWritingSystem.Handle)); } if (argumentList.GetParam("prmGlossFontSize", "") != null) { argumentList.RemoveParam("prmGlossFontSize", ""); argumentList.AddParam("prmGlossFontSize", "", GetNormalStyleFontSize(wsContainer.DefaultAnalysisWritingSystem.Handle)); } #if !__MonoCS__ var xmlReaderSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse }; #else var xmlReaderSettings = new XmlReaderSettings { ProhibitDtd = false }; #endif using (var writer = new StreamWriter(outputFile)) using (var reader = XmlReader.Create(inputFile, xmlReaderSettings)) GetTransform(stylesheetName, stylesheetAssembly).Transform(reader, argumentList, writer); return outputFile; }
/// <summary> /// This version is used inside FLEx when the friendly tool is not active. So, we need to /// build the concordance, but on FLEx's list, and we can assume all the parts and layouts /// are loaded. /// </summary> public bool SetDlgInfo(IWfiWordform wf, Mediator mediator, XmlNode configurationParams) { using (var dlg = new ProgressDialogWorkingOn()) { dlg.Owner = ActiveForm; if (dlg.Owner != null) // I think it's only null when debugging? But play safe. dlg.Icon = dlg.Owner.Icon; dlg.Text = MEStrings.ksFindingOccurrences; dlg.WorkingOnText = MEStrings.ksSearchingOccurrences; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(ActiveForm); dlg.Update(); dlg.BringToFront(); try { var cache = wf.Cache; m_srcwfiWordform = wf; m_cache = cache; if (m_fDisposeMediator && m_mediator != null) m_mediator.Dispose(); m_fDisposeMediator = false; return SetDlgInfoPrivate(mediator, configurationParams); } finally { dlg.Close(); } } }
private ProgressDialogWorkingOn InitProgressDialog() { Form owner = FindForm(); Icon icon = null; if (owner != null) icon = owner.Icon; var dlg = new ProgressDialogWorkingOn { Owner = owner, Icon = icon, Minimum = 0, Maximum = m_cPrompts + m_cTransforms, Text = m_sProgressDialogTitle }; dlg.Show(); return dlg; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Update all the changed wordforms to point at the new Wf. /// Must be called before we change the text of the paragraph, as it /// depends on offsets into the old string. /// This is usually redundant, since updating the text of the paragraph automatically updates the /// segment analysis. However, this can be used to force an upper case occurrence to be analyzed /// as the lower-case wordform (FWR-3134). The paragraph adjustment does not force this back /// (at least not immediately). /// </summary> /// ------------------------------------------------------------------------------------ private void UpdateInstanceOf(ProgressDialogWorkingOn progress) { Debug.Fail( @"use of this method was causing very unpleasant data corruption in texts, the bug it fixed needs addressing though."); var analysesToChange = new List<Tuple<ISegment, int>>(); RespellingSda sda = m_action.RespellSda; foreach (var hvoFake in m_changes) { int hvoSeg = sda.get_ObjectProp(hvoFake, ConcDecorator.kflidSegment); int beginOffset = sda.get_IntProp(hvoFake, ConcDecorator.kflidBeginOffset); if (hvoSeg > 0) { ISegment seg = m_action.RepoSeg.GetObject(hvoSeg); int canal = seg.AnalysesRS.Count; for (int i = 0; i < canal; ++i) { IAnalysis anal = seg.AnalysesRS[i]; if (anal.HasWordform && anal.Wordform.Hvo == m_action.OldWordform) { if (seg.GetAnalysisBeginOffset(i) == beginOffset) { // Remember that we want to change it, but don't do it yet, // because there may be other occurrences in this paragraph, // and changing the analysis to something which may have a different // length could mess things up. analysesToChange.Add(new Tuple<ISegment, int>(seg, i)); } } } } } if (analysesToChange.Count > 0) { var newVal = new[] { m_action.RepoWf.GetObject(m_action.NewWordform) }; foreach (var change in analysesToChange) change.Item1.AnalysesRS.Replace(change.Item2, 1, newVal); } RespellUndoAction.UpdateProgress(progress); }
private void PerformTransformations(string sLastFile, ProgressDialogWorkingOn dlg) { foreach (XmlNode rNode in m_transformsNode.ChildNodes) { sLastFile = ApplyTransform(sLastFile, rNode, dlg); if (m_AlsoSaveTransformNode == rNode) m_sAlsoSaveFileName = sLastFile; } m_sHtmlFileName = sLastFile; }
private void UpdateProgress(string sMessage, ProgressDialogWorkingOn dlg) { dlg.WorkingOnText = sMessage; dlg.PerformStep(); dlg.Refresh(); }
/// <summary> /// Update all the changed wordforms to point at the specified Wf. /// </summary> /// <param name="hvoWf"></param> private void UpdateInstanceOf(int hvoWf, ProgressDialogWorkingOn dlg) { foreach (ParaChangeInfo info in m_changedParas.Values) { foreach (int hvoChange in info.Changes) { if (m_cache.IsDummyObject(hvoChange)) m_cache.VwCacheDaAccessor.CacheObjProp(hvoChange, kflidInstanceOf, hvoWf); else m_cache.MainCacheAccessor.SetObjProp(hvoChange, kflidInstanceOf, hvoWf); } UpdateProgress(dlg); } }