Java tutorial
/* * Copyright 2015 Ritesh Kapoor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ritesh.idea.plugin.ui.toolswindow.reviewpanel; import com.intellij.icons.AllIcons; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffRequest; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.SimpleContentRevision; import com.intellij.ui.GuiUtils; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.table.JBTable; import com.ritesh.idea.plugin.reviewboard.Review; import com.ritesh.idea.plugin.reviewboard.ReviewDataProvider; import com.ritesh.idea.plugin.state.SettingsPage; import com.ritesh.idea.plugin.ui.Icons; import com.ritesh.idea.plugin.ui.action.CustomComponentActionBase; import com.ritesh.idea.plugin.ui.diff.CommentsDiffTool; import com.ritesh.idea.plugin.ui.diff.ReviewDiffRequest; import com.ritesh.idea.plugin.ui.panels.DraftReviewPanel; import com.ritesh.idea.plugin.ui.toolswindow.ReviewChangesTreeList; import com.ritesh.idea.plugin.ui.toolswindow.ReviewTableModel; import com.ritesh.idea.plugin.ui.toolswindow.reviewpanel.ReviewPanelController.ReviewListFilter; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import static com.intellij.openapi.util.text.StringUtil.join; /** * @author Ritesh */ public class ReviewsPanel extends JPanel { // reviewListActionGroup.add(new DoNothingAction(TextFieldWithAutoCompletion.create(project, Arrays.asList("asd", "Asd"), true, null))); // Messages.showWarningDialog("Svn is still in refresh. Please try again later.", "Alter"); // TODO: Check for binary files private JBTable reviewsTable = new JBTable(); private ReviewChangesTreeList changesTree; private ComboBox statusComboBox = new ComboBox(new String[] { "all", "discarded", "pending", "submitted" }); private ComboBox repositoryComboBox = new ComboBox(new String[] { "Select Repository" }); private JBLabel page = new JBLabel(); private JComponent mainReviewToolbar; final Logger LOG = Logger.getInstance(ReviewsPanel.class); private ReviewPanelController controller; private final Project project; public ReviewsPanel(final Project project) { this.project = project; this.controller = new ReviewPanelController(project, this); initUI(); } public void setReviewsList(final int pageNumber, final List<Review> reviews) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { reviewsTable.setModel(new ReviewTableModel(reviews)); reviewsTable.getColumnModel().getColumn(ReviewTableModel.Columns.SUMMARY.getIndex()) .setPreferredWidth(400); reviewsTable.getColumnModel().getColumn(ReviewTableModel.Columns.SUBMITTED_TO.getIndex()) .setPreferredWidth(50); reviewsTable.getColumnModel().getColumn(ReviewTableModel.Columns.SUBMITTER.getIndex()) .setPreferredWidth(50); reviewsTable.getColumnModel().getColumn(ReviewTableModel.Columns.LAST_MODIFIED.getIndex()) .setPreferredWidth(50); page.setText(String.valueOf(pageNumber)); GuiUtils.enableChildren(true, ReviewsPanel.this); } }); } public void setCurrentReview(List<Review.File> files) { final List<Change> changes = new ArrayList<>(); for (Review.File file : files) { FilePath srcFilePath; FilePath patchFilePath; try { Class<?> aClass = Class.forName("com.intellij.openapi.vcs.LocalFilePath"); srcFilePath = (FilePath) aClass.getDeclaredConstructor(String.class, boolean.class) .newInstance(file.srcFileName, false); patchFilePath = (FilePath) aClass.getDeclaredConstructor(String.class, boolean.class) .newInstance(file.dstFileName, false); } catch (Exception e) { try { srcFilePath = (FilePath) Class.forName("com.intellij.openapi.vcs.FilePathImpl") .getDeclaredMethod("createNonLocal", String.class, boolean.class) .invoke(null, file.srcFileName, false); patchFilePath = (FilePath) Class.forName("com.intellij.openapi.vcs.FilePathImpl") .getDeclaredMethod("createNonLocal", String.class, boolean.class) .invoke(null, file.dstFileName, false); } catch (Exception e1) { throw new RuntimeException(e1); } } SimpleContentRevision original = new SimpleContentRevision(file.srcFileContents, srcFilePath, file.sourceRevision); SimpleContentRevision patched = new SimpleContentRevision(file.dstFileContents, patchFilePath, "New Change"); changes.add(new Change(original, patched)); } ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { changesTree.setChangesToDisplay(changes); GuiUtils.enableChildren(true, ReviewsPanel.this); } }); } public void updateRepositories(final List<String> repositories, final String defaultRepository) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { repositoryComboBox.removeAllItems(); repositoryComboBox.addItem("Select Repository"); repositoryComboBox.setSelectedIndex(0); for (String repository : repositories) { repositoryComboBox.addItem(repository); } if (defaultRepository == null) { repositoryComboBox.setSelectedIndex(0); } else { repositoryComboBox.setSelectedItem(defaultRepository); } repositoryComboBox.setEnabled(true); } }); } //TODO remove join private void draftReview() { Review selectedReview = controller.selectedReview(); if (selectedReview != null) { final DraftReviewPanel reviewPanel = new DraftReviewPanel(project, "Update Review Request", selectedReview.summary, selectedReview.description, join(selectedReview.targetPeople, ","), join(selectedReview.targetGroups, ","), selectedReview.respository); if (reviewPanel.showAndGet()) { controller.updateReviewRequest(selectedReview, reviewPanel.getSummary(), reviewPanel.getDescription(), reviewPanel.getTargetPeople(), reviewPanel.getTargetGroup()); } } } public void enablePanel(final boolean enable) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { GuiUtils.enableChildren(ReviewsPanel.this, enable, mainReviewToolbar); } }); } private void loadFileComments() { final Change selectedChange = changesTree.getSelectedChanges().get(0); List<Review.File> selectedFiles = controller.selectedFiles(); for (Review.File file : selectedFiles) { if (file.srcFileName.equals(selectedChange.getBeforeRevision().getFile().getPath())) { controller.loadComments(file); break; } } } public void showCommentsDiff(final Review.File file, final List<Review.File.Comment> comments) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { final Change selectedChange = changesTree.getSelectedChanges().get(0); DiffRequest request = new ReviewDiffRequest(project, selectedChange); final CommentsDiffTool commentsDiffTool = new CommentsDiffTool(file, comments); commentsDiffTool.setActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.updateNewComments(file, commentsDiffTool.getNewComments()); } }); commentsDiffTool.show(request); } }); } private int getSelectedReviewIndex() { return reviewsTable.getSelectedRow(); } @SuppressWarnings("unchecked") private void initUI() { setLayout(new BorderLayout()); changesTree = new ReviewChangesTreeList(project, new ArrayList()); mainReviewToolbar = createMainReviewToolbar(); JPanel reviewsListPanel = new JPanel(new BorderLayout()); JPanel toolbarGroup = new JPanel(new BorderLayout()); toolbarGroup.add(mainReviewToolbar, BorderLayout.WEST); toolbarGroup.add(createReviewListToolbar(), BorderLayout.CENTER); reviewsListPanel.add(toolbarGroup, BorderLayout.PAGE_START); reviewsListPanel.add(new JBScrollPane(reviewsTable), BorderLayout.CENTER); JPanel diffPanel = new JPanel(new BorderLayout()); diffPanel.add(createDiffPanelToolbar(), BorderLayout.PAGE_START); diffPanel.add(changesTree, BorderLayout.CENTER); Splitter splitter = new Splitter(false, 0.7f); splitter.setFirstComponent(reviewsListPanel); splitter.setSecondComponent(diffPanel); add(splitter); reviewsTable.setRowHeight(20); reviewsTable.setShowGrid(false); reviewsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting() || getSelectedReviewIndex() < 0) return; controller.selectedReviewChanged(getSelectedReviewIndex()); } }); statusComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.statusChanged((String) statusComboBox.getSelectedItem()); } }); repositoryComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.repositoryChanged((String) repositoryComboBox.getSelectedItem()); } }); changesTree.setDoubleClickHandler(new Runnable() { @Override public void run() { loadFileComments(); } }); new AnAction() { @Override public void actionPerformed(AnActionEvent anActionEvent) { loadFileComments(); } }.registerCustomShortcutSet(new CustomShortcutSet(CommonShortcuts.getDiff().getShortcuts()), changesTree); // Trigger to load reviews statusComboBox.setSelectedIndex(0); repositoryComboBox.setEnabled(false); controller.loadRepositories(null); } private void refreshPanel() { repositoryComboBox.setEnabled(false); controller.loadRepositories((String) repositoryComboBox.getSelectedItem()); controller.refreshReviews(); } private JComponent createMainReviewToolbar() { DefaultActionGroup actionGroup = new DefaultActionGroup("ReviewBoardMainActionsGroup", false); actionGroup.add(new AnAction("Refresh reviews", "Refresh reviews", AllIcons.Actions.Refresh) { @Override public void actionPerformed(AnActionEvent anActionEvent) { refreshPanel(); } }); actionGroup.add(new AnAction("Browse", "Open the selected review in browser", AllIcons.General.Web) { @Override public void actionPerformed(AnActionEvent anActionEvent) { if (controller.selectedReview() == null) BrowserUtil.browse(ReviewDataProvider.getInstance(project).reviewBoardUrl(project)); else BrowserUtil.browse(ReviewDataProvider.getInstance(project).reviewUrl(project, controller.selectedReview())); } }); actionGroup.add(new AnAction("Settings", "Open review board settings", AllIcons.General.Settings) { @Override public void actionPerformed(AnActionEvent anActionEvent) { ShowSettingsUtil.getInstance().showSettingsDialog(project, SettingsPage.SETTINGS_DISPLAY_NAME); } }); return ActionManager.getInstance().createActionToolbar("ReviewBoardMainActionsGroup", actionGroup, true) .getComponent(); } private JComponent createDiffPanelToolbar() { DefaultActionGroup actionGroup = new DefaultActionGroup("ReviewBoardDiffActionsGroup", false); actionGroup.add(new AnAction("Refresh", "Refresh", AllIcons.Actions.Refresh) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.loadSelectedReview(); } }); actionGroup.addAction( new AnAction("Publish Review", "Publish comments and changes to server", AllIcons.Actions.Export) { @Override public void actionPerformed(AnActionEvent anActionEvent) { if (controller.commentsAvailableForPublish()) { final String reviewComment = Messages.showInputDialog(project, "Review Comment", "Review Comment", null); if (reviewComment != null) { controller.publishReview(reviewComment); } } } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.commentsAvailableForPublish()); } }); actionGroup.add(new Separator()); actionGroup.addAll(changesTree.getTreeActions()); return ActionManager.getInstance().createActionToolbar("ReviewBoardDiffActionGroup", actionGroup, true) .getComponent(); } private JComponent createReviewListToolbar() { DefaultActionGroup actionGroup = new DefaultActionGroup("ReviewBoardListActionGroup", false); actionGroup.add(new Separator()); actionGroup.add(new CustomComponentActionBase(new JBLabel("Status : "))); actionGroup.add(new CustomComponentActionBase(statusComboBox)); actionGroup.add(new Separator()); actionGroup.add(new CustomComponentActionBase(repositoryComboBox)); actionGroup.add(new Separator()); actionGroup.add(new ToggleAction("Incoming", "Show incoming reviews", AllIcons.Ide.IncomingChangesOn) { @Override public boolean isSelected(AnActionEvent anActionEvent) { return controller.reviewListFilter() == ReviewListFilter.INCOMING; } @Override public void setSelected(AnActionEvent anActionEvent, boolean b) { controller.filterChanged(ReviewListFilter.INCOMING); } }); actionGroup.add(new ToggleAction("Outgoing", "Show outgoing reviews", AllIcons.Ide.OutgoingChangesOn) { @Override public boolean isSelected(AnActionEvent anActionEvent) { return controller.reviewListFilter() == ReviewListFilter.OUTGOING; } @Override public void setSelected(AnActionEvent anActionEvent, boolean b) { controller.filterChanged(ReviewListFilter.OUTGOING); } }); actionGroup.add(new ToggleAction("All", "Show all Reviews", AllIcons.General.ProjectStructure) { @Override public boolean isSelected(AnActionEvent anActionEvent) { return controller.reviewListFilter() == ReviewListFilter.ALL; } @Override public void setSelected(AnActionEvent anActionEvent, boolean b) { controller.filterChanged(ReviewListFilter.ALL); } }); actionGroup.add(new Separator()); actionGroup.add(new AnAction("First", "Go to first page", Icons.First) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.loadFirst(); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.isFirstEnabled()); } }); actionGroup.add(new AnAction("Back", "Move page backward", Icons.Back) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.loadPrevious(); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.hasPrevious()); } }); actionGroup.add(new CustomComponentActionBase(page)); actionGroup.add(new AnAction("Forward", "Move page forward", Icons.Forward) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.loadNext(); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.hasNext()); } }); actionGroup.add(new AnAction("Last", "Go to last page", Icons.Last) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.loadLast(); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.isLastEnabled()); } }); actionGroup.add(new Separator()); actionGroup.add(new AnAction("Edit Review", "Edit selected review", AllIcons.Actions.EditSource) { @Override public void actionPerformed(AnActionEvent anActionEvent) { draftReview(); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.selectedReview() != null); } }); actionGroup.add(new AnAction("Ship It", "Ship It", AllIcons.Graph.NodeSelectionMode) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.shipReview(controller.selectedReview()); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.selectedReview() != null); } }); actionGroup.add(new AnAction("Submit Review", "Submit the selected review", AllIcons.Actions.MoveToAnotherChangelist) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.submitReview(controller.selectedReview()); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.selectedReview() != null); } }); actionGroup.add(new AnAction("Discard Review", "Discard the selected review", AllIcons.Actions.Cancel) { @Override public void actionPerformed(AnActionEvent anActionEvent) { controller.discardReview(controller.selectedReview()); } @Override public void update(AnActionEvent e) { e.getPresentation().setEnabled(controller.selectedReview() != null); } }); return ActionManager.getInstance().createActionToolbar("ReviewBoardActions", actionGroup, true) .getComponent(); } }