Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 102461 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.properties (+2 lines)
Lines 239-241 Link Here
239
239
240
RepoPreference.Name=CVS Repositories
240
RepoPreference.Name=CVS Repositories
241
RepoPreference.Description=Preferences that contain the CVS repository connection information
241
RepoPreference.Description=Preferences that contain the CVS repository connection information
242
243
CommentTemplatesPreferencePage.name=Comment Templates
(-)plugin.xml (+10 lines)
Lines 681-686 Link Here
681
   <extension
681
   <extension
682
         point="org.eclipse.ui.preferencePages">
682
         point="org.eclipse.ui.preferencePages">
683
      <page
683
      <page
684
            name="%CommentTemplatesPreferencePage.name"
685
            category="org.eclipse.team.cvs.ui.CVSPreferences"
686
            class="org.eclipse.team.internal.ccvs.ui.CommentTemplatesPreferencePage"
687
            id="org.eclipse.team.cvs.ui.CommentTemplatesPreferences">
688
            <keywordReference id="org.eclipse.team.cvs.ui.cvs"/>
689
      </page>
690
   </extension>
691
   <extension
692
         point="org.eclipse.ui.preferencePages">
693
      <page
684
            name="%ConsolePreferencePage.name"
694
            name="%ConsolePreferencePage.name"
685
            category="org.eclipse.team.cvs.ui.CVSPreferences"
695
            category="org.eclipse.team.cvs.ui.CVSPreferences"
686
            class="org.eclipse.team.internal.ccvs.ui.console.ConsolePreferencesPage"
696
            class="org.eclipse.team.internal.ccvs.ui.console.ConsolePreferencesPage"
(-)src/org/eclipse/team/internal/ccvs/ui/CVSUIMessages.java (-1 / +9 lines)
Lines 815-820 Link Here
815
	public static String CommitCommentArea_2;
815
	public static String CommitCommentArea_2;
816
	public static String CommitCommentArea_3;
816
	public static String CommitCommentArea_3;
817
	public static String CommitCommentArea_4;
817
	public static String CommitCommentArea_4;
818
    public static String CommitCommentArea_5;
818
819
819
	public static String CheckoutProjectOperation_8;
820
	public static String CheckoutProjectOperation_8;
820
	public static String CheckoutProjectOperation_9;
821
	public static String CheckoutProjectOperation_9;
Lines 985-988 Link Here
985
986
986
    public static String OpenChangeSetAction_0;
987
    public static String OpenChangeSetAction_0;
987
    public static String OpenChangeSetAction_1;
988
    public static String OpenChangeSetAction_1;
988
}
989
    
990
    public static String CommentTemplatesPreferencePage_Description;
991
    public static String CommentTemplatesPreferencePage_New;
992
    public static String CommentTemplatesPreferencePage_Edit;
993
    public static String CommentTemplatesPreferencePage_Remove;
994
    public static String CommentTemplatesPreferencePage_EditCommentTemplateTitle;
995
    public static String CommentTemplatesPreferencePage_EditCommentTemplateMessage;
