/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2012 Alex Buloichick 2014 Aaron Madlon-Kay Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ package org.omegat.gui.dialogs; import java.io.File; import java.util.concurrent.CancellationException; import javax.swing.SwingWorker; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.omegat.core.team2.RemoteRepositoryFactory; import org.omegat.util.Log; import org.omegat.util.OStrings; import org.omegat.util.Preferences; import org.omegat.util.ProjectFileStorage; import org.omegat.util.StringUtil; import org.omegat.util.WikiGet; import org.omegat.util.gui.OmegaTFileChooser; import org.omegat.util.gui.StaticUIUtils; /** * * @author Alex Buloichik (alex73mail@gmail.com) * @author Aaron Madlon-Kay */ @SuppressWarnings("serial") public class NewTeamProject extends javax.swing.JDialog { private RepoTypeWorker repoTypeWorker = null; private String repoType; /** * Creates new form NewTeamProject */ public NewTeamProject(java.awt.Frame parent) { super(parent, true); initComponents(); txtRepositoryOrProjectFileURL.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { clearRepo(); } @Override public void removeUpdate(DocumentEvent e) { clearRepo(); } @Override public void changedUpdate(DocumentEvent e) { clearRepo(); } }); txtDirectory.getDocument().addDocumentListener(new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { updateDialog(); } @Override public void insertUpdate(DocumentEvent e) { updateDialog(); } @Override public void changedUpdate(DocumentEvent e) { updateDialog(); } }); StaticUIUtils.setEscapeClosable(this); getRootPane().setDefaultButton(btnOk); setLocationRelativeTo(parent); } public String getRepoType() { return repoType; } public String getRepoUrl() { String url = txtRepositoryOrProjectFileURL.getText().trim(); if (url.startsWith("git!")) { return url.substring("git!".length()); } else if (url.startsWith("svn!")) { return url.substring("svn!".length()); } else { return url; } } public String getSaveLocation() { return txtDirectory.getText().trim(); } private synchronized void detectRepoOrFile() { if (repoType != null || isDetectingRepo()) { return; } String url = txtRepositoryOrProjectFileURL.getText().trim(); if (StringUtil.isEmpty(url)) { return; } if (url.startsWith("git!")) { detectedRepoOrProjectFileLabel.setText(OStrings.getString("TEAM_DETECTED_REPO_GIT")); repoType = "git"; suggestLocalFolder(); } else if (url.startsWith("svn!")) { detectedRepoOrProjectFileLabel.setText(OStrings.getString("TEAM_DETECTED_REPO_SVN")); repoType = "svn"; suggestLocalFolder(); } else { detectedRepoOrProjectFileLabel.setText(OStrings.getString("TEAM_DETECTING_REPO_OR_PROJECT_FILE")); repoTypeWorker = new RepoTypeWorker(url); repoTypeWorker.execute(); } } private synchronized boolean isDetectingRepo() { return repoTypeWorker != null && !repoTypeWorker.isDone(); } private static String getMessageForRepoType(String type) { if ("svn".equals(type)) { return OStrings.getString("TEAM_DETECTED_REPO_SVN"); } else if ("git".equals(type)) { return OStrings.getString("TEAM_DETECTED_REPO_GIT"); } else if ("project-file".equals(type)) { return OStrings.getString("TEAM_DETECTED_PROJECT_FILE"); } else { return OStrings.getString("TEAM_DETECTED_REPO_UNKNOWN"); } } private void suggestLocalFolder() { if (!getSaveLocation().isEmpty()) { return; } String url = txtRepositoryOrProjectFileURL.getText().trim(); String strippedUrl = StringUtil.stripFromEnd(url, ".git", "/", "trunk", "/", "svn"); String dir = Preferences.getPreferenceDefault(Preferences.CURRENT_FOLDER, System.getProperty("user.home")); File suggestion = new File(dir, new File(strippedUrl).getName()).getAbsoluteFile(); txtDirectory.setText(ensureUniquePath(suggestion).getPath()); } private static File ensureUniquePath(File path) { File result = path; int suff = 2; while (result.exists()) { result = new File(path.getPath() + suff); suff++; if (suff > 1000) { // Give up after 1000 break; } } return result; } private void clearRepo() { repoType = null; detectedRepoOrProjectFileLabel.setText(" "); if (repoTypeWorker != null) { repoTypeWorker.cancel(true); } updateDialog(); } private class RepoTypeWorker extends SwingWorker<String, Void> { private final String url; public RepoTypeWorker(String url) { this.url = url; } @Override protected String doInBackground() throws Exception { if ((url.startsWith("http://") || url.startsWith("https://")) && url.endsWith("/omegat.project")) { return detectProjectFile(); } return RemoteRepositoryFactory.detectRepositoryType(url); } protected String detectProjectFile() throws Exception { byte[] file = WikiGet.getURLasByteArray(url); ProjectFileStorage.parseProjectFile(file); return "project-file"; } @Override protected void done() { String type, resultText; try { type = get(); resultText = getMessageForRepoType(type); } catch (CancellationException ex) { type = null; resultText = " "; } catch (Throwable ex) { type = null; // Error strings are project-file-specific because // RemoteRepositoryFactory.detectRepositoryType() doesn't throw // exceptions, so any thrown must be from detectProjectFile(). resultText = OStrings.getString("TEAM_ERROR_DETECTING_PROJECT_FILE"); Log.logErrorRB(ex, "TEAM_ERROR_DETECTING_PROJECT_FILE"); } detectedRepoOrProjectFileLabel.setText(resultText); if (type != null) { suggestLocalFolder(); } repoType = type; updateDialog(); } } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; urlLabel = new javax.swing.JLabel(); txtRepositoryOrProjectFileURL = new javax.swing.JTextField(); detectedRepoOrProjectFileLabel = new javax.swing.JLabel(); localFolderLabel = new javax.swing.JLabel(); txtDirectory = new javax.swing.JTextField(); btnDirectory = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); btnOk = new javax.swing.JButton(); btnCancel = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle(OStrings.getString("TEAM_NEW_HEADER")); // NOI18N getContentPane().setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(urlLabel, OStrings.getString("TEAM_NEW_PROJECT_URL_OR_FILE")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); getContentPane().add(urlLabel, gridBagConstraints); txtRepositoryOrProjectFileURL.setColumns(40); txtRepositoryOrProjectFileURL.setToolTipText(""); txtRepositoryOrProjectFileURL.addFocusListener(new java.awt.event.FocusAdapter() { public void focusLost(java.awt.event.FocusEvent evt) { txtProjectFileURLFocusLost(evt); } }); txtRepositoryOrProjectFileURL.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { txtProjectFileURLActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); getContentPane().add(txtRepositoryOrProjectFileURL, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(detectedRepoOrProjectFileLabel, " "); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; getContentPane().add(detectedRepoOrProjectFileLabel, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(localFolderLabel, OStrings.getString("TEAM_NEW_PROJECT_DIRECTORY")); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); getContentPane().add(localFolderLabel, gridBagConstraints); txtDirectory.setToolTipText(""); txtDirectory.addFocusListener(new java.awt.event.FocusAdapter() { public void focusLost(java.awt.event.FocusEvent evt) { txtDirectoryFocusLost(evt); } }); txtDirectory.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { txtDirectoryActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0); getContentPane().add(txtDirectory, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(btnDirectory, "..."); btnDirectory.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnDirectoryActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 3; gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); getContentPane().add(btnDirectory, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(btnOk, OStrings.getString("BUTTON_OK")); // NOI18N btnOk.setEnabled(false); btnOk.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnOkActionPerformed(evt); } }); jPanel2.add(btnOk); org.openide.awt.Mnemonics.setLocalizedText(btnCancel, OStrings.getString("BUTTON_CANCEL")); // NOI18N btnCancel.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnCancelActionPerformed(evt); } }); jPanel2.add(btnCancel); btnCancel.getAccessibleContext().setAccessibleDescription(""); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 10; gridBagConstraints.gridwidth = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; getContentPane().add(jPanel2, gridBagConstraints); pack(); }// </editor-fold>//GEN-END:initComponents private void updateDialog() { String dir = getSaveLocation(); boolean dirOK = !dir.isEmpty() && !new File(dir).exists(); boolean typeDetected = repoType != null; btnOk.setEnabled(dirOK && typeDetected); } private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed if (repoTypeWorker != null) { repoTypeWorker.cancel(true); } dispose(); }//GEN-LAST:event_btnCancelActionPerformed private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed dispose(); ok = true; }//GEN-LAST:event_btnOkActionPerformed private void btnDirectoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDirectoryActionPerformed NewProjectFileChooser ndc = new NewProjectFileChooser(); String saveDir = getSaveLocation(); if (!saveDir.isEmpty()) { ndc.setSelectedFile(new File(saveDir)); } int ndcResult = ndc.showSaveDialog(this); if (ndcResult == OmegaTFileChooser.APPROVE_OPTION) { txtDirectory.setText(ndc.getSelectedFile().getPath()); } updateDialog(); }//GEN-LAST:event_btnDirectoryActionPerformed private void txtProjectFileURLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtProjectFileURLActionPerformed detectRepoOrFile(); }//GEN-LAST:event_txtProjectFileURLActionPerformed private void txtProjectFileURLFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtProjectFileURLFocusLost detectRepoOrFile(); }//GEN-LAST:event_txtProjectFileURLFocusLost private void txtDirectoryFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtDirectoryFocusLost updateDialog(); }//GEN-LAST:event_txtDirectoryFocusLost private void txtDirectoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtDirectoryActionPerformed updateDialog(); }//GEN-LAST:event_txtDirectoryActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnCancel; private javax.swing.JButton btnDirectory; private javax.swing.JButton btnOk; private javax.swing.JLabel detectedRepoOrProjectFileLabel; private javax.swing.JPanel jPanel2; private javax.swing.JLabel localFolderLabel; public javax.swing.JTextField txtDirectory; public javax.swing.JTextField txtRepositoryOrProjectFileURL; private javax.swing.JLabel urlLabel; // End of variables declaration//GEN-END:variables public boolean ok; }