package gitj.ui;
import iconlib.IconUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import git.Commit;
import git.InvalidRepositoryException;
import git.Repository;
import gitj.Bookmarks;
import gitj.Language;
import gitj.LanguageScanner;
import gitj.Main;
import gitj.Version;
import gitj.tasks.Task;
import gitj.ui.dialogs.DialogCreateStash;
import gitj.ui.dialogs.DialogCreateTag;
import gitj.ui.dialogs.DialogLineCount;
import gitj.ui.dialogs.DialogNew;
import gitj.ui.dialogs.DialogPull;
import gitj.ui.dialogs.DialogPush;
import gitj.ui.dialogs.DialogRemotes;
import gitj.ui.dialogs.DialogTags;
import gitj.utils.GitIconUtils;
import com.redpois0n.pathtree.FileFilter;
import com.redpois0n.pathtree.FileJTree;
import com.redpois0n.pathtree.NodeClickListener;
import com.redpois0n.pathtree.PathTreeNode;
@SuppressWarnings("serial")
public class MainFrame extends JFrame {
public static final Color TABLE_SELECTED = new Color(51, 153, 255);
public static final Color TABLE_GRAY = new Color(240, 240, 240);
private File latestDir;
private Bookmarks bookmarks;
private JPanel contentPane;
private JTabbedPane tabbedPane;
private JTabbedPane leftTabbedPane;
private JSplitPane splitPane;
private FileJTree tree;
private ObjectsPanel objectPane;
private BookmarksPanel bookmarksPanel;
private StatusBar statusBar;
public MainFrame() {
setIconImages(GitIconUtils.getIcons());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1000, 700);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenu mnRepository = new JMenu("Repository");
menuBar.add(mnRepository);
JMenuItem mntmRefresh = new JMenuItem("Refresh");
mntmRefresh.setIcon(IconUtils.getIcon("update-small"));
mntmRefresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
reloadCurrentRepo();
}
});
JMenuItem mntmRemotes = new JMenuItem("Remotes");
mntmRemotes.setIcon(IconUtils.getIcon("remote"));
mntmRemotes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
remotes();
}
});
mnRepository.add(mntmRemotes);
mnRepository.add(mntmRefresh);
JMenuItem mntmTags = new JMenuItem("Tags");
mntmTags.setIcon(IconUtils.getIcon("tag-annotated"));
mntmTags.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showTags();
}
});
mnRepository.add(mntmTags);
JMenuItem mntmLineCount = new JMenuItem("Line Count");
mntmLineCount.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lineCount();
}
});
mnRepository.add(mntmLineCount);
JMenu mnView = new JMenu("View");
menuBar.add(mnView);
JCheckBoxMenuItem chckbxmntmViewLanguageBar = new JCheckBoxMenuItem("View Language Bar");
chckbxmntmViewLanguageBar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getSource();
AbstractPanel panel = getSelectedPanel();
if (panel instanceof MainPanel) {
// TODO
}
}
});
chckbxmntmViewLanguageBar.setSelected(true);
mnView.add(chckbxmntmViewLanguageBar);
mnView.addSeparator();
JMenuItem mntmAddBookmark = new JMenuItem("Add bookmark");
mntmAddBookmark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent paramActionEvent) {
Repository repo = getSelectedRepo();
if (repo != null) {
addBookmark(repo);
}
}
});
mnView.add(mntmAddBookmark);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
contentPane.add(toolBar, BorderLayout.NORTH);
JButton btnCloneNew = new JButton("Clone/New");
btnCloneNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent paramActionEvent) {
newRepo();
}
});
btnCloneNew.setIcon(IconUtils.getIcon("database-add"));
toolBar.add(btnCloneNew);
JButton btnOpen = new JButton("Open");
btnOpen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent paramActionEvent) {
open();
}
});
btnOpen.setIcon(IconUtils.getIcon("folder-open"));
toolBar.add(btnOpen);
toolBar.addSeparator();
JButton btnCommit = new JButton("Commit");
btnCommit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
commit();
}
});
btnCommit.setIcon(IconUtils.getIcon("commit"));
toolBar.add(btnCommit);
JButton btnStash = new JButton("Stash");
btnStash.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
stash();
}
});
btnStash.setIcon(IconUtils.getIcon("stash-big"));
toolBar.add(btnStash);
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
stageSelected();
}
});
JButton btnCheckout = new JButton("Checkout");
btnCheckout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
checkout();
}
});
toolBar.add(btnCheckout);
btnCheckout.setIcon(IconUtils.getIcon("checkout"));
btnAdd.setIcon(IconUtils.getIcon("add-big"));
toolBar.add(btnAdd);
JButton btnRemove = new JButton("Remove");
btnRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
unstageSelected();
}
});
btnRemove.setIcon(IconUtils.getIcon("remove-big"));
toolBar.add(btnRemove);
JButton btnReload = new JButton("Reload");
btnReload.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
reloadCurrentRepo();
}
});
JButton btnTag = new JButton("Tag");
btnTag.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tag();
}
});
btnTag.setIcon(IconUtils.getIcon("tag-big"));
toolBar.add(btnTag);
btnReload.setIcon(IconUtils.getIcon("update"));
toolBar.add(btnReload);
JButton btnFetch = new JButton("Fetch");
btnFetch.setIcon(IconUtils.getIcon("fetch"));
toolBar.add(btnFetch);
JButton btnPull = new JButton("Pull");
btnPull.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
pull();
}
});
btnPull.setIcon(IconUtils.getIcon("pull"));
toolBar.add(btnPull);
JButton btnPush = new JButton("Push");
btnPush.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
push();
}
});
btnPush.setIcon(IconUtils.getIcon("push"));
toolBar.add(btnPush);
splitPane = new JSplitPane();
contentPane.add(splitPane, BorderLayout.CENTER);
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
tabbedPane.addChangeListener(new TabChangeListener());
splitPane.setRightComponent(tabbedPane);
JScrollPane scrollPaneTree = new JScrollPane();
tree = new FileJTree(false);
tree.addFileClickListener(new NodeClickListener() {
@Override
public void itemSelected(PathTreeNode node, String path) {
File file = new File(path);
openFile(node, file);
}
});
bookmarksPanel = new BookmarksPanel(this);
for (String bookmark : Bookmarks.load()) {
File folder = new File(bookmark);
if (folder.exists() && folder.isDirectory()) {
try {
bookmarksPanel.addBookmarkPanel(new BookmarkPanel(bookmarksPanel, new Repository(folder)));
} catch (InvalidRepositoryException e) {
e.printStackTrace();
}
}
}
JScrollPane scrollPaneBookmarks = new JScrollPane();
scrollPaneBookmarks.setViewportView(bookmarksPanel);
scrollPaneTree.setViewportView(tree);
objectPane = new ObjectsPanel(this);
leftTabbedPane = new JTabbedPane(JTabbedPane.TOP);
leftTabbedPane.addTab("Bookmarks", IconUtils.getIcon("bookmark-folder"), scrollPaneBookmarks);
leftTabbedPane.addTab("Files", IconUtils.getIcon("folder-tree"), scrollPaneTree);
leftTabbedPane.addTab("Repository", IconUtils.getIcon("tag-annotated"), objectPane);
splitPane.setLeftComponent(leftTabbedPane);
statusBar = new StatusBar();
contentPane.add(statusBar, BorderLayout.SOUTH);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
splitPane.setDividerLocation(splitPane.getSize().width / 4);
}
});
}
public void addRepoToTree(final Repository repo, String dir) {
tree.setFilter(new FileFilter() {
@Override
public boolean allow(File file) {
try {
return !file.getName().startsWith(".") || repo.isTracked(file);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
});
tree.add(dir, IconUtils.getIcon("repo"));
}
public void openFile(PathTreeNode node, File file) {
File rootDir = new File(node.getText());
Repository repo = getFromName(rootDir.getName());
if (repo != null) {
try {
List<Language> langs = new LanguageScanner(repo, false).scan(true);
for (Language lang : langs) {
for (String ext : lang.getExtensions()) {
if (node.getText().toLowerCase().endsWith(ext)) {
Desktop.getDesktop().open(file); // TODO
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Repository getFromName(String name) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
AbstractPanel panel = (AbstractPanel) tabbedPane.getComponentAt(i);
String tabName = tabbedPane.getTitleAt(i);
if (tabName.equals(name)) {
return panel.getRepository();
}
}
return null;
}
/**
* Loads repository in new panel
* @param repository
*/
public void loadRepository(final Repository repository) {
if (!isOpen(repository)) {
new Thread() {
@Override
public void run() {
try {
statusBar.setUpdating();
statusBar.setText("Loading...");
MainPanel pane = new MainPanel(MainFrame.this, repository);
addPanel(repository.getFolder().getName(), pane, IconUtils.getIcon("repo"));
addRepoToTree(repository, repository.getFolder().getAbsolutePath());
statusBar.update(repository);
bookmarksPanel.reload(repository);
statusBar.setText("");
} catch (Exception ex) {
ex.printStackTrace();
statusBar.error(ex);
}
}
}.start();
} else {
select(repository);
}
}
/**
* Add repository into bookmarks bar
* @param repo
*/
public void addBookmark(Repository repo) {
bookmarksPanel.addBookmarkPanel(new BookmarkPanel(bookmarksPanel, repo));
}
/**
* Add tab
* @param title Tab title
* @param panel
* @param icon
*/
public void addPanel(String title, AbstractPanel panel, ImageIcon icon) {
tabbedPane.addTab(title, icon, panel);
tabbedPane.setSelectedComponent(panel);
}
/**
* Remove tab
* @param panel
*/
public void removePanel(AbstractPanel panel) {
tabbedPane.remove(panel);
}
/**
* Gets selected repo tab
* @return
*/
public Repository getSelectedRepo() {
Component c = tabbedPane.getSelectedComponent();
if (c instanceof AbstractPanel) {
AbstractPanel mp = (AbstractPanel) c;
return mp.getRepository();
}
return null;
}
/**
* Checks if repository has a panel
* @param repo
* @return
*/
public boolean isOpen(Repository repo) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
AbstractPanel panel = (AbstractPanel) tabbedPane.getComponentAt(i);
if (panel instanceof MainPanel && ((MainPanel) panel).getRepository().equals(repo)) {
return true;
}
}
return false;
}
/**
* Selects the repository panel
* @param repo
*/
public void select(Repository repo) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
AbstractPanel panel = (AbstractPanel) tabbedPane.getComponentAt(i);
if (panel instanceof MainPanel && ((MainPanel) panel).getRepository().equals(repo)) {
tabbedPane.setSelectedIndex(i);
}
}
}
/**
* Gets selected tab
* @return
*/
public AbstractPanel getSelectedPanel() {
Component c = tabbedPane.getSelectedComponent();
if (c instanceof AbstractPanel) {
return (AbstractPanel) c;
}
return null;
}
public Commit getSelectedCommit() {
Component c = tabbedPane.getSelectedComponent();
if (c instanceof MainPanel) {
MainPanel panel = (MainPanel) c;
Commit commit = panel.getCommitPanel().getSelectedCommit();
return commit;
}
return null;
}
public void reloadCurrentRepo() {
final AbstractPanel mp = getSelectedPanel();
if (mp != null) {
try {
mp.reload();
reloadRepo(mp.repo);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* Reloads current repo with default status string "Reloading"
* @param repo
*/
public void reloadRepo(Repository repo) {
reloadRepo("Reloading", repo);
}
/**
* Reloads selected repo
*/
public void reloadRepo(final String status, final Repository repo) {
new Thread() {
@Override
public void run() {
try {
statusBar.setUpdating();
statusBar.setText(status);
objectPane.reload(null, repo);
bookmarksPanel.reload(repo);
statusBar.update(repo);
statusBar.setText("");
} catch (Exception e) {
e.printStackTrace();
statusBar.error(e);
}
}
}.start();
}
/**
* Returns tabs
* @return
*/
public Component[] getTabs() {
return tabbedPane.getComponents();
}
/**
* Sets title beginning with "gitj version - "
*/
@Override
public void setTitle(String title) {
if (title == null || title.length() == 0) {
super.setTitle("gitj " + Version.getVersion());
} else {
super.setTitle("gitj " + Version.getVersion() + " - " + title);
}
}
/**
* Opens commit panel for selected repository
*/
public void commit() {
Repository repo = getSelectedRepo();
AbstractPanel panel = getSelectedPanel();
if (repo != null && panel instanceof MainPanel) {
addPanel("Commit", new CommitPanel(this, (MainPanel) panel, repo), IconUtils.getIcon("commit-small"));
}
}
/**
* Opens stash dialog
*/
public void stash() {
Repository repo = getSelectedRepo();
if (repo != null) {
new DialogCreateStash(this, repo).setVisible(true);
}
}
/**
* Stages selected files in current repository
*/
public void stageSelected() {
toggle(true);
}
/**
* Unstages selected files in current repository
*/
public void unstageSelected() {
toggle(false);
}
/**
* Stages or unstages selected files in current repository
* @param stage
*/
public void toggle(boolean stage) {
Repository repo = getSelectedRepo();
AbstractPanel apanel = getSelectedPanel();
if (apanel instanceof AbstractPanel) {
JPanel panel = null;
if (apanel instanceof MainPanel) {
panel = ((MainPanel) apanel).getListPanel();
} else if (apanel instanceof CommitPanel) {
panel = ((CommitPanel) apanel).getListPanel();
}
if (panel instanceof PanelUncommited) {
PanelUncommited pu = (PanelUncommited) panel;
List<String> list;
if (stage) {
list = pu.getSelectedUnstaged();
} else {
list = pu.getSelectedStaged();
}
for (String path : list) {
try {
if (stage) {
repo.stage(path);
} else {
repo.unstage(path);
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
pu.reload();
} catch (Exception e) {
e.printStackTrace();
Main.displayError(e);
}
}
}
}
public void open() {
JFileChooser c = new JFileChooser();
c.setSelectedFile(latestDir);
c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
c.showOpenDialog(null);
File file = c.getSelectedFile();
latestDir = file;
if (file != null) {
try {
Repository repository = new Repository(file);
loadRepository(repository);
} catch (InvalidRepositoryException e) {
e.printStackTrace();
// TODO
}
}
}
public void remotes() {
Repository repo = getSelectedRepo();
if (repo != null) {
new DialogRemotes(repo).setVisible(true);
}
}
public void showTags() {
Repository repo = getSelectedRepo();
if (repo != null) {
new DialogTags(repo).setVisible(true);
}
}
public void checkout() {
}
public void tag() {
Commit commit = getSelectedCommit();
Repository repo = getSelectedRepo();
if (commit != null && repo != null) {
new DialogCreateTag(null, repo, commit).setVisible(true);
}
}
public void push() {
Repository repo = getSelectedRepo();
if (repo != null) {
try {
new DialogPush(this, repo).setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void pull() {
Repository repo = getSelectedRepo();
if (repo != null) {
try {
new DialogPull(this, repo).setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void newRepo() {
new DialogNew().setVisible(true);
}
public void lineCount() {
Repository repo = getSelectedRepo();
if (repo != null) {
new DialogLineCount(repo).setVisible(true);
}
}
public StatusBar getStatusBar() {
return statusBar;
}
public BookmarksPanel getBookmarksPanel() {
return bookmarksPanel;
}
public void runTask(final Task t) {
new Thread() {
@Override
public void run() {
statusBar.getProgressBar().setVisible(true);
statusBar.setText(t.getText());
try {
t.execute();
} catch (Exception e) {
e.printStackTrace();
Main.displayError(e);
statusBar.error(e);
return;
}
statusBar.getProgressBar().setVisible(false);
statusBar.setText("");
reloadCurrentRepo();
}
}.start();
}
public class TabChangeListener implements ChangeListener {
/**
* Called when tab changed
*/
@Override
public void stateChanged(ChangeEvent arg0) {
AbstractPanel panel = MainFrame.this.getSelectedPanel();
Repository repo = MainFrame.this.getSelectedRepo();
if (repo != null) {
MainFrame.this.setTitle(repo.getName());
if (panel instanceof MainPanel) {
try {
objectPane.reload((MainPanel)panel, repo);
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
MainFrame.this.setTitle("");
}
}
}
}