/// <summary> /// Executes a dispatch. /// The dispatch call is executed in a time limited way <see cref="TimeLimitExecutor"/> (200 ms). /// </summary> /// <param name="commandUrl">The command URL to dispatch. Describes the /// feature which should be supported by internally used dispatch object. /// <see cref="https://wiki.openoffice.org/wiki/Framework/Article/OpenOffice.org_2.x_Commands#Draw.2FImpress_commands"/></param> /// <param name="docViewContrl">The document view controller. Points to /// the provider, which should be asked for valid dispatch objects.</param> /// <param name="_frame">Specifies the frame which should be the target /// for this request.</param> /// <param name="_sFlag">Optional search parameter for finding the frame /// if no special TargetFrameName was used.</param> /// <param name="args">Optional arguments for this request They depend on /// the real implementation of the dispatch object.</param> /// <remarks>This function is time limited to 200 ms.</remarks> internal static bool CallDispatch(string commandUrl, XDispatchProvider docViewContrl, String _frame = "", int _sFlag = 0, PropertyValue[] args = null) { bool successs = false; if (!String.IsNullOrWhiteSpace(commandUrl)) { bool abort = TimeLimitExecutor.WaitForExecuteWithTimeLimit( 200, new Action(() => { var disp = GetDispatcher(OO.GetMultiServiceFactory()); if (disp != null) { // A possible result of the executed internal dispatch. // The information behind this any depends on the dispatch! var result = disp.executeDispatch(docViewContrl, commandUrl, _frame, _sFlag, args); if (result.hasValue() && result.Value is unoidl.com.sun.star.frame.DispatchResultEvent) { var val = result.Value as unoidl.com.sun.star.frame.DispatchResultEvent; if (val != null && val.State == (short)DispatchResultState.SUCCESS) { successs = true; } } } }), "Dispatch Call"); successs &= abort; } return(successs); }
/// <summary> /// Returns all services of the object. /// </summary> /// <param name="obj">The obj.</param> /// <param name="debug">if set to <c>true</c> the services will be printed /// to the System.Diagnostics.Debug output.</param> /// <returns>List of all supported service names.</returns> /// <remarks>This function is time limited to 200 ms.</remarks> public static string[] GetAllServicesOfObject(Object obj, bool debug = true) { String output = ""; string[] services = new string[0]; if (obj != null) { try { TimeLimitExecutor.WaitForExecuteWithTimeLimit(200, () => { XServiceInfo si = obj as XServiceInfo; if (si != null) { // FIXME: Access violation on service request try { services = si.getSupportedServiceNames(); if (debug) { output += (services.Length + "\tServices:"); foreach (var item in services) { output += "\n" + ("\tService: " + item); } System.Diagnostics.Debug.WriteLine(output); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Exception happened: " + ex.ToString()); } } else { System.Diagnostics.Debug.WriteLine("Can't get services of Object because it is not a XServiceInfo provider."); } }, "GetAllServices"); } catch (unoidl.com.sun.star.lang.DisposedException) { OO.CheckConnection(); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Can't get services of Object: " + e); } } return(services); }
/// <summary> /// Executes an <code>Action</code> with a time limit in an separate asynchronous Thread and waits until it ends for the return. /// </summary> /// <param name="maxTime">The maximum execution time in milliseconds. After this time the thread will be abort!</param> /// <param name="codeBlock">The code block. Us a e.g. an anonymous delegate such as /// <code>() => { /* Write your time bounded code here*/ }</code></param> /// <param name="name">The name.</param> /// <returns>indication if the execution was done successfully</returns> public static bool WaitForExecuteWithTimeLimit(int maxTime, Action codeBlock, string name = "") { bool success = false; try { var executor = TimeLimitExecutor.ExecuteWithTimeLimit(maxTime, codeBlock, name); while (executor != null && executor.IsAlive && executor.ThreadState == System.Threading.ThreadState.Running) { Thread.Sleep(1); } success = true; } catch (System.Threading.ThreadAbortException) { return(false); } return(success); }
/// <summary> /// Gets a String property. /// </summary> /// <param name="obj">The obj.</param> /// <param name="propName">Name of the property.</param> /// <returns>the value of the property</returns> /// <remarks>ATTENTION: This function is time limited to 100 ms!</remarks> public static String GetStringProperty(Object obj, String propName) { String result = String.Empty; bool succ = TimeLimitExecutor.WaitForExecuteWithTimeLimit(100, new Action(() => { Object value = GetProperty(obj, propName); if (value != null) { var stringValue = value as string; if (stringValue != null) { result = stringValue; } } })); if (!succ) { result = String.Empty; } return(result); }
/// <summary> /// Calls an actions with a previously selection change and a selection reset afterwards. /// </summary> /// <param name="act">The action to call.</param> /// <param name="selectProv">The selection provider - commonly this is the document.</param> /// <param name="selection">The selection. Use <c>null</c> to reset the selection.</param> internal static void ActionWithChangeAndResetSelection(Action act, XSelectionSupplier selectProv, Object selection = null) { try { TimeLimitExecutor.ExecuteWithTimeLimit(1000, () => { try { var oldSel = GetSelection(selectProv); Thread.Sleep(80); var succ = SetSelection(selectProv, selection); Thread.Sleep(80); if (succ && act != null) { act.Invoke(); if (Thread.CurrentThread.IsAlive) { Thread.Sleep(250); } } Thread.Sleep(100); SetSelection(selectProv, oldSel); } catch (Exception ex) { Logger.Instance.Log(LogPriority.ALWAYS, "OoDispatchHelper", "[FATAL ERROR] Can't call dispatch command with selection - Thread interrupted:", ex); } }, "Delete Object"); } catch (ThreadInterruptedException ex) { Logger.Instance.Log(LogPriority.ALWAYS, "OoDispatchHelper", "[FATAL ERROR] Can't call dispatch command with selection - Thread interrupted:", ex); } catch (Exception ex) { Logger.Instance.Log(LogPriority.ALWAYS, "OoDispatchHelper", "[FATAL ERROR] Can't call dispatch command with selection:", ex); } }