KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > internal > AddFromHistoryDialog


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.compare.internal;
12
13 import java.io.*;
14 import com.ibm.icu.text.DateFormat;
15 import com.ibm.icu.text.MessageFormat;
16 import java.util.ArrayList JavaDoc;
17 import com.ibm.icu.util.Calendar;
18 import java.util.Date JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.ResourceBundle JavaDoc;
21
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.events.*;
24 import org.eclipse.swt.graphics.*;
25 import org.eclipse.swt.layout.*;
26 import org.eclipse.swt.widgets.*;
27
28 import org.eclipse.jface.dialogs.*;
29 import org.eclipse.jface.resource.ImageDescriptor;
30 import org.eclipse.jface.viewers.Viewer;
31
32 import org.eclipse.core.resources.*;
33 import org.eclipse.core.runtime.*;
34
35 import org.eclipse.compare.*;
36
37
38 public class AddFromHistoryDialog extends ResizableDialog {
39     
40     static class HistoryInput implements ITypedElement, IEncodedStreamContentAccessor, IModificationDate {
41         IFile fFile;
42         IFileState fFileState;
43         
44         HistoryInput(IFile file, IFileState fileState) {
45             fFile= file;
46             fFileState= fileState;
47         }
48         public InputStream getContents() throws CoreException {
49             return new BufferedInputStream(fFileState.getContents());
50         }
51         public String JavaDoc getCharset() {
52             String JavaDoc charset= null;
53             try {
54                 charset= fFileState.getCharset();
55             } catch (CoreException e) {
56                 // fall through
57
}
58             if (charset == null)
59                 charset= Utilities.getCharset(fFile);
60             return charset;
61         }
62         public String JavaDoc getName() {
63             return fFile.getName();
64         }
65         public String JavaDoc getType() {
66             return fFile.getFileExtension();
67         }
68         public Image getImage() {
69             return CompareUI.getImage(fFile);
70         }
71         public long getModificationDate() {
72             return fFileState.getModificationTime();
73         }
74     }
75     
76     static class FileHistory {
77         private IFile fFile;
78         private IFileState[] fStates;
79         private int fSelected;
80         
81         FileHistory(IFile file) {
82             fFile= file;
83         }
84         
85         IFile getFile() {
86             return fFile;
87         }
88         
89         IFileState[] getStates() {
90             if (fStates == null) {
91                 try {
92                     fStates= fFile.getHistory(new NullProgressMonitor());
93                 } catch (CoreException ex) {
94                     // NeedWork
95
}
96             }
97             return fStates;
98         }
99         
100         IFileState getSelectedState() {
101             return getStates()[fSelected];
102         }
103         
104         void setSelected(IFileState state) {
105             for (int i= 0; i < fStates.length; i++) {
106                 if (fStates[i] == state) {
107                     fSelected= i;
108                     return;
109                 }
110             }
111         }
112         
113         HistoryInput getHistoryInput() {
114             return new HistoryInput(fFile, getSelectedState());
115         }
116         
117         boolean isSelected(int index) {
118             return index == fSelected;
119         }
120     }
121
122     private CompareConfiguration fCompareConfiguration;
123     private ArrayList JavaDoc fArrayList= new ArrayList JavaDoc();
124     private FileHistory fCurrentFileHistory;
125
126     // SWT controls
127
private CompareViewerSwitchingPane fContentPane;
128     private Button fCommitButton;
129     private Table fMemberTable;
130     private CompareViewerPane fMemberPane;
131     private Tree fEditionTree;
132     private CompareViewerPane fEditionPane;
133     private Image fDateImage;
134     private Image fTimeImage;
135
136
137     public AddFromHistoryDialog(Shell parent, ResourceBundle JavaDoc bundle) {
138         super(parent, bundle);
139                     
140         String JavaDoc iconName= Utilities.getString(fBundle, "dateIcon", "obj16/day_obj.gif"); //$NON-NLS-2$ //$NON-NLS-1$
141
ImageDescriptor id= CompareUIPlugin.getImageDescriptor(iconName);
142         if (id != null)
143             fDateImage= id.createImage();
144         iconName= Utilities.getString(fBundle, "timeIcon", "obj16/resource_obj.gif"); //$NON-NLS-1$ //$NON-NLS-2$
145
id= CompareUIPlugin.getImageDescriptor(iconName);
146         if (id != null)
147             fTimeImage= id.createImage();
148     }
149     
150     public boolean select(IContainer root, IFile[] inputFiles) {
151         
152         create(); // create widgets
153

154         String JavaDoc format= Utilities.getString(fBundle, "memberPaneTitle"); //$NON-NLS-1$
155
String JavaDoc title= MessageFormat.format(format, new Object JavaDoc[] { root.getName() });
156         fMemberPane.setImage(CompareUI.getImage(root));
157         fMemberPane.setText(title);
158         
159         // sort input files
160
final int count= inputFiles.length;
161         final IFile[] files= new IFile[count];
162         for (int i= 0; i < count; i++)
163             files[i]= inputFiles[i];
164         if (count > 1)
165             internalSort(files, 0, count-1);
166             
167         
168         String JavaDoc prefix= root.getFullPath().toString();
169         
170         if (fMemberTable != null && !fMemberTable.isDisposed()) {
171             for (int i= 0; i < files.length; i++) {
172                 IFile file= files[i];
173                 String JavaDoc path= file.getFullPath().toString();
174                 if (path.startsWith(prefix))
175                     path= path.substring(prefix.length()+1);
176                 TableItem ti= new TableItem(fMemberTable, SWT.NONE);
177                 ti.setImage(CompareUI.getImage(file));
178                 ti.setText(path);
179                 ti.setData(new FileHistory(file));
180             }
181         }
182         
183         open();
184         
185         return (getReturnCode() == OK) && (fArrayList.size() > 0);
186     }
187         
188     HistoryInput[] getSelected() {
189         HistoryInput[] selected= new HistoryInput[fArrayList.size()];
190         Iterator JavaDoc iter= fArrayList.iterator();
191         for (int i= 0; iter.hasNext(); i++) {
192             FileHistory h= (FileHistory) iter.next();
193             selected[i]= h.getHistoryInput();
194         }
195         return selected;
196     }
197                 
198     protected synchronized Control createDialogArea(Composite parent2) {
199         
200         Composite parent= (Composite) super.createDialogArea(parent2);
201
202         getShell().setText(Utilities.getString(fBundle, "title")); //$NON-NLS-1$
203

204         org.eclipse.compare.Splitter vsplitter= new org.eclipse.compare.Splitter(parent, SWT.VERTICAL);
205         vsplitter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
206                     | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
207
208         vsplitter.addDisposeListener(
209             new DisposeListener() {
210                 public void widgetDisposed(DisposeEvent e) {
211                     if (fDateImage != null)
212                         fDateImage.dispose();
213                     if (fTimeImage != null)
214                         fTimeImage.dispose();
215                 }
216             }
217         );
218         
219         // we need two panes: the left for the elements, the right one for the editions
220
Splitter hsplitter= new Splitter(vsplitter, SWT.HORIZONTAL);
221         
222         Composite c= new Composite(hsplitter, SWT.NONE);
223         GridLayout layout= new GridLayout();
224         layout.marginWidth= 0;
225         layout.marginHeight= 2;
226         layout.verticalSpacing= 2;
227         layout.numColumns= 1;
228         c.setLayout(layout);
229         Label l1= new Label(c, SWT.NONE);
230         l1.setText(Utilities.getString(fBundle, "memberDescription")); //$NON-NLS-1$
231
fMemberPane= new CompareViewerPane(c, SWT.BORDER | SWT.FLAT);
232         GridData gd= new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
233         fMemberPane.setLayoutData(gd);
234
235         fMemberTable= new Table(fMemberPane, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL);
236         fMemberTable.addSelectionListener(
237             new SelectionAdapter() {
238                 public void widgetSelected(SelectionEvent e) {
239                     if (e.detail == SWT.CHECK) {
240                         if (e.item instanceof TableItem) {
241                             TableItem ti= (TableItem) e.item;
242                             if (ti.getChecked())
243                                 fArrayList.add(ti.getData());
244                             else
245                                 fArrayList.remove(ti.getData());
246                                 
247                             if (fCommitButton != null)
248                                 fCommitButton.setEnabled(fArrayList.size() > 0);
249                         }
250                     } else {
251                         handleMemberSelect(e.item);
252                     }
253                 }
254             }
255         );
256                 
257         fMemberPane.setContent(fMemberTable);
258         
259         c= new Composite(hsplitter, SWT.NONE);
260         layout= new GridLayout();
261         layout.marginWidth= 0;
262         layout.marginHeight= 2;
263         layout.verticalSpacing= 2;
264         layout.numColumns= 1;
265         c.setLayout(layout);
266         Label l2= new Label(c, SWT.NONE);
267         l2.setText(Utilities.getString(fBundle, "editionDescription")); //$NON-NLS-1$
268
fEditionPane= new CompareViewerPane(c, SWT.BORDER | SWT.FLAT);
269         gd= new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
270         fEditionPane.setLayoutData(gd);
271         
272         fEditionTree= new Tree(fEditionPane, SWT.H_SCROLL | SWT.V_SCROLL);
273         fEditionTree.addSelectionListener(
274             new SelectionAdapter() {
275                 public void widgetSelected(SelectionEvent e) {
276                     feedContent(e.item);
277                 }
278             }
279         );
280         fEditionPane.setContent(fEditionTree);
281         
282         applyDialogFont(parent); // to avoid applying font to compare viewer
283
fContentPane= new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) {
284             protected Viewer getViewer(Viewer oldViewer, Object JavaDoc input) {
285                 return CompareUI.findContentViewer(oldViewer, input, this, fCompareConfiguration);
286             }
287         };
288         vsplitter.setWeights(new int[] { 30, 70 });
289         
290         return parent;
291     }
292     
293     /*
294      * Feeds selection from member viewer to edition viewer.
295      */

