SVN auth
[fedora-idea.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / dialogs / PropertiesComponent.java
blob576b604379df6c9c53b3795893900c4148ebc0ab
1 /*
2 * Copyright 2000-2009 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 org.jetbrains.idea.svn.dialogs;
18 import com.intellij.openapi.actionSystem.*;
19 import com.intellij.openapi.keymap.KeymapManager;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.util.IconLoader;
22 import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
23 import com.intellij.openapi.vfs.VirtualFile;
24 import com.intellij.openapi.vfs.VirtualFileManager;
25 import com.intellij.openapi.wm.ToolWindowManager;
26 import com.intellij.ui.PopupHandler;
27 import com.intellij.util.containers.HashMap;
28 import org.jetbrains.idea.svn.SvnVcs;
29 import org.tmatesoft.svn.core.SVNException;
30 import org.tmatesoft.svn.core.SVNProperty;
31 import org.tmatesoft.svn.core.SVNPropertyValue;
32 import org.tmatesoft.svn.core.SVNURL;
33 import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
34 import org.tmatesoft.svn.core.wc.SVNPropertyData;
35 import org.tmatesoft.svn.core.wc.SVNRevision;
36 import org.tmatesoft.svn.core.wc.SVNWCClient;
38 import javax.swing.*;
39 import javax.swing.event.ListSelectionEvent;
40 import javax.swing.event.ListSelectionListener;
41 import javax.swing.table.DefaultTableCellRenderer;
42 import javax.swing.table.DefaultTableModel;
43 import java.awt.*;
44 import java.io.File;
45 import java.util.Map;
46 import java.util.TreeMap;
48 /**
49 * Created by IntelliJ IDEA.
50 * User: alex
51 * Date: Jun 20, 2006
52 * Time: 4:39:46 PM
54 public class PropertiesComponent extends JPanel {
55 public static final String ID = "SVN Properties";
56 private JTable myTable;
57 private JTextArea myTextArea;
58 private boolean myIsFollowSelection;
59 private File myFile;
60 private SvnVcs myVcs;
61 private JSplitPane mySplitPane;
62 private static final String CONTEXT_ID = "context";
63 private final CloseAction myCloseAction = new CloseAction();
64 private final RefreshAction myRefreshAction = new RefreshAction();
65 private ActionGroup myPopupActionGroup;
67 public PropertiesComponent() {
68 // register toolwindow and add listener to the selection.
69 myIsFollowSelection = true;
70 init();
73 public void init() {
74 setLayout(new BorderLayout());
75 myTable = new JTable();
76 myTextArea = new JTextArea(0, 0);
77 myTextArea.setEditable(false);
78 JScrollPane scrollPane = new JScrollPane(myTable);
79 mySplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, scrollPane, new JScrollPane(myTextArea));
80 add(mySplitPane, BorderLayout.CENTER);
81 add(createToolbar(), BorderLayout.WEST);
82 final DefaultTableModel model = new DefaultTableModel(createTableModel(new HashMap<String, String>()), new Object[]{"Name", "Value"}) {
83 public boolean isCellEditable(final int row, final int column) {
84 return false;
87 myTable.setModel(model);
88 myTable.setShowVerticalLines(true);
89 myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
90 myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
91 public void valueChanged(ListSelectionEvent e) {
92 int index = myTable.getSelectedRow();
93 if (index >= 0) {
94 Object value = myTable.getValueAt(index, 1);
95 if (value instanceof String) {
96 myTextArea.setText(((String) value));
97 } else {
98 myTextArea.setText("");
100 } else {
101 myTextArea.setText("");
105 myPopupActionGroup = createPopup();
106 PopupHandler.installPopupHandler(myTable, myPopupActionGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
107 PopupHandler.installPopupHandler(scrollPane, myPopupActionGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
108 final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_CLOSE_ACTIVE_TAB);
109 myCloseAction.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), this);
110 myRefreshAction.registerCustomShortcutSet(CommonShortcuts.getRerun(), this);
113 public void setFile(SvnVcs vcs, File file) {
114 final Map<String, String> props = new TreeMap<String, String>();
115 boolean firstTime = myFile == null;
116 if (file != null) {
117 myFile = file;
118 myVcs = vcs;
119 try {
120 vcs.createWCClient().doGetProperty(file, null, SVNRevision.UNDEFINED, SVNRevision.WORKING, false, new ISVNPropertyHandler() {
121 public void handleProperty(File path, SVNPropertyData property) throws SVNException {
122 final SVNPropertyValue value = property.getValue();
123 if (value != null) {
124 props.put(property.getName(), value.getString());
127 public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
129 public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
132 } catch (SVNException e) {
133 props.clear();
136 DefaultTableModel model = (DefaultTableModel) myTable.getModel();
137 model.setDataVector(createTableModel(props), new Object[] {"Name", "Value"});
139 myTable.getColumnModel().setColumnSelectionAllowed(false);
140 myTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
141 protected void setValue(Object value) {
142 if (value != null) {
143 if (value.toString().indexOf('\r') >= 0) {
144 value = value.toString().substring(0, value.toString().indexOf('\r')) + " [...]";
146 if (value.toString().indexOf('\n') >= 0) {
147 value = value.toString().substring(0, value.toString().indexOf('\n')) + " [...]";
150 super.setValue(value);
153 if (firstTime) {
154 mySplitPane.setDividerLocation(.5);
156 if (myTable.getRowCount() > 0) {
157 myTable.getSelectionModel().setSelectionInterval(0, 0);
161 private static Object[][] createTableModel(Map<String, String> model) {
162 Object[][] result = new Object[model.size()][2];
163 int index = 0;
164 for (final String name : model.keySet()) {
165 String value = model.get(name);
166 if (value == null) {
167 value = "";
169 result[index][0] = name;
170 result[index][1] = value;
171 index++;
173 return result;
176 private JComponent createToolbar() {
177 DefaultActionGroup group = new DefaultActionGroup();
178 group.add(new AddPropertyAction());
179 group.add(new EditPropertyAction());
180 group.add(new DeletePropertyAction());
181 group.addSeparator();
182 group.add(new SetKeywordsAction());
183 group.addSeparator();
184 group.add(new FollowSelectionAction());
185 group.add(myRefreshAction);
186 group.add(myCloseAction);
187 return ActionManager.getInstance().createActionToolbar("", group, false).getComponent();
190 private DefaultActionGroup createPopup() {
191 DefaultActionGroup group = new DefaultActionGroup();
192 group.add(new AddPropertyAction());
193 group.add(new EditPropertyAction());
194 group.add(new DeletePropertyAction());
195 group.addSeparator();
196 group.add(new SetKeywordsAction());
197 group.addSeparator();
198 group.add(myRefreshAction);
199 return group;
202 private String getSelectedPropertyName() {
203 int row = myTable.getSelectedRow();
204 if (row < 0) {
205 return null;
207 return (String) myTable.getValueAt(row, 0);
210 private void updateFileStatus(boolean recursive) {
211 if (myFile != null && myVcs != null) {
212 String url = "file://" + myFile.getPath().replace(File.separatorChar, '/');
213 VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
214 if (file != null) {
215 if (recursive && file.isDirectory()) {
216 VcsDirtyScopeManager.getInstance(myVcs.getProject()).dirDirtyRecursively(file, true);
217 } else {
218 VcsDirtyScopeManager.getInstance(myVcs.getProject()).fileDirty(file);
224 private static class CloseAction extends AnAction {
226 public void update(AnActionEvent e) {
227 e.getPresentation().setText("Close");
228 e.getPresentation().setDescription("Close this tool window");
229 e.getPresentation().setIcon(IconLoader.getIcon("/actions/cancel.png"));
232 public void actionPerformed(AnActionEvent e) {
233 Project p = e.getData(PlatformDataKeys.PROJECT);
234 ToolWindowManager.getInstance(p).unregisterToolWindow(ID);
238 private class RefreshAction extends AnAction {
239 public void update(AnActionEvent e) {
240 e.getPresentation().setText("Refresh");
241 e.getPresentation().setDescription("Reload properties");
242 e.getPresentation().setIcon(IconLoader.getIcon("/actions/sync.png"));
243 e.getPresentation().setEnabled(myFile != null);
246 public void actionPerformed(AnActionEvent e) {
247 setFile(myVcs, myFile);
248 updateFileStatus(false);
252 private class SetKeywordsAction extends AnAction {
254 public void update(AnActionEvent e) {
255 e.getPresentation().setText("Edit Keywords");
256 e.getPresentation().setDescription("Manage svn:keywords property");
257 if (!CONTEXT_ID.equals(e.getPlace())) {
258 e.getPresentation().setIcon(IconLoader.getIcon("/actions/properties.png"));
260 e.getPresentation().setEnabled(myFile != null && myFile.isFile());
263 public void actionPerformed(AnActionEvent e) {
264 Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
265 SVNWCClient wcClient = myVcs.createWCClient();
266 SVNPropertyData propValue = null;
267 try {
268 propValue = wcClient.doGetProperty(myFile, SVNProperty.KEYWORDS, SVNRevision.UNDEFINED, SVNRevision.WORKING);
269 } catch (SVNException e1) {
270 // show error message
273 SetKeywordsDialog dialog = new SetKeywordsDialog(project,
274 propValue != null ? SVNPropertyValue.getPropertyAsString(propValue.getValue()) : null);
275 dialog.show();
276 if (dialog.isOK()) {
277 String value = dialog.getKeywords();
278 try {
279 wcClient.doSetProperty(myFile, SVNProperty.KEYWORDS, SVNPropertyValue.create(value), false, false, null);
281 catch (SVNException err) {
282 // show error message
285 setFile(myVcs, myFile);
286 updateFileStatus(false);
290 private class DeletePropertyAction extends AnAction {
291 public void update(AnActionEvent e) {
292 e.getPresentation().setText("Delete Property");
293 e.getPresentation().setDescription("Delete selected property");
294 if (!CONTEXT_ID.equals(e.getPlace())) {
295 e.getPresentation().setIcon(IconLoader.getIcon("/general/remove.png"));
297 e.getPresentation().setEnabled(myFile != null && getSelectedPropertyName() != null);
300 public void actionPerformed(AnActionEvent e) {
301 try {
302 myVcs.createWCClient().doSetProperty(myFile, getSelectedPropertyName(), null, true, false, null);
303 } catch (SVNException error) {
304 // show error message.
306 setFile(myVcs, myFile);
307 updateFileStatus(false);
311 private class AddPropertyAction extends AnAction {
313 public void update(AnActionEvent e) {
314 e.getPresentation().setText("Add Property");
315 e.getPresentation().setDescription("Add new property");
316 if (!CONTEXT_ID.equals(e.getPlace())) {
317 e.getPresentation().setIcon(IconLoader.getIcon("/general/add.png"));
319 e.getPresentation().setEnabled(myFile != null);
322 public void actionPerformed(AnActionEvent e) {
323 Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
324 SetPropertyDialog dialog = new SetPropertyDialog(project, new File[] {myFile}, null,
325 myFile.isDirectory());
326 dialog.show();
327 boolean recursive = false;
328 if (dialog.isOK()) {
329 String name = dialog.getPropertyName();
330 String value = dialog.getPropertyValue();
331 recursive = dialog.isRecursive();
332 SVNWCClient wcClient = myVcs.createWCClient();
333 try {
334 wcClient.doSetProperty(myFile, name, SVNPropertyValue.create(value), false, recursive, null);
336 catch (SVNException err) {
337 // show error message
340 setFile(myVcs, myFile);
341 updateFileStatus(recursive);
345 private class EditPropertyAction extends AnAction {
346 public void update(AnActionEvent e) {
347 e.getPresentation().setText("Edit Property");
348 e.getPresentation().setDescription("Edit selected property value");
349 if (!CONTEXT_ID.equals(e.getPlace())) {
350 e.getPresentation().setIcon(IconLoader.getIcon("/actions/editSource.png"));
352 e.getPresentation().setEnabled(myFile != null && getSelectedPropertyName() != null);
355 public void actionPerformed(AnActionEvent e) {
356 Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
357 SetPropertyDialog dialog = new SetPropertyDialog(project, new File[] {myFile}, getSelectedPropertyName(), myFile.isDirectory());
358 dialog.show();
359 boolean recursive = false;
360 if (dialog.isOK()) {
361 String name = dialog.getPropertyName();
362 String value = dialog.getPropertyValue();
363 recursive = dialog.isRecursive();
364 SVNWCClient wcClient = myVcs.createWCClient();
365 try {
366 wcClient.doSetProperty(myFile, name, SVNPropertyValue.create(value), false, recursive, null);
368 catch (SVNException err) {
369 // show error message
372 setFile(myVcs, myFile);
373 updateFileStatus(recursive);
377 private class FollowSelectionAction extends ToggleAction {
379 public boolean isSelected(AnActionEvent e) {
380 return myIsFollowSelection;
382 public void setSelected(AnActionEvent e, boolean state) {
383 if (state && !myIsFollowSelection) {
384 updateSelection(e);
386 myIsFollowSelection = state;
389 public void update(final AnActionEvent e) {
390 super.update(e);
391 e.getPresentation().setIcon(IconLoader.getIcon("/general/autoscrollFromSource.png"));
392 e.getPresentation().setText("Follow Selection");
393 e.getPresentation().setDescription("Follow Selection");
394 // change file
395 if (myIsFollowSelection) {
396 updateSelection(e);
400 private void updateSelection(AnActionEvent e) {
401 if (myVcs == null) {
402 return;
404 VirtualFile vf = PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
405 if (vf != null) {
406 File f = new File(vf.getPath());
407 if (!f.equals(myFile)) {
408 setFile(myVcs, f);
409 Project p = PlatformDataKeys.PROJECT.getData(e.getDataContext());
410 ToolWindowManager.getInstance(p).getToolWindow(ID).setTitle(f.getName());