예제 #1
0
 private void DeviceRemoved(object sender, RPlotDeviceEventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         RemoveAll(e.Device.DeviceId);
     });
     UnsubscribeDeviceEvents(e.Device);
 }
예제 #2
0
 private void DeviceLocatorModeChanged(object sender, RPlotDeviceEventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         LocatorMode = e.Device.LocatorMode;
         LocatorModeChanged?.Invoke(this, EventArgs.Empty);
     });
 }
예제 #3
0
        private int Search(IList <IRPackageViewModel> packages, string searchString, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(searchString))
            {
                _coreShell.DispatchOnUIThread(() => ApplySearch(packages, cancellationToken));
                return(packages.Count);
            }

            var filteredPackages = new List <IRPackageViewModel>();

            foreach (var package in packages)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(filteredPackages.Count);
                }

                if (package.Name.StartsWithIgnoreCase(searchString))
                {
                    filteredPackages.Add(package);
                }
            }

            _coreShell.DispatchOnUIThread(() => ApplySearch(filteredPackages, cancellationToken));
            return(filteredPackages.Count);
        }
예제 #4
0
 private void ViewModel_LocatorModeChanged(object sender, EventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         UpdateCaption();
         UpdateStatus();
     });
 }
예제 #5
0
        private void SessionOnAfterRequest(object sender, RAfterRequestEventArgs e)
        {
            if (_evaluatorRequest.Count == 0 && e.AddToHistory && e.IsVisible)
            {
                _coreShell.DispatchOnUIThread(() => {
                    if (CurrentWindow == null || CurrentWindow.IsResetting)
                    {
                        return;
                    }

                    ((IInteractiveWindow2)CurrentWindow).AddToHistory(e.Request.TrimEnd());
                    History.AddToHistory(e.Request);
                });
            }
        }
예제 #6
0
 private void ConnectionStateChanged(object sender, ConnectionEventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         IsConnected = e.State;
         UpdateConnections();
     });
 }
예제 #7
0
        public ConnectionManager(IStatusBar statusBar, IRSessionProvider sessionProvider, IRSettings settings, IRInteractiveWorkflow interactiveWorkflow)
        {
            _statusBar       = statusBar;
            _sessionProvider = sessionProvider;
            _brokerConnector = interactiveWorkflow.BrokerConnector;
            _settings        = settings;
            _shell           = interactiveWorkflow.Shell;

            _statusBarViewModel = new ConnectionStatusBarViewModel(this, interactiveWorkflow.Shell);

            _disposableBag = DisposableBag.Create <ConnectionManager>()
                             .Add(_statusBarViewModel)
                             .Add(() => _brokerConnector.BrokerChanged            -= BrokerChanged)
                             .Add(() => interactiveWorkflow.RSession.Connected    -= RSessionOnConnected)
                             .Add(() => interactiveWorkflow.RSession.Disconnected -= RSessionOnDisconnected);

            _brokerConnector.BrokerChanged += BrokerChanged;
            // TODO: Temporary solution - need to separate RHost errors and network connection issues
            interactiveWorkflow.RSession.Connected    += RSessionOnConnected;
            interactiveWorkflow.RSession.Disconnected += RSessionOnDisconnected;

            _shell.DispatchOnUIThread(() => _disposableBag.Add(_statusBar.AddItem(new ConnectionStatusBar {
                DataContext = _statusBarViewModel
            })));

            // Get initial values
            var connections = GetConnectionsFromSettings();

            _connections = new ConcurrentDictionary <Uri, IConnection>(connections);

            UpdateRecentConnections();
            SwitchBrokerToLastConnection();
        }
예제 #8
0
 private void ConnectionStateChanged(object sender, ConnectionEventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         IsConnected        = e.State;
         IsRemote           = e.Connection?.IsRemote ?? false;
         SelectedConnection = e.Connection?.Name;
     });
 }
예제 #9
0
        private void LastActiveTextViewChanged(object sender, ActiveTextViewChangedEventArgs e)
        {
            if (ActiveWindow == null)
            {
                return;
            }

            if (ActiveWindow.TextView.Equals(e.Old) && !ActiveWindow.TextView.Equals(e.New))
            {
                _replLostFocus = true;
                _coreShell.DispatchOnUIThread(CheckPossibleBreakModeFocusChange);
            }

            if (ActiveWindow.TextView.Equals(e.New))
            {
                _coreShell.DispatchOnUIThread(Operations.PositionCaretAtPrompt);
            }
        }
