git4idea: IDEA-22561: renamed OK buttons to appropriate names in dialogs
[fedora-idea.git] / plugins / git4idea / src / git4idea / rebase / GitRebaseEditor.java
blob4122c0b2cad6347b514f0f8ff44c555272e4693e
1 /*
2 * Copyright 2000-2008 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package git4idea.rebase;
18 import com.intellij.openapi.project.Project;
19 import com.intellij.openapi.ui.DialogWrapper;
20 import com.intellij.openapi.util.SystemInfo;
21 import com.intellij.openapi.util.io.FileUtil;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.util.ListWithSelection;
24 import com.intellij.util.ui.ComboBoxTableCellEditor;
25 import com.intellij.util.ui.ComboBoxTableCellRenderer;
26 import git4idea.actions.GitShowAllSubmittedFilesAction;
27 import git4idea.commands.StringScanner;
28 import git4idea.config.GitConfigUtil;
29 import git4idea.i18n.GitBundle;
30 import org.jetbrains.annotations.NonNls;
32 import javax.swing.*;
33 import javax.swing.event.ListSelectionEvent;
34 import javax.swing.event.ListSelectionListener;
35 import javax.swing.event.TableModelEvent;
36 import javax.swing.event.TableModelListener;
37 import javax.swing.table.AbstractTableModel;
38 import javax.swing.table.TableColumn;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ActionListener;
41 import java.io.*;
42 import java.util.ArrayList;
43 import java.util.Arrays;
45 /**
46 * Editor for rebase entries. It allows reordering of
47 * the entries and changing commit status.
49 public class GitRebaseEditor extends DialogWrapper {
50 /**
51 * The table that lists all commits
53 private JTable myCommitsTable;
54 /**
55 * The move up button
57 private JButton myMoveUpButton;
58 /**
59 * The move down button
61 private JButton myMoveDownButton;
62 /**
63 * The view commit button
65 private JButton myViewButton;
66 /**
67 * The root panel
69 private JPanel myPanel;
70 /**
71 * Table model
73 private final MyTableModel myTableModel;
74 /**
75 * The file name
77 private final String myFile;
78 /**
79 * The project
81 private final Project myProject;
82 /**
83 * The git root
85 private final VirtualFile myGitRoot;
86 /**
87 * The cygwin drive prefix
89 @NonNls private static final String CYGDRIVE_PREFIX = "/cygdrive/";
91 /**
92 * The constructor
94 * @param project the project
95 * @param gitRoot the git root
96 * @param file the file to edit
97 * @throws IOException if file could not be loaded
99 protected GitRebaseEditor(final Project project, final VirtualFile gitRoot, String file) throws IOException {
100 super(project, true);
101 myProject = project;
102 myGitRoot = gitRoot;
103 setTitle(GitBundle.getString("rebase.editor.title"));
104 setOKButtonText(GitBundle.getString("rebase.editor.button"));
105 if (SystemInfo.isWindows && file.startsWith(CYGDRIVE_PREFIX)) {
106 final int prefixSize = CYGDRIVE_PREFIX.length();
107 file = file.substring(prefixSize, prefixSize + 1) + ":" + file.substring(prefixSize + 1);
109 myFile = file;
110 myTableModel = new MyTableModel();
111 myTableModel.load(file);
112 myCommitsTable.setModel(myTableModel);
113 myCommitsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
114 TableColumn actionColumn = myCommitsTable.getColumnModel().getColumn(MyTableModel.ACTION);
115 actionColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE);
116 actionColumn.setCellRenderer(ComboBoxTableCellRenderer.INSTANCE);
117 myCommitsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
118 public void valueChanged(final ListSelectionEvent e) {
119 boolean selected = myCommitsTable.getSelectedRowCount() != 0;
120 myMoveUpButton.setEnabled(selected);
121 if (selected) {
122 myViewButton.setEnabled(true);
123 int row = myCommitsTable.getSelectedRow();
124 myMoveUpButton.setEnabled(row != 0);
125 myMoveDownButton.setEnabled(row != myTableModel.myEntries.size() - 1);
127 else {
128 myMoveUpButton.setEnabled(false);
129 myMoveDownButton.setEnabled(false);
130 myViewButton.setEnabled(false);
134 myViewButton.addActionListener(new ActionListener() {
135 public void actionPerformed(final ActionEvent e) {
136 int row = myCommitsTable.getSelectedRow();
137 if (row < 0) {
138 return;
140 GitRebaseEntry entry = myTableModel.myEntries.get(row);
141 GitShowAllSubmittedFilesAction.showSubmittedFiles(project, entry.getCommit(), gitRoot);
144 myMoveUpButton.addActionListener(new ActionListener() {
145 public void actionPerformed(final ActionEvent e) {
146 final int row = myCommitsTable.getSelectedRow();
147 if (myTableModel.moveUp(row)) {
148 myCommitsTable.getSelectionModel().setSelectionInterval(row - 1, row - 1);
152 myMoveDownButton.addActionListener(new ActionListener() {
153 public void actionPerformed(final ActionEvent e) {
154 final int row = myCommitsTable.getSelectedRow();
155 if (myTableModel.moveDown(row)) {
156 myCommitsTable.getSelectionModel().setSelectionInterval(row + 1, row + 1);
160 myTableModel.addTableModelListener(new TableModelListener() {
161 public void tableChanged(final TableModelEvent e) {
162 validateFields();
165 init();
169 * Validate fields
171 private void validateFields() {
172 final ArrayList<GitRebaseEntry> entries = myTableModel.myEntries;
173 if (entries.size() == 0) {
174 setErrorText(GitBundle.getString("rebase.editor.invalid.entryset"));
175 setOKActionEnabled(false);
176 return;
178 int i = 0;
179 while (i < entries.size() && entries.get(i).getAction() == GitRebaseEntry.Action.skip) {
180 i++;
182 if (i < entries.size() && entries.get(i).getAction() == GitRebaseEntry.Action.squash) {
183 setErrorText(GitBundle.getString("rebase.editor.invalid.squash"));
184 setOKActionEnabled(false);
185 return;
187 setErrorText(null);
188 setOKActionEnabled(true);
192 * Save entries back to the file
194 * @throws IOException if there is IO problem with saving
196 public void save() throws IOException {
197 myTableModel.save(myFile);
201 * {@inheritDoc}
203 protected JComponent createCenterPanel() {
204 return myPanel;
208 * {@inheritDoc}
210 @Override
211 protected String getDimensionServiceKey() {
212 return getClass().getName();
216 * {@inheritDoc}
218 @Override
219 protected String getHelpId() {
220 return "reference.VersionControl.Git.RebaseCommits";
224 * Cancel rebase
226 * @throws IOException if file cannot be reset to empty one
228 public void cancel() throws IOException {
229 myTableModel.cancel(myFile);
234 * The table model for the commits
236 private class MyTableModel extends AbstractTableModel {
238 * The action column
240 private static final int ACTION = 0;
242 * The commit hash column
244 private static final int COMMIT = 1;
246 * The subject column
248 private static final int SUBJECT = 2;
251 * The entries
253 final ArrayList<GitRebaseEntry> myEntries = new ArrayList<GitRebaseEntry>();
256 * {@inheritDoc}
258 @Override
259 public Class<?> getColumnClass(final int columnIndex) {
260 return columnIndex == ACTION ? ListWithSelection.class : String.class;
264 * {@inheritDoc}
266 @Override
267 public String getColumnName(final int column) {
268 switch (column) {
269 case ACTION:
270 return GitBundle.getString("rebase.editor.action.column");
271 case COMMIT:
272 return GitBundle.getString("rebase.editor.commit.column");
273 case SUBJECT:
274 return GitBundle.getString("rebase.editor.comment.column");
275 default:
276 throw new IllegalArgumentException("Unsupported column index: " + column);
281 * {@inheritDoc}
283 public int getRowCount() {
284 return myEntries.size();
288 * {@inheritDoc}
290 public int getColumnCount() {
291 return SUBJECT + 1;
295 * {@inheritDoc}
297 public Object getValueAt(final int rowIndex, final int columnIndex) {
298 GitRebaseEntry e = myEntries.get(rowIndex);
299 switch (columnIndex) {
300 case ACTION:
301 return new ListWithSelection<GitRebaseEntry.Action>(Arrays.asList(GitRebaseEntry.Action.values()), e.getAction());
302 case COMMIT:
303 return e.getCommit();
304 case SUBJECT:
305 return e.getSubject();
306 default:
307 throw new IllegalArgumentException("Unsupported column index: " + columnIndex);
312 * {@inheritDoc}
314 @Override
315 @SuppressWarnings({"unchecked"})
316 public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
317 assert columnIndex == ACTION;
318 GitRebaseEntry e = myEntries.get(rowIndex);
319 e.setAction((GitRebaseEntry.Action)aValue);
320 fireTableCellUpdated(rowIndex, columnIndex);
324 * {@inheritDoc}
326 @Override
327 public boolean isCellEditable(final int rowIndex, final int columnIndex) {
328 return columnIndex == ACTION;
332 * Load data from the file
334 * @param file the file to load
335 * @throws IOException if file could not be loaded
337 public void load(final String file) throws IOException {
338 String encoding = GitConfigUtil.getLogEncoding(myProject, myGitRoot);
339 final StringScanner s = new StringScanner(new String(FileUtil.loadFileText(new File(file), encoding)));
340 while (s.hasMoreData()) {
341 if (s.isEol() || s.startsWith('#') || s.startsWith("noop")) {
342 s.nextLine();
343 continue;
345 String action = s.spaceToken();
346 assert "pick".equals(action) : "Initial action should be pick: " + action;
347 String hash = s.spaceToken();
348 String comment = s.line();
349 myEntries.add(new GitRebaseEntry(hash, comment));
354 * Save text to the file
356 * @param file the file to save to
357 * @throws IOException if there is IO problem
359 public void save(final String file) throws IOException {
360 String encoding = GitConfigUtil.getLogEncoding(myProject, myGitRoot);
361 PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
362 try {
363 for (GitRebaseEntry e : myEntries) {
364 if (e.getAction() != GitRebaseEntry.Action.skip) {
365 out.println(e.getAction().toString() + " " + e.getCommit() + " " + e.getSubject());
369 finally {
370 out.close();
375 * Save text to the file
377 * @param file the file to save to
378 * @throws IOException if there is IO problem
380 public void cancel(final String file) throws IOException {
381 PrintWriter out = new PrintWriter(new FileWriter(file));
382 try {
383 //noinspection HardCodedStringLiteral
384 out.println("# rebase is cancelled");
386 finally {
387 out.close();
393 * Move selected row up. If row cannot be moved up, do nothing and return false.
395 * @param row a row to move
396 * @return true if row was moved
398 public boolean moveUp(final int row) {
399 if (row < 1 || row >= myEntries.size()) {
400 return false;
402 myCommitsTable.removeEditor();
403 GitRebaseEntry e = myEntries.get(row);
404 myEntries.set(row, myEntries.get(row - 1));
405 myEntries.set(row - 1, e);
406 fireTableRowsUpdated(row - 1, row);
407 return true;
411 * Move selected row down. If row cannot be moved down, do nothing and return false.
413 * @param row a row to move
414 * @return true if row was moved
416 public boolean moveDown(final int row) {
417 if (row < 0 || row >= myEntries.size() - 1) {
418 return false;
420 myCommitsTable.removeEditor();
421 GitRebaseEntry e = myEntries.get(row);
422 myEntries.set(row, myEntries.get(row + 1));
423 myEntries.set(row + 1, e);
424 fireTableRowsUpdated(row, row + 1);
425 return true;