1 /*
2 * SessionClientEvent.cpp
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16 #include <session/SessionClientEvent.hpp>
17
18 #include <boost/lexical_cast.hpp>
19
20 #include <shared_core/Error.hpp>
21 #include <core/Log.hpp>
22 #include <shared_core/FilePath.hpp>
23 #include <shared_core/SafeConvert.hpp>
24 #include <core/FileSerializer.hpp>
25 #include <core/system/System.hpp>
26
27 using namespace rstudio::core;
28
29 namespace rstudio {
30 namespace session {
31
32 namespace client_events {
33
34 const int kBusy = 1;
35 const int kConsolePrompt = 2;
36 const int kConsoleWriteOutput = 3;
37 const int kConsoleWriteError = 4;
38 const int kShowErrorMessage = 5;
39 const int kShowHelp = 6;
40 const int kBrowseUrl = 7;
41 const int kShowEditor = 11;
42 const int kChooseFile = 13;
43 const int kAbendWarning = 14;
44 const int kQuit = 15;
45 const int kSuicide = 16;
46 const int kFileChanged = 17;
47 const int kWorkingDirChanged = 18;
48 const int kPlotsStateChanged = 19;
49 const int kPackageStatusChanged = 21;
50 const int kPackageStateChanged = 22;
51 const int kLocator = 23;
52 const int kConsoleResetHistory = 25;
53 const int kSessionSerialization = 26;
54 const int kHistoryEntriesAdded = 27;
55 const int kQuotaStatus = 29;
56 const int kFileEdit = 32;
57 const int kShowContent = 33;
58 const int kShowData = 34;
59 const int kAsyncCompletion = 35;
60 const int kSaveActionChanged = 36;
61 const int kConsoleWritePrompt = 37;
62 const int kConsoleWriteInput = 38;
63 const int kShowWarningBar = 39;
64 const int kOpenProjectError = 40;
65 const int kVcsRefresh = 41;
66 const int kAskPass = 42;
67 const int kConsoleProcessOutput = 43;
68 const int kConsoleProcessExit = 44;
69 const int kListChanged = 45;
70 const int kConsoleProcessCreated = 46;
71 const int kUserPrefsChanged = 47;
72 const int kHandleUnsavedChanges = 48;
73 const int kConsoleProcessPrompt = 49;
74 const int kHTMLPreviewStartedEvent = 51;
75 const int kHTMLPreviewOutputEvent = 52;
76 const int kHTMLPreviewCompletedEvent = 53;
77 const int kCompilePdfStartedEvent = 54;
78 const int kCompilePdfOutputEvent = 55;
79 const int kCompilePdfErrorsEvent = 56;
80 const int kCompilePdfCompletedEvent = 57;
81 const int kSynctexEditFile = 58;
82 const int kFindResult = 59;
83 const int kFindOperationEnded = 60;
84 const int kRPubsUploadStatus = 61;
85 const int kBuildStarted = 62;
86 const int kBuildOutput = 63;
87 const int kBuildCompleted = 64;
88 const int kBuildErrors = 65;
89 const int kDirectoryNavigate = 66;
90 const int kDeferredInitCompleted = 67;
91 const int kPlotsZoomSizeChanged = 68;
92 const int kSourceCppStarted = 69;
93 const int kSourceCppCompleted = 70;
94 const int kLoadedPackageUpdates = 71;
95 const int kActivatePane = 72;
96 const int kShowPresentationPane = 73;
97 const int kEnvironmentRefresh = 74;
98 const int kContextDepthChanged = 75;
99 const int kEnvironmentAssigned = 76;
100 const int kEnvironmentRemoved = 77;
101 const int kBrowserLineChanged = 78;
102 const int kPackageLoaded = 79;
103 const int kPackageUnloaded = 80;
104 const int kPresentationPaneRequestCompleted = 81;
105 const int kUnhandledError = 82;
106 const int kErrorHandlerChanged = 83;
107 const int kViewerNavigate = 84;
108 const int kSourceExtendedTypeDetected = 85;
109 const int kShinyViewer = 86;
110 const int kDebugSourceCompleted = 87;
111 const int kRmdRenderStarted = 88;
112 const int kRmdRenderOutput = 89;
113 const int kRmdRenderCompleted = 90;
114 const int kRmdTemplateDiscovered = 91;
115 const int kRmdTemplateDiscoveryCompleted = 92;
116 const int kRmdShinyDocStarted = 93;
117 const int kRmdRSConnectDeploymentOutput = 94;
118 const int kRmdRSConnectDeploymentCompleted = 95;
119 const int kUserPrompt = 96;
120 const int kInstallRtools = 97;
121 const int kInstallShiny = 98;
122 const int kSuspendAndRestart = 99;
123 const int kDataViewChanged = 100;
124 const int kViewFunction = 101;
125 const int kMarkersChanged = 102;
126 const int kEnableRStudioConnect = 103;
127 const int kUpdateGutterMarkers = 104;
128 const int kSnippetsChanged = 105;
129 const int kJumpToFunction = 106;
130 const int kCollabEditStarted = 107;
131 const int kSessionCountChanged = 108;
132 const int kCollabEditEnded = 109;
133 const int kProjectUsersChanged = 110;
134 const int kRVersionsChanged = 111;
135 const int kShinyGadgetDialog = 112;
136 const int kRmdParamsReady = 113;
137 const int kRegisterUserCommand = 114;
138 const int kRmdRSConnectDeploymentFailed = 115;
139 const int kSendToConsole = 119;
140 const int kUserFollowStarted = 120;
141 const int kUserFollowEnded = 121;
142 const int kProjectAccessRevoked = 122;
143 const int kCollabEditSaved = 123;
144 const int kAddinRegistryUpdated = 124;
145 const int kChunkOutput = 125;
146 const int kChunkOutputFinished = 126;
147 const int kRprofStarted = 127;
148 const int kRprofStopped = 128;
149 const int kRprofCreated = 129;
150 const int kEditorCommand = 131;
151 const int kPreviewRmd = 132;
152 const int kWebsiteFileSaved = 133;
153 const int kChunkPlotRefreshed = 134;
154 const int kChunkPlotRefreshFinished = 135;
155 const int kReloadWithLastChanceSave = 136;
156 const int kConnectionUpdated = 139;
157 const int kEnableConnections = 140;
158 const int kConnectionListChanged = 141;
159 const int kActiveConnectionsChanged = 142;
160 const int kConnectionOpened = 143;
161 const int kNotebookRangeExecuted = 144;
162 const int kChunkExecStateChanged = 145;
163 const int kNavigateShinyFrame = 146;
164 const int kUpdateNewConnectionDialog = 147;
165 const int kProjectTemplateRegistryUpdated = 148;
166 const int kTerminalSubprocs = 149;
167 const int kPackageExtensionIndexingCompleted = 150;
168 const int kRStudioAPIShowDialog = 151;
169 const int kRStudioAPIShowDialogCompleted = 152;
170 const int kObjectExplorerEvent = 153;
171 const int kSendToTerminal = 154;
172 const int kClearTerminal = 155;
173 const int kAddTerminal = 156;
174 const int kActivateTerminal = 157;
175 const int kTerminalCwd = 158;
176 const int kAdminNotification = 159;
177 const int kRequestDocumentSave = 160;
178 const int kRequestDocumentSaveCompleted = 161;
179 const int kRequestOpenProject = 162;
180 const int kOpenFileDialog = 163;
181 const int kRemoveTerminal = 164;
182 const int kShowPageViewerEvent = 165;
183 const int kAskSecret = 166;
184 const int kTestsStarted = 167;
185 const int kTestsOutput = 168;
186 const int kTestsCompleted = 169;
187 const int kJobUpdated = 170;
188 const int kJobRefresh = 171;
189 const int kJobOutput = 172;
190 const int kDataOutputCompleted = 173;
191 const int kNewDocumentWithCode = 174;
192 const int kPlumberViewer = 175;
193 const int kAvailablePackagesReady = 176;
194 const int kComputeThemeColors = 177;
195 const int kRequestDocumentClose = 178;
196 const int kRequestDocumentCloseCompleted = 179;
197 const int kExecuteAppCommand = 180;
198 const int kUserStateChanged = 181;
199 const int kHighlightUi = 182;
200 const int kReplaceResult = 183;
201 const int kReplaceUpdated = 184;
202 const int kTutorialCommand = 185;
203 const int kTutorialLaunch = 186;
204 const int kReticulateEvent = 187;
205 const int kEnvironmentChanged = 188;
206 const int kRStudioApiRequest = 189;
207 const int kDocumentCloseAllNoSave = 190;
208 const int kMemoryUsageChanged = 191;
209 const int kCommandCallbacksChanged = 192;
210 const int kConsoleActivate = 193;
211 const int kJobsActivate = 194;
212 }
213
init(int type,const json::Value & data)214 void ClientEvent::init(int type, const json::Value& data)
215 {
216 type_ = type;
217 data_ = data;
218 id_ = core::system::generateUuid();
219 }
220
asJsonObject(int id,json::Object * pObject) const221 void ClientEvent::asJsonObject(int id, json::Object* pObject) const
222 {
223 json::Object& object = *pObject;
224 object["id"] = id;
225 object["type"] = typeName();
226 object["data"] = data();
227 }
228
typeName() const229 std::string ClientEvent::typeName() const
230 {
231 switch (type_)
232 {
233 case client_events::kBusy:
234 return "busy";
235 case client_events::kConsolePrompt:
236 return "console_prompt";
237 case client_events::kConsoleWriteOutput:
238 return "console_output";
239 case client_events::kConsoleWriteError:
240 return "console_error";
241 case client_events::kShowErrorMessage:
242 return "show_error_message";
243 case client_events::kShowHelp:
244 return "show_help";
245 case client_events::kBrowseUrl:
246 return "browse_url";
247 case client_events::kShowEditor:
248 return "show_editor";
249 case client_events::kChooseFile:
250 return "choose_file";
251 case client_events::kAbendWarning:
252 return "abend_warning";
253 case client_events::kQuit:
254 return "quit";
255 case client_events::kSuicide:
256 return "suicide";
257 case client_events::kFileChanged:
258 return "file_changed";
259 case client_events::kWorkingDirChanged:
260 return "working_dir_changed";
261 case client_events::kPlotsStateChanged:
262 return "plots_state_changed";
263 case client_events::kPackageStatusChanged:
264 return "package_status_changed";
265 case client_events::kPackageStateChanged:
266 return "package_state_changed";
267 case client_events::kLocator:
268 return "locator";
269 case client_events::kConsoleResetHistory:
270 return "console_reset_history";
271 case client_events::kSessionSerialization:
272 return "session_serialization";
273 case client_events::kHistoryEntriesAdded:
274 return "history_entries_added";
275 case client_events::kQuotaStatus:
276 return "quota_status";
277 case client_events::kFileEdit:
278 return "file_edit";
279 case client_events::kShowContent:
280 return "show_content";
281 case client_events::kShowData:
282 return "show_data";
283 case client_events::kAsyncCompletion:
284 return "async_completion";
285 case client_events::kSaveActionChanged:
286 return "save_action_changed";
287 case client_events::kConsoleWritePrompt:
288 return "console_write_prompt";
289 case client_events::kConsoleWriteInput:
290 return "console_write_input";
291 case client_events::kShowWarningBar:
292 return "show_warning_bar";
293 case client_events::kOpenProjectError:
294 return "open_project_error";
295 case client_events::kVcsRefresh:
296 return "vcs_refresh";
297 case client_events::kAskPass:
298 return "ask_pass";
299 case client_events::kConsoleProcessOutput:
300 return "console_process_output";
301 case client_events::kConsoleProcessExit:
302 return "console_process_exit";
303 case client_events::kListChanged:
304 return "list_changed";
305 case client_events::kUserPrefsChanged:
306 return "user_prefs_changed";
307 case client_events::kHandleUnsavedChanges:
308 return "handle_unsaved_changes";
309 case client_events::kConsoleProcessPrompt:
310 return "console_process_prompt";
311 case client_events::kConsoleProcessCreated:
312 return "console_process_created";
313 case client_events::kHTMLPreviewStartedEvent:
314 return "html_preview_started_event";
315 case client_events::kHTMLPreviewOutputEvent:
316 return "html_preview_output_event";
317 case client_events::kHTMLPreviewCompletedEvent:
318 return "html_preview_completed_event";
319 case client_events::kCompilePdfStartedEvent:
320 return "compile_pdf_started_event";
321 case client_events::kCompilePdfOutputEvent:
322 return "compile_pdf_output_event";
323 case client_events::kCompilePdfErrorsEvent:
324 return "compile_pdf_errors_event";
325 case client_events::kCompilePdfCompletedEvent:
326 return "compile_pdf_completed_event";
327 case client_events::kSynctexEditFile:
328 return "synctex_edit_file";
329 case client_events::kFindResult:
330 return "find_result";
331 case client_events::kFindOperationEnded:
332 return "find_operation_ended";
333 case client_events::kRPubsUploadStatus:
334 return "rpubs_upload_status";
335 case client_events::kBuildStarted:
336 return "build_started";
337 case client_events::kBuildOutput:
338 return "build_output";
339 case client_events::kBuildCompleted:
340 return "build_completed";
341 case client_events::kBuildErrors:
342 return "build_errors";
343 case client_events::kDirectoryNavigate:
344 return "directory_navigate";
345 case client_events::kDeferredInitCompleted:
346 return "deferred_init_completed";
347 case client_events::kPlotsZoomSizeChanged:
348 return "plots_zoom_size_changed";
349 case client_events::kSourceCppStarted:
350 return "source_cpp_started";
351 case client_events::kSourceCppCompleted:
352 return "source_cpp_completed";
353 case client_events::kLoadedPackageUpdates:
354 return "loaded_package_updates";
355 case client_events::kActivatePane:
356 return "activate_pane";
357 case client_events::kShowPresentationPane:
358 return "show_presentation_pane";
359 case client_events::kEnvironmentRefresh:
360 return "environment_refresh";
361 case client_events::kContextDepthChanged:
362 return "context_depth_changed";
363 case client_events::kEnvironmentAssigned:
364 return "environment_assigned";
365 case client_events::kEnvironmentRemoved:
366 return "environment_removed";
367 case client_events::kBrowserLineChanged:
368 return "browser_line_changed";
369 case client_events::kPackageLoaded:
370 return "package_loaded";
371 case client_events::kPackageUnloaded:
372 return "package_unloaded";
373 case client_events::kPresentationPaneRequestCompleted:
374 return "presentation_pane_request_completed";
375 case client_events::kUnhandledError:
376 return "unhandled_error";
377 case client_events::kErrorHandlerChanged:
378 return "error_handler_changed";
379 case client_events::kViewerNavigate:
380 return "viewer_navigate";
381 case client_events::kSourceExtendedTypeDetected:
382 return "source_extended_type_detected";
383 case client_events::kShinyViewer:
384 return "shiny_viewer";
385 case client_events::kDebugSourceCompleted:
386 return "debug_source_completed";
387 case client_events::kRmdRenderStarted:
388 return "rmd_render_started";
389 case client_events::kRmdRenderOutput:
390 return "rmd_render_output";
391 case client_events::kRmdRenderCompleted:
392 return "rmd_render_completed";
393 case client_events::kRmdShinyDocStarted:
394 return "rmd_shiny_doc_started";
395 case client_events::kRmdRSConnectDeploymentOutput:
396 return "rsconnect_deployment_output";
397 case client_events::kRmdRSConnectDeploymentCompleted:
398 return "rsconnect_deployment_completed";
399 case client_events::kRmdRSConnectDeploymentFailed:
400 return "rsconnect_deployment_failed";
401 case client_events::kUserPrompt:
402 return "user_prompt";
403 case client_events::kInstallRtools:
404 return "install_r_tools";
405 case client_events::kInstallShiny:
406 return "install_shiny";
407 case client_events::kSuspendAndRestart:
408 return "suspend_and_restart";
409 case client_events::kDataViewChanged:
410 return "data_view_changed";
411 case client_events::kViewFunction:
412 return "view_function";
413 case client_events::kMarkersChanged:
414 return "markers_changed";
415 case client_events::kEnableRStudioConnect:
416 return "enable_rstudio_connect";
417 case client_events::kUpdateGutterMarkers:
418 return "update_gutter_markers";
419 case client_events::kSnippetsChanged:
420 return "snippets_changed";
421 case client_events::kJumpToFunction:
422 return "jump_to_function";
423 case client_events::kCollabEditStarted:
424 return "collab_edit_started";
425 case client_events::kSessionCountChanged:
426 return "session_count_changed";
427 case client_events::kCollabEditEnded:
428 return "collab_edit_ended";
429 case client_events::kProjectUsersChanged:
430 return "project_users_changed";
431 case client_events::kRVersionsChanged:
432 return "r_versions_changed";
433 case client_events::kShinyGadgetDialog:
434 return "shiny_gadget_dialog";
435 case client_events::kRmdParamsReady:
436 return "rmd_params_ready";
437 case client_events::kRegisterUserCommand:
438 return "register_user_command";
439 case client_events::kSendToConsole:
440 return "send_to_console";
441 case client_events::kUserFollowStarted:
442 return "user_follow_started";
443 case client_events::kUserFollowEnded:
444 return "user_follow_ended";
445 case client_events::kProjectAccessRevoked:
446 return "project_access_revoked";
447 case client_events::kCollabEditSaved:
448 return "collab_edit_saved";
449 case client_events::kAddinRegistryUpdated:
450 return "addin_registry_updated";
451 case client_events::kChunkOutput:
452 return "chunk_output";
453 case client_events::kChunkOutputFinished:
454 return "chunk_output_finished";
455 case client_events::kRprofStarted:
456 return "rprof_started";
457 case client_events::kRprofStopped:
458 return "rprof_stopped";
459 case client_events::kRprofCreated:
460 return "rprof_created";
461 case client_events::kEditorCommand:
462 return "editor_command";
463 case client_events::kPreviewRmd:
464 return "preview_rmd";
465 case client_events::kWebsiteFileSaved:
466 return "website_file_saved";
467 case client_events::kChunkPlotRefreshed:
468 return "chunk_plot_refreshed";
469 case client_events::kChunkPlotRefreshFinished:
470 return "chunk_plot_refresh_finished";
471 case client_events::kReloadWithLastChanceSave:
472 return "reload_with_last_chance_save";
473 case client_events::kConnectionUpdated:
474 return "connection_updated";
475 case client_events::kEnableConnections:
476 return "enable_connections";
477 case client_events::kConnectionListChanged:
478 return "connection_list_changed";
479 case client_events::kActiveConnectionsChanged:
480 return "active_connections_changed";
481 case client_events::kConnectionOpened:
482 return "connection_opened";
483 case client_events::kNotebookRangeExecuted:
484 return "notebook_range_executed";
485 case client_events::kChunkExecStateChanged:
486 return "chunk_exec_state_changed";
487 case client_events::kNavigateShinyFrame:
488 return "navigate_shiny_frame";
489 case client_events::kUpdateNewConnectionDialog:
490 return "update_new_connection_dialog";
491 case client_events::kProjectTemplateRegistryUpdated:
492 return "project_template_registry_updated";
493 case client_events::kTerminalSubprocs:
494 return "terminal_subprocs";
495 case client_events::kPackageExtensionIndexingCompleted:
496 return "package_extension_indexing_completed";
497 case client_events::kRStudioAPIShowDialog:
498 return "rstudioapi_show_dialog";
499 case client_events::kRStudioAPIShowDialogCompleted:
500 return "rstudioapi_show_dialog_completed";
501 case client_events::kObjectExplorerEvent:
502 return "object_explorer_event";
503 case client_events::kSendToTerminal:
504 return "send_to_terminal";
505 case client_events::kClearTerminal:
506 return "clear_terminal";
507 case client_events::kAddTerminal:
508 return "add_terminal";
509 case client_events::kActivateTerminal:
510 return "activate_terminal";
511 case client_events::kTerminalCwd:
512 return "terminal_cwd";
513 case client_events::kAdminNotification:
514 return "admin_notification";
515 case client_events::kRequestDocumentSave:
516 return "request_document_save";
517 case client_events::kRequestDocumentSaveCompleted:
518 return "request_document_save_completed";
519 case client_events::kRequestOpenProject:
520 return "request_open_project";
521 case client_events::kOpenFileDialog:
522 return "open_file_dialog";
523 case client_events::kRemoveTerminal:
524 return "remove_terminal";
525 case client_events::kShowPageViewerEvent:
526 return "show_page_viewer";
527 case client_events::kAskSecret:
528 return "ask_secret";
529 case client_events::kTestsStarted:
530 return "tests_started";
531 case client_events::kTestsOutput:
532 return "tests_output";
533 case client_events::kTestsCompleted:
534 return "tests_completed";
535 case client_events::kJobUpdated:
536 return "job_updated";
537 case client_events::kJobRefresh:
538 return "job_refresh";
539 case client_events::kJobOutput:
540 return "job_output";
541 case client_events::kDataOutputCompleted:
542 return "data_output_completed";
543 case client_events::kNewDocumentWithCode:
544 return "new_document_with_code";
545 case client_events::kAvailablePackagesReady:
546 return "available_packages_ready";
547 case client_events::kPlumberViewer:
548 return "plumber_viewer";
549 case client_events::kComputeThemeColors:
550 return "compute_theme_colors";
551 case client_events::kRequestDocumentClose:
552 return "request_document_close";
553 case client_events::kRequestDocumentCloseCompleted:
554 return "request_document_close_completed";
555 case client_events::kExecuteAppCommand:
556 return "execute_app_command";
557 case client_events::kUserStateChanged:
558 return "user_state_changed";
559 case client_events::kHighlightUi:
560 return "highlight_ui";
561 case client_events::kReplaceResult:
562 return "replace_result";
563 case client_events::kReplaceUpdated:
564 return "replace_updated";
565 case client_events::kTutorialCommand:
566 return "tutorial_command";
567 case client_events::kTutorialLaunch:
568 return "tutorial_launch";
569 case client_events::kReticulateEvent:
570 return "reticulate_event";
571 case client_events::kEnvironmentChanged:
572 return "environment_changed";
573 case client_events::kRStudioApiRequest:
574 return "rstudioapi_request";
575 case client_events::kDocumentCloseAllNoSave:
576 return "document_close_all_no_save";
577 case client_events::kMemoryUsageChanged:
578 return "memory_usage_changed";
579 case client_events::kCommandCallbacksChanged:
580 return "command_callbacks_changed";
581 case client_events::kConsoleActivate:
582 return "console_activate";
583 case client_events::kJobsActivate:
584 return "jobs_activate";
585 default:
586 LOG_WARNING_MESSAGE("unexpected event type: " +
587 safe_convert::numberToString(type_));
588 return "";
589 }
590 }
591
showEditorEvent(const std::string & content,bool isRCode,bool lineWrapping)592 ClientEvent showEditorEvent(const std::string& content,
593 bool isRCode,
594 bool lineWrapping)
595 {
596 json::Object data;
597 data["content"] = content;
598 data["is_r_code"] = isRCode;
599 data["line_wrapping"] = lineWrapping;
600 return ClientEvent(client_events::kShowEditor, data);
601 }
602
browseUrlEvent(const std::string & url,const std::string & window)603 ClientEvent browseUrlEvent(const std::string& url, const std::string& window)
604 {
605 json::Object browseURLInfo;
606 browseURLInfo["url"] = url;
607 browseURLInfo["window"] = window;
608 return ClientEvent(client_events::kBrowseUrl, browseURLInfo);
609 }
610
611
showErrorMessageEvent(const std::string & title,const std::string & message)612 ClientEvent showErrorMessageEvent(const std::string& title,
613 const std::string& message)
614 {
615 json::Object errorMessage;
616 errorMessage["title"] = title;
617 errorMessage["message"] = message;
618 return ClientEvent(client_events::kShowErrorMessage, errorMessage);
619 }
620
621
622
623
624 } // namespace session
625 } // namespace rstudio
626