예제 #10
0
 public Task <string> ReadUserInput(string prompt, int maximumLength, CancellationToken ct)
 {
     _coreShell.DispatchOnUIThread(() => _interactiveWindow.Write(prompt));
     return(Task.Run(() => {
         using (var reader = _interactiveWindow.ReadStandardInput()) {
             return reader != null ? Task.FromResult(reader.ReadToEnd()) : Task.FromResult("\n");
         }
     }, ct));
 }
예제 #11
0
 private void ConnectionStateChanged(object sender, ConnectionEventArgs e)
 {
     _shell.DispatchOnUIThread(() => {
         IsConnected = e.State;
         foreach (var item in _items)
         {
             item.IsConnected = e.State && item.IsActive;
         }
     });
 }
예제 #12
0
 private void SaveActiveConnectionToSettings()
 {
     _shell.DispatchOnUIThread(() => _settings.LastActiveConnection = ActiveConnection == null
         ? null
         : new ConnectionInfo {
         Name = ActiveConnection.Name,
         Path = ActiveConnection.Path,
         RCommandLineArguments = ActiveConnection.RCommandLineArguments
     });
 }
예제 #13
0
        private void SessionOnBeforeRequest(object sender, RRequestEventArgs e)
        {
            _coreShell.DispatchOnUIThread(() => {
                if (CurrentWindow == null || CurrentWindow.IsRunning)
                {
                    return;
                }

                var projectionBuffer = CurrentWindow.TextView.TextBuffer as IProjectionBuffer;
                if (projectionBuffer == null)
                {
                    return;
                }

                var spanCount = projectionBuffer.CurrentSnapshot.SpanCount;
                projectionBuffer.ReplaceSpans(spanCount - 2, 1, new List <object> {
                    GetPrompt()
                }, EditOptions.None, new object());
            });
        }
예제 #14
0
        /// <summary>
        /// Fetches help on the function from R asynchronously.
        /// When function data is obtained, parsed and the function
        /// index is updated, method invokes <see cref="infoReadyCallback"/>
        /// callback passing the specified parameter. Callback method can now
        /// fetch function information from the index.
        /// </summary>
        private async Task <string> GetFunctionInfoFromEngineAsync(string functionName, string packageName, Action <object, string> infoReadyCallback = null, object parameter = null)
        {
            packageName = packageName ?? await _host.GetFunctionPackageNameAsync(functionName);

            if (string.IsNullOrEmpty(packageName))
            {
                // Even if nothing is found, still notify the callback
                if (infoReadyCallback != null)
                {
                    _coreShell.DispatchOnUIThread(() => {
                        infoReadyCallback(null, null);
                    });
                }
                return(packageName);
            }

            if (infoReadyCallback == null)
            {
                // regular async call
                var rdData = await _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName);

                if (!string.IsNullOrEmpty(rdData))
                {
                    // If package is found update data in the index
                    UpdateIndex(functionName, packageName, rdData);
                }
                return(packageName);
            }

            _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName,
                                                           rdData => {
                if (!string.IsNullOrEmpty(packageName) && !string.IsNullOrEmpty(rdData))
                {
                    // If package is found update data in the index
                    UpdateIndex(functionName, packageName, rdData);
                }
                _coreShell.DispatchOnUIThread(() => infoReadyCallback(parameter, packageName));
            });
            return(packageName);
        }
