diff --git a/build.gradle.kts b/build.gradle.kts index 06bc6b4a..6fda3852 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import java.util.* + plugins { java id("org.jetbrains.intellij") version "1.17.2" @@ -11,6 +13,29 @@ repositories { mavenCentral() } +tasks.register("updateProperties") { + doLast { + val projectVersion = version + val propertiesFile = file("src/main/resources/application.properties") + + if (propertiesFile.exists()) { + val properties = Properties().apply { + load(propertiesFile.inputStream()) + } + + properties.setProperty("version", projectVersion.toString()) + + properties.store(propertiesFile.outputStream(), null) + } else { + println("application.properties file not found!") + } + } +} + +tasks.named("buildPlugin") { + dependsOn("updateProperties") +} + dependencies { // Add the dependencies for the core module implementation("com.devoxx.genie:core:0.1.16") diff --git a/src/main/java/com/devoxx/genie/service/LLMProviderService.java b/src/main/java/com/devoxx/genie/service/LLMProviderService.java index 9cbe536a..5cffd28f 100644 --- a/src/main/java/com/devoxx/genie/service/LLMProviderService.java +++ b/src/main/java/com/devoxx/genie/service/LLMProviderService.java @@ -34,7 +34,6 @@ public static LLMProviderService getInstance() { return ApplicationManager.getApplication().getService(LLMProviderService.class); } - public List getAvailableLLMProviders() { DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); Map> providerKeyMap = new HashMap<>(); diff --git a/src/main/java/com/devoxx/genie/service/PropertiesService.java b/src/main/java/com/devoxx/genie/service/PropertiesService.java new file mode 100644 index 00000000..649438ad --- /dev/null +++ b/src/main/java/com/devoxx/genie/service/PropertiesService.java @@ -0,0 +1,38 @@ +package com.devoxx.genie.service; + +import com.intellij.openapi.application.ApplicationManager; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class PropertiesService { + + private final Properties properties = new Properties(); + + public PropertiesService() { + loadProperties(); + } + + @NotNull + public static PropertiesService getInstance() { + return ApplicationManager.getApplication().getService(PropertiesService.class); + } + + private void loadProperties() { + try (InputStream input = getClass().getClassLoader().getResourceAsStream("application.properties")) { + if (input == null) { + System.out.println("Sorry, unable to find application.properties"); + return; + } + properties.load(input); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + public String getVersion() { + return properties.getProperty("version"); + } +} diff --git a/src/main/java/com/devoxx/genie/ui/processor/FencedCodeBlockProcessor.java b/src/main/java/com/devoxx/genie/ui/processor/FencedCodeBlockProcessor.java index 9e735053..905c49ff 100644 --- a/src/main/java/com/devoxx/genie/ui/processor/FencedCodeBlockProcessor.java +++ b/src/main/java/com/devoxx/genie/ui/processor/FencedCodeBlockProcessor.java @@ -1,37 +1,28 @@ package com.devoxx.genie.ui.processor; import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.ui.component.JHoverButton; import com.devoxx.genie.ui.component.StyleSheetsFactory; -import com.devoxx.genie.ui.util.NotificationUtil; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.CaretModel; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; +import com.devoxx.genie.ui.util.CodeSnippetAction; import org.commonmark.node.FencedCodeBlock; import org.commonmark.renderer.html.HtmlRenderer; import javax.swing.*; import java.awt.*; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import static com.devoxx.genie.ui.util.DevoxxGenieColors.CODE_BG_COLOR; import static com.devoxx.genie.ui.util.DevoxxGenieColors.CODE_BORDER_BG_COLOR; -import static com.devoxx.genie.ui.util.DevoxxGenieIcons.CopyIcon; -import static com.devoxx.genie.ui.util.DevoxxGenieIcons.InsertCodeIcon; public class FencedCodeBlockProcessor implements NodeProcessor { private final ChatMessageContext chatMessageContext; private final FencedCodeBlock fencedCodeBlock; + private final CodeSnippetAction codeSnippetAction; public FencedCodeBlockProcessor(ChatMessageContext chatMessageContext, FencedCodeBlock fencedCodeBlock) { this.chatMessageContext = chatMessageContext; this.fencedCodeBlock = fencedCodeBlock; + this.codeSnippetAction = new CodeSnippetAction(chatMessageContext); } /** @@ -53,67 +44,8 @@ public JPanel process() { // Add components to the overlay panel in the correct order overlayPanel.add(editorPane, BorderLayout.CENTER); // Editor pane at the bottom - overlayPanel.add(createClipBoardButtonPanel(fencedCodeBlock, editorPane), BorderLayout.NORTH); // Button panel on top + overlayPanel.add(codeSnippetAction.createClipBoardButtonPanel(fencedCodeBlock), BorderLayout.NORTH); // Button panel on top return overlayPanel; } - - /** - * Add a clipboard button to the panel. - * - * @param fencedCodeBlock the fenced code block - */ - private JPanel createClipBoardButtonPanel(FencedCodeBlock fencedCodeBlock, JEditorPane editorPane) { - JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 2)); - buttonPanel.setOpaque(true); - buttonPanel.setVisible(true); - - JHoverButton copyButton = new JHoverButton(CopyIcon, true); - copyButton.setToolTipText("Copy to clipboard"); - copyButton.addActionListener(e -> copyToClipboard(fencedCodeBlock.getLiteral())); - copyButton.setVisible(true); - copyButton.setOpaque(true); - buttonPanel.add(copyButton); - - JHoverButton insertButton = new JHoverButton(InsertCodeIcon, true); - insertButton.setToolTipText("Insert code"); - insertButton.addActionListener(e -> insertCode(fencedCodeBlock.getLiteral())); - insertButton.setVisible(true); - insertButton.setOpaque(true); - buttonPanel.add(insertButton); - return buttonPanel; - } - - /** - * Copy the text to the clipboard. - * - * @param codeSnippet the code snippet to copy - */ - private void copyToClipboard(String codeSnippet) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(new StringSelection(codeSnippet), null); - NotificationUtil.sendNotification(chatMessageContext.getProject(), "Code copied to clipboard"); - } - - /** - * Insert the code snippet into the editor. - * - * @param codeSnippet the code snippet to insert - */ - private void insertCode(String codeSnippet) { - FileEditorManager fileEditorManager = FileEditorManager.getInstance(chatMessageContext.getProject()); - Editor selectedTextEditor = fileEditorManager.getSelectedTextEditor(); - Editor editor = fileEditorManager.getSelectedTextEditor(); - if (editor != null && selectedTextEditor != null) { - Document document = selectedTextEditor.getDocument(); - CaretModel caretModel = editor.getCaretModel(); - WriteCommandAction.runWriteCommandAction(chatMessageContext.getProject(), () -> { - try { - document.insertString(caretModel.getOffset(), codeSnippet.subSequence(0, codeSnippet.length())); - } catch (Exception e) { - Logger.getInstance(getClass()).error(e.getMessage()); - } - }); - } - } } diff --git a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java index 95151c93..f727c8a9 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java @@ -1,5 +1,6 @@ package com.devoxx.genie.ui.settings.llm; +import com.devoxx.genie.service.PropertiesService; import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.settings.SettingsComponent; import com.devoxx.genie.ui.util.NotificationUtil; @@ -22,6 +23,8 @@ public class LLMSettingsComponent implements SettingsComponent { public static final String LINK_EMOJI = "\uD83D\uDD17"; public static final String PASSWORD_EMOJI = "\uD83D\uDD11"; + @Getter + private final JTextField projectVersion = new JTextField(PropertiesService.getInstance().getVersion()); @Getter private final JTextField ollamaModelUrlField = new JTextField(stateService.getOllamaModelUrl()); @Getter @@ -101,6 +104,10 @@ public JPanel createSettingsPanel() { .addComponent(createTextWithPasswordButton(googleCSIApiKeyField, "https://programmablesearchengine.google.com/controlpanel/create")) .addComponent(new JLabel("Hide Search Providers")) .addComponent(hideSearchButtonsField) + .addVerticalGap(20) + .addComponent(new JXTitledSeparator("Plugin version")) + .addComponent(new JLabel("v" + projectVersion.getText())) + .addComponent(createTextWithLinkButton(new JLabel("View on GitHub"), "https://github.com/devoxx/DevoxxGenieIDEAPlugin")) .getPanel(); } diff --git a/src/main/java/com/devoxx/genie/ui/util/CodeSnippetAction.java b/src/main/java/com/devoxx/genie/ui/util/CodeSnippetAction.java new file mode 100644 index 00000000..32973325 --- /dev/null +++ b/src/main/java/com/devoxx/genie/ui/util/CodeSnippetAction.java @@ -0,0 +1,68 @@ +package com.devoxx.genie.ui.util; + +import com.devoxx.genie.model.request.ChatMessageContext; +import com.devoxx.genie.ui.component.JHoverButton; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import org.commonmark.node.FencedCodeBlock; + +import javax.swing.*; +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Clipboard; +import java.awt.Toolkit; + +import static com.devoxx.genie.ui.util.DevoxxGenieIcons.CopyIcon; +import static com.devoxx.genie.ui.util.DevoxxGenieIcons.InsertCodeIcon; + +public class CodeSnippetAction { + + private final ChatMessageContext chatMessageContext; + + public CodeSnippetAction(ChatMessageContext chatMessageContext) { + this.chatMessageContext = chatMessageContext; + } + + public JPanel createClipBoardButtonPanel(FencedCodeBlock fencedCodeBlock) { + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 2)); + buttonPanel.setOpaque(true); + + JHoverButton copyButton = new JHoverButton(CopyIcon, true); + copyButton.setToolTipText("Copy to clipboard"); + copyButton.addActionListener(e -> copyToClipboard(fencedCodeBlock.getLiteral())); + buttonPanel.add(copyButton); + + JHoverButton insertButton = new JHoverButton(InsertCodeIcon, true); + insertButton.setToolTipText("Insert code"); + insertButton.addActionListener(e -> insertCode(fencedCodeBlock.getLiteral())); + buttonPanel.add(insertButton); + + return buttonPanel; + } + + private void copyToClipboard(String codeSnippet) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(codeSnippet), null); + NotificationUtil.sendNotification(chatMessageContext.getProject(), "Code copied to clipboard"); + } + + private void insertCode(String codeSnippet) { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(chatMessageContext.getProject()); + Editor editor = fileEditorManager.getSelectedTextEditor(); + if (editor != null) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + WriteCommandAction.runWriteCommandAction(chatMessageContext.getProject(), () -> { + try { + document.insertString(caretModel.getOffset(), codeSnippet); + } catch (Exception e) { + Logger.getInstance(getClass()).error(e.getMessage()); + } + }); + } + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index e01fb3bf..7081bb3d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -231,6 +231,7 @@ + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..885cbd0d --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,2 @@ +#Tue Jun 25 13:55:28 CEST 2024 +version=0.1.20