mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-76142 Gradle support - cannot update IDEA projects once one of build.gradle files changes
1. Added basic infrastructure for the gradle tool window GUI controls; 2. Minor refactoring;
This commit is contained in:
@@ -285,7 +285,7 @@ public final class Presentation implements Cloneable {
|
||||
myChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
public Presentation clone(){
|
||||
try{
|
||||
Presentation presentation = (Presentation)super.clone();
|
||||
presentation.myChangeSupport = new PropertyChangeSupport(presentation);
|
||||
|
||||
@@ -1104,7 +1104,7 @@ public class StringUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Iterable<String> tokenize(@NotNull String s, final StringTokenizer tokenizer) {
|
||||
public static Iterable<String> tokenize(final StringTokenizer tokenizer) {
|
||||
return new Iterable<String>() {
|
||||
public Iterator<String> iterator() {
|
||||
return new Iterator<String>() {
|
||||
|
||||
@@ -55,4 +55,9 @@ gradle.generic.text.error.sdk.undefined=Gradle installation is unknown
|
||||
gradle.home.setting.type.deduced=Gradle location is deduced
|
||||
gradle.home.setting.type.unknown=Gradle location is unknown
|
||||
gradle.home.setting.type.explicit.correct=Gradle location is defined
|
||||
gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect
|
||||
gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect
|
||||
|
||||
gradle.toolwindow.text.no.linked.project=\nThere is no linked Gradle project\nYou may use {link} to add the one.
|
||||
|
||||
gradle.action.link.project.text=Link gradle project
|
||||
gradle.action.link.project.description=Allows to link any gradle project to the current IDE project
|
||||
@@ -58,4 +58,11 @@
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
<action id="Gradle.LinkToProject" class="org.jetbrains.plugins.gradle.config.GradleLinkToProjectAction" icon="/general/add.png"/>
|
||||
<group id="Gradle.ChangeActionsToolbar">
|
||||
<reference id="Gradle.LinkToProject"/>
|
||||
</group>
|
||||
</actions>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
|
||||
/**
|
||||
* Allows to link gradle project to the current IntelliJ IDEA project.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/26/11 5:09 PM
|
||||
*/
|
||||
public class GradleLinkToProjectAction extends AnAction implements DumbAware {
|
||||
|
||||
public GradleLinkToProjectAction() {
|
||||
getTemplatePresentation().setText(GradleBundle.message("gradle.action.link.project.text"));
|
||||
getTemplatePresentation().setDescription(GradleBundle.message("gradle.action.link.project.description"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
// TODO den implement
|
||||
System.out.println("action performed");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionButtonLook;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.ui.SimpleToolWindowPanel;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Base class for high-level Gradle GUI controls used at the Gradle tool window. The basic idea is to encapsulate the same features in
|
||||
* this class and allow to extend it via <code>Template Method</code> pattern. The shared features are listed below:
|
||||
* <pre>
|
||||
* <ul>
|
||||
* <li>provide common actions at the toolbar;</li>
|
||||
* <li>show info control when no gradle project is linked to the current IntelliJ IDEA project;</li>
|
||||
* </ul>
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/26/11 5:19 PM
|
||||
*/
|
||||
public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
|
||||
|
||||
private static final String NON_LINKED_CARD_NAME = "NON_LINKED";
|
||||
private static final String CONTENT_CARD_NAME = "CONTENT";
|
||||
private static final String LINK_BUTTON_MARKER = "{link}";
|
||||
private static final String TOOL_WINDOW_TOOLBAR_ID = "Gradle.ChangeActionsToolbar";
|
||||
private static final String LINK_PROJECT_ACTION_ID = "Gradle.LinkToProject";
|
||||
|
||||
/** Show info control when no gradle project is linked, using {@link CardLayout} for that. */
|
||||
private final CardLayout myLayout = new CardLayout();
|
||||
/** Top-level container, managed by the card layout. */
|
||||
private final JPanel myContent = new JPanel(myLayout);
|
||||
/** Control to show when no gradle project is linked to the current IntelliJ IDEA project. */
|
||||
private final JPanel myNonLinkedInfoPanel = new JPanel();
|
||||
|
||||
protected GradleToolWindowPanel(@NotNull String place) {
|
||||
super(true);
|
||||
final ActionManager actionManager = ActionManager.getInstance();
|
||||
final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ID);
|
||||
ActionToolbar actionToolbar = actionManager.createActionToolbar(place, actionGroup, true);
|
||||
setToolbar(actionToolbar.getComponent());
|
||||
initContent();
|
||||
setContent(myContent);
|
||||
}
|
||||
|
||||
private void initContent() {
|
||||
final JComponent payloadControl = buildContent();
|
||||
myContent.add(ScrollPaneFactory.createScrollPane(payloadControl), CONTENT_CARD_NAME);
|
||||
|
||||
myNonLinkedInfoPanel.setLayout(new GridBagLayout());
|
||||
final Color background = payloadControl.getBackground();
|
||||
myNonLinkedInfoPanel.setBackground(background);
|
||||
List<JComponent> rowComponents = new ArrayList<JComponent>();
|
||||
final String sentence = GradleBundle.message("gradle.toolwindow.text.no.linked.project");
|
||||
for (String s : StringUtil.tokenize(new StringTokenizer(sentence, " \n", true))) {
|
||||
if (s.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (LINK_BUTTON_MARKER.equals(s)) {
|
||||
final ActionManager actionManager = ActionManager.getInstance();
|
||||
final AnAction action = actionManager.getAction(LINK_PROJECT_ACTION_ID);
|
||||
ActionButton button= new ActionButton(
|
||||
action, action.getTemplatePresentation().clone(), GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE, new Dimension(0, 0))
|
||||
{
|
||||
@Override
|
||||
protected void paintButtonLook(Graphics g) {
|
||||
// Don't draw border at the inline button.
|
||||
ActionButtonLook look = getButtonLook();
|
||||
look.paintBackground(g, this);
|
||||
look.paintIcon(g, this, getIcon());
|
||||
}
|
||||
};
|
||||
rowComponents.add(button);
|
||||
}
|
||||
else if (s.contains("\n")) {
|
||||
addRow(rowComponents, background);
|
||||
rowComponents.clear();
|
||||
}
|
||||
else {
|
||||
final JLabel label = new JLabel(s);
|
||||
label.setForeground(payloadControl.getForeground());
|
||||
label.setBackground(background);
|
||||
label.setFont(payloadControl.getFont());
|
||||
rowComponents.add(label);
|
||||
}
|
||||
}
|
||||
if (!rowComponents.isEmpty()) {
|
||||
addRow(rowComponents, background);
|
||||
}
|
||||
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.weighty = 1;
|
||||
constraints.fill = GridBagConstraints.VERTICAL;
|
||||
myNonLinkedInfoPanel.add(Box.createVerticalStrut(1), constraints);
|
||||
myContent.add(myNonLinkedInfoPanel, NON_LINKED_CARD_NAME);
|
||||
|
||||
myLayout.show(myContent, NON_LINKED_CARD_NAME);
|
||||
}
|
||||
|
||||
private void addRow(@NotNull Collection<JComponent> rowComponents, @NotNull Color backgroundColor) {
|
||||
JPanel row = new MultiRowFlowPanel(FlowLayout.CENTER, 0, 3);
|
||||
row.setBackground(backgroundColor);
|
||||
if (rowComponents.isEmpty()) {
|
||||
row.add(new JLabel(" "));
|
||||
}
|
||||
else {
|
||||
for (JComponent component : rowComponents) {
|
||||
row.add(component);
|
||||
}
|
||||
}
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridwidth = GridBagConstraints.REMAINDER;
|
||||
constraints.weightx = 1;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.insets.top = 3;
|
||||
myNonLinkedInfoPanel.add(row, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return GUI control to be displayed at the current tab
|
||||
*/
|
||||
@NotNull
|
||||
protected abstract JComponent buildContent();
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Flow layout calculates necessary size assuming that all components are layed out within a single row.
|
||||
* That may cause troubles during initial space calculation, i.e. panel with flow layout is represented as a
|
||||
* single wide row inside a scroll pane. This panel fixes that by calculating necessary size on its own.
|
||||
* It fixes the width to use as a minimum between a width offered by default flow layout and customizable value
|
||||
* and calculates the height. If the user has an ability to manually change panel size (e.g. indirectly via changing
|
||||
* size of the dialog that serves as a container for the panel), that width is used as a maximum width.
|
||||
*
|
||||
* @author: Denis Zhdanov
|
||||
* @since: Jul 28, 2008
|
||||
*/
|
||||
public class MultiRowFlowPanel extends JPanel {
|
||||
|
||||
private int maximumWidth = Toolkit.getDefaultToolkit().getScreenSize().width / 2;
|
||||
|
||||
public MultiRowFlowPanel(int align, int hGap, int vGap) {
|
||||
super(new FlowLayout(align, hGap, vGap));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a preferred size assuming that the maximum row width is a value returned from
|
||||
* {@link #getMaxRowWidth()}.
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return calculateSize(getMaxRowWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a preferred size assuming that the maximum row width is a value returned from
|
||||
* {@link #getMaxRowWidth()}.
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return calculateSize(getMaxRowWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current representation width if the component is already showed; minimum of default preferred
|
||||
* width (when all components are layed in a single row) and half screen width
|
||||
*/
|
||||
private int getMaxRowWidth() {
|
||||
int result = getSize().width;
|
||||
if (result == 0) {
|
||||
result = Math.min(super.getPreferredSize().width, maximumWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates all child components and calculates the space enough to keep all of them assuming that the width is
|
||||
* fixed.
|
||||
*/
|
||||
private Dimension calculateSize(int maxRowWidth) {
|
||||
FlowLayout layout = (FlowLayout)getLayout();
|
||||
int height = 0;
|
||||
int currentRowWidth = 0;
|
||||
int currentRowHeight = 0;
|
||||
for (int i = 0, count = getComponentCount(); i < count; ++i) {
|
||||
Component comp = getComponent(i);
|
||||
Dimension bounds = comp.getPreferredSize();
|
||||
if (!comp.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
currentRowHeight = Math.max(currentRowHeight, bounds.height);
|
||||
if (currentRowWidth + layout.getHgap() + bounds.width <= maxRowWidth) {
|
||||
if (bounds.width != 0) {
|
||||
currentRowWidth += bounds.width + layout.getHgap();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
height += currentRowHeight + layout.getVgap();
|
||||
currentRowWidth = bounds.width;
|
||||
currentRowHeight = bounds.height;
|
||||
}
|
||||
return new Dimension(maxRowWidth, height + currentRowHeight + 2 * layout.getVgap());
|
||||
}
|
||||
}
|
||||
+13
-1
@@ -1,6 +1,9 @@
|
||||
package org.jetbrains.plugins.gradle.sync;
|
||||
|
||||
import com.intellij.ui.treeStructure.SimpleTree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.config.GradleToolWindowPanel;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -10,11 +13,20 @@ import javax.swing.*;
|
||||
* @author Denis Zhdanov
|
||||
* @since 11/3/11 3:58 PM
|
||||
*/
|
||||
public class GradleProjectStructureChangesPanel extends JPanel {
|
||||
public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
|
||||
private final GradleProjectStructureChangesModel myModel;
|
||||
|
||||
public GradleProjectStructureChangesPanel(@NotNull GradleProjectStructureChangesModel model) {
|
||||
super(GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE);
|
||||
myModel = model;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JComponent buildContent() {
|
||||
// TODO den implement
|
||||
return new SimpleTree();
|
||||
//return new JLabel("project-structure-change-content");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ import javax.swing.*;
|
||||
*/
|
||||
public class GradleConstants {
|
||||
|
||||
public static final Icon GRADLE_ICON = IconLoader.getIcon("/icons/gradle.png");
|
||||
@NonNls public static final String EXTENSION = "gradle";
|
||||
@NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle";
|
||||
public static final Icon GRADLE_ICON = IconLoader.getIcon("/icons/gradle.png");
|
||||
@NonNls public static final String EXTENSION = "gradle";
|
||||
@NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle";
|
||||
@NonNls public static final String TOOL_WINDOW_TOOLBAR_PLACE = "GRADLE_SYNC_CHANGES_TOOLBAR";
|
||||
|
||||
private GradleConstants() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user