예제 #15
0
        public bool ProcessMessage(string message)
        {
            // Note: DispatchOnUIThread is expensive, and can saturate the message pump when there's a lot of output,
            // making UI non-responsive. So avoid using it unless we need it - and we only need it for FlushOutput,
            // and we only need it to handle CR.
            if (message.Length > 1 && message[0] == '\r' && message[1] != '\n')
            {
                _coreShell.DispatchOnUIThread(() => {
                    // Make sure output buffer is up to date
                    _interactiveWindow.FlushOutput();

                    // If message starts with CR we remember current output buffer
                    // length so we can continue writing lines into the same spot.
                    // See txtProgressBar in R.
                    // Store the message and the initial position. All subsequent
                    // messages that start with CR will be written into the same place.
                    if (_messagePos != null)
                    {
                        ProcessReplacement();
                    }

                    // Locate last end of line
                    var snapshot = _interactiveWindow.OutputBuffer.CurrentSnapshot;
                    var line     = snapshot.GetLineFromPosition(snapshot.Length);
                    var text     = message.Substring(1);

                    _messagePos = new MessagePos()
                    {
                        Text              = text,
                        Position          = line.Start,
                        PlaceholderLength = text.Length + 8 // buffer for, say, '| 100%'
                    };

                    // It is important that replacement matches original text length
                    // since interactive window creates fixed colorized spans for errors
                    // and replacement of text by a text with a different length
                    // causes odd changes in color - word may appear partially in
                    // black and partially in red.

                    // Replacement placeholder so we can receive 'buffer changed' event
                    // Placeholder is whitespace that is as long as original message plus
                    // few more space to account for example, for 0% - 100% when CR is used
                    // to display ASCII progress.
                    var placeholder = new string(' ', _messagePos.PlaceholderLength);

                    _interactiveWindow.Write(placeholder);
                    _interactiveWindow.FlushOutput(); // Must flush so we do get 'buffer changed' immediately.
                });
                return(true);
            }
            return(false);
        }
예제 #16
0
 /// <summary>
 /// Fetches help on the function from R asynchronously.
 /// When function data is obtained, parsed and the function
 /// index is updated, method invokes <see cref="infoReadyCallback"/>
 /// callback passing the specified parameter. Callback method can now
 /// fetch function information from the index.
 /// </summary>
 private void GetFunctionInfoFromEngineAsync(string functionName, string packageName, Action <object> infoReadyCallback = null, object parameter = null)
 {
     _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName,
                                                    rdData => {
         UpdateIndex(functionName, rdData);
         if (infoReadyCallback != null)
         {
             _coreShell.DispatchOnUIThread(() => {
                 infoReadyCallback(parameter);
             });
         }
     });
 }
예제 #17
0
        private async Task EnsureAvailablePackagesLoadedAsync()
        {
            var availablePackagesLoaded = await _availableLock.WaitAsync();

            try {
                if (!availablePackagesLoaded)
                {
                    await LoadAvailablePackagesAsync();
                }
            } catch (RPackageManagerException ex) {
                _coreShell.DispatchOnUIThread(() => AddErrorMessage(ex.Message));
            } finally {
                _availableLock.Release();
            }
        }
예제 #18
0
        private void OnHostLoadChanged(object sender, HostLoadChangedEventArgs e)
        {
            _shell.DispatchOnUIThread(() => {
                CpuLoad     = e.HostLoad.CpuLoad;
                MemoryLoad  = e.HostLoad.MemoryLoad;
                NetworkLoad = e.HostLoad.NetworkLoad;

                Tooltip = string.Format(CultureInfo.InvariantCulture,
                                        Resources.HostLoad_Tooltip,
                                        (int)Math.Round(100 * CpuLoad),
                                        (int)Math.Round(100 * MemoryLoad),
                                        (int)Math.Round(100 * NetworkLoad));
            });
        }
예제 #19
0
        public Task <LocatorResult> StartLocatorModeAsync(Guid deviceId, CancellationToken cancellationToken)
        {
            var device = FindDevice(deviceId);

            device.LocatorMode = true;

            _locatorTcs = new TaskCompletionSource <LocatorResult>();
            _locatorCancelTokenRegistration = cancellationToken.Register(() => CancelLocatorMode(device));

            _shell.DispatchOnUIThread(() => {
                var visualComponent = GetVisualComponentForDevice(deviceId);
                visualComponent?.Container.Show(focus: false, immediate: true);
            });

            return(_locatorTcs.Task);
        }
예제 #20
0
        private void Refresh(IRPlot plot)
        {
            _shell.DispatchOnUIThread(() => {
                if (plot != null)
                {
                    PlotImage     = plot.Image;
                    ShowWatermark = false;
                    ShowError     = plot.Image == null;
                }
                else
                {
                    PlotImage     = null;
                    ShowWatermark = true;
                    ShowError     = false;
                }

                DeviceNameChanged?.Invoke(this, EventArgs.Empty);
                PlotChanged?.Invoke(this, EventArgs.Empty);
            });
        }
