44 | A tool by ##author.name## for the Processing programming environment.
45 | Last update, ##date##.
46 |
47 |
48 | ##tool.sentence##
49 | ##tool.paragraph##
50 | Feel free to replace this paragraph with a description of the tool.
51 | Contributed libraries are developed, documented, and maintained by members of the Processing community. Further directions are included with each tool. For feedback and support, please post to the Discourse. We strongly encourage all libraries to be open source, but not all of them are.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
Download
59 |
60 | Download ##tool.name## version ##tool.prettyVersion## (##tool.version##) in
61 | .zip format.
62 |
63 |
Installation
64 |
65 | Unzip and put the extracted ##project.name## folder into the tools folder of your Processing sketches. Reference and examples are included in the ##project.name## folder.
66 |
67 |
68 |
69 |
70 |
71 |
Keywords. ##tool.keywords##
72 |
Reference. Have a look at the javadoc reference here. A copy of the reference is included in the .zip as well.
73 |
Source. The source code of ##tool.name## is available at ##source.host##, and its repository can be browsed here.
74 |
75 |
76 |
77 |
78 |
Examples
79 |
Find a list of examples in the current distribution of ##tool.name##, or have a look at them by following the links below.
136 |
137 |
--------------------------------------------------------------------------------
/resources/build.properties:
--------------------------------------------------------------------------------
1 | # Create tools for the Processing open source programming language and
2 | # environment (http://www.processing.org)
3 | #
4 | # Customize the build properties to make the ant-build-process work for your
5 | # environment. How? Please read the comments below.
6 | #
7 | # The default properties are set for OSX, for Windows-settings please refer to
8 | # comments made under (1) and (2).
9 |
10 |
11 |
12 | # (1)
13 | # Where is your Processing sketchbook located?
14 | # If you are not sure, check the sketchbook location in your Processing
15 | # application preferences.
16 | # ${user.home} points the compiler to your home directory.
17 | # For windows the default path to your sketchbook would be
18 | # ${user.home}/My Documents/Processing (make adjustments below).
19 |
20 | sketchbook.location=${user.home}/Documents/Processing
21 |
22 |
23 |
24 | # (2)
25 | # Where are the jar files located that are required for compiling your tool such
26 | # as e.g. core.jar?
27 | # By default the local classpath location points to folder libs inside Eclipse's
28 | # workspace (by default found in your home directory).
29 | # For Windows the default path would be ${user.home}/workspace/libs (make
30 | # adjustments below).
31 |
32 | classpath.local.location=${user.home}/Documents/Code/p5/processing/build/windows/work
33 |
34 |
35 | # For OSX users.
36 | # The following path will direct you into Processing's application source code
37 | # folder in case you put Processing inside your Applications folder.
38 | # Uncommenting the line below will overwrite the classpath.local.location from
39 | # above.
40 |
41 | #classpath.local.location=/Applications/Processing.app/Contents/Resources/Java/lib/
42 |
43 |
44 | # Add all jar files that are required for compiling your project to the local
45 | # and project classpath, use a comma as delimiter. These jar files must be
46 | # inside your classpath.local.location folder.
47 | #
48 | # For creating a tool, both pde.jar and core.jar are required. (pde.jar should
49 | # then be located inside folder classpath.local.location).
50 | # The best practice would be to place both, core.jar and pde.jar into your local
51 | # classpath location.
52 |
53 | classpath.local.include=core/library/core.jar,lib/pde.jar
54 |
55 |
56 | # Add processing's libraries folder to the classpath.
57 | # If you don't need to include the libraries folder to your classpath, comment
58 | # out the following line.
59 |
60 | classpath.libraries.location=${sketchbook.location}/libraries
61 |
62 |
63 |
64 | # (3)
65 | # Set the java version that should be used to compile your tool.
66 |
67 | java.target.version=1.7
68 |
69 |
70 | # Set the description of the Ant build.xml file.
71 |
72 | ant.description=Git Manager ant build file.
73 |
74 |
75 |
76 | # (4)
77 | # Project details.
78 | # Give your tool a name. The name must not contain spaces or special characters.
79 | # When creating a tool, the name of the main class which implements Tool must be
80 | # the same as the value defined for project.name in your build.properties.
81 |
82 | project.name=GitManager
83 |
84 | # The name as the user will see it. This can contain spaces and special characters.
85 |
86 | project.prettyName=Git Manager
87 |
88 |
89 | # Use 'normal' or 'fast' as value for project.compile.
90 | # 'fast' will only compile the project into your sketchbook.
91 | # 'normal' will compile the distribution including the javadoc-reference and all
92 | # web-files (the compile process here takes longer).
93 |
94 | project.compile=normal
95 |
96 | # All files compiled with project.compile=normal are stored
97 | # in the distribution folder.
98 |
99 |
100 |
101 | # (5)
102 | # The following items are properties that will be used to make changes to the
103 | # web document templates. Values of properties will be inserted into the
104 | # documents automatically.
105 | # If you need more control, you can edit web/index.html and web/tool.properties
106 | # directly.
107 |
108 | author.name=Joel Moniz
109 | author.url=http://joelmoniz.com
110 |
111 |
112 | # Set the web page for your tool.
113 | # This is NOT a direct link to where to download it.
114 |
115 | tool.url=http://joelmoniz.com/git-manager
116 |
117 |
118 | # Set the category of your tool. This must be one (or many) of the following:
119 | # "3D" "Animation" "Compilations" "Data"
120 | # "Fabrication" "Geometry" "GUI" "Hardware"
121 | # "I/O" "Language" "Math" "Simulation"
122 | # "Sound" "Utilities" "Typography" "Video & Vision"
123 | # If a value other than those listed is used, your tool will listed as "Other."
124 |
125 | tool.categories=Utilities
126 |
127 |
128 | # A short sentence (or fragment) to summarize the tool's function. This will be
129 | # shown from inside the PDE when the tool is being installed. Avoid repeating
130 | # the name of your tool here. Also, avoid saying anything redundant like
131 | # mentioning that it's a tool. This should start with a capitalized letter, and
132 | # end with a period.
133 |
134 | tool.sentence=A GUI Git Client for Processing
135 |
136 |
137 | # Additional information suitable for the Processing website. The value of
138 | # 'sentence' always will be prepended, so you should start by writing the
139 | # second sentence here. If your tool only works on certain operating systems,
140 | # mention it here.
141 |
142 | tool.paragraph=A tool to act as a complete and convenient interface for users of various online git repository hosting services, and to integrate the awesomeness of version control with Processing.
143 |
144 |
145 | # Set the source code repository for your project.
146 | # Recommendations for storing your source code online are Google Code or GitHub.
147 |
148 | source.host=GitHub
149 | source.url=https://github.com/joelmoniz/Git-Manager
150 | source.repository=https://github.com/joelmoniz/Git-Manager
151 |
152 |
153 | # The current version of your tool.
154 | # This number must be parsable as an int. It increments once with each release.
155 | # This is used to compare different versions of the same tool, and check if an
156 | # update is available.
157 |
158 | tool.version=3
159 |
160 |
161 | # The version as the user will see it.
162 |
163 | tool.prettyVersion=0.2.2
164 | tool.minRevision=0242
165 | tool.maxRevision=0
166 |
167 | tool.copyright=(c) 2015
168 | tool.dependencies=?
169 | tool.keywords=?
170 |
171 | tested.platform=windows,linux
172 | tested.processingVersion=3.0b4+
173 |
174 |
175 | # Include javadoc references into your project's javadocs.
176 |
177 | javadoc.java.href=http://java.sun.com/javase/6/docs/api/
178 | javadoc.processing.href=http://processing.googlecode.com/svn/trunk/processing/build/javadoc/core/
179 |
--------------------------------------------------------------------------------
/src/git_manager/tool/GitMenuBar.java:
--------------------------------------------------------------------------------
1 | /*
2 | Part of the Git Manager for Processing- http://joelmoniz.com/git-manager/
3 |
4 | A tool for the Processing - http://processing.org
5 |
6 | Copyright (c) 2015 Joel Moniz
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 | USA.
22 | */
23 | package git_manager.tool;
24 |
25 | import javax.swing.JMenu;
26 | import javax.swing.JMenuBar;
27 | import javax.swing.JMenuItem;
28 |
29 | @SuppressWarnings("serial")
30 | public class GitMenuBar extends JMenuBar {
31 |
32 | private JMenu git, onlineRepos, settings, help;
33 |
34 | public GitMenuBar() {
35 | git = new JMenu("Git");
36 | onlineRepos = new JMenu("Online Repos");
37 | settings = new JMenu("Settings");
38 | help = new JMenu("Help");
39 |
40 | congiureMenus();
41 |
42 | }
43 |
44 | private void congiureMenus() {
45 |
46 | populateGitMenu();
47 | populateOnlineMenu();
48 | populateSettingsMenu();
49 | populateHelpMenu();
50 |
51 | this.add(git);
52 | //this.add(onlineRepos); TODO: Uncomment for online
53 | this.add(settings);
54 | this.add(help);
55 | }
56 |
57 | // TODO: Fill this up, and give options proper names
58 | // This is only a list as and when various useful options come into my mind
59 | // for now, not
60 | // necessarily complete (nor necessarily sufficiently meaningful)
61 |
62 | // TODO: Add option to work with remote
63 |
64 | // TODO: Provide a fetch option?
65 |
66 | // TODO: Provide tag-related options
67 | private void populateGitMenu() {
68 |
69 | JMenu submenuCommit = new JMenu("Edit Commits");
70 | JMenu submenuStash = new JMenu("Stash");
71 | JMenu submenuBranch = new JMenu("Branch");
72 |
73 | JMenuItem init = new JMenuItem("Initialize repo");
74 | JMenuItem add = new JMenuItem("Add");
75 | JMenuItem unstage = new JMenuItem("Unstage an added file");
76 | JMenuItem commit = new JMenuItem("Commit");
77 | JMenuItem amend = new JMenuItem("Modify last commit");
78 | JMenuItem checkoutFile = new JMenuItem("Unmodify a file");
79 | JMenuItem snapshot = new JMenuItem("Snapshot");
80 | JMenuItem diff = new JMenuItem("Difference");
81 | JMenuItem commitHistory = new JMenuItem("Commit History");
82 | JMenuItem push = new JMenuItem("Push");
83 | JMenuItem revert = new JMenuItem("Undo a commit");
84 | JMenuItem remove = new JMenuItem("Remove");
85 | JMenuItem status = new JMenuItem("Status");
86 | JMenuItem ignore = new JMenuItem("Ignore Files");
87 |
88 | JMenuItem rebaseSplit = new JMenuItem("Split a Commit");
89 | JMenuItem rebaseSquash = new JMenuItem("Squash Commits");
90 | JMenuItem rebaseChangeMessage = new JMenuItem("Change Commit Messages");
91 | JMenuItem rebaseReorder = new JMenuItem("Reorder Commits");
92 |
93 | JMenuItem stash = new JMenuItem("Save into Stash");
94 | JMenuItem stash_list = new JMenuItem("View Stash");
95 | JMenuItem stash_apply = new JMenuItem("Apply Stashed Changes");
96 | JMenuItem branch = new JMenuItem("Create Branch");
97 | JMenuItem checkoutBranch = new JMenuItem("Change Branch");
98 | JMenuItem mergeBranch = new JMenuItem("Merge Branch");
99 | JMenuItem deleteBranch = new JMenuItem("Delete Branch");
100 | JMenuItem clone = new JMenuItem("Clone a repo");
101 | JMenuItem readMe = new JMenuItem("Add a Read Me file");
102 |
103 | git.add(init);
104 | git.add(snapshot);
105 | git.add(add);
106 | git.add(commit);
107 |
108 | git.addSeparator();
109 |
110 | git.add(clone);
111 | git.add(push);
112 |
113 | git.addSeparator();
114 |
115 | git.add(checkoutFile);
116 | git.add(unstage);
117 | git.add(remove);
118 |
119 | git.addSeparator();
120 |
121 | submenuCommit.add(amend);
122 | submenuCommit.add(amend);
123 | submenuCommit.add(revert);
124 | submenuCommit.add(rebaseChangeMessage);
125 | submenuCommit.add(rebaseSplit);
126 | submenuCommit.add(rebaseSquash);
127 | submenuCommit.add(rebaseReorder);
128 | git.add(submenuCommit);
129 |
130 | git.addSeparator();
131 |
132 | submenuStash.add(stash);
133 | submenuStash.add(stash_list);
134 | submenuStash.add(stash_apply);
135 | git.add(submenuStash);
136 |
137 | git.addSeparator();
138 |
139 | submenuBranch.add(branch);
140 | submenuBranch.add(checkoutBranch);
141 | submenuBranch.add(mergeBranch);
142 | submenuBranch.add(deleteBranch);
143 | git.add(submenuBranch);
144 |
145 | git.addSeparator();
146 |
147 | git.add(diff);
148 | git.add(status);
149 | git.add(commitHistory);
150 |
151 | git.addSeparator();
152 |
153 | git.add(ignore);
154 | git.add(readMe);
155 |
156 | }
157 |
158 | private void populateSettingsMenu() {
159 | JMenuItem config = new JMenuItem("Specify Git Config Settings");
160 | JMenuItem gitToolBarSet = new JMenuItem("Git Option Toolbar");
161 | JMenuItem expLevMenuSet = new JMenuItem("Expertise Level Menu");
162 | JMenuItem repoSet = new JMenuItem("Local Repository");
163 | JMenuItem onlineSet = new JMenuItem("Online Repository");
164 |
165 | settings.add(config);
166 |
167 | settings.addSeparator();
168 |
169 | settings.add(gitToolBarSet);
170 | settings.add(expLevMenuSet);
171 |
172 | settings.addSeparator();
173 |
174 | settings.add(repoSet);
175 | settings.add(onlineSet);
176 | }
177 |
178 | private void populateOnlineMenu() {
179 | JMenuItem gitHub = new JMenuItem("GitHub");
180 | JMenuItem bitBucket = new JMenuItem("BitBucket");
181 | JMenuItem gCode = new JMenuItem("Google Code");
182 |
183 | onlineRepos.add(gitHub);
184 | onlineRepos.add(bitBucket);
185 | onlineRepos.add(gCode);
186 | }
187 |
188 | private void populateHelpMenu() {
189 | JMenuItem gitTutorials = new JMenuItem("New to git?");
190 | JMenuItem gmtTutorials = new JMenuItem("GitManager Tool Tutorials");
191 | JMenuItem bug = new JMenuItem("Report Bug");
192 | JMenuItem featureEnhan = new JMenuItem("Request a feature");
193 | JMenuItem repoEnhan = new JMenuItem("Request an Online Repo");
194 | JMenuItem about = new JMenuItem("About...");
195 |
196 | help.add(gitTutorials);
197 | help.add(gmtTutorials);
198 |
199 | help.addSeparator();
200 |
201 | help.add(bug);
202 | help.add(featureEnhan);
203 | help.add(repoEnhan);
204 |
205 | help.addSeparator();
206 |
207 | help.add(about);
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/src/git_manager/tool/GitGUIFrame.java:
--------------------------------------------------------------------------------
1 | /*
2 | Part of the Git Manager for Processing- http://joelmoniz.com/git-manager/
3 |
4 | A tool for the Processing - http://processing.org
5 |
6 | Copyright (c) 2015 Joel Moniz
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 | USA.
22 | */
23 | package git_manager.tool;
24 |
25 | import git_manager.constants.ProjectDetails;
26 |
27 | import java.awt.Dimension;
28 | import java.awt.GridBagConstraints;
29 | import java.awt.GridBagLayout;
30 | import java.awt.Insets;
31 | import java.awt.event.ActionEvent;
32 | import java.awt.event.ActionListener;
33 | import java.awt.event.WindowAdapter;
34 | import java.awt.event.WindowEvent;
35 |
36 | import javax.swing.JButton;
37 | import javax.swing.JFrame;
38 | import javax.swing.JOptionPane;
39 | import javax.swing.JPanel;
40 |
41 | import processing.app.Base;
42 | import processing.app.Platform;
43 | import processing.app.ui.Editor;
44 | import processing.app.ui.Toolkit;
45 |
46 | public class GitGUIFrame extends JFrame implements ActionListener {
47 |
48 | private static final long serialVersionUID = -7082287925218003592L;
49 |
50 | Editor editor;
51 | GitOperations gitops;
52 | JPanel panel;
53 | GitMenuBar menu;
54 | GitOptionToolbar tool;
55 | // static Point frameLocation;
56 |
57 | int mode = 0;
58 |
59 | public GitGUIFrame(Editor e) {
60 |
61 | editor = e;
62 |
63 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
64 |
65 | // setMinimumSize(new Dimension(600, 500));
66 | setTitle(ProjectDetails.NAME);
67 | setVisible(true);
68 |
69 | menu = new GitMenuBar();
70 | //setJMenuBar(menu); TODO: Uncomment this to display menubar
71 |
72 | tool = new GitOptionToolbar(editor);
73 |
74 | panel = new JPanel(new GridBagLayout());
75 |
76 | add(panel);
77 |
78 | GridBagConstraints c = new GridBagConstraints();
79 |
80 | c.ipady = 20;
81 | c.anchor = GridBagConstraints.PAGE_START;
82 | c.gridx = 0;
83 | c.gridy = 0;
84 | c.gridwidth = 5;
85 | c.weighty = 1.0;
86 | c.weightx = 1;
87 |
88 | if (mode == 2) {
89 | c.insets = new Insets(0, 0, 5, 0);
90 | c.fill = GridBagConstraints.HORIZONTAL;
91 | }
92 | else {
93 | c.insets = new Insets(0, 0, 0, 0);
94 | c.fill = GridBagConstraints.BOTH;
95 | }
96 |
97 | panel.add(tool, c);
98 | // panel.add(tool, c);
99 |
100 | this.setVisible(true);
101 |
102 | c.anchor = GridBagConstraints.CENTER;
103 | c.fill = GridBagConstraints.NONE;
104 | c.gridx = 1;
105 | c.gridy = 1;
106 | c.ipady = 0;
107 | c.gridwidth = 3;
108 | c.insets = new Insets(0, 0, 3, 0);
109 | c.weighty = 0;
110 |
111 | JButton bCreate = new JButton("Click to create repo");
112 | bCreate.addActionListener(this);
113 | if (mode == 2) {
114 | panel.add(bCreate, c);
115 | }
116 | bCreate.setActionCommand("create");
117 |
118 | c.gridx = 1;
119 | c.gridy = 2;
120 | c.gridwidth = 3;
121 | c.insets = new Insets(0, 0, 3, 0);
122 |
123 | JButton bSnap = new JButton("Click to \"Take Snapshot\"");
124 | bSnap.addActionListener(this);
125 | if (mode == 2) {
126 | panel.add(bSnap, c);
127 | }
128 | bSnap.setActionCommand("snapshot");
129 |
130 | c.gridx = 1;
131 | c.gridy = 3;
132 | c.gridwidth = 3;
133 | c.insets = new Insets(0, 0, 3, 0);
134 |
135 | JButton bAdd = new JButton("Add all files");
136 | bAdd.addActionListener(this);
137 | if (mode == 2) {
138 | panel.add(bAdd, c);
139 | }
140 | bAdd.setActionCommand("add");
141 |
142 | c.gridx = 1;
143 | c.gridy = 4;
144 | c.gridwidth = 1;
145 | c.insets = new Insets(0, 0, 3, 0);
146 |
147 | JButton bCommit = new JButton("Commit");
148 | bCommit.addActionListener(this);
149 | if (mode == 2) {
150 | panel.add(bCommit, c);
151 | }
152 | bCommit.setActionCommand("commit");
153 |
154 | c.gridx = 1;
155 | c.gridy = 5;
156 | c.gridwidth = 3;
157 | c.insets = new Insets(0, 0, 3, 0);
158 |
159 | JButton bLogin = new JButton("Push to GitHub");
160 | bLogin.addActionListener(this);
161 | if (mode == 2) {
162 | panel.add(bLogin, c);
163 | }
164 | bLogin.setActionCommand("push");
165 |
166 | Toolkit.setIcon(this);
167 | gitops = new GitOperations(editor);
168 |
169 | this.addWindowListener(new WindowAdapter() {
170 | // Invoked when a window is in the process of being closed.
171 | public void windowClosing(WindowEvent e) {
172 | dispose();
173 | GitManager.frame = null;
174 | }
175 | });
176 | if (mode == 2) {
177 | if (Platform.isLinux()) {
178 | setMinimumSize(new Dimension(700, 530));
179 | setPreferredSize(new Dimension(700, 530));
180 | } else {
181 | setMinimumSize(new Dimension(650, 530));
182 | setPreferredSize(new Dimension(650, 530));
183 | }
184 | setResizable(true);
185 | }
186 | else {
187 | this.pack();
188 | setPreferredSize(new Dimension(this.getWidth(), this.getHeight()));
189 | tool.clearDescription();
190 | setResizable(false); //TODO: Make true for expertise
191 | }
192 |
193 | this.pack();
194 |
195 | // frameLocation = getLocationOnScreen();
196 | //
197 | // this.addComponentListener(new ComponentListener() {
198 | //
199 | // @Override
200 | // public void componentShown(ComponentEvent arg0) {
201 | // frameLocation = getLocationOnScreen();
202 | // }
203 | //
204 | // @Override
205 | // public void componentResized(ComponentEvent arg0) {
206 | // frameLocation = getLocationOnScreen();
207 | // }
208 | //
209 | // @Override
210 | // public void componentMoved(ComponentEvent arg0) {
211 | // frameLocation = getLocationOnScreen();
212 | // }
213 | //
214 | // @Override
215 | // public void componentHidden(ComponentEvent arg0) {
216 | //
217 | // }
218 | // });
219 |
220 | }
221 |
222 | public String getMessage(String dialogText) {
223 | return JOptionPane.showInputDialog(panel, dialogText, null);
224 | }
225 |
226 | public void actionPerformed(ActionEvent e) {
227 | if ("create".equals(e.getActionCommand()))
228 | gitops.initRepo();
229 | else if ("snapshot".equals(e.getActionCommand()))
230 | gitops.addAndCommit(getMessage("Enter commit message"));
231 | else if ("add".equals(e.getActionCommand()))
232 | gitops.addFiles();
233 | else if ("commit".equals(e.getActionCommand()))
234 | gitops.commitChanges(getMessage("Enter commit message"));
235 | else if ("push".equals(e.getActionCommand())) {
236 | gitops.getUnameandPass();
237 | gitops.pushToRemote();
238 | }
239 | }
240 |
241 | }
242 |
--------------------------------------------------------------------------------
/src/git_manager/constants/OptionBar.java:
--------------------------------------------------------------------------------
1 | /*
2 | Part of the Git Manager for Processing- http://joelmoniz.com/git-manager/
3 |
4 | A tool for the Processing - http://processing.org
5 |
6 | Copyright (c) 2015 Joel Moniz
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 | USA.
22 | */
23 | package git_manager.constants;
24 |
25 | public class OptionBar {
26 | public static final String TOOL_ICON_PATH = "/data/toolbar/";
27 | public static final String NOVICE_TOOL_ICON_PATH = TOOL_ICON_PATH
28 | + "novice/";
29 | public static final String ONLINE_REPO_ICON_PATH = TOOL_ICON_PATH
30 | + "logos/";
31 |
32 | public static final String GIT_INIT_ICON = NOVICE_TOOL_ICON_PATH
33 | + "gitinit.png";
34 | public static final String GIT_ADD_ICON = NOVICE_TOOL_ICON_PATH
35 | + "gitadd.png";
36 | public static final String GIT_DIFF_ICON = NOVICE_TOOL_ICON_PATH
37 | + "gitdiff.png";
38 | public static final String GIT_PUSH_ICON = NOVICE_TOOL_ICON_PATH
39 | + "gitpush.png";
40 | public static final String GIT_PULL_ICON = NOVICE_TOOL_ICON_PATH
41 | + "gitpull.png";
42 | public static final String GIT_REVERT_ICON = NOVICE_TOOL_ICON_PATH
43 | + "gitrevert.png";
44 | public static final String GIT_RM_ICON = NOVICE_TOOL_ICON_PATH
45 | + "gitrm.png";
46 | public static final String GIT_LOG_ICON = NOVICE_TOOL_ICON_PATH
47 | + "gitlog.png";
48 | public static final String GIT_STATUS_ICON = NOVICE_TOOL_ICON_PATH
49 | + "gitstatus.png";
50 | public static final String GIT_SNAP_ICON = NOVICE_TOOL_ICON_PATH
51 | + "snapshot.png";
52 |
53 | public static final String BUG_ICON = NOVICE_TOOL_ICON_PATH
54 | + "bug.png";
55 | public static final String HELP_ICON = NOVICE_TOOL_ICON_PATH
56 | + "help_window.png";
57 | public static final String SITE_ICON = NOVICE_TOOL_ICON_PATH
58 | + "globe.png";
59 |
60 |
61 | public static final String GIT_INIT_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
62 | + "gitinit_selected.png";
63 | public static final String GIT_ADD_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
64 | + "gitadd_selected.png";
65 | public static final String GIT_DIFF_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
66 | + "gitdiff_selected.png";
67 | public static final String GIT_PUSH_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
68 | + "gitpush_selected.png";
69 | public static final String GIT_PULL_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
70 | + "gitpull_selected.png";
71 | public static final String GIT_REVERT_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
72 | + "gitrevert_selected.png";
73 | public static final String GIT_RM_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
74 | + "gitrm_selected.png";
75 | public static final String GIT_LOG_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
76 | + "gitlog_selected.png";
77 | public static final String GIT_STATUS_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
78 | + "gitstatus_selected.png";
79 | public static final String GIT_SNAP_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
80 | + "snapshot_selected.png";
81 |
82 | public static final String BUG_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
83 | + "bug_selected.png";
84 | public static final String HELP_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
85 | + "help_window_selected.png";
86 | public static final String SITE_SELECTED_ICON = NOVICE_TOOL_ICON_PATH
87 | + "globe_selected.png";
88 |
89 |
90 | public static final String GIT_INIT_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
91 | + "gitinit_disabled.png";
92 | public static final String GIT_ADD_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
93 | + "gitadd_disabled.png";
94 | public static final String GIT_DIFF_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
95 | + "gitdiff_disabled.png";
96 | public static final String GIT_PUSH_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
97 | + "gitpush_disabled.png";
98 | public static final String GIT_PULL_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
99 | + "gitpull_disabled.png";
100 | public static final String GIT_REVERT_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
101 | + "gitrevert_disabled.png";
102 | public static final String GIT_RM_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
103 | + "gitrm_disabled.png";
104 | public static final String GIT_LOG_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
105 | + "gitlog_disabled.png";
106 | public static final String GIT_STATUS_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
107 | + "gitstatus_disabled.png";
108 | public static final String GIT_SNAP_DISABLED_ICON = NOVICE_TOOL_ICON_PATH
109 | + "snapshot_disabled.png";
110 |
111 |
112 | public static final String REPO_BITBUCKET = ONLINE_REPO_ICON_PATH
113 | + "bitbucket_logo.png";
114 | public static final String REPO_GITHUB = ONLINE_REPO_ICON_PATH
115 | + "GitHub-Mark-120px-plus.png";
116 | public static final String REPO_SOURCEFORGE = ONLINE_REPO_ICON_PATH
117 | + "sourceforge.png";
118 | public static final String REPO_GOOGLE_PROJ_HOST = ONLINE_REPO_ICON_PATH
119 | + "gph.png";
120 |
121 | public static final String ACTION_INIT = "GIT_INIT";
122 | public static final String ACTION_ADD = "GIT_ADD";
123 | public static final String ACTION_DIFF = "GIT_DIFF";
124 | public static final String ACTION_PUSH = "GIT_PUSH";
125 | public static final String ACTION_PULL = "GIT_PULL";
126 | public static final String ACTION_REVERT = "GIT_REVERT";
127 | public static final String ACTION_RM = "GIT_RM";
128 | public static final String ACTION_LOG = "GIT_LOG";
129 | public static final String ACTION_STATUS = "GIT_STATUS";
130 | public static final String ACTION_SNAP = "GIT_SNAP";
131 |
132 | public static final String ACTION_BUG = "BUG";
133 | public static final String ACTION_HELP = "HELP";
134 | public static final String ACTION_SITE = "SITE";
135 |
136 | public static final String DESCRIP_INIT = "Create Repo";
137 | public static final String DESCRIP_ADD = "Stage Files";
138 | public static final String DESCRIP_DIFF = "Show Changes";
139 | public static final String DESCRIP_PUSH = "Push to Online Repo";
140 | public static final String DESCRIP_PULL = "Pull from Online Repo";
141 | public static final String DESCRIP_REVERT = "Undo Commits";
142 | public static final String DESCRIP_RM = "Undo Changes in Repo";
143 | public static final String DESCRIP_LOG = "Show Commits so far";
144 | public static final String DESCRIP_STATUS = "Show Working Tree Status";
145 | public static final String DESCRIP_SNAP = "Save Working Tree State";
146 |
147 | public static final String DESCRIP_BUG = "Report a Bug";
148 | public static final String DESCRIP_HELP = "Help";
149 | public static final String DESCRIP_SITE = "Git Manager Website";
150 |
151 | public static final String MODE_MENU_ARROW = TOOL_ICON_PATH
152 | + "mode-arrow.png";
153 | public static final String MODE_MENU_ARROW_LINUX = TOOL_ICON_PATH
154 | + "mode-arrow-linux.png";
155 | // arrow
156 | // borrowed
157 | // from
158 | // processing
159 |
160 | public static final int ARROW_WIDTH = 7;
161 | public static final int ARROW_HEIGHT = 6;
162 |
163 | public static final int MODE_GAP_WIDTH = 8;
164 | public static final int MODE_BOX_HEIGHT = 6;
165 |
166 |
167 | public static final String HELP_SCREEN = TOOL_ICON_PATH
168 | + "help_screen.png";
169 |
170 | public static final String URL_BUG = "https://github.com/joelmoniz/Git-Manager/issues/new";
171 | public static final String URL_GIT_MANAGER = "http://joelmoniz.com/git-manager/";
172 | }
173 |
--------------------------------------------------------------------------------
/resources/code/ExampleTaglet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
3 | *
4 | * Redistribution and use in source and binary forms, with or
5 | * without modification, are permitted provided that the following
6 | * conditions are met:
7 | *
8 | * -Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | *
11 | * -Redistribution in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in
13 | * the documentation and/or other materials provided with the
14 | * distribution.
15 | *
16 | * Neither the name of Sun Microsystems, Inc. or the names of
17 | * contributors may be used to endorse or promote products derived
18 | * from this software without specific prior written permission.
19 | *
20 | * This software is provided "AS IS," without a warranty of any
21 | * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
22 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
23 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
24 | * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
25 | * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
26 | * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
27 | * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
28 | * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
29 | * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
30 | * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
31 | * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
32 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 | *
34 | * You acknowledge that Software is not designed, licensed or
35 | * intended for use in the design, construction, operation or
36 | * maintenance of any nuclear facility.
37 | */
38 |
39 | import com.sun.tools.doclets.Taglet;
40 | import com.sun.javadoc.*;
41 | import java.util.Map;
42 | import java.io.*;
43 | /**
44 | * A sample Taglet representing @example. This tag can be used in any kind of
45 | * {@link com.sun.javadoc.Doc}. It is not an inline tag. The text is displayed
46 | * in yellow to remind the developer to perform a task. For
47 | * example, "@example Hello" would be shown as:
48 | *
49 | *
50 | * To Do:
51 | *
Fix this!
52 | *
53 | *
54 | *
55 | * @author Jamie Ho
56 | * @since 1.4
57 | */
58 |
59 | public class ExampleTaglet implements Taglet {
60 |
61 | private static final String NAME = "example";
62 | private static final String HEADER = "example To Do:";
63 |
64 | /**
65 | * Return the name of this custom tag.
66 | */
67 | public String getName() {
68 | return NAME;
69 | }
70 |
71 | /**
72 | * Will return true since @example
73 | * can be used in field documentation.
74 | * @return true since @example
75 | * can be used in field documentation and false
76 | * otherwise.
77 | */
78 | public boolean inField() {
79 | return true;
80 | }
81 |
82 | /**
83 | * Will return true since @example
84 | * can be used in constructor documentation.
85 | * @return true since @example
86 | * can be used in constructor documentation and false
87 | * otherwise.
88 | */
89 | public boolean inConstructor() {
90 | return true;
91 | }
92 |
93 | /**
94 | * Will return true since @example
95 | * can be used in method documentation.
96 | * @return true since @example
97 | * can be used in method documentation and false
98 | * otherwise.
99 | */
100 | public boolean inMethod() {
101 | return true;
102 | }
103 |
104 | /**
105 | * Will return true since @example
106 | * can be used in method documentation.
107 | * @return true since @example
108 | * can be used in overview documentation and false
109 | * otherwise.
110 | */
111 | public boolean inOverview() {
112 | return true;
113 | }
114 |
115 | /**
116 | * Will return true since @example
117 | * can be used in package documentation.
118 | * @return true since @example
119 | * can be used in package documentation and false
120 | * otherwise.
121 | */
122 | public boolean inPackage() {
123 | return true;
124 | }
125 |
126 | /**
127 | * Will return true since @example
128 | * can be used in type documentation (classes or interfaces).
129 | * @return true since @example
130 | * can be used in type documentation and false
131 | * otherwise.
132 | */
133 | public boolean inType() {
134 | return true;
135 | }
136 |
137 | /**
138 | * Will return false since @example
139 | * is not an inline tag.
140 | * @return false since @example
141 | * is not an inline tag.
142 | */
143 |
144 | public boolean isInlineTag() {
145 | return false;
146 | }
147 |
148 | /**
149 | * Register this Taglet.
150 | * @param tagletMap the map to register this tag to.
151 | */
152 | public static void register(Map tagletMap) {
153 | ExampleTaglet tag = new ExampleTaglet();
154 | Taglet t = (Taglet) tagletMap.get(tag.getName());
155 | if (t != null) {
156 | tagletMap.remove(tag.getName());
157 | }
158 | tagletMap.put(tag.getName(), tag);
159 | }
160 |
161 | /**
162 | * Given the Tag representation of this custom
163 | * tag, return its string representation.
164 | * @param tag the Tag representation of this custom tag.
165 | */
166 | public String toString(Tag tag) {
167 | return createHTML(readFile(tag.text()));
168 | }
169 |
170 |
171 | /**
172 | * Given an array of Tags representing this custom
173 | * tag, return its string representation.
174 | * @param tags the array of Tags representing of this custom tag.
175 | */
176 | public String toString(Tag[] tags) {
177 | if (tags.length == 0) {
178 | return null;
179 | }
180 | return createHTML(readFile(tags[0].text()));
181 | }
182 |
183 |
184 |
185 | String createHTML(String theString) {
186 | if(theString!=null) {
187 | String dd = "";
193 |
194 | return dd+"\n
" +
195 | "
+Example
" +
196 | "
"+theString+"
" +
197 | "
";
198 | }
199 | return "";
200 | }
201 |
202 |
203 | /**
204 | * check if the examples directory exists and return the example as given in the tag.
205 | * @param theExample the name of the example
206 | */
207 | String readFile(String theExample) {
208 | String record = "";
209 | String myResult = "";
210 | int recCount = 0;
211 | String myDir = "../examples";
212 | File file=new File(myDir);
213 | if(file.exists()==false) {
214 | myDir = "./examples";
215 | }
216 | try {
217 | FileReader fr = new FileReader(myDir+"/"+theExample+"/"+theExample+".pde");
218 | BufferedReader br = new BufferedReader(fr);
219 | record = new String();
220 | while ((record = br.readLine()) != null) {
221 | myResult += record+"\n";
222 | }
223 | } catch (IOException e) {
224 | System.out.println(e);
225 | return null;
226 | }
227 | return myResult;
228 | }
229 | }
230 |
231 |
232 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #
Git Manager
2 |
3 | ## Objective
4 |
5 | The Git Manager is a tool to act as a complete and convenient interface between GitHub and Processing, and to integrate the awesomeness of version control with Processing. It is meant to be able to provide not only all the offline features of Git, but also the power of collaboration and numerous other features that GitHub brings to the table. Though the tool is primarily meant to enable the user to use all of GitHub’s features via the tool, the user will be provided the flexibility to use the tool for Git operations alone, if he/she so chooses (for example, add, commit, branch, etc.). The tool's webpage maybe viewed [**here**](http://joelmoniz.com/git-manager/).
6 |
7 | ## The Git-Manager in an image
8 | 
9 |
10 | ## Installation Instructions
11 |
12 | ### The Easy Way: Installating the Git Manager via the Contribution Manager
13 | The easiest way to install the Git Manager is from within the PDE's Tools Manager:
14 |
15 | * Go to `Tools > Add Tool...`
16 | * Click on `Git Manager`, and click on the `Install` button in the bottom pane
17 |
18 | ### The Hard Way: Manually Installating the Git Manager
19 | To use Git Manager from within the Processing IDE (like a normal tool), do the following:
20 |
21 | * Create a folder named "tools" inside your Sketchbook folder (if not already present). The location of the sketchbook folder is shown in Processing's Preferences dialog.
22 | * Download the latest release ([GitManager.zip](https://github.com/joelmoniz/Git-Manager/releases/tag/latest)) and extract it into the "tools" folder. Ensure that in the tools folder, GitManager folder has src, tools, etc. within it, and not another sub-folder named GitManager.
23 | * Start Processing
24 |
25 | ## Instructions to Build Git Manager
26 | To compile Git Manager, do the following:
27 |
28 | 1. Clone Git Manager into a location of your choice:
29 | Change the directory to where you would like to clone Git Manager to, and the run the following command in the Git Bash Terminal:
30 | `git clone https://github.com/joelmoniz/Git-Manager.git`
31 | Note: If you would like to contribute to the Git Manager, you'll have to fork it instead.
32 | 2. Import the cloned project into Eclipse
33 | 3. Open the build.properties file in the resources folder, and change the property "sketchbook.location" to wherever your Processing sketchbook is located, as instructed in the file
34 | 4. Now, to show the Ant View, go to Window > Show View > Ant
35 | 5. Drag the resources/build.xml file onto the Ant view there
36 | 6. Press the 'Play' button, and voilà!
37 |
38 |
50 |
51 |
52 |
53 |
137 |
--------------------------------------------------------------------------------
/resources/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ${ant.description}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | ${line}
81 | Building the Processing tool, ${project.name} ${tool.version}
82 | ${line}
83 | src path ${project.src}
84 | bin path ${project.bin}
85 | classpath.local ${classpath.local.location}
86 | sketchbook ${sketchbook.location}
87 | java version ${java.target.version}
88 | ${line}
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | ${exampleDir}
341 |
347 |
348 |
354 |
355 |
356 |
357 |
358 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 | ${line}
377 | Name ${project.name}
378 | Version ${tool.prettyVersion} (${tool.version})
379 | Compiled ${project.compile}
380 | Sketchbook ${sketchbook.location}
381 | ${line}
382 | done, finished.
383 | ${line}
384 |
385 |
386 |
387 |
388 |
389 |
--------------------------------------------------------------------------------
/src/git_manager/tool/GitOptionToolbar.java:
--------------------------------------------------------------------------------
1 | /*
2 | Part of the Git Manager for Processing- http://joelmoniz.com/git-manager/
3 |
4 | A tool for the Processing - http://processing.org
5 |
6 | Copyright (c) 2015 Joel Moniz
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 | USA.
22 | */
23 | package git_manager.tool;
24 |
25 | import git_manager.constants.OptionBar;
26 |
27 | import java.awt.Color;
28 | import java.awt.Dimension;
29 | import java.awt.FontMetrics;
30 | import java.awt.Graphics;
31 | import java.awt.event.ActionEvent;
32 | import java.awt.event.ActionListener;
33 | import java.awt.event.MouseEvent;
34 | import java.util.ArrayList;
35 |
36 | import javax.swing.BorderFactory;
37 | import javax.swing.Box;
38 | import javax.swing.BoxLayout;
39 | import javax.swing.ImageIcon;
40 | import javax.swing.JButton;
41 | import javax.swing.JFrame;
42 | import javax.swing.JLabel;
43 | import javax.swing.JMenuItem;
44 | import javax.swing.JOptionPane;
45 | import javax.swing.JPanel;
46 | import javax.swing.JPopupMenu;
47 | import javax.swing.JRadioButtonMenuItem;
48 | import javax.swing.SwingConstants;
49 | import javax.swing.SwingUtilities;
50 | import javax.swing.SwingWorker;
51 | import javax.swing.border.Border;
52 | import javax.swing.event.MouseInputListener;
53 |
54 | import processing.app.Base;
55 | import processing.app.Platform;
56 | import processing.app.ui.Editor;
57 | import processing.app.ui.Toolkit;
58 |
59 | public class GitOptionToolbar extends JPanel implements MouseInputListener,
60 | ActionListener {
61 |
62 | private static final long serialVersionUID = 6679503189108207242L;
63 |
64 | /**
65 | * used to debug the positioning of stuff by adding in borders
66 | */
67 | private static final boolean DEBUG_BORDER = false;
68 |
69 | /**
70 | * Used to add in the horizontal structs between each of the option buttons
71 | */
72 | private static final int space1 = 5;
73 |
74 | /**
75 | * Used to add in tiny vertical structs between each of the tiny buttons
76 | */
77 | private static final int space2 = 2;
78 | // Expertise Selection Menu variables
79 | private int elmX2, elmX1, elmY1, elmY2, elmTextWidth, elmTextAscent;
80 | // ArrayList points;
81 | ArrayList buttons;
82 |
83 | // Repo Selection Menu variables
84 | private int rsmX2, rsmX1, rsmY1, rsmY2;
85 | private JLabel buttonDescription;
86 | private GitOperations gitops;
87 | private Editor editor;
88 | private JPanel buttonToolbar;
89 | private JPanel descriptionToolbar;
90 | private JPanel tinyToolbar;
91 |
92 | public GitOptionToolbar(Editor e) {
93 | this.setName("ActionBar");
94 | this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
95 | // this.setBounds(0, 0, 400, 145);
96 | this.setVisible(true);
97 | // this.setFloatable(false);
98 | this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
99 | // this.setOrientation(JToolBar.VERTICAL);
100 |
101 | buttonDescription = new JLabel();
102 | // TODO: Add padding instead of adding the space
103 | buttonDescription.setText(OptionBar.DESCRIP_STATUS + " ");
104 | // if (Base.isLinux())
105 | // buttonDescription.setForeground(Color.BLACK);
106 | // else
107 | buttonDescription.setForeground(Color.WHITE);
108 |
109 | if (DEBUG_BORDER) {
110 | buttonDescription.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
111 | }
112 | // points = new ArrayList();
113 | buttons = new ArrayList();
114 |
115 | buttonToolbar = new JPanel();
116 | descriptionToolbar = new JPanel();
117 | tinyToolbar = new JPanel();
118 |
119 | editor = e;
120 |
121 | gitops = new GitOperations(editor);
122 |
123 | buttonToolbar.setLayout(new BoxLayout(buttonToolbar, BoxLayout.LINE_AXIS));
124 | buttonToolbar.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
125 | descriptionToolbar.setLayout(new BoxLayout(descriptionToolbar, BoxLayout.LINE_AXIS));
126 | tinyToolbar.setLayout(new BoxLayout(tinyToolbar, BoxLayout.PAGE_AXIS));
127 | tinyToolbar.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
128 |
129 | populateButtonBar();
130 | populateDescribeBar();
131 | populateTinyBar();
132 |
133 | JPanel pna = new JPanel();
134 | pna.setLayout(new BoxLayout(pna, BoxLayout.PAGE_AXIS));
135 | pna.add(buttonToolbar);
136 | // pna.add(Box.createHorizontalGlue());
137 | pna.add(descriptionToolbar);
138 |
139 | if (DEBUG_BORDER) {
140 | buttonToolbar
141 | .setBorder(BorderFactory.createCompoundBorder(BorderFactory
142 | .createMatteBorder(1, 1, 1, 1, Color.CYAN), buttonToolbar
143 | .getBorder()));
144 | tinyToolbar.setBorder(BorderFactory.createCompoundBorder(BorderFactory
145 | .createMatteBorder(1, 1, 1, 1, Color.PINK), tinyToolbar.getBorder()));
146 | descriptionToolbar.setBorder(BorderFactory
147 | .createMatteBorder(1, 1, 1, 1, Color.YELLOW));
148 | pna.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.GREEN));
149 | }
150 |
151 | // this.add(pna, BorderLayout.PAGE_START);
152 | //// this.add(buttonToolbar, BorderLayout.PAGE_START);
153 | //// this.add(tinyToolbar, BorderLayout.LINE_END);
154 | // this.add(descriptionToolbar, BorderLayout.CENTER);
155 |
156 | this.add(pna);
157 | // this.add(Box.createHorizontalGlue());
158 | //
159 | // JPanel pan = new JPanel();
160 | // pan.setLayout(new BoxLayout(pan, BoxLayout.LINE_AXIS));
161 | // pan.setBackground(Color.BLACK);
162 | // pan.setOpaque(true);
163 | //
164 | // pan.add(Box.createHorizontalGlue());
165 | // pan.add(tinyToolbar);
166 | //
167 | // this.add(pan);
168 |
169 | this.add(tinyToolbar);
170 |
171 | // buttonToolbar.setPreferredSize(this.getPreferredSize());
172 | buttonToolbar.setBackground(Color.BLACK);
173 | buttonToolbar.setOpaque(true);
174 | // buttonToolbar.setFloatable(false);
175 |
176 | descriptionToolbar.setBackground(Color.BLACK);
177 | descriptionToolbar.setOpaque(true);
178 | // descriptionToolbar.setFloatable(false);
179 |
180 | tinyToolbar.setBackground(Color.BLACK);
181 | tinyToolbar.setOpaque(true);
182 |
183 | pna.setBackground(Color.BLACK);
184 | pna.setOpaque(true);
185 |
186 | disableButtons();
187 |
188 | // JLabel t = new JLabel("Test");
189 | // t.setForeground(Color.WHITE);
190 | // descriptionToolbar.add(t);
191 |
192 | // addMouseListener(this);
193 | // addMouseMotionListener(this);
194 | this.setPreferredSize(this.getPreferredSize());
195 | }
196 |
197 | private void populateButtonBar() {
198 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
199 | this.buttonToolbar.add(addButton(OptionBar.GIT_INIT_ICON, OptionBar.ACTION_INIT,
200 | OptionBar.DESCRIP_INIT, OptionBar.GIT_INIT_SELECTED_ICON,
201 | OptionBar.GIT_INIT_ICON));
202 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
203 | this.buttonToolbar.add(addButton(OptionBar.GIT_SNAP_ICON, OptionBar.ACTION_SNAP,
204 | OptionBar.DESCRIP_SNAP, OptionBar.GIT_SNAP_SELECTED_ICON,
205 | OptionBar.GIT_SNAP_DISABLED_ICON));
206 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
207 | // TODO: Uncomment this to add in a git diff
208 | // this.add(addButton(OptionBar.GIT_DIFF_ICON, OptionBar.ACTION_DIFF,
209 | // OptionBar.DESCRIP_DIFF, OptionBar.GIT_DIFF_SELECTED_ICON));
210 | // this.add(Box.createHorizontalStrut(space1));
211 | this.buttonToolbar.add(addButton(OptionBar.GIT_PUSH_ICON, OptionBar.ACTION_PUSH,
212 | OptionBar.DESCRIP_PUSH, OptionBar.GIT_PUSH_SELECTED_ICON,
213 | OptionBar.GIT_PUSH_DISABLED_ICON));
214 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
215 | this.buttonToolbar.add(addButton(OptionBar.GIT_PULL_ICON, OptionBar.ACTION_PULL,
216 | OptionBar.DESCRIP_PULL, OptionBar.GIT_PULL_SELECTED_ICON,
217 | OptionBar.GIT_PULL_DISABLED_ICON));
218 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
219 | this.buttonToolbar.add(addButton(OptionBar.GIT_REVERT_ICON, OptionBar.ACTION_REVERT,
220 | OptionBar.DESCRIP_REVERT, OptionBar.GIT_REVERT_SELECTED_ICON,
221 | OptionBar.GIT_REVERT_DISABLED_ICON));
222 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
223 | this.buttonToolbar.add(addButton(OptionBar.GIT_RM_ICON, OptionBar.ACTION_RM,
224 | OptionBar.DESCRIP_RM, OptionBar.GIT_RM_SELECTED_ICON,
225 | OptionBar.GIT_RM_DISABLED_ICON));
226 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
227 | this.buttonToolbar.add(addButton(OptionBar.GIT_LOG_ICON, OptionBar.ACTION_LOG,
228 | OptionBar.DESCRIP_LOG, OptionBar.GIT_LOG_SELECTED_ICON,
229 | OptionBar.GIT_LOG_DISABLED_ICON));
230 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
231 | this.buttonToolbar.add(addButton(OptionBar.GIT_STATUS_ICON, OptionBar.ACTION_STATUS,
232 | OptionBar.DESCRIP_STATUS, OptionBar.GIT_STATUS_SELECTED_ICON,
233 | OptionBar.GIT_STATUS_DISABLED_ICON));
234 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
235 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
236 | this.buttonToolbar.add(buttonDescription);
237 | this.buttonToolbar.add(Box.createHorizontalStrut(space1));
238 |
239 | this.buttonToolbar.add(Box.createHorizontalGlue());
240 | }
241 |
242 | // TODO: Add all this in into OptionBar class
243 | private void populateDescribeBar() {
244 |
245 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
246 | this.descriptionToolbar.add(addLabel("Start", 41, 0));
247 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
248 | this.descriptionToolbar.add(addLabel("Commit", 41, 0));
249 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
250 | // TODO: Uncomment this to add in a git diff
251 | // this.add(addButton(OptionBar.GIT_DIFF_ICON, OptionBar.ACTION_DIFF,
252 | // OptionBar.DESCRIP_DIFF, OptionBar.GIT_DIFF_SELECTED_ICON));
253 | // this.add(Box.createHorizontalStrut(space1));
254 | this.descriptionToolbar.add(addLabel("Online", 41*2, 1));
255 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
256 | this.descriptionToolbar.add(addLabel("Undo", 41+42, 1));
257 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
258 | this.descriptionToolbar.add(addLabel("Logs", 41+42, 1));
259 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
260 | this.descriptionToolbar.add(Box.createHorizontalStrut(space1));
261 |
262 | // TODO: Can add something to descibe in more details here
263 | // this.descriptionToolbar.add(buttonDescription);
264 |
265 | this.descriptionToolbar.add(Box.createHorizontalGlue());
266 |
267 | }
268 |
269 | // TODO: Figure out why on earth all havoc breaks lose when I use
270 | // Box.createVerticalStruct() instead of the incorrect Box.createHorizontalStruct()
271 | private void populateTinyBar() {
272 | this.tinyToolbar.add(addButton(OptionBar.HELP_ICON, OptionBar.ACTION_HELP,
273 | OptionBar.DESCRIP_HELP, OptionBar.HELP_SELECTED_ICON,
274 | OptionBar.HELP_ICON));
275 | this.tinyToolbar.add(Box.createHorizontalStrut(space2));
276 | this.tinyToolbar.add(addButton(OptionBar.BUG_ICON, OptionBar.ACTION_BUG,
277 | OptionBar.DESCRIP_BUG, OptionBar.BUG_SELECTED_ICON,
278 | OptionBar.BUG_ICON));
279 | this.tinyToolbar.add(Box.createHorizontalStrut(space2));
280 | this.tinyToolbar.add(addButton(OptionBar.SITE_ICON, OptionBar.ACTION_SITE,
281 | OptionBar.DESCRIP_SITE, OptionBar.SITE_SELECTED_ICON,
282 | OptionBar.SITE_ICON));
283 | this.tinyToolbar.add(Box.createVerticalGlue());
284 | }
285 |
286 | protected JButton addButton(String imageLocation, String actionCommand,
287 | String buttonName, String rolloverImageLocation,
288 | String disabledImageLocation) {
289 | JButton b = new JButton();
290 | ImageIcon icon = new ImageIcon(this.getClass().getResource(
291 | imageLocation));
292 | ImageIcon rolloverIcon = new ImageIcon(this.getClass().getResource(
293 | rolloverImageLocation));
294 |
295 | /*
296 | // Image normalImage = icon.getImage();
297 | // Image grayImage = GrayFilter.createDisabledImage(normalImage);
298 |
299 | final int w = icon.getIconWidth();
300 | final int h = icon.getIconHeight();
301 | GraphicsEnvironment ge =
302 | GraphicsEnvironment.getLocalGraphicsEnvironment();
303 | GraphicsDevice gd = ge.getDefaultScreenDevice();
304 | GraphicsConfiguration gc = gd.getDefaultConfiguration();
305 | BufferedImage image = gc.createCompatibleImage(w, h);
306 | Graphics2D g2d = image.createGraphics();
307 | icon.paintIcon(null, g2d, 0, 0);
308 | Image grayImage = GrayFilter.createDisabledImage(image);
309 | */
310 |
311 | ImageIcon disabledIcon =
312 | new ImageIcon(this.getClass().getResource(disabledImageLocation));
313 |
314 | // b.setLayout(new BorderLayout());
315 | // b.setIcon(icon);
316 | // JLabel label = new JLabel(icon);
317 | // b.add(label);
318 | b.setIcon(icon);
319 | b.setRolloverEnabled(true);
320 | b.setRolloverIcon(rolloverIcon);
321 | b.setDisabledIcon(disabledIcon);
322 | // b.setIconTextGap(0);
323 | // b.setMargin(new Insets(0, 0, 0, 0));
324 | // b.setSize(d);
325 | b.setFocusPainted(false);
326 | b.setBackground(Color.black);
327 | Border emptyBorder = BorderFactory.createEmptyBorder();
328 | b.setBorder(emptyBorder);
329 | b.setName(buttonName);
330 | b.setActionCommand(actionCommand);
331 | b.addActionListener(this);
332 | b.addMouseListener(this);
333 | b.addMouseMotionListener(this);
334 |
335 | if (DEBUG_BORDER) {
336 | b.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE), b.getBorder()));
337 | }
338 |
339 | buttons.add(b);
340 |
341 | return b;
342 | }
343 |
344 | protected JLabel addLabel(String content, int buttonWidth, int separatorCount) {
345 | JLabel label = new JLabel(content, SwingConstants.CENTER);
346 | // label.setAlignmentX(Component.BOTTOM_ALIGNMENT);
347 | // label.setAlignmentY(Component.);
348 | label.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.WHITE));
349 | label.setForeground(Color.WHITE);
350 | label.setPreferredSize(new Dimension(buttonWidth + separatorCount*space1,
351 | label.getHeight()));
352 | return label;
353 | }
354 |
355 | protected void showHelpMenu(final String imageLocation) {
356 | SwingUtilities.invokeLater(new Runnable() {
357 |
358 | @Override
359 | public void run() {
360 | JFrame f = new JFrame("Git Manager Help");
361 | JPanel p = new JPanel();
362 |
363 | // TODO: Should a BufferedImage be used instead?
364 | ImageIcon icon = new ImageIcon(this.getClass().getResource(imageLocation));
365 | JLabel imLabel = new JLabel(icon);
366 | p.add(imLabel);
367 | f.add(p);
368 | Toolkit.setIcon(f);
369 | f.pack();
370 | f.setVisible(true);
371 | }
372 | });
373 | }
374 |
375 | @Override
376 | public void paintComponent(Graphics g) {
377 | super.paintComponent(g);
378 | // try {
379 | // UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
380 | // } catch (ClassNotFoundException e) {
381 | // e.printStackTrace();
382 | // } catch (InstantiationException e) {
383 | // e.printStackTrace();
384 | // } catch (IllegalAccessException e) {
385 | // e.printStackTrace();
386 | // } catch (UnsupportedLookAndFeelException e) {
387 | // e.printStackTrace();
388 | // }
389 | this.setOpaque(true);
390 | this.setBackground(Color.BLACK);
391 | initializeDimensions(g);
392 | //renderRepoSelectionMenu(g); TODO: Uncomment for online
393 | //renderExpertiseLevelMenu(g); TODO: Uncomment for expertise
394 |
395 | }
396 |
397 | // ALWAYS call renderExpertiseLevelMenu() before renderRepoSelectionMenu()
398 |
399 | void renderExpertiseLevelMenu(Graphics g) {
400 |
401 | if (Platform.isLinux()) {
402 | g.setColor(new Color(0, 0, 0));
403 | g.drawImage(
404 | new ImageIcon((this.getClass()
405 | .getResource(OptionBar.MODE_MENU_ARROW_LINUX)))
406 | .getImage(), elmX2 - OptionBar.ARROW_WIDTH
407 | - OptionBar.MODE_GAP_WIDTH, elmY1 + 1
408 | + (elmY2 - elmY1 - 1 - OptionBar.ARROW_HEIGHT) / 2,
409 | OptionBar.ARROW_WIDTH, OptionBar.ARROW_HEIGHT, null);
410 | } else {
411 | g.setColor(new Color(255, 255, 255));
412 | g.drawImage(
413 | new ImageIcon((this.getClass()
414 | .getResource(OptionBar.MODE_MENU_ARROW)))
415 | .getImage(), elmX2 - OptionBar.ARROW_WIDTH
416 | - OptionBar.MODE_GAP_WIDTH, elmY1 + 1
417 | + (elmY2 - elmY1 - 1 - OptionBar.ARROW_HEIGHT) / 2,
418 | OptionBar.ARROW_WIDTH, OptionBar.ARROW_HEIGHT, null);
419 | }
420 | g.setFont(this.getFont());
421 |
422 | // the following few pieces of code have been adapted from
423 | // Processing so as to resemble it
424 |
425 | g.drawRect(elmX1, elmY1, elmX2 - elmX1, elmY2 - elmY1 - 1);
426 | g.drawString("Novice", elmX1 + OptionBar.MODE_GAP_WIDTH, elmY1
427 | + (OptionBar.MODE_BOX_HEIGHT + elmTextAscent) / 2
428 | + elmTextAscent / 3);
429 |
430 | }
431 |
432 | void renderRepoSelectionMenu(Graphics g) {
433 | if (Platform.isLinux())
434 | g.setColor(new Color(0, 0, 0));
435 | else
436 | g.setColor(new Color(255, 255, 255));
437 |
438 | g.drawRect(rsmX1, rsmY1, rsmX2 - rsmX1, rsmY2 - rsmY1 - 1);
439 | if (Platform.isLinux())
440 | g.drawImage(
441 | new ImageIcon((this.getClass()
442 | .getResource(OptionBar.MODE_MENU_ARROW_LINUX)))
443 | .getImage(), rsmX1 + OptionBar.MODE_GAP_WIDTH,
444 | rsmY1 + 1 + (rsmY2 - rsmY1 - 1 - OptionBar.ARROW_HEIGHT)
445 | / 2, OptionBar.ARROW_WIDTH, OptionBar.ARROW_HEIGHT,
446 | null);
447 | else
448 | g.drawImage(
449 | new ImageIcon((this.getClass()
450 | .getResource(OptionBar.MODE_MENU_ARROW)))
451 | .getImage(), rsmX1 + OptionBar.MODE_GAP_WIDTH,
452 | rsmY1 + 1 + (rsmY2 - rsmY1 - 1 - OptionBar.ARROW_HEIGHT)
453 | / 2, OptionBar.ARROW_WIDTH, OptionBar.ARROW_HEIGHT,
454 | null);
455 | }
456 |
457 | void initializeDimensions(Graphics g) {
458 | FontMetrics metrics = g.getFontMetrics(this.getFont());
459 |
460 | elmTextWidth = metrics.stringWidth("Novice");
461 | elmTextAscent = metrics.getHeight();
462 | elmX2 = getWidth() - 46;
463 | elmX1 = elmX2
464 | - (OptionBar.MODE_GAP_WIDTH + elmTextWidth
465 | + OptionBar.MODE_GAP_WIDTH + OptionBar.ARROW_WIDTH + OptionBar.MODE_GAP_WIDTH);
466 | elmY1 = (getHeight() - 4 * OptionBar.MODE_BOX_HEIGHT) / 2;
467 | elmY2 = elmY1 + OptionBar.MODE_BOX_HEIGHT + elmTextAscent;
468 |
469 | rsmY1 = elmY1;
470 | rsmY2 = elmY2;
471 | rsmX1 = elmX1 - OptionBar.MODE_GAP_WIDTH - OptionBar.MODE_GAP_WIDTH
472 | - OptionBar.ARROW_WIDTH - OptionBar.MODE_GAP_WIDTH;
473 | rsmX2 = elmX1 - OptionBar.MODE_GAP_WIDTH;
474 |
475 | }
476 |
477 | @Override
478 | public void mousePressed(MouseEvent e) {
479 | int x = e.getX();
480 | int y = e.getY();
481 |
482 | // System.out.println("clicked x,y: " + x + " " + y);
483 |
484 | if (x > elmX1 && x < elmX2 && y > elmY1 && y < elmY2) {
485 | expertiseLevelMenuRender(e);
486 | return;
487 | }
488 |
489 | if (x > rsmX1 && x < rsmX2 && y > rsmY1 && y < rsmY2) {
490 | //onlineRepoMenuRender(e); TODO: Uncomment for online
491 | return;
492 | }
493 | }
494 |
495 | private void expertiseLevelMenuRender(MouseEvent e) {
496 | JPopupMenu popup = new JPopupMenu("Expertise Level");
497 |
498 | JRadioButtonMenuItem item = new JRadioButtonMenuItem("Novice");
499 | // doesn't need a listener, since it doesn't do anything
500 | item.setSelected(true);
501 | popup.add(item);
502 |
503 | JMenuItem item2 = new JMenuItem("Pro");
504 | item2.addActionListener(new ActionListener() {
505 | public void actionPerformed(ActionEvent e) {
506 |
507 | }
508 | });
509 | popup.add(item2);
510 | popup.setVisible(true);
511 | popup.show(e.getComponent(), e.getX(), e.getY());
512 | popup.requestFocus();
513 |
514 | }
515 |
516 | private void onlineRepoMenuRender(MouseEvent e) {
517 |
518 | // TODO: Add separators between the items
519 | JPopupMenu popup = new JPopupMenu("Online Repo Selection");
520 | popup.setLayout(new BoxLayout(popup,BoxLayout.X_AXIS));
521 |
522 | JMenuItem item = new JMenuItem(new ImageIcon(this.getClass()
523 | .getResource(OptionBar.REPO_GITHUB)));
524 |
525 | item.addActionListener(new ActionListener() {
526 | public void actionPerformed(ActionEvent e) {
527 | SwingWorker worker = new SwingWorker() {
528 | @Override
529 | public Void doInBackground() {
530 | new GitGHOperations();
531 | return null;
532 | }
533 | //
534 | // @Override
535 | // public void done() {
536 | // }
537 | };
538 | worker.execute();
539 | }
540 | });
541 | popup.add(item);
542 |
543 | // popup.add(Box.createHorizontalStrut(5));
544 | // popup.add(new JSeparator(SwingConstants.VERTICAL));
545 | // popup.add(Box.createHorizontalStrut(5));
546 |
547 | JMenuItem item2 = new JMenuItem(new ImageIcon(this.getClass()
548 | .getResource(OptionBar.REPO_BITBUCKET)));
549 | item2.addActionListener(new ActionListener() {
550 | public void actionPerformed(ActionEvent e) {
551 | SwingWorker worker = new SwingWorker() {
552 | @Override
553 | public Void doInBackground() {
554 | new GitBBOperations();
555 | return null;
556 | }
557 | //
558 | // @Override
559 | // public void done() {
560 | // }
561 | };
562 | worker.execute();
563 | new GitBBOperations();
564 | }
565 | });
566 | popup.add(item2);
567 |
568 | // popup.add(Box.createHorizontalStrut(5));
569 | // popup.add(new JSeparator(SwingConstants.VERTICAL));
570 | // popup.add(Box.createHorizontalStrut(5));
571 |
572 | JMenuItem item3 = new JMenuItem(new ImageIcon(this.getClass()
573 | .getResource(OptionBar.REPO_SOURCEFORGE)));
574 | item3.addActionListener(new ActionListener() {
575 | public void actionPerformed(ActionEvent e) {
576 |
577 | }
578 | });
579 | popup.add(item3);
580 |
581 | popup.pack();
582 | popup.setVisible(true);
583 | popup.show(e.getComponent(), e.getX() - 120, e.getY());
584 | // TODO: 120 has been hard-coded to push the menu to the left.
585 | // Replace with sum of all image widths
586 | popup.requestFocus();
587 |
588 | JMenuItem item4 = new JMenuItem(new ImageIcon(this.getClass()
589 | .getResource(OptionBar.REPO_GOOGLE_PROJ_HOST)));
590 | item4.addActionListener(new ActionListener() {
591 | public void actionPerformed(ActionEvent e) {
592 |
593 | }
594 | });
595 | popup.add(item4);
596 |
597 | popup.pack();
598 | popup.setVisible(true);
599 | popup.show(e.getComponent(), e.getX() - 120, e.getY());
600 | // TODO: 120 has been hard-coded to push the menu to the left.
601 | // Replace with sum of all image widths
602 | popup.requestFocus();
603 | }
604 |
605 | public void clearDescription() {
606 | buttonDescription.setText("");
607 | }
608 |
609 | // @Override
610 | // public boolean isRollover() {
611 | // return super.isRollover();
612 | // }
613 |
614 | @Override
615 | public void mouseClicked(MouseEvent e) {
616 | }
617 |
618 | @Override
619 | public void mouseReleased(MouseEvent e) {
620 | }
621 |
622 | @Override
623 | public void mouseEntered(MouseEvent e) {
624 | String prnt = e.getComponent().getName();
625 | // TODO: if ()
626 | buttonDescription.setText(prnt);
627 | }
628 |
629 | @Override
630 | public void mouseExited(MouseEvent e) {
631 | buttonDescription.setText("");
632 | }
633 |
634 | @Override
635 | public void mouseDragged(MouseEvent e) {
636 | }
637 |
638 | @Override
639 | public void mouseMoved(MouseEvent e) {
640 | }
641 |
642 | @Override
643 | public void actionPerformed(ActionEvent e) {
644 | String a = e.getActionCommand();
645 | if (a.equals(OptionBar.ACTION_INIT)) {
646 | ((JButton)e.getSource()).getModel().setRollover(false);
647 | buttonDescription.setText("");
648 | gitops.initRepo();
649 | }
650 | else if (a.equals(OptionBar.ACTION_ADD))
651 | gitops.addFiles();
652 | else if (a.equals(OptionBar.ACTION_DIFF)) {
653 | gitops.printDiffWithHead();
654 | }
655 | else if (a.equals(OptionBar.ACTION_PUSH)) {
656 | ((JButton)e.getSource()).getModel().setRollover(false);
657 | buttonDescription.setText("");
658 | System.out.println("Pushing...");
659 | // TODO: Design a button different from the current push and the
660 | // push that displays on mouseover which remains until the push
661 | // action is complete, and then changes back to original push
662 | // button
663 | SwingWorker worker = new SwingWorker() {
664 | @Override
665 | public Void doInBackground() {
666 | gitops.getUnameandPass();
667 | gitops.pushToRemote();
668 | return null;
669 | }
670 | //
671 | // @Override
672 | // public void done() {
673 | // }
674 | };
675 | worker.execute();
676 | }
677 | else if (a.equals(OptionBar.ACTION_REVERT)) {
678 | ((JButton)e.getSource()).getModel().setRollover(false);
679 | buttonDescription.setText("");
680 | gitops.revertCommit();
681 | }
682 | else if (a.equals(OptionBar.ACTION_LOG))
683 | gitops.printLogs();
684 | else if (a.equals(OptionBar.ACTION_SNAP)) {
685 | ((JButton)e.getSource()).getModel().setRollover(false);
686 | buttonDescription.setText("");
687 | gitops.addAndCommit(getMessage("Enter commit message"));
688 | }
689 | else if (a.equals(OptionBar.ACTION_RM)) {
690 | ((JButton)e.getSource()).getModel().setRollover(false);
691 | buttonDescription.setText("");
692 | gitops.resetHard();
693 | }
694 | else if (a.equals(OptionBar.ACTION_STATUS)) {
695 | gitops.displayStatus();
696 | }
697 | else if (a.equals(OptionBar.ACTION_PULL))
698 | {
699 | System.out.println("Pulling...");
700 | ((JButton)e.getSource()).getModel().setRollover(false);
701 | buttonDescription.setText("");
702 | // TODO: Design a button different from the current pull and the
703 | // pull that displays on mouseover which remains until the pull
704 | // action is complete, and then changes back to original pull
705 | // button- almost identical to the similar todo for push
706 | SwingWorker worker = new SwingWorker() {
707 | @Override
708 | public Void doInBackground() {
709 | gitops.pullFromRemote();
710 | return null;
711 | }
712 | //
713 | // @Override
714 | // public void done() {
715 | // }
716 | };
717 | worker.execute();
718 | }
719 | else if (a.equals(OptionBar.ACTION_HELP)) {
720 | showHelpMenu(OptionBar.HELP_SCREEN);
721 | }
722 | else if (a.equals(OptionBar.ACTION_BUG)) {
723 | Platform.openURL(OptionBar.URL_BUG);
724 | }
725 | else if (a.equals(OptionBar.ACTION_SITE)) {
726 | Platform.openURL(OptionBar.URL_GIT_MANAGER);
727 | }
728 | disableButtons();
729 |
730 | }
731 |
732 | public void disableButtons() {
733 | for (JButton b: buttons) {
734 | if (b.getName().equals(OptionBar.DESCRIP_INIT)) {
735 | b.setEnabled(!gitops.repoExists());
736 | }
737 | else if (b.getName().equals(OptionBar.DESCRIP_SNAP)
738 | || b.getName().equals(OptionBar.DESCRIP_PULL)
739 | || b.getName().equals(OptionBar.DESCRIP_LOG)
740 | || b.getName().equals(OptionBar.DESCRIP_STATUS)) {
741 | b.setEnabled(gitops.repoExists());
742 | }
743 | else if (b.getName().equals(OptionBar.DESCRIP_PUSH)
744 | || b.getName().equals(OptionBar.DESCRIP_REVERT)
745 | || b.getName().equals(OptionBar.DESCRIP_RM)) {
746 | b.setEnabled(gitops.hasCommit());
747 | }
748 | }
749 | }
750 |
751 | public String getMessage(String dialogText) {
752 | return JOptionPane.showInputDialog(this, dialogText, null);
753 | }
754 | }
755 |
--------------------------------------------------------------------------------
/src/git_manager/tool/GitOperations.java:
--------------------------------------------------------------------------------
1 | /*
2 | Part of the Git Manager for Processing- http://joelmoniz.com/git-manager/
3 |
4 | A tool for the Processing - http://processing.org
5 |
6 | Copyright (c) 2015 Joel Moniz
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 | USA.
22 | */
23 | package git_manager.tool;
24 |
25 | import git_manager.utils.HintTextField;
26 |
27 | import java.awt.Dimension;
28 | import java.awt.GridLayout;
29 | import java.io.ByteArrayOutputStream;
30 | import java.io.File;
31 | import java.io.IOException;
32 | import java.io.InputStream;
33 | import java.nio.file.Files;
34 | import java.util.ArrayList;
35 | import java.util.Date;
36 | import java.util.Iterator;
37 | import java.util.List;
38 | import java.util.Set;
39 |
40 | import javax.swing.BoxLayout;
41 | import javax.swing.JCheckBox;
42 | import javax.swing.JFrame;
43 | import javax.swing.JLabel;
44 | import javax.swing.JOptionPane;
45 | import javax.swing.JPanel;
46 | import javax.swing.JPasswordField;
47 | import javax.swing.JScrollPane;
48 | import javax.swing.JTextField;
49 |
50 | import org.eclipse.jgit.api.Git;
51 | import org.eclipse.jgit.api.MergeResult;
52 | import org.eclipse.jgit.api.PullResult;
53 | import org.eclipse.jgit.api.ResetCommand;
54 | import org.eclipse.jgit.api.ResetCommand.ResetType;
55 | import org.eclipse.jgit.api.RevertCommand;
56 | import org.eclipse.jgit.api.Status;
57 | import org.eclipse.jgit.api.errors.CheckoutConflictException;
58 | import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
59 | import org.eclipse.jgit.api.errors.GitAPIException;
60 | import org.eclipse.jgit.api.errors.InvalidRemoteException;
61 | import org.eclipse.jgit.api.errors.NoFilepatternException;
62 | import org.eclipse.jgit.api.errors.NoHeadException;
63 | import org.eclipse.jgit.api.errors.NoMessageException;
64 | import org.eclipse.jgit.api.errors.TransportException;
65 | import org.eclipse.jgit.api.errors.UnmergedPathsException;
66 | import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
67 | import org.eclipse.jgit.diff.DiffEntry;
68 | import org.eclipse.jgit.diff.DiffFormatter;
69 | import org.eclipse.jgit.errors.AmbiguousObjectException;
70 | import org.eclipse.jgit.errors.IncorrectObjectTypeException;
71 | import org.eclipse.jgit.errors.NoWorkTreeException;
72 | import org.eclipse.jgit.errors.RevisionSyntaxException;
73 | import org.eclipse.jgit.internal.storage.file.FileRepository;
74 | import org.eclipse.jgit.lib.Constants;
75 | import org.eclipse.jgit.lib.ObjectId;
76 | import org.eclipse.jgit.lib.ObjectReader;
77 | import org.eclipse.jgit.lib.Repository;
78 | import org.eclipse.jgit.lib.StoredConfig;
79 | import org.eclipse.jgit.revwalk.RevCommit;
80 | import org.eclipse.jgit.transport.CredentialsProvider;
81 | import org.eclipse.jgit.transport.FetchResult;
82 | import org.eclipse.jgit.transport.PushResult;
83 | import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
84 | import org.eclipse.jgit.treewalk.CanonicalTreeParser;
85 |
86 | import processing.app.Messages;
87 | import processing.app.ui.Editor;
88 |
89 | public class GitOperations {
90 |
91 | public static String GITIGNORE_LOCATION = "/data/code/sample_gitignore.txt";
92 | Editor editor;
93 | File gitDir;
94 | File thisDir;
95 | Git git;
96 | String uName, pass, remote;
97 |
98 | public GitOperations(Editor editor) {
99 | this.editor = editor;
100 | // if (Base.isLinux())
101 | // gitDir = new File(editor.getSketch().getFolder().getAbsolutePath()
102 | // + "/.git");
103 | // else
104 | gitDir = new File(editor.getSketch().getFolder().getAbsolutePath(), ".git");
105 | thisDir = new File(editor.getSketch().getFolder().getAbsolutePath());
106 | try {
107 | git = new Git(new FileRepository(gitDir));
108 | } catch (IOException e) {
109 | e.printStackTrace();
110 | }
111 |
112 | }
113 |
114 | public void initRepo() {
115 | if (repoExists()) {
116 | System.out.println("Repo already exists!");
117 | return;
118 | }
119 |
120 | try {
121 | // System.out.println(gitDir.getAbsolutePath());
122 | Git.init().setDirectory(thisDir).setBare(false).call();
123 | getConfigParameters();
124 | createGitIgnore();
125 | System.out.println("New repo created.");
126 | } catch (InvalidRemoteException e) {
127 | e.printStackTrace();
128 | } catch (TransportException e) {
129 | e.printStackTrace();
130 | } catch (GitAPIException e) {
131 | e.printStackTrace();
132 | }
133 | }
134 |
135 | public boolean repoExists() {
136 | return gitDir.exists();
137 | }
138 |
139 | public boolean hasCommit() {
140 | if (!repoExists())
141 | return false;
142 | Iterable commits;
143 | try {
144 | commits = git.log().call();
145 | for( RevCommit commit : commits ) {
146 | return true;
147 | }
148 | } catch (NoHeadException e) {
149 | // This error keeps popping up when there are no commits
150 | // Don't wanna freak out/annoy the user
151 | // e.printStackTrace();
152 | } catch (GitAPIException e) {
153 | e.printStackTrace();
154 | }
155 | return false;
156 | }
157 |
158 | public int getCommitCount() {
159 | if (!repoExists())
160 | return -1;
161 | Iterable commits;
162 | int count = -1;
163 | try {
164 | commits = git.log().call();
165 | count = 0;
166 | for( RevCommit commit : commits ) {
167 | count++;
168 | }
169 | } catch (NoHeadException e) {
170 | // This error keeps popping up when there are no commits
171 | // Don't wanna freak out/annoy the user
172 | count = 0;
173 | // e.printStackTrace();
174 | } catch (GitAPIException e) {
175 | e.printStackTrace();
176 | }
177 | return count;
178 | }
179 |
180 | // TODO: Ensure that repo name == sketchname
181 | public void createGitIgnore() {
182 | InputStream sourceGitignore = this.getClass().getResourceAsStream(GITIGNORE_LOCATION);
183 | File destGitignore = new File(thisDir.getAbsolutePath(), ".gitignore");
184 | try {
185 | if (!destGitignore.exists()) {
186 | Files.copy(sourceGitignore, destGitignore.toPath());
187 | }
188 | } catch (IOException e) {
189 | e.printStackTrace();
190 | }
191 | }
192 |
193 | public void getConfigParameters() {
194 | StoredConfig config = git.getRepository().getConfig();
195 | String name = config.getString("user", null, "name");
196 | String email = config.getString("user", null, "email");
197 | if (name != null && email != null) {
198 | Object[] options = { "Yes", "No" };
199 | // TODO: Probably get this on the EDT instead
200 | int n = JOptionPane.showOptionDialog(new JFrame(), "The following global "
201 | + "user details have been detected:\n Name: "
202 | + name + "\n Email: " + email + "\n\nContinue with these details?",
203 | "Who's there?",
204 | JOptionPane.YES_NO_OPTION,
205 | JOptionPane.QUESTION_MESSAGE, null,
206 | options, options[1]);
207 | if (n==JOptionPane.YES_OPTION) {
208 | return;
209 | }
210 | }
211 |
212 | // TODO: Definitely make this nicer- better parsing and error handling, etc.
213 | // TODO: On the EDT with this too!
214 | // Adapted from http://www.edu4java.com/en/swing/swing3.html
215 | name = "";
216 | email = "";
217 | while (name.isEmpty() || email.isEmpty()) {
218 | JPanel configPanel = new JPanel();
219 | configPanel.setLayout(null);
220 | configPanel.setPreferredSize(new Dimension(300, 80));
221 |
222 | JLabel nameLabel = new JLabel("Name");
223 | nameLabel.setBounds(10, 10, 80, 25);
224 | configPanel.add(nameLabel);
225 |
226 | JTextField nameText = new JTextField(20);
227 | nameText.setBounds(100, 10, 160, 25);
228 | configPanel.add(nameText);
229 | nameText.setText(name);
230 |
231 | JLabel emailLabel = new JLabel("Email");
232 | emailLabel.setBounds(10, 40, 80, 25);
233 | configPanel.add(emailLabel);
234 |
235 | JTextField emailText = new JTextField(20);
236 | emailText.setBounds(100, 40, 160, 25);
237 | configPanel.add(emailText);
238 | emailText.setText(email);
239 |
240 | JOptionPane.showMessageDialog(new JFrame(),
241 | configPanel, "User details",
242 | JOptionPane.PLAIN_MESSAGE, null);
243 |
244 | name = nameText.getText();
245 | email = emailText.getText();
246 |
247 | if (name.isEmpty() || email.isEmpty()) {
248 | JOptionPane.showMessageDialog(new JFrame(),
249 | "Neither the name nor the email address can be left blank", "Nopes",
250 | JOptionPane.ERROR_MESSAGE, null);
251 | }
252 | }
253 |
254 | config.setString("user", null, "name", name);
255 | config.setString("user", null, "email", email);
256 | try {
257 | config.save();
258 | } catch (IOException e) {
259 | e.printStackTrace();
260 | }
261 | }
262 |
263 | public void initBareRepo() {
264 | Repository repo;
265 | try {
266 | repo = new FileRepository(thisDir);
267 | repo.create(true);
268 | System.out.println("Bare repo created.");
269 | } catch (IOException e) {
270 | e.printStackTrace();
271 | }
272 | }
273 |
274 | public void cloneRepo(File cloneFrom, File cloneTo) {
275 | try {
276 | Git.cloneRepository().setURI(cloneFrom.getAbsolutePath())
277 | .setDirectory(cloneTo).setBranch("master").setBare(false)
278 | .setRemote("origin").setNoCheckout(false).call();
279 | } catch (InvalidRemoteException e) {
280 | e.printStackTrace();
281 | } catch (TransportException e) {
282 | e.printStackTrace();
283 | } catch (GitAPIException e) {
284 | e.printStackTrace();
285 | }
286 | }
287 |
288 | public void addAndCommit(String comment) {
289 |
290 | if (comment == null) {
291 | System.out.println("Commit Cancelled");
292 | return;
293 | }
294 | if (comment.equals("")) {
295 | int result = JOptionPane.showConfirmDialog(null,
296 | "You have not entered a commit message. Proceed anyway?",
297 | "No commit message warning", JOptionPane.OK_CANCEL_OPTION);
298 |
299 | if (result != JOptionPane.OK_OPTION) {
300 | System.out.println("Commit Cancelled");
301 | return;
302 | }
303 | }
304 |
305 | try {
306 | git.add().addFilepattern(".").call();
307 | git.commit().setMessage(comment).call();
308 | System.out.println("Snapshot complete");
309 | } catch (NoFilepatternException e) {
310 | e.printStackTrace();
311 | } catch (GitAPIException e) {
312 | e.printStackTrace();
313 | }
314 | }
315 |
316 | public void addFiles() {
317 |
318 | try {
319 | git.add().addFilepattern(".").call();
320 | System.out.println("All files added");
321 | } catch (GitAPIException e) {
322 | e.printStackTrace();
323 | }
324 | }
325 |
326 | public void commitChanges(String comment) {
327 |
328 | if (comment == null) {
329 | System.out.println("Commit Cancelled");
330 | return;
331 | }
332 | if (comment.equals("")) {
333 | int result = JOptionPane.showConfirmDialog(null,
334 | "You have not entered a commit message. Proceed anyway?",
335 | "No commit message warning", JOptionPane.OK_CANCEL_OPTION);
336 |
337 | if (result != JOptionPane.OK_OPTION) {
338 | System.out.println("Commit Cancelled");
339 | return;
340 | }
341 | }
342 | try {
343 | git.commit().setMessage(comment).call();
344 | System.out.println("Commit complete");
345 | } catch (NoHeadException e) {
346 | e.printStackTrace();
347 | } catch (NoMessageException e) {
348 | e.printStackTrace();
349 | } catch (UnmergedPathsException e) {
350 | e.printStackTrace();
351 | } catch (ConcurrentRefUpdateException e) {
352 | e.printStackTrace();
353 | } catch (WrongRepositoryStateException e) {
354 | e.printStackTrace();
355 | } catch (GitAPIException e) {
356 | e.printStackTrace();
357 | }
358 | }
359 |
360 | public void pushToRemote() {
361 |
362 | if (uName == null || pass == null || remote == null) {
363 | System.out.println("Push cancelled");
364 | return;
365 | }
366 | if (uName.equals("") || pass.equals("") || remote.equals("")) {
367 | if (uName.equals(""))
368 | System.out.println("Please enter a valid username");
369 |
370 | if (pass.equals(""))
371 | System.out.println("Please enter a valid password");
372 |
373 | if (remote.equals(""))
374 | System.out
375 | .println("Please enter a valid online repository address");
376 | uName = pass = remote = null;
377 | return;
378 | }
379 |
380 | if (!remote.endsWith(".git")) {
381 | remote = remote + ".git";
382 | }
383 |
384 | storeRemote();
385 |
386 | // Get TransportException when project is >1Mb
387 | // TODO: Fix this:
388 | // https://groups.google.com/forum/#!topic/bitbucket-users/OUsa8sb_Ti4
389 | CredentialsProvider cp = new UsernamePasswordCredentialsProvider(uName,
390 | pass);
391 |
392 | Iterable pc;
393 | try {
394 | pc = git.push().setRemote(remote).setCredentialsProvider(cp).call();
395 | for (PushResult pushResult : pc) {
396 | System.out.println(pushResult.getURI());
397 | }
398 | System.out.println("Push Complete");
399 |
400 | } catch (InvalidRemoteException e) {
401 | e.printStackTrace();
402 | } catch (TransportException e) {
403 | // System.out
404 | // .println("Please use a project of size <1MB when pushing (will be resolved soon)...");
405 | e.printStackTrace();
406 | } catch (GitAPIException e) {
407 | e.printStackTrace();
408 | } finally {
409 | uName = null;
410 | remote = null;
411 | pass = null;
412 | }
413 |
414 | }
415 |
416 | void storeRemote() {
417 | StoredConfig cofig = git.getRepository().getConfig();
418 | String configRemote = cofig.getString("remote", "origin", "url");
419 | // String configUname = cofig.getString("remote", "origin", "url");
420 |
421 | if (configRemote == null || !configRemote.equals(remote)) {
422 | cofig.setString("remote", "origin", "url", remote);
423 | cofig.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
424 | try {
425 | cofig.save();
426 | } catch (IOException e) {
427 | e.printStackTrace();
428 | }
429 | }
430 | }
431 |
432 | void storeMergeBranch() {
433 | StoredConfig cofig = git.getRepository().getConfig();
434 |
435 | cofig.setString("branch", "master", "remote", "origin");
436 | cofig.setString("branch", "master", "merge", "refs/heads/master");
437 | try {
438 | cofig.save();
439 | } catch (IOException e) {
440 | e.printStackTrace();
441 | }
442 | }
443 |
444 | void getUnameandPass() {
445 | JTextField uName = new JTextField(15);
446 | JPasswordField pass = new JPasswordField(15);
447 | HintTextField remote = new HintTextField("https://github.com/uname/repo.git");
448 |
449 | JPanel panel = new JPanel(new GridLayout(0, 1));
450 | JPanel un = new JPanel();
451 | JPanel un2 = new JPanel();
452 | JPanel un3 = new JPanel();
453 | un.add(new JLabel("Username: "));
454 | un.add(uName);
455 | panel.add(un);
456 | un2.add(new JLabel("Password: "));
457 | un2.add(pass);
458 | panel.add(un2);
459 | un3.add(new JLabel("Repo:"));
460 | un3.add(remote);
461 | panel.add(un3);
462 |
463 | StoredConfig cofig = git.getRepository().getConfig();
464 | String remt = cofig.getString("remote", "origin", "url");
465 |
466 | if (remt != null && !remt.isEmpty()) {
467 | remote.setText(remt);
468 | }
469 |
470 | int result = JOptionPane.showConfirmDialog(null, panel,
471 | "Login Credentials", JOptionPane.OK_CANCEL_OPTION,
472 | JOptionPane.PLAIN_MESSAGE);
473 | if (result == JOptionPane.OK_OPTION) {
474 | this.uName = uName.getText();
475 | this.pass = new String(pass.getPassword());
476 | this.remote = remote.getText();
477 | }
478 | }
479 |
480 | boolean getRemote() {
481 | HintTextField remote = new HintTextField("https://github.com/uname/repo.git");
482 |
483 | JPanel panel = new JPanel(new GridLayout(0, 1));
484 | JPanel un3 = new JPanel();
485 | un3.add(new JLabel("Repo:"));
486 | un3.add(remote);
487 | panel.add(un3);
488 |
489 | StoredConfig cofig = git.getRepository().getConfig();
490 | String remt = cofig.getString("remote", "origin", "url");
491 |
492 | if (remt != null && !remt.isEmpty()) {
493 | remote.setText(remt);
494 | remote.disableHint();
495 | }
496 |
497 | int result = JOptionPane.showConfirmDialog(null, panel,
498 | "Remote address", JOptionPane.OK_CANCEL_OPTION,
499 | JOptionPane.PLAIN_MESSAGE);
500 | if (result == JOptionPane.OK_OPTION) {
501 | this.remote = remote.getText();
502 | }
503 | return (result == JOptionPane.OK_OPTION);
504 | }
505 |
506 | public void pullFromRemote() {
507 | if (!getRemote()) {
508 | System.out.println("Pull cancelled.");
509 | return;
510 | }
511 | storeRemote();
512 | storeMergeBranch();
513 | PullResult result;
514 | try {
515 | result = git.pull().call();
516 | FetchResult fetchResult = result.getFetchResult();
517 | MergeResult mergeResult = result.getMergeResult();
518 | // TODO: Handle merge conflicts :O
519 | // TODO: Handle NoHeadException (repo not initialized)
520 | // TODO: Handle InvalidConfigurationException (no pushes made till now-
521 | // configure remote manually)
522 | System.out.println(mergeResult.getMergeStatus());
523 | // System.out.println("fetch status: " + fetchResult.getMessages());
524 | } catch (InvalidRemoteException e) {
525 | e.printStackTrace();
526 | } catch (TransportException e) {
527 | // System.out
528 | // .println("Please use a project of size <1MB when pushing (will be resolved soon)...");
529 | e.printStackTrace();
530 | } catch (GitAPIException e) {
531 | e.printStackTrace();
532 | }
533 | }
534 |
535 | public void displayStatus() {
536 | Status status;
537 | try {
538 | status = git.status().call();
539 | if (status.isClean()) {
540 | System.out.println("No changes made in sketch since last commit");
541 | }
542 | else {
543 | Set conflicts = status.getConflicting();
544 | Set untracked = status.getUntracked();
545 | Set added = status.getAdded();
546 | Set changed = status.getChanged();
547 | Set deleted = status.getRemoved();
548 | // deleted.addAll(status.getMissing());
549 | Set missing = status.getMissing();
550 | Set modified = status.getModified();
551 |
552 | // TODO: Explanations not technically sound- intended for first time users not fully familiar with git
553 | printFileStatus("Added", "Files not present in the last commit/snapshot, but will be added in the next commit", added);
554 | printFileStatus("Changed", "Files present in the last commit/snapshot whose modifications will added in the next commit", changed);
555 | printFileStatus("Deleted", "File whose deletion will be recorded in the next commit", deleted);
556 | printFileStatus("Missing", "File whose deletion will be not recorded in the next commit", missing);
557 | printFileStatus("Modified", "File present in the last snapshot/commit, subsequently modified, whose modifications will not yet be added in the next commit", modified);
558 | printFileStatus("Untracked", "New files not yet present in any commits", untracked);
559 |
560 | if (!conflicts.isEmpty()) {
561 | System.out.println("Warning: Conflicts detected in the following files");
562 | printFileStatus("", "", conflicts);
563 | }
564 | }
565 | } catch (NoWorkTreeException e) {
566 | e.printStackTrace();
567 | } catch (GitAPIException e) {
568 | e.printStackTrace();
569 | }
570 |
571 | }
572 |
573 | private void printFileStatus(String type, String description, Set files) {
574 | if (!files.isEmpty()) {
575 | if (type != null && !type.isEmpty()) {
576 | System.out.println("\n" + type + " Files (" + description + "):");
577 | }
578 | for (String f : files) {
579 | System.out.println("\t" + f);
580 | }
581 | }
582 | }
583 |
584 | public void resetHard() {
585 | ResetCommand reset = git.reset();
586 | reset.setRef(Constants.HEAD);
587 | // reset.addPath(".");
588 | reset.setMode(ResetType.HARD);
589 | try {
590 | // Though this should actually have GitManager.frame as the parent, I think
591 | // having editor as the parent is far more convenient, since I observe that I generally
592 | // tend to keep tool window at the corner and the processing IDE in the centre,
593 | // and prefer the dialog box displaying at the center... I think...
594 | int x = Messages.showYesNoQuestion(editor, "Reset sketch to previous commit?", "Are you sure you want to reset the entire skecthbook to the exact state it was in the previous commit?", "All changes made since then will be permanently lost.");
595 | if (x == JOptionPane.YES_OPTION) {
596 | x = Messages.showYesNoQuestion(editor, "Really reset sketch to previous commit?", "Are you absolutely, positively sure you want to reset the entire skecthbook to the exact state it was in the previous commit?", "All changes made since then will be permanently lost, and even git can't recover them.");
597 | if (x == JOptionPane.YES_OPTION) {
598 | reset.call();
599 | System.out.println("Hard reset completed. Sketch is now exactly like the last snapshot/commit.");
600 | }
601 | }
602 | } catch (CheckoutConflictException e) {
603 | e.printStackTrace();
604 | } catch (GitAPIException e) {
605 | e.printStackTrace();
606 | }
607 | }
608 |
609 | // TODO: Finish off a proper diff function
610 | void printDiffWithHead() {
611 | Repository repository = git.getRepository();
612 | ObjectId oldHead;
613 | try {
614 | oldHead = repository.resolve("HEAD~1^{tree}");
615 | ObjectId head = repository.resolve("HEAD^{tree}");
616 |
617 | System.out.println("Printing diff between tree: " + oldHead + " and "
618 | + head);
619 |
620 | // prepare the two iterators to compute the diff between
621 | ObjectReader reader = repository.newObjectReader();
622 | CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
623 | oldTreeIter.reset(reader, oldHead);
624 | CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
625 | newTreeIter.reset(reader, head);
626 |
627 | // finally get the list of changed files
628 | List diffs = git.diff().setNewTree(newTreeIter)
629 | .setOldTree(oldTreeIter).call();
630 | for (DiffEntry entry : diffs) {
631 | System.out.println("Entry: " + entry);
632 | }
633 | System.out.println("----------------------");
634 |
635 | DiffFormatter df = new DiffFormatter( new ByteArrayOutputStream() );
636 | df.setRepository( git.getRepository() );
637 | List entries = df.scan( oldTreeIter, newTreeIter );
638 |
639 | for( DiffEntry entry : entries ) {
640 | System.out.println( entry );
641 | }
642 |
643 | System.out.println("Done");
644 |
645 | repository.close();
646 | } catch (RevisionSyntaxException e) {
647 | e.printStackTrace();
648 | } catch (AmbiguousObjectException e) {
649 | e.printStackTrace();
650 | } catch (IncorrectObjectTypeException e) {
651 | e.printStackTrace();
652 | } catch (IOException e) {
653 | e.printStackTrace();
654 | } catch (GitAPIException e) {
655 | e.printStackTrace();
656 | }
657 | }
658 |
659 | // Source: https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/ShowLog.java
660 | // Refer source for things like log for specific file, specific branch, etc.
661 | public void printLogs() {
662 | if (!hasCommit()) {
663 | System.out.println("\nNo commits exist yet. No logs to show.");
664 | return;
665 | }
666 | Iterable logs = getLogs();
667 |
668 | if (logs != null) {
669 | int count = 0;
670 | System.out.println("\n");
671 | for (RevCommit rev : logs) {
672 | System.out.println("Commit ID: " + rev.getId().getName() + "\n" +
673 | "Author: " + rev.getAuthorIdent().toExternalString() + "\n" +
674 | "Date: " + new Date(rev.getCommitTime()) + "\n\n" +
675 | rev.getFullMessage() + "\n" +
676 | "----------------------------------------------------------");
677 | count++;
678 | }
679 | System.out.println("\nTotal " + count + " commits overall on current branch");
680 | }
681 | }
682 |
683 | public void revertCommit() {
684 | RevertCommand revert = git.revert();
685 | Iterable logs = getLogs();
686 |
687 | if (logs != null) {
688 | // revert.include(logs.iterator().next());
689 | CommitCheckBox commitCheck = new CommitCheckBox(logs);
690 | if (commitCheck.logs.isEmpty()) {
691 | System.out.println("No commits selected to be undone");
692 | }
693 | else {
694 | try {
695 | System.out.println("The following commits will be undone:");
696 | for (RevCommit rc: commitCheck.logs) {
697 | revert.include(rc);
698 | System.out.println(" " + rc.getShortMessage());
699 | }
700 | revert.call();
701 | System.out.println("Done.");
702 | } catch (NoMessageException e) {
703 | e.printStackTrace();
704 | } catch (UnmergedPathsException e) {
705 | e.printStackTrace();
706 | } catch (ConcurrentRefUpdateException e) {
707 | e.printStackTrace();
708 | } catch (WrongRepositoryStateException e) {
709 | e.printStackTrace();
710 | } catch (GitAPIException e) {
711 | e.printStackTrace();
712 | }
713 | }
714 | }
715 | }
716 |
717 | class CommitCheckBox {
718 |
719 | ArrayList logs;
720 | ArrayList checkboxList;
721 | JFrame frame;
722 | JPanel cbPanel;
723 | JScrollPane scrollPane;
724 |
725 | CommitCheckBox(Iterable logsIterable) {
726 | Iterator logs = logsIterable.iterator();
727 | this.logs = new ArrayList<>();
728 | this.checkboxList = new ArrayList<>();
729 | ArrayList loglist = new ArrayList<>();
730 | frame = new JFrame();
731 | cbPanel = new JPanel();
732 | Dimension d = new Dimension(300, 400);
733 | // cbPanel.setPreferredSize(d);
734 | // cbPanel.setMaximumSize(d);
735 | // cbPanel.setMinimumSize(d);
736 | cbPanel.setLayout(new BoxLayout(cbPanel, BoxLayout.Y_AXIS));
737 |
738 | while (logs.hasNext()) {
739 | RevCommit log = logs.next();
740 | loglist.add(log);
741 |
742 | JCheckBox cb = new JCheckBox(log.getShortMessage());
743 | this.checkboxList.add(cb);
744 | cbPanel.add(cb);
745 | }
746 |
747 | scrollPane = new JScrollPane(cbPanel);
748 | scrollPane.setPreferredSize(d);
749 | scrollPane.setMaximumSize(d);
750 | scrollPane.setMinimumSize(d);
751 | scrollPane.getVerticalScrollBar().setUnitIncrement(16);
752 | Object[] options = { "Revert", "Cancel" };
753 | // TODO: Probably get this on the EDT instead
754 | int n = JOptionPane.showOptionDialog(new JFrame(), scrollPane, "Undo Commits",
755 | JOptionPane.YES_NO_OPTION,
756 | JOptionPane.QUESTION_MESSAGE, null,
757 | options, options[1]);
758 | if (n == JOptionPane.YES_OPTION) { // Afirmative
759 | //....
760 | // System.out.println("Yes!");
761 | // TODO: Is this a little hacky?
762 | int i = 0;
763 | for (JCheckBox c : checkboxList) {
764 | if (c.isSelected()) {
765 | this.logs.add(loglist.get(i));
766 | }
767 | i++;
768 | }
769 | }
770 | /*
771 | Do Nothing
772 | else if (n == JOptionPane.NO_OPTION) { // negative
773 | System.out.println("No!");
774 | }
775 | else if (n == JOptionPane.CLOSED_OPTION) { // closed the dialog
776 | System.out.println("Closed!");
777 | }
778 | */
779 | }
780 | }
781 |
782 | private Iterable getLogs() {
783 | Iterable logs = null;
784 | try {
785 | logs = git.log().call();
786 | } catch (NoHeadException e) {
787 | e.printStackTrace();
788 | } catch (GitAPIException e) {
789 | e.printStackTrace();
790 | }
791 | return logs;
792 | }
793 | }
794 |
--------------------------------------------------------------------------------