Skip to content

Commit ef16240

Browse files
author
pkolovos
committed
implement chat gpt view with ask context menu option
1 parent d5bcaf5 commit ef16240

5 files changed

Lines changed: 192 additions & 3 deletions

File tree

src/main/java/gr/sqlbrowserfx/SqlBrowserFXApp.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,19 @@
7070
import javafx.scene.control.Tab;
7171
import javafx.scene.control.TabPane;
7272
import javafx.scene.control.TextField;
73+
import javafx.scene.input.Clipboard;
74+
import javafx.scene.input.ClipboardContent;
7375
import javafx.scene.input.KeyCode;
7476
import javafx.scene.input.KeyEvent;
77+
import javafx.scene.input.MouseButton;
78+
import javafx.scene.input.MouseEvent;
7579
import javafx.scene.layout.BorderPane;
7680
import javafx.scene.layout.HBox;
7781
import javafx.scene.layout.Priority;
7882
import javafx.scene.layout.VBox;
7983
import javafx.scene.text.Font;
8084
import javafx.scene.text.TextAlignment;
85+
import javafx.scene.web.WebView;
8186
import javafx.stage.DirectoryChooser;
8287
import javafx.stage.FileChooser;
8388
import javafx.stage.Stage;
@@ -458,6 +463,75 @@ private MenuBar createMenu(DockPane dockPane) {
458463
dockNode.dock(dockPane, DockPos.RIGHT);
459464
});
460465