예제 #21
0
        private void FileWatcherError(object sender, EventArgs args)
        {
            _fileWatcher.Error -= FileWatcherError;
            _coreShell.DispatchOnUIThread(() => {
                foreach (var iVsProjectLazy in _cpsIVsProjects)
                {
                    IVsProject iVsProject;
                    try {
                        iVsProject = iVsProjectLazy.Value;
                    } catch (Exception) {
                        continue;
                    }

                    if (iVsProject.AsUnconfiguredProject() != _unconfiguredProject)
                    {
                        continue;
                    }

                    var solution = VsAppShell.Current.GetGlobalService <IVsSolution>(typeof(SVsSolution));
                    solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject, (IVsHierarchy)iVsProject, 0);
                    return;
                }
            });
        }
 private void OnBrokerChanged(object sender, BrokerStateChangedEventArgs e)
 {
     _shell.DispatchOnUIThread(() => UpdateWindowTitle(e.IsConnected));
 }
예제 #23
0
        /// <summary>
        /// Main asyncronous task body
        /// </summary>
        void ProcessTextChanges(TextChange changeToProcess, bool async, Func <bool> isCancelledCallback)
        {
            lock (_disposeLock) {
                if (_editorTree == null || _disposed || isCancelledCallback())
                {
                    return;
                }

                EditorTreeChangeCollection treeChanges = null;
                // Cache id since it can change if task is canceled
                long taskId = TaskId;

                try {
                    AstRoot rootNode;

                    // We only need read lock since changes will be applied
                    // from the main thread
                    if (async)
                    {
                        rootNode = _editorTree.AcquireReadLock(_treeUserId);
                    }
                    else
                    {
                        rootNode = _editorTree.GetAstRootUnsafe();
                    }

                    treeChanges = new EditorTreeChangeCollection(changeToProcess.Version, changeToProcess.FullParseRequired);
                    TextChangeProcessor changeProcessor = new TextChangeProcessor(_editorTree, rootNode, isCancelledCallback);

                    bool fullParseRequired = changeToProcess.FullParseRequired;
                    if (fullParseRequired)
                    {
                        changeProcessor.FullParse(treeChanges, changeToProcess.NewTextProvider);
                    }
                    else
                    {
                        changeProcessor.ProcessChange(changeToProcess, treeChanges);
                    }
                } finally {
                    if (async && _editorTree != null)
                    {
                        _editorTree.ReleaseReadLock(_treeUserId);
                    }
                }

                // Lock should be released at this point since actual application
                // of tree changes is going to be happen from the main thread.

                if (!isCancelledCallback() && treeChanges != null)
                {
                    // Queue results for the main thread application. This must be done before
                    // signaling that the task is complete since if EnsureProcessingComplete
                    // is waiting it will want to apply changes itself rather than wait for
                    // the DispatchOnUIThread to go though and hence it will need all changes
                    // stored and ready for application.

                    _backgroundParsingResults.Enqueue(treeChanges);
                }

                // Signal task complete now so if main thread is waiting
                // it can proceed and appy the changes immediately.
                SignalTaskComplete(taskId);

                if (_backgroundParsingResults.Count > 0)
                {
                    _uiThreadTransitionRequestTime = DateTime.UtcNow;

                    // It is OK to post results while main thread might be working
                    // on them since if if it does, by the time posted request comes
                    // queue will already be empty.
                    if (async)
                    {
                        // Post request to apply tree changes to the main thread.
                        // This must NOT block or else task will never enter 'RanToCompletion' state.
                        _shell.DispatchOnUIThread(ApplyBackgroundProcessingResults);
                    }
                    else
                    {
                        // When processing is synchronous, apply changes and fire events right away.
                        ApplyBackgroundProcessingResults();
                    }
                }
            }
        }
예제 #24
0
 private void SaveActiveConnectionToSettings()
 {
     _shell.DispatchOnUIThread(() => _settings.LastActiveConnection = ActiveConnection == null
         ? null
         : new ConnectionInfo(ActiveConnection));
 }
예제 #25
0
 public void Write(string text)
 {
     _coreShell.DispatchOnUIThread(() => _workflowLazy.Value.ActiveWindow?.InteractiveWindow?.WriteErrorLine(text));
 }