296     private void handleMemberSelect(Widget w) {
297         Object JavaDoc data= null;
298         if (w != null)
299             data= w.getData();
300         if (data instanceof FileHistory) {
301             
302             FileHistory h= (FileHistory) data;
303             fCurrentFileHistory= h;
304             
305             IFile file= h.getFile();
306             IFileState[] states= h.getStates();
307             
308             fEditionPane.setImage(CompareUI.getImage(file));
309             String JavaDoc pattern= Utilities.getString(fBundle, "treeTitleFormat"); //$NON-NLS-1$
310
String JavaDoc title= MessageFormat.format(pattern, new Object JavaDoc[] { file.getName() });
311             fEditionPane.setText(title);
312             
313             if (fEditionTree != null) {
314                 fEditionTree.setRedraw(false);
315                 fEditionTree.removeAll();
316                 for (int i= 0; i < states.length; i++) {
317                     addEdition(new HistoryInput(file, states[i]), h.isSelected(i));
318                 }
319                 fEditionTree.setRedraw(true);
320             }
321         } else
322             fCurrentFileHistory= null;
323     }
324     
325     /*
326      * Adds the given Pair to the edition tree.
327      * It takes care of creating tree nodes for different dates.
328      */

329     private void addEdition(HistoryInput input, boolean isSelected) {
330         if (fEditionTree == null || fEditionTree.isDisposed())
331             return;
332         
333         IFileState state= input.fFileState;
334         
335         // find last day
336
TreeItem[] days= fEditionTree.getItems();
337         TreeItem lastDay= null;
338         if (days.length > 0)
339             lastDay= days[days.length-1];
340                         
341         long ldate= state.getModificationTime();
342         long day= dayNumber(ldate);
343         Date JavaDoc date= new Date JavaDoc(ldate);
344         if (lastDay == null || day != dayNumber(((Date JavaDoc)lastDay.getData()).getTime())) {
345             lastDay= new TreeItem(fEditionTree, SWT.NONE);
346             lastDay.setImage(fDateImage);
347             String JavaDoc df= DateFormat.getDateInstance().format(date);
348             long today= dayNumber(System.currentTimeMillis());
349             
350             String JavaDoc formatKey;
351             if (day == today)
352                 formatKey= "todayFormat"; //$NON-NLS-1$
353
else if (day == today-1)
354                 formatKey= "yesterdayFormat"; //$NON-NLS-1$
355
else
356                 formatKey= "dayFormat"; //$NON-NLS-1$
357
String JavaDoc pattern= Utilities.getString(fBundle, formatKey);
358             if (pattern != null)
359                 df= MessageFormat.format(pattern, new String JavaDoc[] { df });
360             lastDay.setText(df);
361             lastDay.setData(date);
362         }
363         TreeItem ti= new TreeItem(lastDay, SWT.NONE);
364         ti.setImage(fTimeImage);
365         ti.setText(DateFormat.getTimeInstance().format(date));
366         ti.setData(input);
367
368         if (isSelected) {
369             lastDay.setExpanded(true);
370             fEditionTree.setSelection(new TreeItem[] { ti });
371             feedContent(ti);
372         }
373     }
374                         
375     /*
376      * Returns the number of s since Jan 1st, 1970.
377      * The given date is converted to GMT and daylight saving is taken into account too.
378      */