466+
var chatGPTMenuItem = new MenuItem("Open ChatGPT", JavaFXUtils.createIcon("/icons/web.png"));
467+
chatGPTMenuItem.setOnAction(event -> {
468+
var webView = new WebView();
469+
var webEngine = webView.getEngine();
470+
// Force dark color scheme via CSS injection
471+
String darkModeCSS = """
472+
(function() {
473+
const style = document.createElement('style');
474+
style.textContent = `
475+
:root {
476+
color-scheme: dark;
477+
background-color: #222222 !important;
478+
color: #e0e0e0 !important;
479+
}
480+
html, body *:not(pre):not(pre *) {
481+
background-color: #222222 !important;
482+
color: #e0e0e0 !important;
483+
margin: 0 !important;
484+
485+
}
486+
`;
487+
document.documentElement.appendChild(style);
488+
})();
489+
""";
490+
491+
// Load ChatGPT and then apply dark mode styling
492+
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
493+
if (newState == javafx.concurrent.Worker.State.SUCCEEDED) {
494+
webEngine.executeScript(darkModeCSS);
495+
}
496+
});
497+
webEngine.load("https://chatgpt.com/");
498+
499+
var copySelectedHtmlText = new MenuItem("Copy Selected Text");
500+
copySelectedHtmlText.setOnAction(_ -> {
501+
var text = (String) webView.getEngine().executeScript("""
502+
(function() {
503+
let text = "";
504+
505+
if (window.getSelection) {
506+
text = window.getSelection().toString();
507+
} else if (document.selection && document.selection.type != "Control") {
508+
text = document.selection.createRange().text;
509+
}
510+
511+
return text;
512+
})();
513+
""");
514+
var clipboard = Clipboard.getSystemClipboard();
515+
var content = new ClipboardContent();
516+
content.putString(text);
517+
clipboard.setContent(content);
518+
});
519+
var contextMenu = new ContextMenu(copySelectedHtmlText);
520+
webView.setContextMenuEnabled(false); // disable native WebView menu
521+
webView.addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEvent -> {
522+
if (mouseEvent.getButton() == MouseButton.SECONDARY) { // right-click
523+
contextMenu.show(webView, mouseEvent.getScreenX(), mouseEvent.getScreenY());
524+
mouseEvent.consume(); // prevent default
525+
} else {
526+
contextMenu.hide();
527+
}
528+
});
529+
530+
SqlBrowserFXAppManager.setChatGptWebEngine(webEngine);
531+
new DockNode(dockPane, webView, "ChatGPT", JavaFXUtils.createIcon("/icons/web.png"));
532+
533+
});
534+
461535
var jsonTableViewItem = new MenuItem("Open JSON Table View", JavaFXUtils.createIcon("/icons/web.png"));
462536
jsonTableViewItem.setOnAction(event -> {
463537
var jsonTableView = this.createJsonTableView();
@@ -490,7 +564,7 @@ private MenuBar createMenu(DockPane dockPane) {
490564

491565
menu1.getItems().addAll(sqlPaneViewItem, dbDiagramItem, new SeparatorMenuItem(),
492566
filesTreeViewItem, jsonTableViewItem, new SeparatorMenuItem(),
493-
sqlConsoleViewItem, logItem);
567+
sqlConsoleViewItem, logItem, chatGPTMenuItem);
494568

495569
final var menu2 = new Menu("Restful Service", JavaFXUtils.createIcon("/icons/web.png"));
496570
var restServiceStartItem = new MenuItem("Start Restful Service", JavaFXUtils.createIcon("/icons/play.png"));

src/main/java/gr/sqlbrowserfx/SqlBrowserFXAppManager.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import gr.sqlbrowserfx.dock.nodes.DSqlConsolePane;
1212
import gr.sqlbrowserfx.dock.nodes.DSqlPane;
1313
import gr.sqlbrowserfx.nodes.sqlpane.SqlPane;
14+
import javafx.scene.web.WebEngine;
1415

1516
public class SqlBrowserFXAppManager {
1617

@@ -21,6 +22,7 @@ public class SqlBrowserFXAppManager {
2122
private static final List<SqlPane> SQL_PANES = new ArrayList<>();
2223
private static final List<DDBTreeView> DB_TREE_VIEWS = new ArrayList<>();
2324
private static String DB_TYPE = "sqlite";
25+
private static WebEngine chatGptWebEngine;
2426

2527
public static SqlConnector getConfigSqlConnector() {
2628
return SQL_CONNECTOR;
@@ -79,4 +81,27 @@ public static void registerDDBTreeView(DDBTreeView treeView) {
7981
public static void unregisterDDBTreeView(DDBTreeView treeView) {
8082
DB_TREE_VIEWS.remove(treeView);
8183
}
84+
85+
public static void setChatGptWebEngine(WebEngine webEngine) {
86+
chatGptWebEngine = webEngine;
87+
}
88+
89+
public static void askChatGpt(String question) {
90+
String safeText = question.replace("\\", "\\\\").replace("\"", "\\\"")
91+
.replace("\n", "\\n").replace("\r", "");
92+
93+
String js = """
94+
(function() {
95+
const el = document.getElementById('prompt-textarea');
96+
el.innerText = "%s";
97+
setTimeout(() => {
98+
const btn = document.getElementById('composer-submit-button');
99+
btn.click();
100+
}, 500);
101+
102+
})();
103+
""".formatted(safeText);
104+
105+
chatGptWebEngine.executeScript(js);
106+
}
82107
}

src/main/java/gr/sqlbrowserfx/nodes/codeareas/AutoCompleteCodeArea.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.fxmisc.wellbehaved.event.InputMap;
2222
import org.fxmisc.wellbehaved.event.Nodes;
2323

24+
import gr.sqlbrowserfx.SqlBrowserFXAppManager;
2425
import gr.sqlbrowserfx.factories.DialogFactory;
2526
import gr.sqlbrowserfx.nodes.ContextMenuOwner;
2627
import gr.sqlbrowserfx.nodes.InputMapOwner;
@@ -328,6 +329,12 @@ public ContextMenu createContextMenu() {
328329

329330
var menuItemSuggestions = new MenuItem("Suggestions", JavaFXUtils.createIcon("/icons/suggestion.png"));
330331
menuItemSuggestions.setOnAction(event -> this.autoCompleteAction(this.simulateControlSpaceEvent()));
332+
333+
var menuItemAskChatGpt = new MenuItem("Ask ChatGpt", JavaFXUtils.createIcon("/icons/suggestion.png"));
334+
menuItemAskChatGpt.setOnAction(event -> {
335+
SqlBrowserFXAppManager.askChatGpt("Check fllowing sql code for errors, keep your answer short with mainly code examples: " + (this.getSelectedText() != null ? this.getSelectedText() : this.getText().toString()));
336+
});
337+
331338

332339
var menuItemSearchAndReplace = new MenuItem("Search...", JavaFXUtils.createIcon("/icons/magnify.png"));
333340
menuItemSearchAndReplace.setOnAction(action -> this.showSearchAndReplacePopup());
@@ -374,7 +381,7 @@ public ContextMenu createContextMenu() {
374381
new SeparatorMenuItem(),
375382
menuItemFormat, menuItemFormat3,
376383
new SeparatorMenuItem(),
377-
menuItemSearchAndReplace, menuItemGoToLine, menuItemSuggestions,
384+
menuItemSearchAndReplace, menuItemGoToLine, menuItemSuggestions, menuItemAskChatGpt,
378385
new SeparatorMenuItem(),
379386
menuItemSaveAs);
380387
return menu;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package sqlbrowserfx;
2+
3+
import java.io.IOException;
4+
5+
import gr.sqlbrowserfx.nodes.codeareas.java.JavaCodeArea;
6+
import javafx.application.Application;
7+
import javafx.scene.Scene;
8+
import javafx.scene.control.Button;
9+
import javafx.scene.control.ScrollPane;
10+
import javafx.scene.layout.VBox;
11+
import javafx.scene.web.WebView;
12+
import javafx.stage.Stage;
13+
14+
public class ChatGptWebViewTestGui extends Application {
15+
16+
@Override
17+
public void start(Stage primaryStage) throws IOException {
18+
var webView = new WebView();
19+
var webEngine = webView.getEngine();
20+
// Force dark color scheme via CSS injection
21+
String darkModeCSS = """
22+
(function() {
23+
const style = document.createElement('style');
24+
style.textContent = `
25+
:root {
26+
color-scheme: dark;
27+
background-color: #222222 !important;
28+
color: #e0e0e0 !important;
29+
}
30+
html, body *:not(pre):not(pre *) {
31+
background-color: #222222 !important;
32+
color: #e0e0e0 !important;
33+
margin: 0 !important;
34+
35+
}
36+
`;
37+
document.documentElement.appendChild(style);
38+
})();
39+
""";
40+
41+
// Load ChatGPT and then apply dark mode styling
42+
webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
43+
if (newState == javafx.concurrent.Worker.State.SUCCEEDED) {
44+
webEngine.executeScript(darkModeCSS);
45+
}
46+
});
47+
webEngine.load("https://chatgpt.com/");
48+
49+
var pasteButton = new Button("test");
50+
pasteButton.setOnAction(event -> {
51+
String safeText = "This is a test text pasted from java"
52+
.replace("\\", "\\\\")
53+
.replace("\"", "\\\"")
54+
.replace("\n", "\\n")
55+
.replace("\r", "");
56+
57+
String js = """
58+
(function() {
59+
const el = document.getElementById('prompt-textarea');
60+
el.innerText = "%s";
61+
setTimeout(() => {
62+
const btn = document.getElementById('composer-submit-button');
63+
btn.click();
64+
}, 500);
65+
66+
})();
67+
""".formatted(safeText);
68+
69+
webEngine.executeScript(js);
70+
});
71+
Scene scene = new Scene(
72+
new VBox(pasteButton, webView)
73+
);
74+
scene.getStylesheets().add("/styles/flat-dark.css");
75+
primaryStage.setScene(scene);
76+
primaryStage.show();
77+
}
78+
79+
public static void main(String[] args) {
80+
launch(args);
81+
}
82+
83+
}

src/test/java/sqlbrowserfx/GuiTestStarter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public class GuiTestStarter {
44

55
public static void main(String[] args) {
6-
SqlPaneTestGui.main(args);
6+
ChatGptWebViewTestGui.main(args);
77
}
88

99
}

0 commit comments

Comments
 (0)