996
}
(-)src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java (+1 lines)
Lines 41-46 Link Here
41
import org.eclipse.team.internal.ui.TeamUIPlugin;
41
import org.eclipse.team.internal.ui.TeamUIPlugin;
42
import org.eclipse.team.internal.ui.Utils;
42
import org.eclipse.team.internal.ui.Utils;
43
import org.eclipse.ui.*;
43
import org.eclipse.ui.*;
44
import org.eclipse.ui.dialogs.PreferencesUtil;
44
import org.eclipse.ui.plugin.AbstractUIPlugin;
45
import org.eclipse.ui.plugin.AbstractUIPlugin;
45
import org.osgi.framework.BundleContext;
46
import org.osgi.framework.BundleContext;
46
47
(-)src/org/eclipse/team/internal/ccvs/ui/CommitCommentArea.java (-11 / +64 lines)
Lines 26-31 Link Here
26
import org.eclipse.team.internal.ccvs.core.*;
26
import org.eclipse.team.internal.ccvs.core.*;
27
import org.eclipse.team.internal.ui.SWTUtils;
27
import org.eclipse.team.internal.ui.SWTUtils;
28
import org.eclipse.team.internal.ui.dialogs.DialogArea;
28
import org.eclipse.team.internal.ui.dialogs.DialogArea;
29
import org.eclipse.ui.dialogs.PreferencesUtil;
29
30
30
/**
31
/**
31
 * This area provides the widgets for providing the CVS commit comment
32
 * This area provides the widgets for providing the CVS commit comment
Lines 125-159 Link Here
125
        
126
        
126
        private final String fMessage;
127
        private final String fMessage;
127
        private final String [] fComments;
128
        private final String [] fComments;
129
        private final String[] fCommentTemplates;
128
        private final Combo fCombo;
130
        private final Combo fCombo;
129
        
131
        
130
        
132
        
131
        public ComboBox(Composite composite, String message, String [] options) {
133
        public ComboBox(Composite composite, String message, String [] options,
134
                String[] commentTemplates) {
132
            
135
            
133
            fMessage= message;
136
            fMessage= message;
134
            fComments= options;
137
            fComments= options;
138
            fCommentTemplates = commentTemplates;
135
            
139
            
136
            fCombo = new Combo(composite, SWT.READ_ONLY);
140
            fCombo = new Combo(composite, SWT.READ_ONLY);
137
            fCombo.setLayoutData(SWTUtils.createHFillGridData());
141
            fCombo.setLayoutData(SWTUtils.createHFillGridData());
138
            
142
            
139
            // populate the previous comment list
143
            // populate the previous comment list
140
            fCombo.add(fMessage);
144
            populateList(fCommentTemplates, fComments);
141
            for (int i = 0; i < fComments.length; i++) {
142
                fCombo.add(HistoryView.flattenText(fComments[i]));
143
            }
144
            fCombo.setText(fMessage);
145
            
145
            
146
            // We don't want to have an initial selection
146
            // We don't want to have an initial selection
147
            // (see bug 32078: http://bugs.eclipse.org/bugs/show_bug.cgi?id=32078)
147
            // (see bug 32078: http://bugs.eclipse.org/bugs/show_bug.cgi?id=32078)
148
            fCombo.addFocusListener(this);
148
            fCombo.addFocusListener(this);
149
            fCombo.addSelectionListener(this);
149
            fCombo.addSelectionListener(this);
150
        }
150
        }
151
152
		private void populateList(String[] templates, String[] comments) {
153
			fCombo.removeAll();
154
			
155
			fCombo.add(fMessage);
156
            for (int i = 0; i < templates.length; i++) {
157
                fCombo.add("TEMPL: " + HistoryView.flattenText(templates[i]));
158
            }
159
            // TODO: add divider here and remove "TEMPL:" above
160
            // (note: widgetSelected() below must be changed accordingly)
161
            for (int i = 0; i < comments.length; i++) {
162
                fCombo.add(HistoryView.flattenText(comments[i]));
163
            }
164
            fCombo.setText(fMessage);
165
		}
151
        
166
        
152
        public void widgetSelected(SelectionEvent e) {
167
        public void widgetSelected(SelectionEvent e) {
153
            final int index = fCombo.getSelectionIndex();
168
            int index = fCombo.getSelectionIndex();
154
            if (index > 0) {
169
            if (index > 0) {
170
                index--;
155
                setChanged();
171
                setChanged();
156
                notifyObservers(fComments[index - 1]);
172
                
173
                // map from combo box index to array index
174
                String message;
175
                if (index < fCommentTemplates.length) {
176
                	message = fCommentTemplates[index];
177
                } else {
178
                	message = fComments[index - fCommentTemplates.length];
179
                }
180
                notifyObservers(message);
157
            }
181
            }
158
        }
182
        }
159
        
183
        
Lines 178-187 Link Here
178
        public void setEnabled(boolean enabled) {
202
        public void setEnabled(boolean enabled) {
179
            fCombo.setEnabled(enabled);
203
            fCombo.setEnabled(enabled);
180
        }
204
        }
205
206
		void setCommentTemplates(String[] templates) {
207
			populateList(templates, fComments);
208
		}
181
    }
209
    }
182
    
210
    
183
    private static final String EMPTY_MESSAGE= CVSUIMessages.CommitCommentArea_0; //$NON-NLS-1$
211
    private static final String EMPTY_MESSAGE= CVSUIMessages.CommitCommentArea_0; //$NON-NLS-1$
184
    private static final String COMBO_MESSAGE= CVSUIMessages.CommitCommentArea_1; //$NON-NLS-1$
212
    private static final String COMBO_MESSAGE= CVSUIMessages.CommitCommentArea_1; //$NON-NLS-1$
213
    private static final String CONFIGURE_TEMPLATES_MESSAGE= CVSUIMessages.CommitCommentArea_5; //$NON-NLS-1$
185
    
214
    
186
    public static final String OK_REQUESTED = "OkRequested";//$NON-NLS-1$
215
    public static final String OK_REQUESTED = "OkRequested";//$NON-NLS-1$
187
    public static final String COMMENT_MODIFIED = "CommentModified";//$NON-NLS-1$
216
    public static final String COMMENT_MODIFIED = "CommentModified";//$NON-NLS-1$
Lines 206-224 Link Here
206
        fTextBox= new TextBox(fComposite, EMPTY_MESSAGE, getInitialComment());
235
        fTextBox= new TextBox(fComposite, EMPTY_MESSAGE, getInitialComment());
207
        
236
        
208
        final String [] comments = CVSUIPlugin.getPlugin().getRepositoryManager().getPreviousComments();
237
        final String [] comments = CVSUIPlugin.getPlugin().getRepositoryManager().getPreviousComments();
209
        fComboBox= new ComboBox(fComposite, COMBO_MESSAGE, comments);
238
        final String[] commentTemplates = CVSUIPlugin.getPlugin().getRepositoryManager().getCommentTemplates();
239
        fComboBox= new ComboBox(fComposite, COMBO_MESSAGE, comments, commentTemplates);
240
        
241
        Link templatesPrefsLink = new Link(fComposite, 0);
242
        templatesPrefsLink.setText("<a href=\"configureTemplates\">" + //$NON-NLS-1$
243
        		CONFIGURE_TEMPLATES_MESSAGE + "</a>"); //$NON-NLS-1$
244
        templatesPrefsLink.addSelectionListener(new SelectionListener() {
245
			public void widgetDefaultSelected(SelectionEvent e) {
246
				openCommentTemplatesPreferencePage();
247
			}
248
		
249
			public void widgetSelected(SelectionEvent e) {
250
				openCommentTemplatesPreferencePage();
251
			}
252
		});
210
        
253
        
211
        fComboBox.addObserver(fTextBox);
254
        fComboBox.addObserver(fTextBox);
212
    }
255
    }
213
    
256
    
214
    public String getComment(boolean save) {
257
    void openCommentTemplatesPreferencePage() {
258
		PreferencesUtil.createPreferenceDialogOn(
259
				null,
260
				"org.eclipse.team.cvs.ui.CommentTemplatesPreferences",
261
				new String[] { "org.eclipse.team.cvs.ui.CommentTemplatesPreferences" },
262
				null).open();
263
		fComboBox.setCommentTemplates(
264
				CVSUIPlugin.getPlugin().getRepositoryManager().getCommentTemplates());
265
	}
266
267
	public String getComment(boolean save) {
215
        final String comment= fTextBox.getText();
268
        final String comment= fTextBox.getText();
216
        if (comment == null)
269
        if (comment == null)
217
            return ""; //$NON-NLS-1$
270
            return ""; //$NON-NLS-1$
218
        
271
        
219
        final String stripped= strip(comment);
272
        final String stripped= strip(comment);
220
        if (save && comment.length() > 0)
273
        if (save && comment.length() > 0)
221
            CVSUIPlugin.getPlugin().getRepositoryManager().addComment(comment);
274
            CVSUIPlugin.getPlugin().getRepositoryManager().addComment(comment, false);
222
275
223
        return stripped;
276
        return stripped;
224
    }
277
    }
(-)src/org/eclipse/team/internal/ccvs/ui/messages.properties (+8 lines)
Lines 853-858 Link Here
853
CommitCommentArea_2=Empty commit comment
853
CommitCommentArea_2=Empty commit comment
854
CommitCommentArea_3=The commit comment is empty. Are you sure you would like to continue with an empty comment?
854
CommitCommentArea_3=The commit comment is empty. Are you sure you would like to continue with an empty comment?
855
CommitCommentArea_4=Re&member decision?
855
CommitCommentArea_4=Re&member decision?
856
CommitCommentArea_5=Configure Comment Templates...
856
857
857
858
858
859
Lines 1039-1041 Link Here
1039
UncommittedChangesDialog_3=&The dirty resources contained in ''{0}''
1040
UncommittedChangesDialog_3=&The dirty resources contained in ''{0}''
1040
UncommittedChangesDialog_4=&The full path of ''{0}''
1041
UncommittedChangesDialog_4=&The full path of ''{0}''
1041
AddWizard_0=Add to Version Control
1042
AddWizard_0=Add to Version Control
1043
1044
CommentTemplatesPreferencePage_Description=Create, edit or remove comment templates:
1045
CommentTemplatesPreferencePage_New=New...
1046
CommentTemplatesPreferencePage_Edit=Edit...
1047
CommentTemplatesPreferencePage_Remove=Remove
1048
CommentTemplatesPreferencePage_EditCommentTemplateTitle=Enter Comment Template
1049
CommentTemplatesPreferencePage_EditCommentTemplateMessage=Please enter a comment template:
(-)src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java (-11 / +136 lines)
Lines 47-54 Link Here
47
	// new state file
47
	// new state file
48
	private static final String REPOSITORIES_VIEW_FILE = "repositoriesView.xml"; //$NON-NLS-1$
48
	private static final String REPOSITORIES_VIEW_FILE = "repositoriesView.xml"; //$NON-NLS-1$
49
	private static final String COMMENT_HIST_FILE = "commitCommentHistory.xml"; //$NON-NLS-1$
49
	private static final String COMMENT_HIST_FILE = "commitCommentHistory.xml"; //$NON-NLS-1$
50
    private static final String COMMENT_TEMPLATES_FILE = "commentTemplates.xml"; //$NON-NLS-1$
50
	static final String ELEMENT_COMMIT_COMMENT = "CommitComment"; //$NON-NLS-1$
51
	static final String ELEMENT_COMMIT_COMMENT = "CommitComment"; //$NON-NLS-1$
51
	static final String ELEMENT_COMMIT_HISTORY = "CommitComments"; //$NON-NLS-1$
52
	static final String ELEMENT_COMMIT_HISTORY = "CommitComments"; //$NON-NLS-1$
53
    static final String ELEMENT_COMMENT_TEMPLATES = "CommitCommentTemplates"; //$NON-NLS-1$
52
54
53
	private Map repositoryRoots = new HashMap();
55
	private Map repositoryRoots = new HashMap();
54
	
56
	
Lines 56-61 Link Here
56
58
57
	// The previously remembered comment
59
	// The previously remembered comment
58
	static String[] previousComments = new String[0];
60
	static String[] previousComments = new String[0];
61
    static String[] commentTemplates = new String[0];
59
	
62
	
60
	public static boolean notifyRepoView = true;
63
	public static boolean notifyRepoView = true;
61
	
64
	
Lines 303-308 Link Here
303
	public void startup() {
306
	public void startup() {
304
		loadState();
307
		loadState();
305
		loadCommentHistory();
308
		loadCommentHistory();
309
        loadCommentTemplates();
306
		CVSProviderPlugin.getPlugin().addRepositoryListener(new ICVSListener() {
310
		CVSProviderPlugin.getPlugin().addRepositoryListener(new ICVSListener() {
307
			public void repositoryAdded(ICVSRepositoryLocation root) {
311
			public void repositoryAdded(ICVSRepositoryLocation root) {
308
				rootAdded(root);
312
				rootAdded(root);
Lines 316-321 Link Here
316
	public void shutdown() throws TeamException {
320
	public void shutdown() throws TeamException {
317
		saveState();
321
		saveState();
318
		saveCommentHistory();
322
		saveCommentHistory();
323
        saveCommentTemplates();
319
	}
324
	}
320
	
325
	
321
	private void loadState() {
326
	private void loadState() {
Lines 372-377 Link Here
372
			CVSUIPlugin.log(e);
377
			CVSUIPlugin.log(e);
373
		}
378
		}
374
	}
379
	}
380
    private void loadCommentTemplates() {
381
        IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation().append(COMMENT_TEMPLATES_FILE);
382
        File file = pluginStateLocation.toFile();
383
        if (!file.exists()) return;
384
        try {
385
            BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
386
            try {
387
                readCommentTemplates(is);
388
            } finally {
389
                is.close();
390
            }
391
        } catch (IOException e) {
392
            CVSUIPlugin.log(Status.ERROR, CVSUIMessages.RepositoryManager_ioException, e); //$NON-NLS-1$
393
        } catch (TeamException e) {
394
            CVSUIPlugin.log(e);
395
        }
396
    }
375
	
397
	
376
	protected void saveState() throws TeamException {
398
	protected void saveState() throws TeamException {
377
		IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
399
		IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
Lines 430-435 Link Here
430
			throw new CVSException(NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String[] { COMMENT_HIST_FILE }), ex); //$NON-NLS-1$
452
			throw new CVSException(NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String[] { COMMENT_HIST_FILE }), ex); //$NON-NLS-1$
431
		}
453
		}
432
	}
454
	}
455
    private void readCommentTemplates(InputStream stream) throws IOException, TeamException {
456
        try {
457
            SAXParserFactory factory = SAXParserFactory.newInstance();
458
            SAXParser parser = factory.newSAXParser();
459
            parser.parse(new InputSource(stream), new CommentTemplatesContentHandler());
460
        } catch (SAXException ex) {
461
            throw new CVSException(NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String[] { COMMENT_TEMPLATES_FILE }), ex); //$NON-NLS-1$
462
        } catch (ParserConfigurationException ex) {
463
            throw new CVSException(NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String[] { COMMENT_TEMPLATES_FILE }), ex); //$NON-NLS-1$
464
        }
465
    }
433
	
466
	
434
	private void readOldState(DataInputStream dis) throws IOException, TeamException {
467
	private void readOldState(DataInputStream dis) throws IOException, TeamException {
435
		int repoSize = dis.readInt();
468
		int repoSize = dis.readInt();
Lines 512-523 Link Here
512
		 		 throw new TeamException(new Status(Status.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_save, new String[] { histFile.getAbsolutePath() }), e)); //$NON-NLS-1$
545
		 		 throw new TeamException(new Status(Status.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_save, new String[] { histFile.getAbsolutePath() }), e)); //$NON-NLS-1$
513
		 }
546
		 }
514
	}
547
	}
548
    protected void saveCommentTemplates() throws TeamException {
549
        IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
550
        File tempFile = pluginStateLocation.append(COMMENT_TEMPLATES_FILE + ".tmp").toFile(); //$NON-NLS-1$
551
        File histFile = pluginStateLocation.append(COMMENT_TEMPLATES_FILE).toFile();
552
        try {
553
                 XMLWriter writer = new XMLWriter(new BufferedOutputStream(new FileOutputStream(tempFile)));
554
                 try {
555
                         writeCommentTemplates(writer);
556
                 } finally {
557
                         writer.close();
558
                 }
559
                 if (histFile.exists()) {
560
                         histFile.delete();
561
                 }
562
                 boolean renamed = tempFile.renameTo(histFile);
563
                 if (!renamed) {
564
                         throw new TeamException(new Status(Status.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_rename, new String[] { tempFile.getAbsolutePath() }), null)); //$NON-NLS-1$
565
                 }
566
         } catch (IOException e) {
567
                 throw new TeamException(new Status(Status.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_save, new String[] { histFile.getAbsolutePath() }), e)); //$NON-NLS-1$
568
         }
569
    }
515
	private void writeCommentHistory(XMLWriter writer) {
570
	private void writeCommentHistory(XMLWriter writer) {
516
		writer.startTag(ELEMENT_COMMIT_HISTORY, null, false);
571
		writer.startTag(ELEMENT_COMMIT_HISTORY, null, false);
517
		for (int i=0; i<previousComments.length && i<MAX_COMMENTS; i++)
572
		for (int i=0; i<previousComments.length && i<MAX_COMMENTS; i++)
518
			writer.printSimpleTag(ELEMENT_COMMIT_COMMENT, previousComments[i]);
573
			writer.printSimpleTag(ELEMENT_COMMIT_COMMENT, previousComments[i]);
519
		writer.endTag(ELEMENT_COMMIT_HISTORY);
574
		writer.endTag(ELEMENT_COMMIT_HISTORY);
520
	}
575
	}
576
    private void writeCommentTemplates(XMLWriter writer) {
577
        writer.startTag(ELEMENT_COMMENT_TEMPLATES, null, false);
578
        for (int i=0; i<commentTemplates.length; i++)
579
            writer.printSimpleTag(ELEMENT_COMMIT_COMMENT, commentTemplates[i]);
580
        writer.endTag(ELEMENT_COMMENT_TEMPLATES);
581
    }
521
		 
582
		 
522
	public void addRepositoryListener(IRepositoryListener listener) {
583
	public void addRepositoryListener(IRepositoryListener listener) {
523
		listeners.add(listener);
584
		listeners.add(listener);
Lines 778-798 Link Here
778
		return previousComments;
839
		return previousComments;
779
	}
840
	}
780
841
842
    /**
843
     * Get list of comment templates.
844
     */