379     private long dayNumber(long date) {
380         int ONE_DAY_MS= 24*60*60 * 1000; // one day in milli seconds
381

382         Calendar calendar= Calendar.getInstance();
383         long localTimeOffset= calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
384         
385         return (date + localTimeOffset) / ONE_DAY_MS;
386     }
387     
388     /*
389      * Feeds the tree viewer's selection to the contentviewer
390      */

391     private void feedContent(Widget w) {
392         if (fContentPane != null && !fContentPane.isDisposed()) {
393             Object JavaDoc o= w.getData();
394             if (o instanceof HistoryInput) {
395                 HistoryInput selected= (HistoryInput) o;
396                 fContentPane.setInput(selected);
397                 fContentPane.setText(getEditionLabel(selected));
398                 fContentPane.setImage(fTimeImage);
399                 
400                 if (fCurrentFileHistory != null)
401                     fCurrentFileHistory.setSelected(selected.fFileState);
402             } else {
403                 fContentPane.setInput(null);
404             }
405         }
406     }
407     
408     protected String JavaDoc getEditionLabel(HistoryInput input) {
409         String JavaDoc format= Utilities.getString(fBundle, "historyEditionLabel", null); //$NON-NLS-1$
410
if (format == null)
411             format= Utilities.getString(fBundle, "editionLabel"); //$NON-NLS-1$
412
if (format == null)
413             format= "x{0}"; //$NON-NLS-1$
414

415         long modDate= input.getModificationDate();
416         String JavaDoc date= DateFormat.getDateTimeInstance().format(new Date JavaDoc(modDate));
417         
418         return MessageFormat.format(format, new Object JavaDoc[] { date });
419     }
420             
421     /* (non-Javadoc)
422      * Method declared on Dialog.
423      */

