1 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 ; 17 import com.ibm.icu.util.Calendar; 18 import java.util.Date ; 19 import java.util.Iterator ; 20 import java.util.ResourceBundle ; 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 getCharset() { 52 String charset= null; 53 try { 54 charset= fFileState.getCharset(); 55 } catch (CoreException e) { 56 } 58 if (charset == null) 59 charset= Utilities.getCharset(fFile); 60 return charset; 61 } 62 public String getName() { 63 return fFile.getName(); 64 } 65 public String 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 } 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 fArrayList= new ArrayList (); 124 private FileHistory fCurrentFileHistory; 125 126 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 bundle) { 138 super(parent, bundle); 139 140 String iconName= Utilities.getString(fBundle, "dateIcon", "obj16/day_obj.gif"); ImageDescriptor id= CompareUIPlugin.getImageDescriptor(iconName); 142 if (id != null) 143 fDateImage= id.createImage(); 144 iconName= Utilities.getString(fBundle, "timeIcon", "obj16/resource_obj.gif"); 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(); 154 String format= Utilities.getString(fBundle, "memberPaneTitle"); String title= MessageFormat.format(format, new Object [] { root.getName() }); 156 fMemberPane.setImage(CompareUI.getImage(root)); 157 fMemberPane.setText(title); 158 159 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 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 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 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")); 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 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")); 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")); 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); fContentPane= new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) { 284 protected Viewer getViewer(Viewer oldViewer, Object 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 296 private void handleMemberSelect(Widget w) { 297 Object 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 pattern= Utilities.getString(fBundle, "treeTitleFormat"); String title= MessageFormat.format(pattern, new Object [] { 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 329 private void addEdition(HistoryInput input, boolean isSelected) { 330 if (fEditionTree == null || fEditionTree.isDisposed()) 331 return; 332 333 IFileState state= input.fFileState; 334 335 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 date= new Date (ldate); 344 if (lastDay == null || day != dayNumber(((Date )lastDay.getData()).getTime())) { 345 lastDay= new TreeItem(fEditionTree, SWT.NONE); 346 lastDay.setImage(fDateImage); 347 String df= DateFormat.getDateInstance().format(date); 348 long today= dayNumber(System.currentTimeMillis()); 349 350 String formatKey; 351 if (day == today) 352 formatKey= "todayFormat"; else if (day == today-1) 354 formatKey= "yesterdayFormat"; else 356 formatKey= "dayFormat"; String pattern= Utilities.getString(fBundle, formatKey); 358 if (pattern != null) 359 df= MessageFormat.format(pattern, new String [] { 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 379 private long dayNumber(long date) { 380 int ONE_DAY_MS= 24*60*60 * 1000; 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 391 private void feedContent(Widget w) { 392 if (fContentPane != null && !fContentPane.isDisposed()) { 393 Object 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 getEditionLabel(HistoryInput input) { 409 String format= Utilities.getString(fBundle, "historyEditionLabel", null); if (format == null) 411 format= Utilities.getString(fBundle, "editionLabel"); if (format == null) 413 format= "x{0}"; 415 long modDate= input.getModificationDate(); 416 String date= DateFormat.getDateTimeInstance().format(new Date (modDate)); 417 418 return MessageFormat.format(format, new Object [] { date }); 419 } 420 421 424 protected void createButtonsForButtonBar(Composite parent) { 425 String buttonLabel= Utilities.getString(fBundle, "buttonLabel", IDialogConstants.OK_LABEL); 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 435 private static boolean greaterThan(IFile f1, IFile f2) { 436 String [] ss1= f1.getFullPath().segments(); 437 String [] 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 s1= i < l1 ? ss1[i] : ""; String s2= i < l2 ? ss2[i] : ""; 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 |