|
Added
Link Here
|
| 1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 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 |
|
| 12 |
package org.eclipse.ui.internal; |
| 13 |
|
| 14 |
import java.util.ArrayList; |
| 15 |
import java.util.Arrays; |
| 16 |
import java.util.HashMap; |
| 17 |
import java.util.HashSet; |
| 18 |
import java.util.Iterator; |
| 19 |
import java.util.List; |
| 20 |
import java.util.Map; |
| 21 |
import java.util.Set; |
| 22 |
|
| 23 |
import org.eclipse.core.runtime.Assert; |
| 24 |
import org.eclipse.core.runtime.CoreException; |
| 25 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 26 |
import org.eclipse.core.runtime.ListenerList; |
| 27 |
import org.eclipse.core.runtime.SubProgressMonitor; |
| 28 |
import org.eclipse.jface.dialogs.ErrorDialog; |
| 29 |
import org.eclipse.jface.dialogs.IDialogConstants; |
| 30 |
import org.eclipse.jface.dialogs.MessageDialog; |
| 31 |
import org.eclipse.jface.operation.IRunnableWithProgress; |
| 32 |
import org.eclipse.jface.viewers.ArrayContentProvider; |
| 33 |
import org.eclipse.jface.viewers.ILabelProvider; |
| 34 |
import org.eclipse.jface.viewers.IStructuredContentProvider; |
| 35 |
import org.eclipse.osgi.util.NLS; |
| 36 |
import org.eclipse.swt.SWT; |
| 37 |
import org.eclipse.swt.widgets.Composite; |
| 38 |
import org.eclipse.swt.widgets.Shell; |
| 39 |
import org.eclipse.ui.IModelLifecycleListener; |
| 40 |
import org.eclipse.ui.ISaveableModel; |
| 41 |
import org.eclipse.ui.ISaveableModelManager; |
| 42 |
import org.eclipse.ui.ISaveableModelSource; |
| 43 |
import org.eclipse.ui.ISaveablePart; |
| 44 |
import org.eclipse.ui.ISaveablePart2; |
| 45 |
import org.eclipse.ui.IWorkbenchPart; |
| 46 |
import org.eclipse.ui.IWorkbenchWindow; |
| 47 |
import org.eclipse.ui.ModelLifecycleEvent; |
| 48 |
import org.eclipse.ui.PlatformUI; |
| 49 |
import org.eclipse.ui.dialogs.ListSelectionDialog; |
| 50 |
import org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor; |
| 51 |
import org.eclipse.ui.model.WorkbenchPartLabelProvider; |
| 52 |
|
| 53 |
/** |
| 54 |
* @since 3.2 |
| 55 |
* |
| 56 |
*/ |
| 57 |
public class SaveableModelManager implements ISaveableModelManager { |
| 58 |
|
| 59 |
private ListenerList listeners = new ListenerList(); |
| 60 |
|
| 61 |
// event source (mostly ISaveableModelSource) -> Set of ISaveableModel |
| 62 |
private Map modelMap = new HashMap(); |
| 63 |
|
| 64 |
// reference counting map, ISaveableModel -> Integer |
| 65 |
private Map modelRefCounts = new HashMap(); |
| 66 |
|
| 67 |
public ISaveableModel[] getOpenModels() { |
| 68 |
return (ISaveableModel[]) modelRefCounts.keySet().toArray( |
| 69 |
new ISaveableModel[modelRefCounts.size()]); |
| 70 |
} |
| 71 |
|
| 72 |
// returns true if this model has not yet been in getModels() |
| 73 |
private boolean addModel(Object source, ISaveableModel model) { |
| 74 |
boolean result = false; |
| 75 |
Set modelsForSource = (Set) modelMap.get(source); |
| 76 |
if (modelsForSource == null) { |
| 77 |
modelsForSource = new HashSet(); |
| 78 |
modelMap.put(source, modelsForSource); |
| 79 |
} |
| 80 |
if (modelsForSource.add(model)) { |
| 81 |
result = incrementRefCount(modelRefCounts, model); |
| 82 |
} |
| 83 |
return result; |
| 84 |
} |
| 85 |
|
| 86 |
/** |
| 87 |
* returns true if the given key was added for the first time |
| 88 |
* |
| 89 |
* @param referenceMap |
| 90 |
* @param key |
| 91 |
* @return true if the ref count of the given key is now 1 |
| 92 |
*/ |
| 93 |
private boolean incrementRefCount(Map referenceMap, Object key) { |
| 94 |
boolean result = false; |
| 95 |
Integer refCount = (Integer) referenceMap.get(key); |
| 96 |
if (refCount == null) { |
| 97 |
result = true; |
| 98 |
refCount = new Integer(0); |
| 99 |
} |
| 100 |
referenceMap.put(key, new Integer(refCount.intValue() + 1)); |
| 101 |
return result; |
| 102 |
} |
| 103 |
|
| 104 |
/** |
| 105 |
* returns true if the given key has been removed |
| 106 |
* |
| 107 |
* @param referenceMap |
| 108 |
* @param key |
| 109 |
* @return true if the ref count of the given key was 1 |
| 110 |
*/ |
| 111 |
private boolean decrementRefCount(Map referenceMap, Object key) { |
| 112 |
boolean result = false; |
| 113 |
Integer refCount = (Integer) referenceMap.get(key); |
| 114 |
Assert.isTrue(refCount != null); |
| 115 |
if (refCount.intValue() == 1) { |
| 116 |
referenceMap.remove(key); |
| 117 |
result = true; |
| 118 |
} else { |
| 119 |
referenceMap.put(key, new Integer(refCount.intValue() - 1)); |
| 120 |
} |
| 121 |
return result; |
| 122 |
} |
| 123 |
|
| 124 |
// returns true if this model was removed from getModels(); |
| 125 |
private boolean removeModel(Object source, ISaveableModel model) { |
| 126 |
boolean result = false; |
| 127 |
Set modelsForSource = (Set) modelMap.get(source); |
| 128 |
if (modelsForSource == null) { |
| 129 |
modelsForSource = new HashSet(); |
| 130 |
modelMap.put(source, modelsForSource); |
| 131 |
} |
| 132 |
if (modelsForSource.remove(model)) { |
| 133 |
result = decrementRefCount(modelRefCounts, model); |
| 134 |
if (modelsForSource.isEmpty()) { |
| 135 |
modelMap.remove(source); |
| 136 |
} |
| 137 |
} |
| 138 |
return result; |
| 139 |
} |
| 140 |
|
| 141 |
public void handleModelLifecycleEvent(ModelLifecycleEvent event) { |
| 142 |
ISaveableModel[] modelArray = event.getModels(); |
| 143 |
switch (event.getEventType()) { |
| 144 |
case ModelLifecycleEvent.POST_OPEN: |
| 145 |
addModels(event.getSource(), modelArray); |
| 146 |
break; |
| 147 |
case ModelLifecycleEvent.PRE_CLOSE: |
| 148 |
ISaveableModel[] models = event.getModels(); |
| 149 |
Map modelsDecrementing = new HashMap(); |
| 150 |
Set modelsClosing = new HashSet(); |
| 151 |
for (int i = 0; i < models.length; i++) { |
| 152 |
incrementRefCount(modelsDecrementing, models[i]); |
| 153 |
} |
| 154 |
|
| 155 |
fillModelsClosing(modelsClosing, modelsDecrementing); |
| 156 |
boolean canceled = promptForSavingIfNecessary(PlatformUI |
| 157 |
.getWorkbench().getActiveWorkbenchWindow(), modelsClosing, |
| 158 |
!event.isForce()); |
| 159 |
if (canceled) { |
| 160 |
event.setVeto(true); |
| 161 |
} |
| 162 |
break; |
| 163 |
case ModelLifecycleEvent.POST_CLOSE: |
| 164 |
removeModels(event.getSource(), modelArray); |
| 165 |
break; |
| 166 |
case ModelLifecycleEvent.DIRTY_CHANGED: |
| 167 |
fireModelLifecycleEvent(new ModelLifecycleEvent(this, event |
| 168 |
.getEventType(), event.getModels(), false)); |
| 169 |
break; |
| 170 |
} |
| 171 |
} |
| 172 |
|
| 173 |
/** |
| 174 |
* @param source |
| 175 |
* @param modelArray |
| 176 |
*/ |
| 177 |
private void removeModels(Object source, ISaveableModel[] modelArray) { |
| 178 |
List removed = new ArrayList(); |
| 179 |
for (int i = 0; i < modelArray.length; i++) { |
| 180 |
ISaveableModel model = modelArray[i]; |
| 181 |
if (removeModel(source, model)) { |
| 182 |
removed.add(model); |
| 183 |
} |
| 184 |
} |
| 185 |
if (removed.size() > 0) { |
| 186 |
fireModelLifecycleEvent(new ModelLifecycleEvent(this, |
| 187 |
ModelLifecycleEvent.POST_OPEN, (ISaveableModel[]) removed |
| 188 |
.toArray(new ISaveableModel[removed.size()]), false)); |
| 189 |
} |
| 190 |
} |
| 191 |
|
| 192 |
/** |
| 193 |
* @param source |
| 194 |
* @param modelArray |
| 195 |
*/ |
| 196 |
private void addModels(Object source, ISaveableModel[] modelArray) { |
| 197 |
List added = new ArrayList(); |
| 198 |
for (int i = 0; i < modelArray.length; i++) { |
| 199 |
ISaveableModel model = modelArray[i]; |
| 200 |
if (addModel(source, model)) { |
| 201 |
added.add(model); |
| 202 |
} |
| 203 |
} |
| 204 |
if (added.size() > 0) { |
| 205 |
fireModelLifecycleEvent(new ModelLifecycleEvent(this, |
| 206 |
ModelLifecycleEvent.POST_OPEN, (ISaveableModel[]) added |
| 207 |
.toArray(new ISaveableModel[added.size()]), false)); |
| 208 |
} |
| 209 |
} |
| 210 |
|
| 211 |
/** |
| 212 |
* @param event |
| 213 |
*/ |
| 214 |
private void fireModelLifecycleEvent(ModelLifecycleEvent event) { |
| 215 |
Object[] listenerArray = listeners.getListeners(); |
| 216 |
for (int i = 0; i < listenerArray.length; i++) { |
| 217 |
((IModelLifecycleListener) listenerArray[i]) |
| 218 |
.handleModelLifecycleEvent(event); |
| 219 |
} |
| 220 |
} |
| 221 |
|
| 222 |
public void addModelLifecycleListener(IModelLifecycleListener listener) { |
| 223 |
listeners.add(listener); |
| 224 |
} |
| 225 |
|
| 226 |
public void removeModelLifecycleListener(IModelLifecycleListener listener) { |
| 227 |
listeners.remove(listener); |
| 228 |
} |
| 229 |
|
| 230 |
/** |
| 231 |
* @param editorsToClose |
| 232 |
* @param save |
| 233 |
* @param window |
| 234 |
* @return the post close info to be passed to postClose |
| 235 |
*/ |
| 236 |
public Object preCloseParts(List editorsToClose, boolean save, |
| 237 |
final IWorkbenchWindow window) { |
| 238 |
// reference count (how many occurrences of a model will go away?) |
| 239 |
PostCloseInfo postCloseInfo = new PostCloseInfo(); |
| 240 |
for (Iterator it = editorsToClose.iterator(); it.hasNext();) { |
| 241 |
IWorkbenchPart part = (IWorkbenchPart) it.next(); |
| 242 |
postCloseInfo.partsClosing.add(part); |
| 243 |
if (part instanceof ISaveablePart) { |
| 244 |
ISaveablePart saveablePart = (ISaveablePart) part; |
| 245 |
if (save && !saveablePart.isSaveOnCloseNeeded()) { |
| 246 |
// pretend for now that this part is not closing |
| 247 |
continue; |
| 248 |
} |
| 249 |
} |
| 250 |
if (save && part instanceof ISaveablePart2) { |
| 251 |
ISaveablePart2 saveablePart2 = (ISaveablePart2) part; |
| 252 |
// TODO show saveablePart2 before prompting, see |
| 253 |
// EditorManager.saveAll |
| 254 |
int response = SaveableHelper.savePart(saveablePart2, window, |
| 255 |
true); |
| 256 |
// only include this part in the following logic if it returned |
| 257 |
// DEFAULT |
| 258 |
if (response != ISaveablePart2.DEFAULT) { |
| 259 |
continue; |
| 260 |
} |
| 261 |
} |
| 262 |
ISaveableModel[] modelsFromSource = getSaveableModels(part); |
| 263 |
for (int i = 0; i < modelsFromSource.length; i++) { |
| 264 |
incrementRefCount(postCloseInfo.modelsDecrementing, |
| 265 |
modelsFromSource[i]); |
| 266 |
} |
| 267 |
} |
| 268 |
fillModelsClosing(postCloseInfo.modelsClosing, |
| 269 |
postCloseInfo.modelsDecrementing); |
| 270 |
if (save) { |
| 271 |
boolean canceled = promptForSavingIfNecessary(window, |
| 272 |
postCloseInfo.modelsClosing, true); |
| 273 |
if (canceled) { |
| 274 |
return null; |
| 275 |
} |
| 276 |
} |
| 277 |
return postCloseInfo; |
| 278 |
} |
| 279 |
|
| 280 |
/** |
| 281 |
* @param window |
| 282 |
* @param modelsClosing |
| 283 |
* @param canCancel |
| 284 |
* @return true if the user canceled |
| 285 |
*/ |
| 286 |
private boolean promptForSavingIfNecessary(final IWorkbenchWindow window, |
| 287 |
Set modelsClosing, boolean canCancel) { |
| 288 |
// TODO prompt for saving of dirty modelsDecrementing but not closing |
| 289 |
// (changes |
| 290 |
// won't be lost) |
| 291 |
|
| 292 |
List modelsToSave = new ArrayList(); |
| 293 |
for (Iterator it = modelsClosing.iterator(); it.hasNext();) { |
| 294 |
ISaveableModel modelClosing = (ISaveableModel) it.next(); |
| 295 |
if (modelClosing.isDirty()) { |
| 296 |
modelsToSave.add(modelClosing); |
| 297 |
} |
| 298 |
} |
| 299 |
return modelsToSave.isEmpty() ? false : promptForSaving(modelsToSave, |
| 300 |
window, canCancel); |
| 301 |
} |
| 302 |
|
| 303 |
/** |
| 304 |
* @param modelsClosing |
| 305 |
* @param modelsDecrementing |
| 306 |
*/ |
| 307 |
private void fillModelsClosing(Set modelsClosing, Map modelsDecrementing) { |
| 308 |
for (Iterator it = modelsDecrementing.keySet().iterator(); it.hasNext();) { |
| 309 |
ISaveableModel model = (ISaveableModel) it.next(); |
| 310 |
if (modelsDecrementing.get(model).equals(modelRefCounts.get(model))) { |
| 311 |
modelsClosing.add(model); |
| 312 |
} |
| 313 |
} |
| 314 |
} |
| 315 |
|
| 316 |
/** |
| 317 |
* @param modelsToSave |
| 318 |
* @param window |
| 319 |
* @param canCancel |
| 320 |
* @return true if the user canceled |
| 321 |
*/ |
| 322 |
private boolean promptForSaving(List modelsToSave, |
| 323 |
final IWorkbenchWindow window, boolean canCancel) { |
| 324 |
// Save parts, exit the method if cancel is pressed. |
| 325 |
if (modelsToSave.size() > 0) { |
| 326 |
if (modelsToSave.size() == 1) { |
| 327 |
ISaveableModel model = (ISaveableModel) modelsToSave.get(0); |
| 328 |
String message = NLS.bind( |
| 329 |
WorkbenchMessages.EditorManager_saveChangesQuestion, |
| 330 |
model.getName()); |
| 331 |
// Show a dialog. |
| 332 |
String[] buttons = new String[] { IDialogConstants.YES_LABEL, |
| 333 |
IDialogConstants.NO_LABEL, |
| 334 |
IDialogConstants.CANCEL_LABEL }; |
| 335 |
MessageDialog d = new MessageDialog(window.getShell(), |
| 336 |
WorkbenchMessages.Save_Resource, null, message, |
| 337 |
MessageDialog.QUESTION, buttons, 0); |
| 338 |
|
| 339 |
int choice = SaveableHelper.testGetAutomatedResponse(); |
| 340 |
if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) { |
| 341 |
choice = d.open(); |
| 342 |
} |
| 343 |
|
| 344 |
// Branch on the user choice. |
| 345 |
// The choice id is based on the order of button labels |
| 346 |
// above. |
| 347 |
switch (choice) { |
| 348 |
case ISaveablePart2.YES: // yes |
| 349 |
break; |
| 350 |
case ISaveablePart2.NO: // no |
| 351 |
modelsToSave.clear(); |
| 352 |
break; |
| 353 |
default: |
| 354 |
case ISaveablePart2.CANCEL: // cancel |
| 355 |
return true; |
| 356 |
} |
| 357 |
} else { |
| 358 |
ListSelectionDialog dlg = new MyListSelectionDialog(window |
| 359 |
.getShell(), modelsToSave, new ArrayContentProvider(), |
| 360 |
new WorkbenchPartLabelProvider(), |
| 361 |
EditorManager.RESOURCES_TO_SAVE_MESSAGE, canCancel); |
| 362 |
dlg.setInitialSelections(modelsToSave.toArray()); |
| 363 |
dlg.setTitle(EditorManager.SAVE_RESOURCES_TITLE); |
| 364 |
|
| 365 |
// this "if" statement aids in testing. |
| 366 |
if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) { |
| 367 |
int result = dlg.open(); |
| 368 |
// Just return null to prevent the operation continuing |
| 369 |
if (result == IDialogConstants.CANCEL_ID) |
| 370 |
return true; |
| 371 |
|
| 372 |
modelsToSave = Arrays.asList(dlg.getResult()); |
| 373 |
} |
| 374 |
} |
| 375 |
} |
| 376 |
// Create save block. |
| 377 |
final List finalModels = modelsToSave; |
| 378 |
IRunnableWithProgress progressOp = new IRunnableWithProgress() { |
| 379 |
public void run(IProgressMonitor monitor) { |
| 380 |
IProgressMonitor monitorWrap = new EventLoopProgressMonitor( |
| 381 |
monitor); |
| 382 |
monitorWrap.beginTask("", finalModels.size()); //$NON-NLS-1$ |
| 383 |
for (Iterator i = finalModels.iterator(); i.hasNext();) { |
| 384 |
ISaveableModel model = (ISaveableModel) i.next(); |
| 385 |
// handle case where this model got saved as a result of |
| 386 |
// saving another |
| 387 |
if (!model.isDirty()) { |
| 388 |
monitor.worked(1); |
| 389 |
continue; |
| 390 |
} |
| 391 |
try { |
| 392 |
model.doSave(new SubProgressMonitor(monitorWrap, 1)); |
| 393 |
} catch (CoreException e) { |
| 394 |
ErrorDialog.openError(window.getShell(), |
| 395 |
WorkbenchMessages.Error, e.getMessage(), e |
| 396 |
.getStatus()); |
| 397 |
} |
| 398 |
if (monitorWrap.isCanceled()) |
| 399 |
break; |
| 400 |
} |
| 401 |
monitorWrap.done(); |
| 402 |
} |
| 403 |
}; |
| 404 |
|
| 405 |
// Do the save. |
| 406 |
if (!SaveableHelper.runProgressMonitorOperation( |
| 407 |
WorkbenchMessages.Save_All, progressOp, window)) { |
| 408 |
// cancelled |
| 409 |
return true; |
| 410 |
} |
| 411 |
return false; |
| 412 |
} |
| 413 |
|
| 414 |
private static class PostCloseInfo { |
| 415 |
private List partsClosing = new ArrayList(); |
| 416 |
|
| 417 |
private Map modelsDecrementing = new HashMap(); |
| 418 |
|
| 419 |
private Set modelsClosing = new HashSet(); |
| 420 |
} |
| 421 |
|
| 422 |
/** |
| 423 |
* @param postCloseInfoObject |
| 424 |
*/ |
| 425 |
public void postClose(Object postCloseInfoObject) { |
| 426 |
PostCloseInfo postCloseInfo = (PostCloseInfo) postCloseInfoObject; |
| 427 |
List removed = new ArrayList(); |
| 428 |
for (Iterator it = postCloseInfo.partsClosing.iterator(); it.hasNext();) { |
| 429 |
IWorkbenchPart part = (IWorkbenchPart) it.next(); |
| 430 |
ISaveableModel[] modelArray = getSaveableModels(part); |
| 431 |
for (int i = 0; i < modelArray.length; i++) { |
| 432 |
ISaveableModel model = modelArray[i]; |
| 433 |
if (removeModel(part, model)) { |
| 434 |
removed.add(model); |
| 435 |
} |
| 436 |
} |
| 437 |
} |
| 438 |
if (removed.size() > 0) { |
| 439 |
fireModelLifecycleEvent(new ModelLifecycleEvent(this, |
| 440 |
ModelLifecycleEvent.POST_CLOSE, (ISaveableModel[]) removed |
| 441 |
.toArray(new ISaveableModel[removed.size()]), false)); |
| 442 |
} |
| 443 |
} |
| 444 |
|
| 445 |
/** |
| 446 |
* Returns the saveable models provided by the given part. If the part does |
| 447 |
* not provide any models, a default model is returned representing the |
| 448 |
* part. |
| 449 |
* |
| 450 |
* @param part |
| 451 |
* the workbench part |
| 452 |
* @return the saveable models |
| 453 |
*/ |
| 454 |
private ISaveableModel[] getSaveableModels(IWorkbenchPart part) { |
| 455 |
if (part instanceof ISaveableModelSource) { |
| 456 |
ISaveableModelSource source = (ISaveableModelSource) part; |
| 457 |
return source.getModels(); |
| 458 |
} else if (part instanceof ISaveablePart) { |
| 459 |
return new ISaveableModel[] { new DefaultSaveableModel(part) }; |
| 460 |
} else { |
| 461 |
return new ISaveableModel[0]; |
| 462 |
} |
| 463 |
} |
| 464 |
|
| 465 |
/** |
| 466 |
* @param actualPart |
| 467 |
*/ |
| 468 |
public void postOpen(IWorkbenchPart part) { |
| 469 |
addModels(part, getSaveableModels(part)); |
| 470 |
} |
| 471 |
|
| 472 |
/** |
| 473 |
* @param actualPart |
| 474 |
*/ |
| 475 |
public void dirtyChanged(IWorkbenchPart part) { |
| 476 |
ISaveableModel[] saveableModels = getSaveableModels(part); |
| 477 |
if (saveableModels.length > 0) { |
| 478 |
fireModelLifecycleEvent(new ModelLifecycleEvent(this, |
| 479 |
ModelLifecycleEvent.DIRTY_CHANGED, saveableModels, false)); |
| 480 |
} |
| 481 |
} |
| 482 |
|
| 483 |
/** |
| 484 |
* For testing purposes. Not to be called by clients. |
| 485 |
* |
| 486 |
* @param model |
| 487 |
* @return |
| 488 |
*/ |
| 489 |
public Object[] testGetSourcesForModel(ISaveableModel model) { |
| 490 |
List result = new ArrayList(); |
| 491 |
for (Iterator it = modelMap.entrySet().iterator(); it.hasNext();) { |
| 492 |
Map.Entry entry = (Map.Entry) it.next(); |
| 493 |
Set values = (Set) entry.getValue(); |
| 494 |
if (values.contains(model)) { |
| 495 |
result.add(entry.getKey()); |
| 496 |
} |
| 497 |
} |
| 498 |
return result.toArray(); |
| 499 |
} |
| 500 |
|
| 501 |
private static final class MyListSelectionDialog extends |
| 502 |
ListSelectionDialog { |
| 503 |
private final boolean canCancel; |
| 504 |
|
| 505 |
private MyListSelectionDialog(Shell shell, Object input, |
| 506 |
IStructuredContentProvider contentprovider, |
| 507 |
ILabelProvider labelProvider, String message, boolean canCancel) { |
| 508 |
super(shell, input, contentprovider, labelProvider, message); |
| 509 |
this.canCancel = canCancel; |
| 510 |
if (!canCancel) { |
| 511 |
int shellStyle = getShellStyle(); |
| 512 |
shellStyle &= ~SWT.CLOSE; |
| 513 |
setShellStyle(shellStyle); |
| 514 |
} |
| 515 |
} |
| 516 |
|
| 517 |
protected void createButtonsForButtonBar(Composite parent) { |
| 518 |
createButton(parent, IDialogConstants.OK_ID, |
| 519 |
IDialogConstants.OK_LABEL, true); |
| 520 |
if (canCancel) { |
| 521 |
createButton(parent, IDialogConstants.CANCEL_ID, |
| 522 |
IDialogConstants.CANCEL_LABEL, false); |
| 523 |
} |
| 524 |
} |
| 525 |
} |
| 526 |
|
| 527 |
} |