424     protected void createButtonsForButtonBar(Composite parent) {
425         String JavaDoc buttonLabel= Utilities.getString(fBundle, "buttonLabel", IDialogConstants.OK_LABEL); //$NON-NLS-1$
426
// a 'Cancel' and a 'Add' button
427
fCommitButton= createButton(parent, IDialogConstants.OK_ID, buttonLabel, true);
428         fCommitButton.setEnabled(false);
429         createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
430     }
431     
432     /*
433      * Returns true if the pathname of f1 comes after f2
434      */

435     private static boolean greaterThan(IFile f1, IFile f2) {
436         String JavaDoc[] ss1= f1.getFullPath().segments();
437         String JavaDoc[] ss2= f2.getFullPath().segments();
438         int l1= ss1.length;
439         int l2= ss2.length;
440         int n= Math.max(l1, l2);
441         
442         for (int i= 0; i < n; i++) {
443             String JavaDoc s1= i < l1 ? ss1[i] : ""; //$NON-NLS-1$
444
String JavaDoc s2= i < l2 ? ss2[i] : ""; //$NON-NLS-1$
445
int rc= s1.compareToIgnoreCase(s2);
446             if (rc != 0)
447                 return rc < 0;
448         }
449         return false;
450     }
451     
452     private static void internalSort(IFile[] keys, int left, int right) {
453     
454         int original_left= left;
455         int original_right= right;
456         
457         IFile mid= keys[(left + right) / 2];
458         do {
459             while (greaterThan(keys[left], mid))
460                 left++;
461             
462             while (greaterThan(mid, keys[right]))
463                 right--;
464         
465             if (left <= right) {
466                 IFile tmp= keys[left];
467                 keys[left]= keys[right];
468                 keys[right]= tmp;
469                 left++;
470                 right--;
471             }
472         } while (left <= right);
473         
474         if (original_left < right)
475             internalSort(keys, original_left, right);
476         
477         if (left < original_right)
478             internalSort(keys, left, original_right);
479     }
480 }
481
Popular Tags