1 11 12 package org.eclipse.ui.internal.cheatsheets.composite.views; 13 14 import java.util.HashMap ; 15 import java.util.Map ; 16 import java.util.Observable ; 17 import java.util.Observer ; 18 19 import org.eclipse.jface.viewers.ISelection; 20 import org.eclipse.jface.viewers.ISelectionChangedListener; 21 import org.eclipse.jface.viewers.IStructuredSelection; 22 import org.eclipse.jface.viewers.SelectionChangedEvent; 23 import org.eclipse.jface.viewers.StructuredSelection; 24 import org.eclipse.swt.SWT; 25 import org.eclipse.swt.custom.SashForm; 26 import org.eclipse.swt.events.ControlAdapter; 27 import org.eclipse.swt.events.ControlEvent; 28 import org.eclipse.swt.events.SelectionAdapter; 29 import org.eclipse.swt.events.SelectionEvent; 30 import org.eclipse.swt.graphics.Point; 31 import org.eclipse.swt.layout.GridData; 32 import org.eclipse.swt.layout.GridLayout; 33 import org.eclipse.swt.widgets.Composite; 34 import org.eclipse.swt.widgets.Control; 35 import org.eclipse.swt.widgets.Menu; 36 import org.eclipse.swt.widgets.MenuItem; 37 import org.eclipse.ui.forms.FormColors; 38 import org.eclipse.ui.forms.HyperlinkSettings; 39 import org.eclipse.ui.forms.IFormColors; 40 import org.eclipse.ui.forms.ManagedForm; 41 import org.eclipse.ui.forms.events.HyperlinkAdapter; 42 import org.eclipse.ui.forms.events.HyperlinkEvent; 43 import org.eclipse.ui.forms.widgets.FormText; 44 import org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin; 45 import org.eclipse.ui.internal.cheatsheets.ICheatSheetResource; 46 import org.eclipse.ui.internal.cheatsheets.Messages; 47 import org.eclipse.ui.internal.cheatsheets.actions.IMenuContributor; 48 import org.eclipse.ui.internal.cheatsheets.composite.explorer.RestartAllAction; 49 import org.eclipse.ui.internal.cheatsheets.composite.explorer.TreeExplorerMenu; 50 import org.eclipse.ui.internal.cheatsheets.composite.model.AbstractTask; 51 import org.eclipse.ui.internal.cheatsheets.composite.model.CompositeCheatSheetModel; 52 import org.eclipse.ui.internal.cheatsheets.composite.model.CompositeCheatSheetSaveHelper; 53 import org.eclipse.ui.internal.cheatsheets.composite.model.EditableTask; 54 import org.eclipse.ui.internal.cheatsheets.composite.parser.ICompositeCheatsheetTags; 55 import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetRegistryReader; 56 import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetRegistryReader.TaskExplorerNode; 57 import org.eclipse.ui.internal.cheatsheets.state.ICheatSheetStateManager; 58 import org.eclipse.ui.internal.cheatsheets.views.Page; 59 import org.eclipse.ui.internal.cheatsheets.views.ViewUtilities; 60 import org.eclipse.ui.internal.provisional.cheatsheets.ICompositeCheatSheetTask; 61 import org.eclipse.ui.internal.provisional.cheatsheets.TaskEditor; 62 import org.eclipse.ui.internal.provisional.cheatsheets.TaskExplorer; 63 import org.eclipse.ui.part.PageBook; 64 65 68 69 public class CompositeCheatSheetPage extends Page implements ISelectionChangedListener, IMenuContributor { 70 71 public static final String REVIEW_TAG = "__review__"; public static final String END_REVIEW_TAG = "__endReview__"; public static final String GOTO_TASK_TAG = "__goto__"; public static final String START_HREF = "__start__"; public static final String SKIP_HREF = "__skip__"; 77 private ManagedForm mform; 78 private PageBook explorerContainer; 79 private PageBook taskEditorContainer; 80 private CompositeCheatSheetModel model; 81 private TaskExplorer currentExplorer; 82 private DescriptionPanel descriptionPanel; 83 84 private CompositeCheatSheetSaveHelper saveHelper; 85 86 private ICompositeCheatSheetTask selectedTask; 87 private boolean initialized = false;; 88 89 public CompositeCheatSheetPage(CompositeCheatSheetModel model, ICheatSheetStateManager stateManager) { 90 this.model = model; 91 saveHelper = new CompositeCheatSheetSaveHelper(stateManager); 92 } 93 94 public void createPart(Composite parent) { 95 init(parent.getDisplay()); 96 toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode(HyperlinkSettings.UNDERLINE_HOVER); 97 form = toolkit.createScrolledForm(parent); 98 form.setLayoutData(new GridData(GridData.FILL_BOTH)); 99 FormColors colors = toolkit.getColors(); 100 108 toolkit.decorateFormHeading(form.getForm()); 109 mform = new ManagedForm(toolkit, form); 110 GridLayout glayout = new GridLayout(); 111 glayout.marginHeight = 0; 112 glayout.marginWidth = 0; 113 form.getBody().setLayout(glayout); 114 final SashForm sash = new SashForm(form.getBody(), SWT.NULL); 115 GridData gd = new GridData(GridData.FILL_BOTH); 116 gd.widthHint = 10; 117 gd.heightHint = 10; 118 sash.setLayoutData(gd); 119 sash.addControlListener(new ControlAdapter() { 120 public void controlResized(ControlEvent e) { 121 Point size = sash.getSize(); 122 if (size.x>size.y) 123 sash.setOrientation(SWT.HORIZONTAL); 124 else 125 sash.setOrientation(SWT.VERTICAL); 126 updateSashPanelMargins(sash); 127 } 128 }); 129 sash.setBackground(colors.getColor(IFormColors.TB_BG)); 130 131 Composite explorerPanel = new Composite(sash, SWT.NULL); 132 explorerPanel.setBackground(colors.getColor(IFormColors.TB_BORDER)); 133 GridLayout playout = new GridLayout(); 134 playout.marginWidth = 0; 135 playout.marginTop = 2; 136 playout.marginBottom = 0; 137 explorerPanel.setLayout(playout); 138 toolkit.adapt(explorerPanel); 139 explorerContainer = new PageBook(explorerPanel, SWT.NULL); 140 explorerContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); 141 Composite editorPanel = new Composite(sash, SWT.NULL); 142 playout = new GridLayout(); 143 playout.marginWidth = 0; 144 playout.marginHeight = 0; 145 editorPanel.setLayout(playout); 146 editorPanel.setBackground(colors.getColor(IFormColors.TB_BORDER)); 147 taskEditorContainer = new PageBook(editorPanel, SWT.NULL); 148 toolkit.adapt(taskEditorContainer); 149 taskEditorContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); 150 } 151 152 private void updateSashPanelMargins(SashForm sash) { 153 Control [] children = sash.getChildren(); 154 int orientation = sash.getOrientation(); 155 GridLayout layout = (GridLayout)((Composite)children[0]).getLayout(); 157 if (orientation==SWT.HORIZONTAL) { 158 layout.marginBottom = 0; 159 layout.marginRight = 1; 160 } 161 else { 162 layout.marginBottom = 1; 163 layout.marginRight = 0; 164 } 165 layout = (GridLayout)((Composite)children[1]).getLayout(); 167 if (orientation==SWT.HORIZONTAL) { 168 layout.marginTop = 0; 169 layout.marginLeft = 1; 170 } 171 else { 172 layout.marginTop = 1; 173 layout.marginLeft = 0; 174 } 175 ((Composite)children[0]).layout(); 176 ((Composite)children[1]).layout(); 177 } 178 179 public void dispose() { 180 mform.dispose(); 181 super.dispose(); 182 } 183 184 private void setInputModel(CompositeCheatSheetModel model, Map layout) { 185 this.model = model; 186 mform.getForm().setText(ViewUtilities.escapeForLabel(model.getName())); 187 String explorerId = model.getTaskExplorerId(); 188 setCurrentExplorerFromId(explorerId); 189 String selectedTaskId = (String ) layout.get(ICompositeCheatsheetTags.SELECTED_TASK); 190 ICompositeCheatSheetTask selectedTask= null; 191 if (selectedTaskId != null) { 192 selectedTask = model.getDependencies().getTask(selectedTaskId); 193 if (selectedTask != null) { 194 currentExplorer.setSelection(new StructuredSelection(selectedTask), true); 195 } 196 } 197 if (selectedTask != null) { 198 updateSelectedTask(selectedTask); 199 } else { 200 updateSelectedTask(model.getRootTask()); 201 } 202 model.addObserver(new Observer () { 203 public void update(Observable o, Object arg) { 204 ICompositeCheatSheetTask task = (ICompositeCheatSheetTask)arg; 205 if (currentExplorer!=null) 206 currentExplorer.taskUpdated(task); 207 updateTask(task); 208 } 209 }); 210 } 211 212 private void setCurrentExplorerFromId(String explorerId) { 213 TaskExplorer explorer = getTaskExplorer(explorerId); 214 if (explorer!=null) { 215 explorer.setCompositeCheatSheet(this.model); 216 explorer.setFocus(); 217 setExplorerVisible(explorerId); 218 } 219 } 220 221 private void setExplorerVisible(String id) { 222 Control [] excontrols = explorerContainer.getChildren(); 223 TaskExplorer explorer=null; 224 for (int i=0; i<excontrols.length; i++) { 225 Control excontrol = excontrols[i]; 226 explorer = (TaskExplorer)excontrol.getData(ICompositeCheatsheetTags.EXPLORER); 227 if (explorer.getId().equals(id)) { 228 explorerContainer.showPage(excontrol); 229 setCurrentExplorer(explorer); 230 return; 231 } 232 } 233 } 234 235 private void setCurrentExplorer(TaskExplorer explorer) { 236 if (currentExplorer!=null) { 237 currentExplorer.getSelectionProvider().removeSelectionChangedListener(this); 238 } 239 currentExplorer = explorer; 240 currentExplorer.getSelectionProvider().addSelectionChangedListener(this); 241 updateForSelection(currentExplorer.getSelectionProvider().getSelection()); 242 } 243 244 private TaskExplorer getTaskExplorer(String id) { 245 Control [] excontrols = explorerContainer.getChildren(); 246 TaskExplorer explorer=null; 247 for (int i=0; i<excontrols.length; i++) { 248 Control excontrol = excontrols[i]; 249 Object data = excontrol.getData(ICompositeCheatsheetTags.EXPLORER); 250 if (data instanceof TaskExplorer) { 251 explorer = (TaskExplorer)data; 252 if (explorer.getId().equals(id)) { 253 return explorer; 254 } 255 } 256 } 257 258 260 TaskExplorerManager explorerManager = TaskExplorerManager.getInstance(); 261 explorer = explorerManager.getExplorer(id); 262 if (explorer != null) { 263 explorer.createControl(explorerContainer, mform.getToolkit()); 264 explorer.getControl().setData(ICompositeCheatsheetTags.EXPLORER, explorer); 265 new TreeExplorerMenu(explorer); 266 } 267 return explorer; 268 } 269 270 public void selectionChanged(SelectionChangedEvent event) { 271 updateForSelection(event.getSelection()); 272 } 273 274 private void updateForSelection(ISelection selection) { 275 Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); 276 if (selectedElement instanceof ICompositeCheatSheetTask) { 277 updateSelectedTask((ICompositeCheatSheetTask)selectedElement); 278 } 279 } 280 281 private void updateSelectedTask(ICompositeCheatSheetTask task) { 282 selectedTask = task; 283 updateTask(selectedTask); 284 } 285 286 290 private void updateTask(ICompositeCheatSheetTask task) { 291 if (task==null || task != selectedTask) return; 292 if ( task instanceof EditableTask) { 293 EditableTask editable = (EditableTask)task; 294 if (editable.getState() == ICompositeCheatSheetTask.IN_PROGRESS) { 295 showEditor(editable); 296 return; 297 } else if (editable.isUnderReview()) { 298 if (editable.getState() == ICompositeCheatSheetTask.COMPLETED) { 299 showEditor(editable); 300 } else { 301 endReview(editable); 302 } 303 return; 304 } 305 } 306 showDescription(task); 307 } 308 309 public void saveState() { 310 Map layout = new HashMap (); 311 if (selectedTask != null) { 312 layout.put(ICompositeCheatsheetTags.SELECTED_TASK, selectedTask.getId()); 313 } 314 saveHelper.saveCompositeState(model, layout); 315 } 316 317 private void showDescription(final ICompositeCheatSheetTask task) { 318 if (descriptionPanel==null) { 319 createDescriptionPanel(); 320 } 321 descriptionPanel.showDescription(task); 322 setCurrentEditor(descriptionPanel.getControl()); 323 } 324 325 private void createDescriptionPanel() { 326 descriptionPanel = new DescriptionPanel(mform, taskEditorContainer); 327 descriptionPanel.addHyperlinkListener(new DescriptionLinkListener()); 328 } 329 330 333 private void showEditor(EditableTask task) { 334 if (task == selectedTask) { 335 TaskEditor editor = getTaskEditor(task); 336 if (editor!= null) { 337 if (!task.isEditorInitialized()) { 338 task.setInput(model.getTaskMemento(task.getId())); 339 } 340 setCurrentEditor(editor.getControl().getParent()); 341 } 342 } 343 } 344 345 private void addHyperlink(StringBuffer buf, String href, String imageRef, String message) { 346 buf.append("<p><a HREF=\""); buf.append(href); 348 buf.append("\">"); buf.append("<img HREF=\""); buf.append(imageRef); 351 buf.append("\"/> "); buf.append(message); 353 buf.append("</a></p>"); } 355 356 private void reviewTask(EditableTask task) { 357 TaskEditor taskEditor = getTaskEditor(task); 358 Composite container = taskEditor.getControl().getParent(); 359 Composite separator = toolkit.createCompositeSeparator(container); 360 GridData data = new GridData(); 361 data.heightHint = 1; 362 data.horizontalAlignment = SWT.FILL; 363 separator.setLayoutData(data); 364 FormText text = toolkit.createFormText(container, false); 365 text.setImage(DescriptionPanel.REVIEW_IMAGE, CheatSheetPlugin.getPlugin().getImage(ICheatSheetResource.COMPOSITE_TASK_REVIEW)); 366 text.addHyperlinkListener(getEndReviewListener()); 367 text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 368 StringBuffer buf = new StringBuffer (); 369 buf.append("<form>"); addHyperlink(buf, END_REVIEW_TAG + task.getId(), DescriptionPanel.REVIEW_IMAGE, Messages.COMPOSITE_PAGE_END_REVIEW ); 371 buf.append("</form>"); text.setText(buf.toString(), true, false); 373 task.setUnderReview(true); 374 container.layout(true); 375 showEditor(task); 376 } 377 378 private void endReview(EditableTask task) { 379 TaskEditor taskEditor = getTaskEditor(task); 380 Control editorControl = taskEditor.getControl(); 381 Composite container = editorControl.getParent(); 382 Control[] children = container.getChildren(); 383 for (int i = children.length -2; i < children.length; i++) { 384 children[i].dispose(); 385 } 386 task.setUnderReview(false); 387 showDescription(task); 388 container.layout(); 389 } 390 391 private void setCurrentEditor(Control c) { 392 taskEditorContainer.showPage(c); 393 } 394 395 399 private final class DescriptionLinkListener extends HyperlinkAdapter { 400 public void linkActivated(HyperlinkEvent e) { 401 String ref = (String )e.getHref(); 402 if (ref.equals(START_HREF)) { 403 Object data = descriptionPanel.getControl().getData(ICompositeCheatsheetTags.TASK); 404 if (data instanceof EditableTask) { 405 EditableTask task = (EditableTask)data; 406 task.setStarted(); 407 } 408 } 409 if (ref.equals(SKIP_HREF)) { 410 Object data = descriptionPanel.getControl().getData(ICompositeCheatsheetTags.TASK); 411 if (data instanceof AbstractTask) { 412 AbstractTask task = (AbstractTask)data; 413 task.setState(ICompositeCheatSheetTask.SKIPPED); 414 } 415 } 416 if (ref.equals(REVIEW_TAG)) { 417 Object data = descriptionPanel.getControl().getData(ICompositeCheatsheetTags.TASK); 418 if (data instanceof EditableTask) { 419 reviewTask((EditableTask) data); 420 } 421 } 422 if (ref.startsWith(GOTO_TASK_TAG)) { 423 String next = ref.substring(GOTO_TASK_TAG.length()); 424 AbstractTask nextTask = 425 model.getDependencies().getTask(next); 426 currentExplorer.setSelection 427 (new StructuredSelection(nextTask), true); 428 } 429 } 430 } 431 432 436 private final class EndReviewListener extends HyperlinkAdapter { 437 public void linkActivated(HyperlinkEvent e) { 438 String ref = (String )e.getHref(); 439 if (ref.startsWith(END_REVIEW_TAG)) { 440 String next = ref.substring(END_REVIEW_TAG.length()); 441 AbstractTask task = 442 model.getDependencies().getTask(next); 443 endReview((EditableTask)task); 444 } 445 } 446 } 447 448 private EndReviewListener endReviewListener; 449 450 private EndReviewListener getEndReviewListener() { 451 if (endReviewListener == null) { 452 endReviewListener = new EndReviewListener(); 453 } 454 return endReviewListener; 455 } 456 457 458 461 private TaskEditor getTaskEditor(EditableTask editable) { 462 if (editable.getEditor() == null) { 463 TaskEditor editor = TaskEditorManager.getInstance().getEditor(editable.getKind()); 465 if (editor != null) { 466 Composite editorPanel = new Composite(taskEditorContainer, SWT.NULL); 467 GridLayout layout = new GridLayout(); 468 layout.marginWidth = 0; 469 layout.marginHeight = 0; 470 editorPanel.setLayout(layout); 471 mform.getToolkit().adapt(editorPanel); 472 editor.createControl(editorPanel, mform.getToolkit()); 473 editable.setEditor(editor); 474 GridData gridData = new GridData(GridData.FILL_BOTH); 475 editor.getControl().setLayoutData(gridData); 476 } 477 } 478 return editable.getEditor(); 479 } 480 481 public Control getControl() { 482 return form; 483 } 484 485 protected String getTitle() { 486 return model.getName(); 487 } 488 489 public void initialized() { 490 model.setSaveHelper(saveHelper); 492 Map layout = new HashMap (); 493 model.loadState(layout); 494 setInputModel(model, layout); 495 initialized = true; 496 } 497 498 public int contributeToViewMenu(Menu menu, int index) { 499 if (!initialized) { 500 return index; 501 } 502 index = contributeExplorerMenuItem(menu, index); 503 return contributeRestartMenuItem(menu, index); 504 } 505 506 private int contributeRestartMenuItem(Menu menu, int index) { 507 MenuItem item = new MenuItem(menu, SWT.PUSH, index++); 508 item.setText(Messages.RESTART_ALL_MENU); 509 item.setImage(CheatSheetPlugin.getPlugin().getImage(ICheatSheetResource.COMPOSITE_RESTART_ALL)); 510 item.addSelectionListener(new SelectionAdapter() { 511 public void widgetSelected(SelectionEvent e) { 512 if (model != null) { 513 if (RestartAllAction.confirmRestart()) { 514 restart(null); 515 } 516 } 517 } 518 }); 519 return index; 520 } 521 522 private int contributeExplorerMenuItem(Menu menu, int index) { 523 String [] explorerIds = CheatSheetRegistryReader.getInstance().getExplorerIds(); 524 if (explorerIds.length == 1) { 525 return index; } 527 MenuItem menuItem = new MenuItem(menu, SWT.CASCADE, index++); 528 529 menuItem.setText(Messages.EXPLORER_PULLDOWN_MENU); 530 531 Menu subMenu = new Menu(menu); 532 menuItem.setMenu(subMenu); 533 534 for (int i = 0; i < explorerIds.length; i++) { 535 final String id = explorerIds[i]; 536 TaskExplorerNode node = CheatSheetRegistryReader.getInstance().findTaskExplorer(id); 537 boolean isCurrentExplorer = id.equals(currentExplorer.getId()); 538 int style = isCurrentExplorer ? SWT.RADIO: SWT.PUSH; 539 MenuItem item = new MenuItem(subMenu, style); 540 item.setText(node.getName()); 541 item.setSelection(isCurrentExplorer); 542 item.setImage(TaskExplorerManager.getInstance().getImage(id)); 543 item.addSelectionListener(new SelectionAdapter() { 544 public void widgetSelected(SelectionEvent e) { 545 setCurrentExplorerFromId(id); 546 } 547 }); 548 } 549 550 return index; 551 } 552 553 public void restart(Map cheatSheetData) { 554 model.resetAllTasks(cheatSheetData); 555 currentExplorer.setSelection 556 (new StructuredSelection(model.getRootTask()), true); 557 558 } 559 560 } 561 | Popular Tags |