| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.cvsSupport2.ui.experts.checkout; |
| |
| import com.intellij.CvsBundle; |
| import com.intellij.cvsSupport2.config.CvsApplicationLevelConfiguration; |
| import com.intellij.cvsSupport2.config.CvsRootConfiguration; |
| import com.intellij.cvsSupport2.connections.CvsEnvironment; |
| import com.intellij.cvsSupport2.cvsBrowser.CvsElement; |
| import com.intellij.cvsSupport2.cvsBrowser.CvsFile; |
| import com.intellij.cvsSupport2.cvsoperations.common.CvsCommandOperation; |
| import com.intellij.cvsSupport2.cvsoperations.cvsLog.LocalPathIndifferentLogOperation; |
| import com.intellij.cvsSupport2.cvsoperations.cvsLog.LogOperation; |
| import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.TagsProvider; |
| import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.TagsProviderOnEnvironment; |
| import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.ui.DateOrRevisionOrTagSettings; |
| import com.intellij.cvsSupport2.ui.ChangeKeywordSubstitutionPanel; |
| import com.intellij.cvsSupport2.ui.experts.WizardStep; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.VerticalFlowLayout; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.vcs.VcsException; |
| import com.intellij.openapi.vcs.checkout.CheckoutStrategy; |
| import com.intellij.ui.ColoredListCellRenderer; |
| import com.intellij.ui.ScrollPaneFactory; |
| import com.intellij.ui.SimpleTextAttributes; |
| import com.intellij.ui.components.JBList; |
| import com.intellij.util.PlatformIcons; |
| import com.intellij.util.containers.HashSet; |
| import com.intellij.util.ui.UIUtil; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.netbeans.lib.cvsclient.command.KeywordSubstitution; |
| |
| import javax.swing.*; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import java.awt.*; |
| import java.io.File; |
| import java.util.*; |
| import java.util.List; |
| |
| /** |
| * author: lesya |
| */ |
| public class ChooseCheckoutMode extends WizardStep { |
| |
| private File mySelectedLocation; |
| private final Collection<File> myCvsPaths = new ArrayList<File>(); |
| private final DefaultListModel myCheckoutModeModel = new DefaultListModel(); |
| private final JList myCheckoutModeList = new JBList(myCheckoutModeModel); |
| private final JCheckBox myMakeNewFilesReadOnly = new JCheckBox(CvsBundle.message("checkbox.make.new.files.read.only")); |
| private final JCheckBox myPruneEmptyDirectories = new JCheckBox(CvsBundle.message("checkbox.prune.empty.directories")); |
| private final ChangeKeywordSubstitutionPanel myChangeKeywordSubstitutionPanel; |
| private final DateOrRevisionOrTagSettings myDateOrRevisionOrTagSettings; |
| |
| private final JPanel myCenterPanel = new JPanel(new CardLayout()); |
| |
| @NonNls public static final String LIST = "LIST"; |
| @NonNls public static final String MESSAGE = "MESSSAGE"; |
| @NonNls private final JLabel myMessage = new JLabel("XXX"); |
| |
| private CvsRootConfiguration myConfiguration = null; |
| |
| public ChooseCheckoutMode(Project project, CheckoutWizard wizard) { |
| super("###", wizard); |
| myCheckoutModeList.setCellRenderer(new ColoredListCellRenderer() { |
| @Override |
| protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { |
| final CheckoutStrategy checkoutStrategy = (CheckoutStrategy)value; |
| append(checkoutStrategy.getResult().getAbsolutePath(), new SimpleTextAttributes(Font.PLAIN, list.getForeground())); |
| setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON); |
| } |
| }); |
| myCheckoutModeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { |
| @Override |
| public void valueChanged(ListSelectionEvent e) { |
| getWizard().updateButtons(); |
| } |
| }); |
| |
| myCheckoutModeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| final CvsApplicationLevelConfiguration config = CvsApplicationLevelConfiguration.getInstance(); |
| myMakeNewFilesReadOnly.setSelected(config.MAKE_CHECKED_OUT_FILES_READONLY); |
| myPruneEmptyDirectories.setSelected(config.CHECKOUT_PRUNE_EMPTY_DIRECTORIES); |
| myChangeKeywordSubstitutionPanel = |
| new ChangeKeywordSubstitutionPanel(KeywordSubstitution.getValue(config.CHECKOUT_KEYWORD_SUBSTITUTION)); |
| |
| myCenterPanel.add(LIST, ScrollPaneFactory.createScrollPane(myCheckoutModeList)); |
| final JPanel messagePanel = new JPanel(new BorderLayout(2,4)); |
| messagePanel.add(myMessage, BorderLayout.NORTH); |
| messagePanel.setBackground(UIUtil.getTableBackground()); |
| myMessage.setBackground(UIUtil.getTableBackground()); |
| myCenterPanel.add(MESSAGE, ScrollPaneFactory.createScrollPane(messagePanel)); |
| |
| myDateOrRevisionOrTagSettings = new DateOrRevisionOrTagSettings(new TagsProviderOnEnvironment() { |
| @Nullable |
| @Override |
| protected CvsEnvironment getCvsEnvironment() { |
| return getWizard().getSelectedConfiguration(); |
| } |
| |
| @Override |
| public String getModule() { |
| final CvsElement[] selectedElements = getWizard().getSelectedElements(); |
| String module = null; |
| for (CvsElement element : selectedElements) { |
| final String checkoutPath = element.getCheckoutPath(); |
| if (module == null) { |
| module = checkoutPath; |
| continue; |
| } |
| final String commonParentModule = findCommonParentModule(module, checkoutPath); |
| if (commonParentModule == null) { |
| return super.getModule(); |
| } |
| module = commonParentModule; |
| } |
| return module; |
| } |
| }, project); |
| |
| init(); |
| } |
| |
| private static String findCommonParentModule(String module1, String module2) { |
| int diff = indexOfFirstDifference(module1, module2); |
| if (diff == 0) { |
| return null; |
| } |
| if (diff == module1.length()) { |
| return module1; |
| } |
| if (module1.charAt(diff - 1) == '/') { |
| return module1.substring(0, diff); |
| } |
| else { |
| int index = module1.lastIndexOf('/', diff); |
| if (index < 0) { |
| return null; |
| } |
| return module1.substring(0, index); |
| } |
| } |
| |
| private static int indexOfFirstDifference(@NotNull String a, @NotNull String b) { |
| int max = Math.min(a.length(), b.length()); |
| for (int i = 0; i < max; i++) { |
| final char c = a.charAt(i); |
| if (c != b.charAt(i)) { |
| return i; |
| } |
| } |
| return max; |
| } |
| |
| @Override |
| protected CheckoutWizard getWizard() { |
| return (CheckoutWizard)super.getWizard(); |
| } |
| |
| @Override |
| public boolean nextIsEnabled() { |
| if (myCvsPaths.size() == 1) |
| return myCheckoutModeList.getSelectedValue() != null; |
| else |
| return true; |
| } |
| |
| @Override |
| protected JComponent createComponent() { |
| final JPanel result = new JPanel(new BorderLayout(4, 2)); |
| result.add(myCenterPanel, BorderLayout.CENTER); |
| result.add(createOptionsPanel(), BorderLayout.SOUTH); |
| return result; |
| } |
| |
| private JPanel createOptionsPanel() { |
| final JPanel result = new JPanel(new VerticalFlowLayout()); |
| result.add(myMakeNewFilesReadOnly); |
| result.add(myPruneEmptyDirectories); |
| result.add(myChangeKeywordSubstitutionPanel.getComponent()); |
| result.add(myDateOrRevisionOrTagSettings.getPanel()); |
| return result; |
| } |
| |
| @Override |
| public JComponent getPreferredFocusedComponent() { |
| return myCheckoutModeList; |
| } |
| |
| @Override |
| public void activate() { |
| final File selectedLocation = getWizard().getSelectedLocation(); |
| final Collection<File> cvsPaths = getSelectedFiles(); |
| |
| if (!FileUtil.filesEqual(selectedLocation, mySelectedLocation) || !Comparing.equal(cvsPaths, myCvsPaths)) { |
| mySelectedLocation = selectedLocation; |
| myCvsPaths.clear(); |
| myCvsPaths.addAll(cvsPaths); |
| |
| if (myCvsPaths.size() == 1) { |
| show(LIST); |
| rebuildList(); |
| } |
| else { |
| setStepTitle(CvsBundle.message("info.text.selected.modules.will.be.checked.out.to")); |
| final StringBuilder message = composeLocationsMessage(); |
| myMessage.setText(message.toString()); |
| show(MESSAGE); |
| getWizard().updateButtons(); |
| } |
| } |
| else if (selectedLocation == null) { |
| getWizard().updateButtons(); |
| } |
| final CvsRootConfiguration configuration = getWizard().getSelectedConfiguration(); |
| if (myConfiguration != configuration) { |
| myDateOrRevisionOrTagSettings.updateFrom(configuration.DATE_OR_REVISION_SETTINGS); |
| myConfiguration = configuration; |
| } |
| } |
| |
| private StringBuilder composeLocationsMessage() { |
| @NonNls final StringBuilder message = new StringBuilder("<html><p>"); |
| message.append(mySelectedLocation.getAbsolutePath()).append("</p>"); |
| for (File file : myCvsPaths) { |
| message.append("<p> -").append(file.getPath()).append("</p>"); |
| } |
| return message; |
| } |
| |
| private Collection<File> getSelectedFiles() { |
| final Collection<File> allFiles = new HashSet<File>(); |
| final CvsElement[] selection = getWizard().getSelectedElements(); |
| if (selection == null) return allFiles; |
| for (CvsElement cvsElement : selection) { |
| allFiles.add(new File(cvsElement.getCheckoutPath())); |
| } |
| |
| final ArrayList<File> result = new ArrayList<File>(); |
| |
| for (File file : allFiles) { |
| if (!hasParentIn(allFiles, file)) result.add(file); |
| } |
| |
| Collections.sort(result, new Comparator<File>(){ |
| @Override |
| public int compare(File file, File file1) { |
| return file.getPath().compareTo(file1.getPath()); |
| } |
| }); |
| return result; |
| } |
| |
| private static boolean hasParentIn(Collection<File> allFiles, File file) { |
| final String filePath = file.getPath(); |
| for (File file1 : allFiles) { |
| if (FileUtil.filesEqual(file1, file)) continue; |
| if (filePath.startsWith(file1.getPath())) return true; |
| } |
| return false; |
| } |
| |
| private void rebuildList() { |
| final File selected = myCvsPaths.iterator().next(); |
| setStepTitle(CvsBundle.message("dialog.title.check.out.to", selected)); |
| myCheckoutModeModel.removeAllElements(); |
| |
| final boolean forFile = getWizard().getSelectedElements()[0] instanceof CvsFile; |
| final CheckoutStrategy[] strategies = CheckoutStrategy.createAllStrategies(mySelectedLocation, selected, forFile); |
| final Collection<File> results = new HashSet(); |
| final List<CheckoutStrategy> resultModes = new ArrayList(); |
| for (CheckoutStrategy strategy : strategies) { |
| final File resultFile = strategy.getResult(); |
| if (resultFile != null && !results.contains(resultFile)) { |
| results.add(resultFile); |
| resultModes.add(strategy); |
| } |
| } |
| |
| Collections.sort(resultModes); |
| for (CheckoutStrategy resultMode : resultModes) { |
| myCheckoutModeModel.addElement(resultMode); |
| } |
| myCheckoutModeList.setSelectedIndex(0); |
| } |
| |
| private void show(String mode) { |
| ((CardLayout)myCenterPanel.getLayout()).show(myCenterPanel, mode); |
| } |
| |
| public boolean getMakeNewFilesReadOnly() { |
| return myMakeNewFilesReadOnly.isSelected(); |
| } |
| |
| public boolean getPruneEmptyDirectories() { |
| return myPruneEmptyDirectories.isSelected(); |
| } |
| |
| public boolean useAlternativeCheckoutLocation() { |
| if (myCvsPaths.size() == 1) { |
| final CheckoutStrategy checkoutStrategy = (CheckoutStrategy)myCheckoutModeList.getSelectedValue(); |
| return checkoutStrategy.useAlternativeCheckoutLocation(); |
| } |
| else { |
| return false; |
| } |
| } |
| |
| public File getCheckoutDirectory() { |
| if (myCvsPaths.size() == 1) { |
| final CheckoutStrategy checkoutStrategy = (CheckoutStrategy)myCheckoutModeList.getSelectedValue(); |
| return checkoutStrategy.getCheckoutDirectory(); |
| } |
| else { |
| return mySelectedLocation; |
| } |
| } |
| |
| public KeywordSubstitution getKeywordSubstitution() { |
| return myChangeKeywordSubstitutionPanel.getKeywordSubstitution(); |
| } |
| |
| public void saveDateOrRevisionSettings(CvsRootConfiguration configuration) { |
| myDateOrRevisionOrTagSettings.saveTo(configuration.DATE_OR_REVISION_SETTINGS); |
| } |
| } |