845
    public String[] getCommentTemplates() {
846
        return commentTemplates;
847
    }
848
    
781
	/**
849
	/**
782
	 * Method addComment.
850
	 * Method addComment.
783
	 * @param string
851
	 * @param string
784
	 */
852
	 */
785
	public void addComment(String comment) {
853
	public void addComment(String comment, boolean template) {
786
		// Only add the comment if its not there already
854
        if (template) {
787
		if (containsComment(comment)) return;
855
            addCommentTemplate(comment);
788
		// Insert the comment as the first element
856
        } else {
789
		String[] newComments = new String[Math.min(previousComments.length + 1, MAX_COMMENTS)];
857
            addComment(comment);
790
		newComments[0] = comment;
858
        }
791
		for (int i = 1; i < newComments.length; i++) {
859
	}
792
			newComments[i] = previousComments[i-1];
860
    
793
		}
861
    private void addCommentTemplate(String comment) {
794
		previousComments = newComments;
862
        // Only add the comment if its not there already
795
	}
863
        if (containsCommentTemplate(comment))
864
            return;
865
866
        // remove from list of regular comments if there
867
        if (containsComment(comment)) {
868
            List newComments = new ArrayList();
869
            for (int i = 0; i < previousComments.length; i++) {
870
                if (!previousComments[i].equals(comment))
871
                    newComments.add(previousComments[i]);
872
            }
873
            previousComments = (String[]) newComments.toArray(new String[0]);
874
        }
875
876
        // Insert the comment as first element
877
        String[] newComments = new String[commentTemplates.length + 1];
878
        System.arraycopy(commentTemplates, 0, newComments, 1, commentTemplates.length);
879
        newComments[0] = comment;
880
        commentTemplates = newComments;
881
    }
