mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-08 18:31:19 +00:00
Ability to edit generated code (#220)
* Ability to edit generated code inside the chat toolwindow * Improve icon behaviour * Fix browseFolderListener automatic disposal by recreating the inputs on each action * Replace label
This commit is contained in:
parent
d05f7d4583
commit
7ff48dc928
5 changed files with 96 additions and 58 deletions
|
|
@ -17,7 +17,7 @@ public class DeleteConversationAction extends AnAction {
|
|||
private final Runnable onDelete;
|
||||
|
||||
public DeleteConversationAction(Runnable onDelete) {
|
||||
super("Delete Conversation", "Delete single conversation", AllIcons.General.Remove);
|
||||
super("Delete Conversation", "Delete single conversation", AllIcons.Actions.GC);
|
||||
this.onDelete = onDelete;
|
||||
EditorActionsUtil.registerOrReplaceAction(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ import com.intellij.openapi.actionSystem.ActionToolbar;
|
|||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import javax.swing.Icon;
|
||||
|
||||
public class IconActionButton extends ActionButton {
|
||||
|
||||
public IconActionButton(String tooltipText, Icon icon, AnAction onAction) {
|
||||
super(onAction,
|
||||
getPresentation(tooltipText, icon),
|
||||
public IconActionButton(AnAction action) {
|
||||
super(action,
|
||||
getPresentation(action),
|
||||
ActionPlaces.TOOLWINDOW_CONTENT,
|
||||
ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE);
|
||||
}
|
||||
|
||||
private static Presentation getPresentation(String tooltipText, Icon icon) {
|
||||
var presentation = new Presentation(tooltipText);
|
||||
presentation.setIcon(icon);
|
||||
private static Presentation getPresentation(AnAction action) {
|
||||
var actionPresentation = action.getTemplatePresentation();
|
||||
var presentation = new Presentation(actionPresentation.getText());
|
||||
presentation.setIcon(actionPresentation.getIcon());
|
||||
return presentation;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat;
|
||||
|
||||
import static com.intellij.openapi.ui.DialogWrapper.OK_EXIT_CODE;
|
||||
import static ee.carlrobert.codegpt.util.FileUtils.findFileNameExtensionMapping;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.icons.AllIcons.Actions;
|
||||
import com.intellij.ide.util.EditorHelper;
|
||||
import com.intellij.openapi.Disposable;
|
||||
|
|
@ -69,7 +70,7 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
var timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
|
||||
var fileName = "temp_" + timestamp + fileNameExtensionMapping.getValue();
|
||||
var lightVirtualFile = new LightVirtualFile(
|
||||
String.format("%s/%s", PathManager.getTempPath(), fileName), code);
|
||||
format("%s/%s", PathManager.getTempPath(), fileName), code);
|
||||
var document = FileDocumentManager.getInstance().getDocument(lightVirtualFile);
|
||||
if (document == null) {
|
||||
document = EditorFactory.getInstance().createDocument(code);
|
||||
|
|
@ -87,7 +88,7 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
|
||||
String originalGroupId = ((EditorEx) editor).getContextMenuGroupId();
|
||||
if (originalGroupId != null) {
|
||||
AnAction originalGroup = ActionManager.getInstance().getAction(originalGroupId);
|
||||
AnAction originalGroup = ActionManager.getInstance().getAction(originalGroupId);
|
||||
if (originalGroup instanceof ActionGroup) {
|
||||
group.addAll(((ActionGroup) originalGroup).getChildren(null));
|
||||
}
|
||||
|
|
@ -130,14 +131,13 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
|
||||
private JPanel createHeaderActions() {
|
||||
var wrapper = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
wrapper.add(new IconActionButton("New File", Actions.AddFile, new NewFileAction()));
|
||||
wrapper.add(new IconActionButton(new EditAction()));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton("Copy", AllIcons.Actions.Copy, new CopyAction()));
|
||||
wrapper.add(new IconActionButton(new NewFileAction()));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton(
|
||||
"Replace in Main Editor",
|
||||
AllIcons.Actions.Replace,
|
||||
new ReplaceInMainEditorAction()));
|
||||
wrapper.add(new IconActionButton(new CopyAction()));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton(new ReplaceInMainEditorAction()));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
|
@ -146,25 +146,49 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
}
|
||||
|
||||
class EditAction extends AnAction {
|
||||
|
||||
EditAction() {
|
||||
super("Edit Source", "Edit Source description", Actions.EditSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent event) {
|
||||
var editorEx = ((EditorEx) editor);
|
||||
editorEx.setViewer(!editorEx.isViewer());
|
||||
|
||||
var viewer = editorEx.isViewer();
|
||||
editorEx.setCaretVisible(!viewer);
|
||||
editorEx.setCaretEnabled(!viewer);
|
||||
|
||||
var settings = editorEx.getSettings();
|
||||
settings.setCaretRowShown(!viewer);
|
||||
|
||||
event.getPresentation().setIcon(viewer ? Actions.EditSource : Actions.Show);
|
||||
event.getPresentation().setText(viewer ? "Edit Source" : "Disable Editing");
|
||||
|
||||
var locationOnScreen = ((MouseEvent) event.getInputEvent()).getLocationOnScreen();
|
||||
locationOnScreen.y = locationOnScreen.y - 16;
|
||||
}
|
||||
}
|
||||
|
||||
class NewFileAction extends AnAction {
|
||||
|
||||
private final TextFieldWithBrowseButton textFieldWithBrowseButton;
|
||||
private final JBTextField fileNameTextField;
|
||||
|
||||
NewFileAction() {
|
||||
var fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
|
||||
fileChooserDescriptor.setForcedToUseIdeaFileChooser(true);
|
||||
|
||||
textFieldWithBrowseButton = new TextFieldWithBrowseButton();
|
||||
textFieldWithBrowseButton.addBrowseFolderListener(
|
||||
new TextBrowseFolderListener(fileChooserDescriptor, project));
|
||||
fileNameTextField = new JBTextField("Untitled" + fileNameExtensionMapping.getValue());
|
||||
fileNameTextField.setColumns(30);
|
||||
super("New File", "New File description", Actions.AddFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
if (getDialogBuilder().show() == 0) {
|
||||
var fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
|
||||
fileChooserDescriptor.setForcedToUseIdeaFileChooser(true);
|
||||
var textFieldWithBrowseButton = new TextFieldWithBrowseButton();
|
||||
textFieldWithBrowseButton.addBrowseFolderListener(
|
||||
new TextBrowseFolderListener(fileChooserDescriptor, project));
|
||||
var fileNameTextField = new JBTextField("Untitled" + fileNameExtensionMapping.getValue());
|
||||
fileNameTextField.setColumns(30);
|
||||
|
||||
if (showDialog(textFieldWithBrowseButton, fileNameTextField) == OK_EXIT_CODE) {
|
||||
var file = FileUtils.createFile(
|
||||
textFieldWithBrowseButton.getText(),
|
||||
fileNameTextField.getText(),
|
||||
|
|
@ -182,21 +206,27 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private DialogBuilder getDialogBuilder() {
|
||||
var dialogBuilder = new DialogBuilder(project);
|
||||
dialogBuilder.setTitle("New File");
|
||||
dialogBuilder.setCenterPanel(FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("File name:", fileNameTextField)
|
||||
.addLabeledComponent("Destination:", textFieldWithBrowseButton)
|
||||
.getPanel());
|
||||
private int showDialog(
|
||||
TextFieldWithBrowseButton textFieldWithBrowseButton,
|
||||
JBTextField fileNameTextField) {
|
||||
var dialogBuilder = new DialogBuilder(project)
|
||||
.title("New File")
|
||||
.centerPanel(FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("File name:", fileNameTextField)
|
||||
.addLabeledComponent("Destination:", textFieldWithBrowseButton)
|
||||
.getPanel());
|
||||
dialogBuilder.addOkAction();
|
||||
dialogBuilder.addCancelAction();
|
||||
return dialogBuilder;
|
||||
return dialogBuilder.show();
|
||||
}
|
||||
}
|
||||
|
||||
class CopyAction extends AnAction {
|
||||
|
||||
CopyAction() {
|
||||
super("Copy", "Copy description", Actions.Copy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent event) {
|
||||
StringSelection stringSelection = new StringSelection(editor.getDocument().getText());
|
||||
|
|
@ -212,6 +242,10 @@ public class ChatToolWindowTabPanelEditor implements Disposable {
|
|||
|
||||
class ReplaceInMainEditorAction extends AnAction {
|
||||
|
||||
ReplaceInMainEditorAction() {
|
||||
super("Replace in Main Editor", "Replace in Main Editor description", Actions.Replace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent event) {
|
||||
var project = event.getProject();
|
||||
|
|
|
|||
|
|
@ -82,22 +82,24 @@ public class ResponsePanel extends JPanel {
|
|||
}
|
||||
|
||||
public void addReloadAction(Runnable onReload) {
|
||||
addIconActionButton(new IconActionButton("Reload response", Actions.Refresh, new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
enableActions(false);
|
||||
onReload.run();
|
||||
}
|
||||
}));
|
||||
addIconActionButton(new IconActionButton(
|
||||
new AnAction("Reload Response", "Reload response description", Actions.Refresh) {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
enableActions(false);
|
||||
onReload.run();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public void addDeleteAction(Runnable onDelete) {
|
||||
addIconActionButton(new IconActionButton("Delete response", Actions.GC, new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
onDelete.run();
|
||||
}
|
||||
}));
|
||||
addIconActionButton(new IconActionButton(
|
||||
new AnAction("Delete Response", "Delete response description", Actions.GC) {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
onDelete.run();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void addIconActionButton(IconActionButton iconActionButton) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package ee.carlrobert.codegpt.toolwindow.conversations;
|
|||
|
||||
import static ee.carlrobert.codegpt.util.ThemeUtils.getPanelBackgroundColor;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
|
|
@ -17,28 +16,29 @@ import ee.carlrobert.codegpt.toolwindow.ModelIconLabel;
|
|||
import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class ConversationPanel extends JPanel {
|
||||
|
||||
ConversationPanel(@NotNull Project project, @NotNull Conversation conversation, @NotNull Runnable onDelete) {
|
||||
ConversationPanel(
|
||||
@NotNull Project project,
|
||||
@NotNull Conversation conversation,
|
||||
@NotNull Runnable onDelete) {
|
||||
super(new BorderLayout());
|
||||
setBackground(JBColor.background());
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
SettingsState.getInstance().sync(conversation);
|
||||
project.getService(StandardChatToolWindowContentManager.class).displayConversation(conversation);
|
||||
project.getService(StandardChatToolWindowContentManager.class)
|
||||
.displayConversation(conversation);
|
||||
}
|
||||
});
|
||||
addStyles(isSelected(conversation));
|
||||
|
|
@ -84,14 +84,16 @@ class ConversationPanel extends JPanel {
|
|||
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 0;
|
||||
headerPanel.add(new IconActionButton("Delete conversation", AllIcons.Actions.GC, new DeleteConversationAction(onDelete)), gbc);
|
||||
headerPanel.add(new IconActionButton(new DeleteConversationAction(onDelete)), gbc);
|
||||
|
||||
var bottomPanel = new JPanel(new BorderLayout());
|
||||
bottomPanel.setBackground(getPanelBackgroundColor());
|
||||
bottomPanel.add(new JLabel(conversation.getUpdatedOn()
|
||||
.format(DateTimeFormatter.ofPattern("M/d/yyyy, h:mm:ss a"))), BorderLayout.WEST);
|
||||
if (conversation.getModel() != null) {
|
||||
bottomPanel.add(new ModelIconLabel(conversation.getClientCode(), conversation.getModel()), BorderLayout.EAST);
|
||||
bottomPanel.add(
|
||||
new ModelIconLabel(conversation.getClientCode(), conversation.getModel()),
|
||||
BorderLayout.EAST);
|
||||
}
|
||||
|
||||
var textPanel = new JPanel(new BorderLayout());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue