private FwLinkArgs Pop(LinkedList <FwLinkArgs> stack) { FwLinkArgs lnk = stack.Last.Value; stack.RemoveLast(); return(lnk); }
private void Push(LinkedList <FwLinkArgs> stack, FwLinkArgs context) { stack.AddLast(context); while (stack.Count > kmaxDepth) { stack.RemoveFirst(); } }
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { Guid guid = m_cache.LangProject.PhFeatureSystemOA.Guid; m_link = new FwLinkArgs("phonologicalFeaturesAdvancedEdit", guid); m_btnCancel.PerformClick(); DialogResult = DialogResult.Ignore; }
/// <summary> /// NOTE: This will not handle link requests for other databases/applications. To handle other /// databases or applications, pass a FwAppArgs to the IFieldWorksManager.HandleLinkRequest method. /// </summary> /// <returns></returns> public bool OnFollowLink(object lnk) { CheckDisposed(); m_fFollowingLink = true; m_cBackStackOrig = m_backStack.Count; m_lnkActive = lnk as FwLinkArgs; return(FollowActiveLink()); }
/// <summary> /// /// </summary> /// <returns></returns> public bool OnAddContextToHistory(object _link) { CheckDisposed(); //Debug.WriteLineIf(RuntimeSwitches.linkListenerSwitch.TraceInfo, "OnAddContextToHistory(" + m_currentContext + ")", RuntimeSwitches.linkListenerSwitch.DisplayName); FwLinkArgs lnk = (FwLinkArgs)_link; if (lnk.EssentiallyEquals(m_currentContext)) { //Debug.WriteLineIf(RuntimeSwitches.linkListenerSwitch.TraceInfo, " Link equals current context.", RuntimeSwitches.linkListenerSwitch.DisplayName); return(true); } if (m_currentContext != null && //not where we just came from via a "Back" call ((m_forwardStack.Count == 0) || (m_currentContext != m_forwardStack.Last.Value))) { //Debug.WriteLineIf(RuntimeSwitches.linkListenerSwitch.TraceInfo, " Pushing current to back: " + m_currentContext, RuntimeSwitches.linkListenerSwitch.DisplayName); Push(m_backStack, m_currentContext); } // Try to omit intermediate targets which are added to the stack when switching // tools. This doesn't work in OnFollowLink() because the behavior of following // the link is not synchronous even when SendMessage is used at the first two // levels of handling. if (m_fFollowingLink && lnk.EssentiallyEquals(m_lnkActive)) { int howManyAdded = m_backStack.Count - m_cBackStackOrig; for ( ; howManyAdded > 1; --howManyAdded) { m_backStack.RemoveLast(); } m_fFollowingLink = false; m_cBackStackOrig = 0; m_lnkActive = null; } // The forward stack should be cleared by jump operations that are NOT spawned by // a Back or Forward (ie, history) operation. This is the standard behavior in // browsers, for example (as far as I know). if (m_fUsingHistory) { if (lnk.EssentiallyEquals(m_lnkActive)) { m_fUsingHistory = false; m_lnkActive = null; } } else { m_forwardStack.Clear(); } m_currentContext = lnk; return(true); }
/// <summary> /// /// </summary> /// <returns></returns> public bool OnHistoryForward(object unused) { CheckDisposed(); if (m_forwardStack.Count > 0) { m_fUsingHistory = true; m_lnkActive = Pop(m_forwardStack); FollowActiveLink(); } return(true); }
internal string LinkRef(int hvo) { ICmObjectRepository repo = m_cache.ServiceLocator.GetInstance <ICmObjectRepository>(); if (!repo.IsValidObjectId(hvo)) { return(null); } Guid guid = repo.GetObject(hvo).Guid; FwLinkArgs link = new FwLinkArgs("lexiconEdit", guid); return(link.ToString()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the incoming link, after the right window of the right application on the right /// project has been activated. /// See the class comment on FwLinkArgs for details on how all the parts of hyperlinking work. /// </summary> /// <param name="link">The link.</param> /// ------------------------------------------------------------------------------------ public override void HandleIncomingLink(FwLinkArgs link) { CheckDisposed(); // Get window that uses the given DB. FwXWindow fwxwnd = m_rgMainWindows.Count > 0 ? (FwXWindow)m_rgMainWindows[0] : null; if (fwxwnd != null) { fwxwnd.Mediator.SendMessage("FollowLink", link); bool topmost = fwxwnd.TopMost; fwxwnd.TopMost = true; fwxwnd.TopMost = topmost; fwxwnd.Activate(); } }
/// <summary> /// /// </summary> /// <returns></returns> public bool OnHistoryBack(object unused) { CheckDisposed(); if (m_backStack.Count > 0) { if (m_currentContext != null) { Push(m_forwardStack, m_currentContext); } m_fUsingHistory = true; m_lnkActive = Pop(m_backStack); FollowActiveLink(); } return(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Appends the given text as a hyperlink to the given URL. /// </summary> /// <param name="strBldr">The string builder.</param> /// <param name="ws">The HVO of the writing system to use for the added text.</param> /// <param name="sLinkText">The text which should appear as the hyperlink text</param> /// <param name="sUrl">The URL that is the target of the hyperlink.</param> /// <param name="stylesheet">The stylesheet.</param> /// <returns><c>true</c> if the hyperlink was successfully inserted; <c>false</c> /// otherwise (indicating that the hyperlink style could not be found in the given /// stylesheet). In either case, the link text will be appended to the string builder. /// </returns> /// ------------------------------------------------------------------------------------ public static bool AddHyperlink(ITsStrBldr strBldr, int ws, string sLinkText, string sUrl, LcmStyleSheet stylesheet) { var hyperlinkStyle = stylesheet.FindStyle(StyleServices.Hyperlink); if (hyperlinkStyle == null) { return(false); } if (stylesheet != null && stylesheet.Cache != null && stylesheet.Cache.ProjectId != null) { sUrl = FwLinkArgs.FixSilfwUrlForCurrentProject(sUrl, stylesheet.Cache.ProjectId.Name); } int ichStart = strBldr.Length; strBldr.Replace(ichStart, ichStart, sLinkText, StyleUtils.CharStyleTextProps(null, ws)); StringServices.MarkTextInBldrAsHyperlink(strBldr, ichStart, strBldr.Length, sUrl, hyperlinkStyle); return(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Attempt to show the most appropriate passage for the object indicated in the link. /// </summary> /// <param name="link"></param> /// ------------------------------------------------------------------------------------ public override void HandleIncomingLink(FwLinkArgs link) { ICmObject target; if (!Cache.ServiceLocator.ObjectRepository.TryGetObject(link.TargetGuid, out target)) { return; // can't even get the target object! } var targetRef = GetTargetRef(target); if (targetRef == null) { return; // don't know how to go there yet. } var mainWnd = this.ActiveMainWindow as TeMainWnd; if (mainWnd == null) { throw new Exception("life stinks"); } mainWnd.GotoVerse(targetRef); }
/// <summary> /// Executes in two distinct scenarios. /// /// 1. If disposing is true, the method has been called directly /// or indirectly by a user's code via the Dispose method. /// Both managed and unmanaged resources can be disposed. /// /// 2. If disposing is false, the method has been called by the /// runtime from inside the finalizer and you should not reference (access) /// other managed objects, as they already have been garbage collected. /// Only unmanaged resources can be disposed. /// </summary> /// <param name="disposing"></param> /// <remarks> /// If any exceptions are thrown, that is fine. /// If the method is being done in a finalizer, it will be ignored. /// If it is thrown by client code calling Dispose, /// it needs to be handled by fixing the bug. /// /// If subclasses override this method, they should call the base implementation. /// </remarks> protected virtual void Dispose(bool disposing) { System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); // Must not be run more than once. if (m_isDisposed) { return; } if (disposing) { // Dispose managed resources here. if (m_mediator != null) { m_mediator.RemoveColleague(this); m_mediator.PropertyTable.SetProperty("LinkListener", null, false); m_mediator.PropertyTable.SetPropertyPersistence("LinkListener", false); } if (m_backStack != null) { m_backStack.Clear(); } if (m_forwardStack != null) { m_forwardStack.Clear(); } } // Dispose unmanaged resources here, whether disposing is true or false. m_mediator = null; m_currentContext = null; m_backStack = null; m_forwardStack = null; m_isDisposed = true; }
/// ----------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="LinkListener"/> class. /// </summary> /// ----------------------------------------------------------------------------------- public LinkListener() { m_backStack = new LinkedList <FwLinkArgs>(); m_forwardStack = new LinkedList <FwLinkArgs>(); m_currentContext = null; }
private bool FollowActiveLink() { try { //Debug.Assert(!(m_lnkActive is FwAppArgs), "Beware: This will not handle link requests for other databases/applications." + // " To handle other databases or applications, pass the FwAppArgs to the IFieldWorksManager.HandleLinkRequest method."); if (m_lnkActive.ToolName == "default") { // Need some smarts here. The link creator was not sure what tool to use. // The object may also be a child we don't know how to jump to directly. var cache = (FdoCache)m_mediator.PropertyTable.GetValue("cache"); ICmObject target; if (!cache.ServiceLocator.ObjectRepository.TryGetObject(m_lnkActive.TargetGuid, out target)) { return(false); // or message? } var realTarget = GetObjectToShowInTool(target); string realTool; var majorObject = realTarget.Owner ?? realTarget; var app = FwUtils.ksFlexAbbrev; switch (majorObject.ClassID) { case ReversalIndexTags.kClassId: realTool = "reversalToolEditComplete"; break; case TextTags.kClassId: realTool = "interlinearEdit"; break; case LexEntryTags.kClassId: realTool = "lexiconEdit"; break; case ScriptureTags.kClassId: return(false); // Todo: don't know how to handle this yet. //app = FwUtils.ksTeAbbrev; //realTool = "reversalToolEditComplete"; //break; case CmPossibilityListTags.kClassId: // The area listener knows about the possible list tools. // Unfortunately AreaListener is in an assembly we can't reference. // But there may be custom ones, so just listing them all here does not seem to be an option, // and anyway it would be hard to maintain. // Thus we've created this method (on AreaListener) which we call awkwardly throught the mediator. var parameters = new object[2]; parameters[0] = majorObject; m_mediator.SendMessage("GetToolForList", parameters); realTool = (string)parameters[1]; break; case RnResearchNbkTags.kClassId: realTool = "notebookEdit"; break; case DsConstChartTags.kClassId: realTarget = ((IDsConstChart)majorObject).BasedOnRA; realTool = "interlinearEdit"; // Enhance JohnT: do something to make it switch to Discourse tab break; case LexDbTags.kClassId: // other things owned by this?? default: return(false); // can't jump to it...should we put up a message? } m_lnkActive = new FwLinkArgs(realTool, realTarget.Guid); // Todo JohnT: need to do something special here if we c } // It's important to do this AFTER we set the real tool name if it is "default". Otherwise, the code that // handles the jump never realizes we have reached the desired tool (as indicated by the value of // SuspendLoadingRecordUntilOnJumpToRecord) and we stop recording context history and various similar problems. if (m_lnkActive.TargetGuid != Guid.Empty) { // allow tools to skip loading a record if we're planning to jump to one. // interested tools will need to reset this "JumpToRecord" property after handling OnJumpToRecord. m_mediator.PropertyTable.SetProperty("SuspendLoadingRecordUntilOnJumpToRecord", m_lnkActive.ToolName + "," + m_lnkActive.TargetGuid.ToString(), PropertyTable.SettingsGroup.LocalSettings); m_mediator.PropertyTable.SetPropertyPersistence("SuspendLoadingRecordUntilOnJumpToRecord", false); } m_mediator.SendMessage("SetToolFromName", m_lnkActive.ToolName); // Note: It can be Guid.Empty in cases where it was never set, // or more likely, when the HVO was set to -1. if (m_lnkActive.TargetGuid != Guid.Empty) { FdoCache cache = (FdoCache)m_mediator.PropertyTable.GetValue("cache"); ICmObject obj = cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(m_lnkActive.TargetGuid); if (obj is IReversalIndexEntry && m_lnkActive.ToolName == "reversalToolEditComplete") { // For the reversal index tool, just getting the tool right isn't enough. We // also need to be showing the proper index. (See FWR-1105.) string sGuid = (string)m_mediator.PropertyTable.GetValue("ReversalIndexGuid"); if (!sGuid.Equals(obj.Owner.Guid.ToString())) { m_mediator.PropertyTable.SetProperty("ReversalIndexGuid", obj.Owner.Guid.ToString()); } } // Allow this to happen after the processing of the tool change above by using the Broadcast // method on the mediator, the SendMessage would process it before the above msg and it would // use the wrong RecordList. (LT-3260) m_mediator.BroadcastMessageUntilHandled("JumpToRecord", obj.Hvo); } foreach (Property property in m_lnkActive.PropertyTableEntries) { m_mediator.PropertyTable.SetProperty(property.name, property.value); //TODO: I can't think at the moment of what to do about setting //the persistence or ownership of the property...at the moment the only values we're putting //in there are strings or bools } m_mediator.BroadcastMessageUntilHandled("LinkFollowed", m_lnkActive); } catch (Exception err) { string s; if (err.InnerException != null && !string.IsNullOrEmpty(err.InnerException.Message)) { s = String.Format(xWorksStrings.UnableToFollowLink0, err.InnerException.Message); } else { s = xWorksStrings.UnableToFollowLink; } MessageBox.Show(s, xWorksStrings.FailedJump, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); return(false); } return(true); //we handled this. }
/// <summary> /// Handle launching of the MSA editor. /// </summary> protected override void HandleChooser() { VectorReferenceLauncher vrl = null; using (MsaInflectionFeatureListDlg dlg = new MsaInflectionFeatureListDlg()) { IFsFeatStruc originalFs = m_obj as IFsFeatStruc; Slice parentSlice = Slice; if (originalFs == null) { int owningFlid; int parentSliceClass = (int)parentSlice.Object.ClassID; switch (parentSliceClass) { case MoAffixAllomorphTags.kClassId: IMoAffixAllomorph allo = parentSlice.Object as IMoAffixAllomorph; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, allo, owningFlid); break; /*case LexEntryInflTypeTags.kClassId: * ILexEntryInflType leit = parentSlice.Object as ILexEntryInflType; * owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; * dlg.SetDlgInfo(m_cache, m_mediator, leit, owningFlid); * break;*/ default: IMoMorphSynAnalysis msa = parentSlice.Object as IMoMorphSynAnalysis; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, msa, owningFlid); break; } } else { dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, originalFs, (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid); } const string ksPath = "/group[@id='Linguistics']/group[@id='Morphology']/group[@id='FeatureChooser']/"; dlg.Text = StringTable.Table.GetStringWithXPath("InflectionFeatureTitle", ksPath); dlg.Prompt = StringTable.Table.GetStringWithXPath("InflectionFeaturePrompt", ksPath); dlg.LinkText = StringTable.Table.GetStringWithXPath("InflectionFeatureLink", ksPath); DialogResult result = dlg.ShowDialog(parentSlice.FindForm()); if (result == DialogResult.OK) { // Note that this may set m_obj to null. dlg.FS will be null if all inflection features have been // removed. That is a valid state for this slice; m_obj deleted is not. m_obj = dlg.FS; m_msaInflectionFeatureListDlgLauncherView.Init(m_cache, dlg.FS); } else if (result == DialogResult.Yes) { // Get the VectorReferenceLauncher for the Inflection Features slice. // Since we're not changing tools, we want to change the chooser dialog. // See LT-5913 for motivation. Control ctl = this.Parent; while (ctl != null && !(ctl is Slice)) { ctl = ctl.Parent; } Slice slice = ctl as Slice; if (slice != null) { DataTree dt = slice.ContainingDataTree; for (int i = 0; i < dt.Slices.Count; ++i) { Slice sliceT = dt.FieldOrDummyAt(i); vrl = sliceT.Control as VectorReferenceLauncher; if (vrl != null) { if (vrl.Flid == PartOfSpeechTags.kflidInflectableFeats) { break; } vrl = null; } } } if (vrl == null) { // We do, too, need to change tools! Sometimes this slice shows up in a different context, // such as the main data entry view. See LT-7167. // go to m_highestPOS in editor // TODO: this should be reviewed by someone who knows how these links should be done // I'm just guessing. // Also, is there some way to know the application name and tool name without hard coding them? var linkJump = new FwLinkArgs("posEdit", dlg.HighestPOS.Guid); m_mediator.PostMessage("FollowLink", linkJump); } else { vrl.HandleExternalChooser(); } } } }
private void btnAdd_Click(object sender, EventArgs e) { // Get the checked occurrences; List <int> occurrences = m_rbv.CheckedItems; if (occurrences == null || occurrences.Count == 0) { // do nothing. return; } List <int> uniqueSegments = (from fake in occurrences select m_clerk.VirtualListPublisher.get_ObjectProp(fake, ConcDecorator.kflidSegment)).Distinct().ToList (); int insertIndex = m_owningSense.ExamplesOS.Count; // by default, insert at the end. if (m_les != null) { // we were given a LexExampleSentence, so set our insertion index after the given one. insertIndex = m_owningSense.ExamplesOS.IndexOf(m_les) + 1; } UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoAddExamples, LexEdStrings.ksRedoAddExamples, m_cache.ActionHandlerAccessor, () => { int cNewExamples = 0; ILexExampleSentence newLexExample = null; foreach (int segHvo in uniqueSegments) { var seg = m_cache.ServiceLocator.GetObject(segHvo) as ISegment; if (cNewExamples == 0 && m_les != null && m_les.Example.BestVernacularAlternative.Text == "***" && (m_les.TranslationsOC == null || m_les.TranslationsOC.Count == 0) && m_les.Reference.Length == 0) { // we were given an empty LexExampleSentence, so use this one for our first new Example. newLexExample = m_les; } else { // create a new example sentence. newLexExample = m_cache.ServiceLocator.GetInstance <ILexExampleSentenceFactory>().Create(); m_owningSense.ExamplesOS.Insert(insertIndex + cNewExamples, newLexExample); cNewExamples++; } // copy the segment string into the new LexExampleSentence // Enhance: bold the relevant occurrence(s). // LT-11388 Make sure baseline text gets copied into correct ws var baseWs = GetBestVernWsForNewExample(seg); newLexExample.Example.set_String(baseWs, seg.BaselineText); if (seg.FreeTranslation.AvailableWritingSystemIds.Length > 0) { var trans = m_cache.ServiceLocator.GetInstance <ICmTranslationFactory>().Create(newLexExample, m_cache.ServiceLocator.GetInstance <ICmPossibilityRepository>().GetObject( CmPossibilityTags.kguidTranFreeTranslation)); trans.Translation.CopyAlternatives(seg.FreeTranslation); } if (seg.LiteralTranslation.AvailableWritingSystemIds.Length > 0) { var trans = m_cache.ServiceLocator.GetInstance <ICmTranslationFactory>().Create(newLexExample, m_cache.ServiceLocator.GetInstance <ICmPossibilityRepository>().GetObject( CmPossibilityTags.kguidTranLiteralTranslation)); trans.Translation.CopyAlternatives(seg.LiteralTranslation); } // copy the reference. ITsString tssRef = seg.Paragraph.Reference(seg, seg.BeginOffset); // convert the plain reference string into a link. ITsStrBldr tsb = tssRef.GetBldr(); FwLinkArgs fwl = new FwLinkArgs("interlinearEdit", seg.Owner.Owner.Guid); // It's not clear how to focus in on something smaller than the text when following // a link. //fwl.PropertyTableEntries.Add(new Property("LinkSegmentGuid", seg.Guid.ToString())); tsb.SetStrPropValue(0, tsb.Length, (int)FwTextPropType.ktptObjData, (char)FwObjDataTypes.kodtExternalPathName + fwl.ToString()); tsb.SetStrPropValue(0, tsb.Length, (int)FwTextPropType.ktptNamedStyle, "Hyperlink"); newLexExample.Reference = tsb.GetString(); } }); }
/// <summary> /// Handle launching of the LexEntryInflType features editor. /// </summary> protected override void HandleChooser() { VectorReferenceLauncher vrl = null; using (FeatureSystemInflectionFeatureListDlg dlg = new FeatureSystemInflectionFeatureListDlg()) { IFsFeatStruc originalFs = m_obj as IFsFeatStruc; Slice parentSlice = Slice; if (originalFs == null) { int owningFlid; ILexEntryInflType leit = parentSlice.Object as ILexEntryInflType; owningFlid = (parentSlice as FeatureSystemInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, leit, owningFlid); } else { dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, originalFs, (parentSlice as FeatureSystemInflectionFeatureListDlgLauncherSlice).Flid); } const string ksPath = "/group[@id='Linguistics']/group[@id='Morphology']/group[@id='FeatureChooser']/"; dlg.Text = StringTable.Table.GetStringWithXPath("InflectionFeatureTitle", ksPath); dlg.Prompt = StringTable.Table.GetStringWithXPath("InflectionFeaturesPrompt", ksPath); dlg.LinkText = StringTable.Table.GetStringWithXPath("InflectionFeaturesLink", ksPath); DialogResult result = dlg.ShowDialog(parentSlice.FindForm()); if (result == DialogResult.OK) { if (dlg.FS != null) { m_obj = dlg.FS; } m_msaInflectionFeatureListDlgLauncherView.Init(m_cache, dlg.FS); } else if (result == DialogResult.Yes) { /* * // Get the VectorReferenceLauncher for the Inflection Features slice. * // Since we're not changing tools, we want to change the chooser dialog. * // See LT-5913 for motivation. * Control ctl = this.Parent; * while (ctl != null && !(ctl is Slice)) * ctl = ctl.Parent; * Slice slice = ctl as Slice; * if (slice != null) * { * DataTree dt = slice.ContainingDataTree; * for (int i = 0; i < dt.Slices.Count; ++i) * { * Slice sliceT = dt.FieldOrDummyAt(i); * vrl = sliceT.Control as VectorReferenceLauncher; * if (vrl != null) * { * if (vrl.Flid == PartOfSpeechTags.kflidInflectableFeats) * break; * vrl = null; * } * } * } * if (vrl == null) * { * // We do, too, need to change tools! Sometimes this slice shows up in a different context, * // such as the main data entry view. See LT-7167. * // go to m_highestPOS in editor * // TODO: this should be reviewed by someone who knows how these links should be done * // I'm just guessing. * // Also, is there some way to know the application name and tool name without hard coding them? */ var linkJump = new FwLinkArgs("featuresAdvancedEdit", m_cache.LanguageProject.MsFeatureSystemOA.Guid); m_mediator.PostMessage("FollowLink", linkJump); /*} * else * { * vrl.HandleExternalChooser(); * }*/ } } }