882
    
883
    private void addComment(String comment) {
884
        // Only add the comment if its not there already
885
        if (containsComment(comment))
886
            return;
887
888
        // remove from list of comment templates if there
889
        if (containsCommentTemplate(comment)) {
890
            List newComments = new ArrayList();
891
            for (int i = 0; i < commentTemplates.length; i++) {
892
                if (!commentTemplates[i].equals(comment))
893
                    newComments.add(commentTemplates[i]);
894
            }
895
            commentTemplates = (String[]) newComments.toArray(new String[0]);
896
        }
897
        
898
        // Insert the comment as the first element
899
        String[] newComments = new String[Math.min(
900
                previousComments.length + 1, MAX_COMMENTS)];
901
        newComments[0] = comment;
902
        for (int i = 1; i < newComments.length; i++) {
903
            newComments[i] = previousComments[i - 1];
904
        }
905
        previousComments = newComments;
906
    }
796
907
797
	private boolean containsComment(String comment) {
908
	private boolean containsComment(String comment) {
798
		for (int i = 0; i < previousComments.length; i++) {
909
		for (int i = 0; i < previousComments.length; i++) {
Lines 802-805 Link Here
802
		}
913
		}
803
		return false;
914
		return false;
804
	}
915
	}
916
    
917
    private boolean containsCommentTemplate(String comment) {
918
        for (int i = 0; i < commentTemplates.length; i++) {
919
            if (commentTemplates[i].equals(comment)) {
920
                return true;
921
            }
922
        }
923
        return false;
924
    }
