/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified IFwMainWnd from the list of windows. /// </summary> /// <param name="fwMainWindow">The IFwMainWnd to remove</param> /// ------------------------------------------------------------------------------------ public override void RemoveWindow(IFwMainWnd fwMainWindow) { base.RemoveWindow(fwMainWindow); Debug.Assert(!IsDisposed, "Shuting down the app should have happened asynchronously after we get called"); if (MainWindows.Count == 1 && MainWindows[0] is NotesMainWnd) { NotesWindow = null; // Notes window is the only window left } }
/// <summary> /// Try to find a WfiWordform object corresponding the the focus selection. /// If successful return its guid, otherwise, return Guid.Empty. /// </summary> /// <returns></returns> internal static Guid ActiveWordform(FdoCache cache, Mediator mediator) { IApp app = mediator.PropertyTable.GetValue("App") as IApp; if (app == null) { return(Guid.Empty); } IFwMainWnd window = app.ActiveMainWindow as IFwMainWnd; if (window == null) { return(Guid.Empty); } IRootSite activeView = window.ActiveView; if (activeView == null) { return(Guid.Empty); } List <IVwRootBox> roots = activeView.AllRootBoxes(); if (roots.Count < 1) { return(Guid.Empty); } SelectionHelper helper = SelectionHelper.Create(roots[0].Site); if (helper == null) { return(Guid.Empty); } ITsString word = helper.SelectedWord; if (word == null || word.Length == 0) { return(Guid.Empty); } #if WANTPORT // FWR-2784 int hvoWordform = cache.LangProject.WordformInventoryOA.GetWordformId(word); if (hvoWordform == 0 || cache.IsDummyObject(hvoWordform)) { return(Guid.Empty); } return(cache.GetGuidFromId(hvoWordform)); #else return(Guid.Empty); #endif }
public override void RemoveWindow(IFwMainWnd fwMainWindow) { //base.RemoveWindow(fwMainWindow); We never added it. }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified IFwMainWnd from the list of windows. If it is ok to close down /// the application and the count of main windows is zero, then this method will also /// shut down the application. /// </summary> /// <param name="fwMainWindow">The IFwMainWnd to remove</param> /// ------------------------------------------------------------------------------------ public virtual void RemoveWindow(IFwMainWnd fwMainWindow) { if (IsDisposed || BeingDisposed) return; if (!m_rgMainWindows.Contains(fwMainWindow)) return; // It isn't our window. // NOTE: The main window that was passed in is most likely already disposed, so // make sure we don't call anything that would throw an ObjectDisposedException! m_rgMainWindows.Remove(fwMainWindow); Form form = (Form)fwMainWindow; form.Activated -= fwMainWindow_Activated; form.HandleDestroyed -= fwMainWindow_HandleDestroyed; if (m_activeMainWindow == fwMainWindow) m_activeMainWindow = null; // Just in case if (m_rgMainWindows.Count == 0) m_fwManager.ExecuteAsync(m_fwManager.ShutdownApp, this); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates a new main window and initializes it. The specified App is responsible for /// creating the proper main window type. /// </summary> /// <param name="app">The app</param> /// <param name="fNewCache"><c>true</c> if we didn't reuse an existing cache</param> /// <param name="wndCopyFrom">The window to copy from (optional).</param> /// <param name="fOpeningNewProject"><c>true</c> if opening a new project</param> /// <returns>True if the main window was create and initialized successfully</returns> /// ------------------------------------------------------------------------------------ internal static bool CreateAndInitNewMainWindow(FwApp app, bool fNewCache, Form wndCopyFrom, bool fOpeningNewProject) { Debug.Assert(app == s_flexApp || app == s_teApp); WriteSplashScreen(app.GetResourceString("kstidInitWindow")); Form fwMainWindow; try { // Construct the new window, of the proper derived type fwMainWindow = app.NewMainAppWnd(s_splashScreen, fNewCache, wndCopyFrom, fOpeningNewProject); // Let the application do its initialization of the new window using (new DataUpdateMonitor(fwMainWindow, "Creating new main window")) app.InitAndShowMainWindow(fwMainWindow, wndCopyFrom); // It seems to get activated before we connect the Activate event. But it IS active by now; // so just record it now as the active one. s_activeMainWnd = (IFwMainWnd)fwMainWindow; } catch (StartupException ex) { // REVIEW: Can this actually happen when just creating a new main window? CloseSplashScreen(); MessageBox.Show(ex.Message, Properties.Resources.ksErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } CloseSplashScreen(); if (!((IFwMainWnd)fwMainWindow).OnFinishedInit()) return false; // did not initialize properly! fwMainWindow.Activated += FwMainWindowActivated; fwMainWindow.Closing += FwMainWindowClosing; return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Shutdowns the specified application. The application will be disposed of immediately. /// If no other applications are running, then FieldWorks will also be shutdown. /// </summary> /// <param name="app">The application to shut down.</param> /// <param name="fSaveSettings">True to have the application save its settings, /// false otherwise</param> /// ------------------------------------------------------------------------------------ internal static void ShutdownApp(FwApp app, bool fSaveSettings) { if (app != s_teApp && app != s_flexApp) throw new ArgumentException("Application must belong to this FieldWorks", "app"); if (fSaveSettings) app.SaveSettings(); if (s_activeMainWnd != null && app.MainWindows.Contains(s_activeMainWnd)) { // The application that owns the active main window is being disposed. This // means that the window is, most likely, already disposed. s_activeMainWnd = null; } RecordLastAppForProject(); if (app == s_teApp) s_teApp = null; else if (app == s_flexApp) s_flexApp = null; // Make sure we do this after we set the variables to null to keep a race condition // from happening where we want to GetOrCreateApplication() for the app that is // being disposed. try { app.Dispose(); } catch { // continue shutdown even with an exception. It's possible we're shutting down because // of a crash and we don't know what state the application is in. } ExitIfNoAppsRunning(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the Activated event of FieldWorks Main Windows. /// </summary> /// <param name="sender">The main window that just got activated.</param> /// <param name="e">The <see cref="T:System.EventArgs"/> Not used.</param> /// ------------------------------------------------------------------------------------ private static void FwMainWindowActivated(object sender, EventArgs e) { if (sender is IFwMainWnd) s_activeMainWnd = sender as IFwMainWnd; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the Closing event of FieldWorks Main Windows. /// </summary> /// <param name="sender">The main window that is closing.</param> /// <param name="e">The <see cref="T:System.ComponentModel.CancelEventArgs"/> Not used.</param> /// ------------------------------------------------------------------------------------ private static void FwMainWindowClosing(object sender, CancelEventArgs e) { if (s_activeMainWnd == sender) { // Remember the settings, so that, if we end up saving some changes // related to it, we can record the last saved project. s_settingsForLastClosedWindow = s_activeMainWnd.App.RegistrySettings; // Make sure the closing main window is not considered the active main window s_activeMainWnd = null; } }
private static bool SafelyReportException(Exception error, IFwMainWnd parent, bool isLethal) { using (new IgnoreAppMessageProccessing(s_teApp)) using (new IgnoreAppMessageProccessing(s_flexApp)) { // Be very, very careful about changing stuff here. Code here MUST not throw exceptions, // even when the application is in a crashed state. For example, error reporting failed // before I added the static registry keys, because getting App.SettingsKey failed somehow. RegistryKey appKey = FwRegistryHelper.FieldWorksRegistryKey; if (parent != null && parent.App != null && parent.App == s_teApp && s_teAppKey != null) appKey = s_teAppKey; else if (parent != null && parent.App != null && parent.App == s_flexApp && s_flexAppKey != null) appKey = s_flexAppKey; return ErrorReporter.ReportException(error, appKey, SupportEmail, parent as Form, isLethal); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Displays the error. /// </summary> /// <param name="exception">The exception.</param> /// <param name="parent">The parent.</param> /// <returns><c>true</c> to exit application, <c>false</c> to continue</returns> /// ------------------------------------------------------------------------------------ private static bool DisplayError(Exception exception, IFwMainWnd parent) { try { // To disable displaying a message box, put // <add key="ShowUI" value="False"/> // in the <appSettings> section of the .config file (see MSDN for details). if (ShowUI) { bool fIsLethal = !(exception is ConfigurationException || exception is ContinuableErrorException || exception.InnerException is ContinuableErrorException); if (SafelyReportException(exception, parent, fIsLethal)) { // User chose to exit the application. Make sure that the program can be // properly shut down after displaying the exception. (FWR-3179) ResetStateForForcedShutdown(); return true; } return false; } // Make sure that the program can be properly shut down after displaying the exception. (FWR-3179) ResetStateForForcedShutdown(); if (exception is ExternalException && (uint)(((ExternalException)exception).ErrorCode) == 0x8007000E) // E_OUTOFMEMORY { Trace.Assert(false, ResourceHelper.GetResourceString("kstidMiscError"), ResourceHelper.GetResourceString("kstidOutOfMemory")); return true; } Debug.Assert(exception.Message != string.Empty || exception is COMException, "Oops - we got an empty exception description. Change the code to handle that!"); Exception innerE = ExceptionHelper.GetInnerMostException(exception); string strMessage = ResourceHelper.GetResourceString("kstidProgError") + ResourceHelper.GetResourceString("kstidFatalError"); string strReport = string.Format(ResourceHelper.GetResourceString("kstidGotException"), SupportEmail, exception.Source, Version, ExceptionHelper.GetAllExceptionMessages(exception), innerE.Source, innerE.TargetSite.Name, ExceptionHelper.GetAllStackTraces(exception)); Trace.Assert(false, strMessage, strReport); } catch { // we ignore any exceptions that might happen during reporting this error } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified IFwMainWnd from the list of windows. /// </summary> /// <param name="fwMainWindow">The IFwMainWnd to remove</param> /// ------------------------------------------------------------------------------------ public override void RemoveWindow(IFwMainWnd fwMainWindow) { base.RemoveWindow(fwMainWindow); Debug.Assert(!IsDisposed, "Shuting down the app should have happened asynchronously after we get called"); if (MainWindows.Count == 1 && MainWindows[0] is NotesMainWnd) NotesWindow = null; // Notes window is the only window left }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified IFwMainWnd from the list of windows, returning the cache /// associated with it if the cache should be removed separately. There are situations /// where the cache must not be removed at the time the window is removed, but where /// the code that uses the cache invalidates fwMainWindow.m_mediator, which stores the /// access to the cache. /// </summary> /// <param name="fwMainWindow">The IFwMainWnd to remove</param> /// <param name="wndCache">returns null or FdoCache object to pass to RemoveFdoCache() /// later.</param> /// ------------------------------------------------------------------------------------ public void RemoveWindow(IFwMainWnd fwMainWindow, out FdoCache wndCache) { CheckDisposed(); wndCache = null; Form form = (Form)fwMainWindow; if (!m_rgMainWindows.Contains(fwMainWindow) || form.Disposing || form.IsDisposed) { return; // It isn't our window. Or it is dead or dying. } FdoCache mainWndCache = fwMainWindow.Cache; bool fCacheStillInUse = false; // Look for the cache in the other main windows. foreach (IFwMainWnd mainWnd in MainWindows) { if (mainWnd != null && mainWnd != fwMainWindow) fCacheStillInUse |= (mainWnd.Cache == mainWndCache); } if (!fCacheStillInUse) wndCache = mainWndCache; m_rgMainWindows.Remove(fwMainWindow); if (m_fOkToClose && m_rgMainWindows.Count == 0) { wndCache = null; RemoveFdoCache(mainWndCache); } if (m_activeMainWindow == fwMainWindow) m_activeMainWindow = null; Form oldForm = fwMainWindow as Form; if (oldForm != null) { // JohnT: being paranoid here, surely it MUST be a form? // Assuming that's so, we no longer want to know about it in the unlikely // event of its being activated again, and hence don't need to know about // its handle being destroyed. oldForm.Activated -= new EventHandler(fwMainWindow_Activated); oldForm.HandleDestroyed -= new EventHandler(fwMainWindow_HandleDestroyed); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Removes the specified IFwMainWnd from the list of windows and removes the cache /// associated with it. /// </summary> /// <param name="fwMainWindow">The IFwMainWnd to remove</param> /// ------------------------------------------------------------------------------------ public void RemoveWindow(IFwMainWnd fwMainWindow) { CheckDisposed(); FdoCache wndCache = null; RemoveWindow(fwMainWindow, out wndCache); if (wndCache != null) RemoveFdoCache(wndCache); }