]> source.dussan.org Git - gitblit.git/commitdiff
Add custom fields to the manager
authorJohn Crygier <john.crygier@aon.com>
Mon, 7 May 2012 14:58:56 +0000 (09:58 -0500)
committerJohn Crygier <john.crygier@aon.com>
Mon, 7 May 2012 14:58:56 +0000 (09:58 -0500)
src/com/gitblit/client/EditRepositoryDialog.java
src/com/gitblit/client/RepositoriesPanel.java
src/com/gitblit/client/VerticalFlowLayout.java [new file with mode: 0644]

index 156de15de1793b5be4a8b5390859ccec42aed995..6ad75c6c4ff6590b80c290443884ee29ac75fda1 100644 (file)
@@ -28,6 +28,7 @@ import java.awt.event.KeyEvent;
 import java.text.MessageFormat;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Set;\r
@@ -44,10 +45,12 @@ import javax.swing.JList;
 import javax.swing.JOptionPane;\r
 import javax.swing.JPanel;\r
 import javax.swing.JRootPane;\r
+import javax.swing.JScrollPane;\r
 import javax.swing.JTabbedPane;\r
 import javax.swing.JTextField;\r
 import javax.swing.KeyStroke;\r
 import javax.swing.ListCellRenderer;\r
+import javax.swing.ScrollPaneConstants;\r
 \r
 import com.gitblit.Constants.AccessRestrictionType;\r
 import com.gitblit.Constants.FederationStrategy;\r
@@ -117,6 +120,8 @@ public class EditRepositoryDialog extends JDialog {
        private JLabel postReceiveInherited;\r
 \r
        private Set<String> repositoryNames;\r
+       \r
+       private JPanel customFieldsPanel;\r
 \r
        public EditRepositoryDialog(int protocolVersion) {\r
                this(protocolVersion, new RepositoryModel());\r
@@ -277,6 +282,11 @@ public class EditRepositoryDialog extends JDialog {
                JPanel postReceivePanel = new JPanel(new BorderLayout(5, 5));\r
                postReceivePanel.add(postReceivePalette, BorderLayout.CENTER);\r
                postReceivePanel.add(postReceiveInherited, BorderLayout.WEST);\r
+               \r
+               customFieldsPanel = new JPanel(new VerticalFlowLayout());\r
+               JScrollPane customFieldsScrollPane = new JScrollPane(customFieldsPanel);\r
+               customFieldsScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);\r
+               customFieldsScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);\r
 \r
                JTabbedPane panel = new JTabbedPane(JTabbedPane.TOP);\r
                panel.addTab(Translation.get("gb.general"), fieldsPanel);\r
@@ -290,6 +300,9 @@ public class EditRepositoryDialog extends JDialog {
                }\r
                panel.addTab(Translation.get("gb.preReceiveScripts"), preReceivePanel);\r
                panel.addTab(Translation.get("gb.postReceiveScripts"), postReceivePanel);\r
+               \r
+               panel.addTab(Translation.get("gb.customFields"), customFieldsScrollPane);\r
+               \r
 \r
                JButton createButton = new JButton(Translation.get("gb.save"));\r
                createButton.addActionListener(new ActionListener() {\r
@@ -331,11 +344,15 @@ public class EditRepositoryDialog extends JDialog {
                pack();\r
                nameField.requestFocus();\r
        }\r
-\r
+       \r
        private JPanel newFieldPanel(String label, JComponent comp) {\r
+               return newFieldPanel(label, 150, comp);\r
+       }\r
+\r
+       private JPanel newFieldPanel(String label, int labelSize, JComponent comp) {\r
                JLabel fieldLabel = new JLabel(label);\r
                fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD));\r
-               fieldLabel.setPreferredSize(new Dimension(150, 20));\r
+               fieldLabel.setPreferredSize(new Dimension(labelSize, 20));\r
                JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));\r
                panel.add(fieldLabel);\r
                panel.add(comp);\r
@@ -448,6 +465,15 @@ public class EditRepositoryDialog extends JDialog {
                repository.indexedBranches = indexedBranchesPalette.getSelections();\r
                repository.preReceiveScripts = preReceivePalette.getSelections();\r
                repository.postReceiveScripts = postReceivePalette.getSelections();\r
+               \r
+               // Custom Fields\r
+               repository.customFields = new HashMap<String, String>();\r
+               \r
+               for (Component aCustomFieldPanel : customFieldsPanel.getComponents()) {\r
+                       JTextField textField = (JTextField) ((JPanel)aCustomFieldPanel).getComponent(1);\r
+                       repository.customFields.put(textField.getName(), textField.getText());\r
+               }\r
+               \r
                return true;\r
        }\r
 \r