925
    
926
    public void replaceAndSaveCommentTemplates(String[] templates) throws TeamException {
927
    	commentTemplates = templates;
928
    	saveCommentTemplates();
929
    }
805
}
930
}
(-)src/org/eclipse/team/internal/ccvs/ui/CommentTemplateEditDialog.java (+260 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.team.internal.ccvs.ui;
12
13
import org.eclipse.jface.dialogs.Dialog;
14
import org.eclipse.jface.dialogs.IDialogConstants;
15
import org.eclipse.jface.dialogs.IInputValidator;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.events.ModifyEvent;
18
import org.eclipse.swt.events.ModifyListener;
19
import org.eclipse.swt.layout.GridData;
20
import org.eclipse.swt.widgets.Button;
21
import org.eclipse.swt.widgets.Composite;
22
import org.eclipse.swt.widgets.Control;
23
import org.eclipse.swt.widgets.Label;
24
import org.eclipse.swt.widgets.Shell;
25
import org.eclipse.swt.widgets.Text;
26
27
/**
28
 * A simple input dialog for soliciting an input string from the user.
29
 * <p>
30
 * This concrete dialog class can be instantiated as is, or further subclassed as
31
 * required.
32
 * </p>
33
 */
34
public class CommentTemplateEditDialog extends Dialog {
35
    /**
36
     * The title of the dialog.
37
     */
38
    private String title;
39
40
    /**
41
     * The message to display, or <code>null</code> if none.
42
     */
43
    private String message;
44
45
    /**
46
     * The input value; the empty string by default.
47
     */
48
    private String value = "";//$NON-NLS-1$
49
50
    /**
51
     * The input validator, or <code>null</code> if none.
52
     */
53
    private IInputValidator validator;
54
55
    /**
56
     * Ok button widget.
57
     */
58
    private Button okButton;
59
60
    /**
61
     * Input text widget.
62
     */
63
    private Text text;
64
65
    /**
66
     * Error message label widget.
67
     */
68
    private Text errorMessageText;
69
70
    /**
71
     * Creates an input dialog with OK and Cancel buttons. Note that the dialog
72
     * will have no visual representation (no widgets) until it is told to open.
73
     * <p>
74
     * Note that the <code>open</code> method blocks for input dialogs.
75
     * </p>
76
     * 
77
     * @param parentShell
78
     *            the parent shell, or <code>null</code> to create a top-level
79
     *            shell
80
     * @param dialogTitle
81
     *            the dialog title, or <code>null</code> if none
82
     * @param dialogMessage
83
     *            the dialog message, or <code>null</code> if none
84
     * @param initialValue
85
     *            the initial input value, or <code>null</code> if none
86
     *            (equivalent to the empty string)
87
     * @param validator
88
     *            an input validator, or <code>null</code> if none
89
     */
90
    public CommentTemplateEditDialog(Shell parentShell, String dialogTitle,
91
            String dialogMessage, String initialValue, IInputValidator validator) {
92
        super(parentShell);
93
        this.title = dialogTitle;
94
        message = dialogMessage;
95
        if (initialValue == null)
96
            value = "";//$NON-NLS-1$
97
        else
98
            value = initialValue;
99
        this.validator = validator;
100
    }
101
102
    /*
103
     * (non-Javadoc) Method declared on Dialog.
104
     */
105
    protected void buttonPressed(int buttonId) {
106
        if (buttonId == IDialogConstants.OK_ID) {
107
            value = text.getText();
108
        } else {
109
            value = null;
110
        }
111
        super.buttonPressed(buttonId);
112
    }
113
114
    /*
115
     * (non-Javadoc)
116
     * 
117
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
118
     */
119
    protected void configureShell(Shell shell) {
120
        super.configureShell(shell);
121
        if (title != null)
122
            shell.setText(title);
123
    }
124
125
    /*
126
     * (non-Javadoc)
127
     * 
128
     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
129
     */
130
    protected void createButtonsForButtonBar(Composite parent) {
131
        // create OK and Cancel buttons by default
132
        okButton = createButton(parent, IDialogConstants.OK_ID,
133
                IDialogConstants.OK_LABEL, true);
134
        createButton(parent, IDialogConstants.CANCEL_ID,
135
                IDialogConstants.CANCEL_LABEL, false);
136
        //do this here because setting the text will set enablement on the ok
137
        // button
138
        text.setFocus();
139
        if (value != null) {
140
            text.setText(value);
141
            text.selectAll();
142
        }
143
    }
144
145
    /*
146
     * (non-Javadoc) Method declared on Dialog.
147
     */
148
    protected Control createDialogArea(Composite parent) {
149
        // create composite
150
        Composite composite = (Composite) super.createDialogArea(parent);
151
        // create message
152
        if (message != null) {
153
            Label label = new Label(composite, SWT.WRAP);
154
            label.setText(message);
155
            GridData data = new GridData(GridData.GRAB_HORIZONTAL
156
                    | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
157
                    | GridData.VERTICAL_ALIGN_CENTER);
158
            data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
159
            label.setLayoutData(data);
160
            label.setFont(parent.getFont());
161
        }
162
        text = new Text(composite, SWT.MULTI | SWT.BORDER);
163
        GridData gd = new GridData(GridData.GRAB_HORIZONTAL
164
                | GridData.HORIZONTAL_ALIGN_FILL);
165
		gd.heightHint = convertHeightInCharsToPixels(5);
166
		text.setLayoutData(gd);
167
        text.addModifyListener(new ModifyListener() {
168
            public void modifyText(ModifyEvent e) {
169
                validateInput();
170
            }
171
        });
172
        errorMessageText = new Text(composite, SWT.READ_ONLY);
173
        errorMessageText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
174
                | GridData.HORIZONTAL_ALIGN_FILL));
175
        errorMessageText.setBackground(errorMessageText.getDisplay()
176
                .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
177
178
        applyDialogFont(composite);
179
        return composite;
180
    }
181
182
    /**
183
     * Returns the error message label.
184
     * 
185
     * @return the error message label
186
     * @deprecated use setErrorMessage(String) instead
187
     */
188
    protected Label getErrorMessageLabel() {
189
        return null;
190
    }
191
192
    /**
193
     * Returns the ok button.
194
     * 
195
     * @return the ok button
196
     */
197
    protected Button getOkButton() {
198
        return okButton;
199
    }
200
201
    /**
202
     * Returns the text area.
203
     * 
204
     * @return the text area
205
     */
206
    protected Text getText() {
207
        return text;
208
    }
209
210
    /**
211
     * Returns the validator.
212
     * 
213
     * @return the validator
214
     */
215
    protected IInputValidator getValidator() {
216
        return validator;
217
    }
218
219
    /**
220
     * Returns the string typed into this input dialog.
221
     * 
222
     * @return the input string
223
     */
224
    public String getValue() {
225
        return value;
226
    }
227
228
    /**
229
     * Validates the input.
230
     * <p>
231
     * The default implementation of this framework method delegates the request
232
     * to the supplied input validator object; if it finds the input invalid,
233
     * the error message is displayed in the dialog's message line. This hook
234
     * method is called whenever the text changes in the input field.
235
     * </p>
236
     */
237
    protected void validateInput() {
238
        String errorMessage = null;
239
        if (validator != null) {
240
            errorMessage = validator.isValid(text.getText());
241
        }
242
        // Bug 16256: important not to treat "" (blank error) the same as null
243
        // (no error)
244
        setErrorMessage(errorMessage);
245
    }
246
247
    /**
248
     * Sets or clears the error message.
249
     * If not <code>null</code>, the OK button is disabled.
250
     * 
251
     * @param errorMessage
252
     *            the error message, or <code>null</code> to clear
253
     * @since 3.0
254
     */
255
    public void setErrorMessage(String errorMessage) {
256
        errorMessageText.setText(errorMessage == null ? "" : errorMessage); //$NON-NLS-1$
257
        okButton.setEnabled(errorMessage == null);
258
        errorMessageText.getParent().update();
259
    }
260
}
(-)src/org/eclipse/team/internal/ccvs/ui/CommentTemplatesPreferencePage.java (+234 lines)
Added Link Here
1
package org.eclipse.team.internal.ccvs.ui;
2
3
import org.eclipse.jface.dialogs.Dialog;
4
import org.eclipse.jface.dialogs.IDialogConstants;
5
import org.eclipse.jface.preference.PreferencePage;
6
import org.eclipse.jface.viewers.DoubleClickEvent;
7
import org.eclipse.jface.viewers.IDoubleClickListener;
8
import org.eclipse.jface.viewers.ISelectionChangedListener;
9
import org.eclipse.jface.viewers.IStructuredSelection;
10
import org.eclipse.jface.viewers.LabelProvider;
11
import org.eclipse.jface.viewers.ListViewer;
12
import org.eclipse.jface.viewers.SelectionChangedEvent;
13
import org.eclipse.jface.viewers.Viewer;
14
import org.eclipse.jface.viewers.ViewerSorter;
15
import org.eclipse.jface.window.Window;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.layout.GridData;
18
import org.eclipse.swt.layout.GridLayout;
19
import org.eclipse.swt.widgets.Button;
20
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.swt.widgets.Event;
23
import org.eclipse.swt.widgets.Label;
24
import org.eclipse.swt.widgets.List;
25
import org.eclipse.swt.widgets.Listener;
26
import org.eclipse.swt.widgets.Text;
27
import org.eclipse.team.core.TeamException;
28
import org.eclipse.ui.IWorkbench;
29
import org.eclipse.ui.IWorkbenchPreferencePage;
30
31
public class CommentTemplatesPreferencePage extends PreferencePage implements
32
		IWorkbenchPreferencePage, ISelectionChangedListener {
33
34
	private ListViewer viewer;
35
	private Button editButton;
36
	private Button removeButton;
37
	private Text preview;
38
39
	protected Control createContents(Composite ancestor) {
40
		Composite parent = new Composite(ancestor, SWT.NONE);
41
		GridLayout layout = new GridLayout();
42
		layout.marginWidth = 0;
43
		layout.marginHeight = 0;
44
		layout.numColumns = 1;
45
		parent.setLayout(layout);
46
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));
47
48
		createListAndButtons(parent);
49
50
		Label previewLabel = new Label(parent, SWT.NONE);
51
		previewLabel.setText("Preview:");
52
		
53
		preview = new Text(parent, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
54
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
55
		gd.heightHint = convertHeightInCharsToPixels(5);
56
		preview.setLayoutData(gd);
57
		
58
		Dialog.applyDialogFont(ancestor);
59
		
60
		return parent;
61
	}
62
63
	private Composite createListAndButtons(Composite parent) {
64
		Composite listAndButtons = new Composite(parent, SWT.NONE);
65
		GridLayout layout = new GridLayout();
66
		layout.marginWidth = 0;
67
		layout.marginHeight = 0;
68
		layout.numColumns = 2;
69
		listAndButtons.setLayout(layout);
70
		listAndButtons.setLayoutData(new GridData(GridData.FILL_BOTH));
71
		
72
		viewer = new ListViewer(listAndButtons);
73
		viewer.setLabelProvider(new LabelProvider() {
74
			public String getText(Object element) {
75
				String template = (String) element;
76
				return HistoryView.flattenText(template);
77
			}
78
		});
79
		viewer.addSelectionChangedListener(this);
80
		viewer.setSorter(new ViewerSorter() {
81
			public int compare(Viewer viewer, Object e1, Object e2) {
82
				String template1 = HistoryView.flattenText((String) e1);
83
				String template2 = HistoryView.flattenText((String) e2);
84
				return template1.compareToIgnoreCase(template2);
85
			}
86
		});
87
		viewer.addDoubleClickListener(new IDoubleClickListener() {
88
			public void doubleClick(DoubleClickEvent event) {
89
				editTemplate();
90
			}
91
		});
92
		List list = viewer.getList();
93
		list.setLayoutData(new GridData(GridData.FILL_BOTH));
94
		
95
		// populate list
96
		String[] templates =
97
			CVSUIPlugin.getPlugin().getRepositoryManager().getCommentTemplates();
98
		for (int i = 0; i < templates.length; i++) {
99
			viewer.add(templates[i]);
100
		}
101
102
		createButtons(listAndButtons);
103
		return listAndButtons;
104
	}