@@ -525,6 +551,21 @@ public class EditRepositoryDialog extends JDialog {
        public List<String> getPermittedTeams() {\r
                return teamsPalette.getSelections();\r
        }\r
+       \r
+       public void setCustomFields(RepositoryModel repository, List<String> customFields) {\r
+               customFieldsPanel.removeAll();\r
+               \r
+               for (String customFieldDef : customFields) {\r
+                       String[] customFieldProperty = customFieldDef.split("=");\r
+                       String fieldName = customFieldProperty[0];\r
+                       String fieldLabel = customFieldProperty[1];\r
+                       \r
+                       JTextField textField = new JTextField(repository.customFields.get(fieldName), 50);\r
+                       textField.setName(fieldName);\r
+                       \r
+                       customFieldsPanel.add(newFieldPanel(fieldLabel, 250, textField));\r
+               }\r
+       }\r
 \r
        /**\r
         * ListCellRenderer to display descriptive text about the access\r
index 685a70a6edf32b0b6ccd5a6ccca96453007c54e1..89ec60540b2f984d469f1f401eeceeaed2136fbb 100644 (file)
@@ -47,6 +47,7 @@ import javax.swing.table.TableRowSorter;
 \r
 import com.gitblit.Constants;\r
 import com.gitblit.Constants.RpcRequest;\r
+import com.gitblit.Keys;\r
 import com.gitblit.models.FeedModel;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.utils.StringUtils;\r
@@ -430,6 +431,7 @@ public abstract class RepositoriesPanel extends JPanel {
                                gitblit.getPreReceiveScriptsInherited(repository), repository.preReceiveScripts);\r
                dialog.setPostReceiveScripts(gitblit.getPostReceiveScriptsUnused(repository),\r
                                gitblit.getPostReceiveScriptsInherited(repository), repository.postReceiveScripts);\r
+               dialog.setCustomFields(repository, gitblit.getSettings().get(Keys.repository.customFields).getStrings());\r
                dialog.setVisible(true);\r
                final RepositoryModel revisedRepository = dialog.getRepository();\r
                final List<String> permittedUsers = dialog.getPermittedUsers();\r
diff --git a/src/com/gitblit/client/VerticalFlowLayout.java b/src/com/gitblit/client/VerticalFlowLayout.java
new file mode 100644 (file)
index 0000000..d799cb3
--- /dev/null
@@ -0,0 +1,496 @@
+package com.gitblit.client;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+/**
+ * A flow layout arranges components in a directional flow, much
+ * like lines of text in a paragraph. The flow direction is
+ * determined by the container's <code>componentOrientation</code>
+ * property and may be one of two values:
+ * <ul>
+ * <li><code>ComponentOrientation.TOP_TO_BOTTOM</code>
+ * <li><code>ComponentOrientation.BOTTOM_TO_TOP</code>
+ * </ul>
+ * Flow layouts are typically used
+ * to arrange buttons in a panel. It arranges buttons
+ * horizontally until no more buttons fit on the same line.
+ * The line alignment is determined by the <code>align</code>
+ * property. The possible values are:
+ * <ul>
+ * <li>{@link #TOP TOP}
+ * <li>{@link #BOTTOM BOTTOM}
+ * <li>{@link #CENTER CENTER}
+ * <li>{@link #LEADING LEADING}
+ * <li>{@link #TRAILING TRAILING}
+ * </ul>
+ * <p>
+ */
+public class VerticalFlowLayout implements LayoutManager, java.io.Serializable
+{
+    /**
+     * This value indicates that each row of components
+     * should be left-justified.
+     */
+    public static final int TOP     = 0;
+
+    /**
+     * This value indicates that each row of components
+     * should be centered.
+     */
+    public static final int CENTER    = 1;
+
+    /**
+     * This value indicates that each row of components
+     * should be right-justified.
+     */
+    public static final int BOTTOM     = 2;
+
+    /**
+     * <code>align</code> is the property that determines
+     * how each column distributes empty space.
+     * It can be one of the following three values:
+     * <ul>
+     * <code>TOP</code>
+     * <code>BOTTOM</code>
+     * <code>CENTER</code>
+     * </ul>
+     *
+     * @see #getAlignment
+     * @see #setAlignment
+     */
+    int align;     // This is the one we actually use
+
+    /**
+     * The flow layout manager allows a seperation of
+     * components with gaps.  The horizontal gap will
+     * specify the space between components and between
+     * the components and the borders of the
+     * <code>Container</code>.
+     *
+     * @see #getHgap()
+     * @see #setHgap(int)
+     */
+    int hgap;
+
+    /**
+     * The flow layout manager allows a seperation of
+     * components with gaps.  The vertical gap will
+     * specify the space between rows and between the
+     * the rows and the borders of the <code>Container</code>.
+     *
+     * @see #getHgap()
+     * @see #setHgap(int)
+     */
+    int vgap;
+
+    /**
+     * Constructs a new <code>VerticalFlowLayout</code> with a centered alignment and a
+     * default 5-unit horizontal and vertical gap.
+     */
+    public VerticalFlowLayout()
+    {
+        this(CENTER, 5, 5);
+    }
+
+    /**
+     * Constructs a new <code>VerticalFlowLayout</code> with the specified
+     * alignment and a default 5-unit horizontal and vertical gap.
+     * The value of the alignment argument must be one of
+     * <code>VerticalFlowLayout.TOP</code>, <code>VerticalFlowLayout.BOTTOM</code>,
+     * or <code>VerticalFlowLayout.CENTER</code>
+     * @param align the alignment value
+     */
+    public VerticalFlowLayout(int align)
+    {
+        this(align, 5, 5);
+    }
+
+    /**
+     * Creates a new flow layout manager with the indicated alignment
+     * and the indicated horizontal and vertical gaps.
+     * <p>
+     * The value of the alignment argument must be one of
+     * <code>VerticalFlowLayout.TOP</code>, <code>VerticalFlowLayout.BOTTOM</code>,
+     * or <code>VerticalFlowLayout.CENTER</code>.
+     * @param     align   the alignment value
+     * @param     hgap  the horizontal gap between components
+     *                   and between the components and the
+     *                   borders of the <code>Container</code>
+     * @param     vgap  the vertical gap between components
+     *                   and between the components and the
+     *                   borders of the <code>Container</code>
+     */
+    public VerticalFlowLayout(int align, int hgap, int vgap)
+    {
+        this.hgap = hgap;
+        this.vgap = vgap;
+        setAlignment(align);
+    }
+
+    /**
+     * Gets the alignment for this layout.
+     * Possible values are <code>VerticalFlowLayout.TOP</code>,
+     * <code>VerticalFlowLayout.BOTTOM</code> or <code>VerticalFlowLayout.CENTER</code>,
+     * @return   the alignment value for this layout
+     * @see     java.awt.VerticalFlowLayout#setAlignment
+     * @since     JDK1.1
+     */
+    public int getAlignment()
+    {
+        return align;
+    }
+
+    /**
+     * Sets the alignment for this layout. Possible values are
+     * <ul>
+     * <li><code>VerticalFlowLayout.TOP</code>
+     * <li><code>VerticalFlowLayout.BOTTOM</code>
+     * <li><code>VerticalFlowLayout.CENTER</code>
+     * </ul>
+     * @param     align one of the alignment values shown above
+     * @see     #getAlignment()
+     * @since     JDK1.1
+     */
+    public void setAlignment(int align)
+    {
+        this.align = align;
+    }
+
+    /**
+     * Gets the horizontal gap between components
+     * and between the components and the borders
+     * of the <code>Container</code>
+     *
+     * @return   the horizontal gap between components
+     *           and between the components and the borders
+     *           of the <code>Container</code>
+     * @see     java.awt.VerticalFlowLayout#setHgap
+     * @since     JDK1.1
+     */
+    public int getHgap() {
+        return hgap;
+    }
+
+    /**
+     * Sets the horizontal gap between components and
+     * between the components and the borders of the
+     * <code>Container</code>.
+     *
+     * @param hgap the horizontal gap between components
+     *           and between the components and the borders
+     *           of the <code>Container</code>
+     * @see     java.awt.VerticalFlowLayout#getHgap
+     * @since     JDK1.1
+     */
+    public void setHgap(int hgap) {
+        this.hgap = hgap;
+    }
+
+    /**
+     * Gets the vertical gap between components and
+     * between the components and the borders of the
+     * <code>Container</code>.
+     *
+     * @return   the vertical gap between components
+     *           and between the components and the borders
+     *           of the <code>Container</code>
+     * @see     java.awt.VerticalFlowLayout#setVgap
+     * @since     JDK1.1
+     */
+    public int getVgap() {
+        return vgap;
+    }
+
+    /**
+     * Sets the vertical gap between components and between
+     * the components and the borders of the <code>Container</code>.
+     *
+     * @param vgap the vertical gap between components
+     *           and between the components and the borders
+     *           of the <code>Container</code>
+     * @see     java.awt.VerticalFlowLayout#getVgap
+     */
+    public void setVgap(int vgap) {
+        this.vgap = vgap;
+    }
+
+    /**
+     * Adds the specified component to the layout.
+     * Not used by this class.
+     * @param name the name of the component
+     * @param comp the component to be added
+     */
+    public void addLayoutComponent(String name, Component comp) {
+    }
+
+    /**
+     * Removes the specified component from the layout.
+     * Not used by this class.
+     * @param comp the component to remove
+     * @see    java.awt.Container#removeAll
+     */
+    public void removeLayoutComponent(Component comp) {
+    }
+
+    /**
+     * Returns the preferred dimensions for this layout given the
+     * <i>visible</i> components in the specified target container.
+     *
+     * @param target the container that needs to be laid out
+     * @return  the preferred dimensions to lay out the
+     *          subcomponents of the specified container
+     * @see Container
+     * @see #minimumLayoutSize
+     * @see    java.awt.Container#getPreferredSize
+     */
+    public Dimension preferredLayoutSize(Container target)
+    {
+    synchronized (target.getTreeLock())
+    {
+        Dimension dim = new Dimension(0, 0);
+        int nmembers = target.getComponentCount();
+        boolean firstVisibleComponent = true;
+
+        for (int i = 0 ; i < nmembers ; i++)
+        {
+            Component m = target.getComponent(i);
+
+            if (m.isVisible())
+            {
+                Dimension d = m.getPreferredSize();
+                dim.width = Math.max(dim.width, d.width);
+
+                if (firstVisibleComponent)
+                {
+                    firstVisibleComponent = false;
+                }
+                else
+                {
+                    dim.height += vgap;
+                }
+
+                dim.height += d.height;
+            }
+        }
+
+        Insets insets = target.getInsets();
+        dim.width += insets.left + insets.right + hgap*2;
+        dim.height += insets.top + insets.bottom + vgap*2;
+        return dim;
+    }
+    }
+
+    /**
+     * Returns the minimum dimensions needed to layout the <i>visible</i>
+     * components contained in the specified target container.
+     * @param target the container that needs to be laid out
+     * @return  the minimum dimensions to lay out the
+     *          subcomponents of the specified container
+     * @see #preferredLayoutSize
+     * @see    java.awt.Container
+     * @see    java.awt.Container#doLayout
+     */
+    public Dimension minimumLayoutSize(Container target)
+    {
+    synchronized (target.getTreeLock())
+    {
+        Dimension dim = new Dimension(0, 0);
+        int nmembers = target.getComponentCount();
+        boolean firstVisibleComponent = true;
+
+        for (int i = 0 ; i < nmembers ; i++)
+        {
+            Component m = target.getComponent(i);
+            if (m.isVisible())
+            {
+                Dimension d = m.getMinimumSize();
+                dim.width = Math.max(dim.width, d.width);
+
+                if (firstVisibleComponent)
+                {
+                    firstVisibleComponent = false;
+                }
+                else
+                {
+                    dim.height += vgap;
+                }
+
+                dim.height += d.height;
+            }
+        }
+
+
+        Insets insets = target.getInsets();
+        dim.width += insets.left + insets.right + hgap*2;
+        dim.height += insets.top + insets.bottom + vgap*2;
+        return dim;
+    }
+    }
+
+    /**
+     * Lays out the container. This method lets each
+     * <i>visible</i> component take
+     * its preferred size by reshaping the components in the
+     * target container in order to satisfy the alignment of
+     * this <code>VerticalFlowLayout</code> object.
+     *
+     * @param target the specified component being laid out
+     * @see Container
+     * @see    java.awt.Container#doLayout
+     */
+    public void layoutContainer(Container target)
+    {
+    synchronized (target.getTreeLock())
+    {
+        Insets insets = target.getInsets();
+        int maxHeight = target.getSize().height - (insets.top + insets.bottom + vgap*2);
+        int nmembers = target.getComponentCount();
+        int x = insets.left + hgap;
+        int y = 0;
+        int columnWidth = 0;
+        int start = 0;
+
+        boolean ttb = target.getComponentOrientation().isLeftToRight();
+
+        for (int i = 0 ; i < nmembers ; i++)
+        {
+            Component m = target.getComponent(i);
+
+            if (m.isVisible())
+            {
+                Dimension d = m.getPreferredSize();
+                m.setSize(d.width, d.height);
+
+                if ((y == 0) || ((y + d.height) <= maxHeight))
+                {
+                    if (y > 0)
+                    {
+                        y += vgap;
+                    }
+
+                    y += d.height;
+                    columnWidth = Math.max(columnWidth, d.width);
+                }
+                else
+                {
+                    moveComponents(target, x, insets.top + vgap, columnWidth, maxHeight - y, start, i, ttb);
+                    y = d.height;
+                    x += hgap + columnWidth;
+                    columnWidth = d.width;
+                    start = i;
+                }
+            }
+        }
+
+        moveComponents(target, x, insets.top + vgap, columnWidth, maxHeight - y, start, nmembers, ttb);
+    }
+    }
+
+    /**
+     * Centers the elements in the specified row, if there is any slack.
+     * @param target the component which needs to be moved
+     * @param x the x coordinate
+     * @param y the y coordinate
+     * @param width the width dimensions
+     * @param height the height dimensions
+     * @param columnStart the beginning of the column
+     * @param columnEnd the the ending of the column
+     */
+    private void moveComponents(
+        Container target, int x, int y, int width, int height, int columnStart, int columnEnd, boolean ttb)
+    {
+        switch (align)
+        {
+            case TOP:
+                y += ttb ? 0 : height;
+                break;
+            case CENTER:
+                y += height / 2;
+                break;
+            case BOTTOM:
+                y += ttb ? height : 0;
+                break;
+        }
+
+        for (int i = columnStart ; i < columnEnd ; i++)
+        {
+            Component m = target.getComponent(i);
+
+            if (m.isVisible())
+            {
+                int cx;
+                cx = x + (width - m.getSize().width) / 2;
+
+                if (ttb)
+                {
+                    m.setLocation(cx, y);
+                }
+                else
+                {
+                    m.setLocation(cx, target.getSize().height - y - m.getSize().height);
+                }
+
+                y += m.getSize().height + vgap;
+            }
+        }
+    }
+
+    /**
+     * Returns a string representation of this <code>VerticalFlowLayout</code>
+     * object and its values.
+     * @return   a string representation of this layout
+     */
+    public String toString()
+    {
+        String str = "";
+
+        switch (align)
+        {
+            case TOP:    str = ",align=top"; break;
+            case CENTER: str = ",align=center"; break;
+            case BOTTOM: str = ",align=bottom"; break;
+        }
+
+        return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
+    }
+
+
+    public static void main(String[] args)
+    {
+        JPanel main = new JPanel( new BorderLayout() );
+
+        final JPanel buttons = new JPanel(new VerticalFlowLayout() );
+//      buttons.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
+        main.add(buttons, BorderLayout.CENTER);
+
+        for (int i = 0; i < 7; i++)
+        {
+            buttons.add( new JRadioButton("button " + i) );
+        }
+
+        JButton button = new JButton("Add Radio Button");
+        main.add(button, BorderLayout.SOUTH);
+        button.addActionListener( new ActionListener()
+        {
+            private int i = 8;
+
+            public void actionPerformed(ActionEvent e)
+            {
+                buttons.add( new JRadioButton("button R Us" + i++) );
+                buttons.revalidate();
+//              pack();
+            }
+        });
+
+        JFrame frame = new JFrame();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.add(main);
+        frame.setSize(300, 300);
+        frame.setLocationRelativeTo(null);
+        frame.setVisible(true);
+    }
+
+
+}
\ No newline at end of file