105
106
	private void createButtons(Composite parent) {
107
		Composite buttons = new Composite(parent, SWT.NONE);
108
		buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
109
		GridLayout layout = new GridLayout();
110
		layout.marginHeight = 0;
111
		layout.marginWidth = 0;
112
		buttons.setLayout(layout);
113
114
		Button newButton = new Button(buttons, SWT.PUSH);
115
		newButton.setText(CVSUIMessages.CommentTemplatesPreferencePage_New);
116
		GridData data = new GridData();
117
		data.horizontalAlignment = GridData.FILL;
118
		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
119
		data.widthHint = Math.max(widthHint,
120
				newButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
121
		newButton.setLayoutData(data);
122
		newButton.setEnabled(true);
123
		newButton.addListener(SWT.Selection, new Listener() {
124
			public void handleEvent(Event event) {
125
				newTemplate();
126
			}
127
		});
128
129
		editButton = new Button(buttons, SWT.PUSH);
130
		editButton.setText(CVSUIMessages.CommentTemplatesPreferencePage_Edit);
131
		data = new GridData();
132
		data.horizontalAlignment = GridData.FILL;
133
		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
134
		data.widthHint = Math.max(widthHint,
135
				editButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
136
		editButton.setLayoutData(data);
137
		editButton.setEnabled(false);
138
		editButton.addListener(SWT.Selection, new Listener() {
139
			public void handleEvent(Event e) {
140
				editTemplate();
141
			}
142
		});
143
144
		removeButton = new Button(buttons, SWT.PUSH);
145
		removeButton.setText(CVSUIMessages.CommentTemplatesPreferencePage_Remove);
146
		data = new GridData();
147
		data.horizontalAlignment = GridData.FILL;
148
		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
149
		data.widthHint = Math.max(widthHint,
150
				removeButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
151
		removeButton.setLayoutData(data);
152
		removeButton.setEnabled(false);
153
		removeButton.addListener(SWT.Selection, new Listener() {
154
			public void handleEvent(Event e) {
155
				remove();
156
			}
157
		});
158
	}
159
	
160
	public void init(IWorkbench workbench) {
161
		setDescription(CVSUIMessages.CommentTemplatesPreferencePage_Description);
162
	}
163
164
	public void selectionChanged(SelectionChangedEvent event) {
165
		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
166
		switch (selection.size()) {
167
			case 0:
168
				editButton.setEnabled(false);
169
				removeButton.setEnabled(false);
170
				preview.setText("");
171
				break;
172
			
173
			case 1:
174
				editButton.setEnabled(true);
175
				removeButton.setEnabled(true);
176
				preview.setText((String) selection.getFirstElement());
177
				break;
178
			
179
			default:
180
				editButton.setEnabled(false);
181
				removeButton.setEnabled(true);
182
				preview.setText("");
183
				break;
184
		}
185
	}
186
	
187
	void newTemplate() {
188
		CommentTemplateEditDialog dialog = new CommentTemplateEditDialog(
189
				getShell(),
190
				CVSUIMessages.CommentTemplatesPreferencePage_EditCommentTemplateTitle,
191
				CVSUIMessages.CommentTemplatesPreferencePage_EditCommentTemplateMessage,
192
				"", null);
193
		if (dialog.open() == Window.OK) {
194
			viewer.add(dialog.getValue());
195
		}
196
	}
197
198
	void editTemplate() {
199
		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
200
		if (selection.size() == 1) {
201
			String oldTemplate = (String) selection.getFirstElement();
202
			CommentTemplateEditDialog dialog = new CommentTemplateEditDialog(
203
					getShell(),
204
					CVSUIMessages.CommentTemplatesPreferencePage_EditCommentTemplateTitle,
205
					CVSUIMessages.CommentTemplatesPreferencePage_EditCommentTemplateMessage,
206
					oldTemplate, null);
207
			if (dialog.open() == Window.OK) {
208
				viewer.remove(oldTemplate);
209
				viewer.add(dialog.getValue());
210
			}
211
		}
212
	}
213
	
214
	void remove() {
215
		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
216
		viewer.remove(selection.toArray());
217
	}
218
	
219
	public boolean performOk() {
220
		int numTemplates = viewer.getList().getItemCount();
221
		String[] templates = new String[numTemplates];
222
		for (int i = 0; i < numTemplates; i++) {
223
			templates[i] = (String) viewer.getElementAt(i);
224
		}
225
		try {
226
			CVSUIPlugin.getPlugin().getRepositoryManager()
227
				.replaceAndSaveCommentTemplates(templates);
228
		} catch (TeamException e) {
229
			// TODO: handle save error
230
		}
231
		
232
		return super.performOk();
233
	}
234
}
(-)src/org/eclipse/team/internal/ccvs/ui/repo/CommentTemplatesContentHandler.java (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2003 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.team.internal.ccvs.ui.repo;
13
14
import java.util.Vector;
15
16
import org.xml.sax.SAXException;
17
import org.xml.sax.helpers.DefaultHandler;
18
import org.xml.sax.Attributes;
19
20
class CommentTemplatesContentHandler extends DefaultHandler {
21
22
	private StringBuffer buffer;
23
	private Vector comments;
24
	public CommentTemplatesContentHandler() {
25
	}
26
27
	/**
28
	 * @see ContentHandler#characters(char[], int, int)
29
	 */
30
	public void characters(char[] chars, int startIndex, int length) throws SAXException {
31
		if (buffer == null) return;
32
		buffer.append(chars, startIndex, length);
33
	}
34
35
	/**
36
	 * @see ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
37
	 */
38
	public void startElement(
39
			String namespaceURI,
40
			String localName,
41
			String qName,
42
			Attributes atts)
43
			throws SAXException {
44
		
45
		String elementName = getElementName(namespaceURI, localName, qName);
46
		if (elementName.equals(RepositoryManager.ELEMENT_COMMIT_COMMENT)) {
47
			buffer = new StringBuffer();
48
			return;
49
		} 
50
		if (elementName.equals(RepositoryManager.ELEMENT_COMMENT_TEMPLATES)) {
51
			comments = new Vector();
52
			return;
53
		}
54
	}
55
	
56
	/**
57
	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
58
	 */
59
	public void endElement(String namespaceURI, String localName, String qName) {
60
		String elementName = getElementName(namespaceURI, localName, qName);
61
		if (elementName.equals(RepositoryManager.ELEMENT_COMMIT_COMMENT)) {
62
			comments.add(buffer.toString());
63
			buffer = null;
64
			return;
65
		} 
66
		if (elementName.equals(RepositoryManager.ELEMENT_COMMENT_TEMPLATES)) {
67
			RepositoryManager.commentTemplates = new String[comments.size()];
68
			comments.copyInto(RepositoryManager.commentTemplates);
69
			return;
70
		} 
71
	}
72
	
73
	/*
74
	 * Couldn't figure out from the SAX API exactly when localName vs. qName is used.
75
	 * However, the XML for project sets doesn't use namespaces so either of the two names
76
	 * is fine. Therefore, use whichever one is provided.
77
	 */
78
	private String getElementName(String namespaceURI, String localName, String qName) {
79
		if (localName != null && localName.length() > 0) {
80
			return localName;
81
		} else {
82
			return qName;
83
		}
84
	}
85
}

Return to bug 102461