1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 560168 14 *******************************************************************************/ 15 package org.eclipse.help.ui.internal.views; 16 17 import java.io.UnsupportedEncodingException; 18 import java.net.MalformedURLException; 19 import java.net.URL; 20 import java.net.URLDecoder; 21 import java.text.Collator; 22 import java.util.ArrayList; 23 import java.util.HashMap; 24 import java.util.Iterator; 25 import java.util.Map; 26 import java.util.Set; 27 28 import org.eclipse.core.runtime.Platform; 29 import org.eclipse.core.runtime.jobs.Job; 30 import org.eclipse.help.IContext; 31 import org.eclipse.help.IContextProvider; 32 import org.eclipse.help.IHelpResource; 33 import org.eclipse.help.IIndexEntry; 34 import org.eclipse.help.IToc; 35 import org.eclipse.help.ITopic; 36 import org.eclipse.help.UAContentFilter; 37 import org.eclipse.help.internal.base.BaseHelpSystem; 38 import org.eclipse.help.internal.base.HelpBasePlugin; 39 import org.eclipse.help.internal.base.HelpEvaluationContext; 40 import org.eclipse.help.internal.base.IHelpBaseConstants; 41 import org.eclipse.help.internal.base.MissingContentManager; 42 import org.eclipse.help.internal.base.util.LinkUtil; 43 import org.eclipse.help.internal.protocols.HelpURLConnection; 44 import org.eclipse.help.internal.search.federated.IndexerJob; 45 import org.eclipse.help.internal.util.ProductPreferences; 46 import org.eclipse.help.search.ISearchEngine2; 47 import org.eclipse.help.ui.internal.DefaultHelpUI; 48 import org.eclipse.help.ui.internal.HelpUIPlugin; 49 import org.eclipse.help.ui.internal.HelpUIResources; 50 import org.eclipse.help.ui.internal.IHelpUIConstants; 51 import org.eclipse.help.ui.internal.Messages; 52 import org.eclipse.jface.action.Action; 53 import org.eclipse.jface.action.IAction; 54 import org.eclipse.jface.action.IContributionManager; 55 import org.eclipse.jface.action.IMenuListener; 56 import org.eclipse.jface.action.IMenuManager; 57 import org.eclipse.jface.action.IStatusLineManager; 58 import org.eclipse.jface.action.IToolBarManager; 59 import org.eclipse.jface.action.MenuManager; 60 import org.eclipse.jface.action.Separator; 61 import org.eclipse.jface.action.SubMenuManager; 62 import org.eclipse.jface.action.SubStatusLineManager; 63 import org.eclipse.jface.action.SubToolBarManager; 64 import org.eclipse.jface.dialogs.MessageDialogWithToggle; 65 import org.eclipse.jface.operation.IRunnableContext; 66 import org.eclipse.jface.preference.IPreferenceStore; 67 import org.eclipse.jface.viewers.ISelectionProvider; 68 import org.eclipse.jface.viewers.IStructuredSelection; 69 import org.eclipse.jface.viewers.Viewer; 70 import org.eclipse.jface.viewers.ViewerFilter; 71 import org.eclipse.osgi.util.NLS; 72 import org.eclipse.swt.SWT; 73 import org.eclipse.swt.SWTError; 74 import org.eclipse.swt.custom.BusyIndicator; 75 import org.eclipse.swt.events.FocusEvent; 76 import org.eclipse.swt.events.FocusListener; 77 import org.eclipse.swt.events.SelectionEvent; 78 import org.eclipse.swt.events.SelectionListener; 79 import org.eclipse.swt.graphics.Image; 80 import org.eclipse.swt.graphics.Point; 81 import org.eclipse.swt.graphics.Rectangle; 82 import org.eclipse.swt.widgets.Composite; 83 import org.eclipse.swt.widgets.Control; 84 import org.eclipse.swt.widgets.Layout; 85 import org.eclipse.swt.widgets.Menu; 86 import org.eclipse.swt.widgets.Shell; 87 import org.eclipse.ui.IActionBars; 88 import org.eclipse.ui.IMemento; 89 import org.eclipse.ui.ISharedImages; 90 import org.eclipse.ui.IWorkbenchPart; 91 import org.eclipse.ui.IWorkbenchWindow; 92 import org.eclipse.ui.PlatformUI; 93 import org.eclipse.ui.SubActionBars; 94 import org.eclipse.ui.actions.ActionFactory; 95 import org.eclipse.ui.activities.ActivityManagerEvent; 96 import org.eclipse.ui.activities.IActivityManagerListener; 97 import org.eclipse.ui.forms.IFormPart; 98 import org.eclipse.ui.forms.ManagedForm; 99 import org.eclipse.ui.forms.events.HyperlinkEvent; 100 import org.eclipse.ui.forms.widgets.FormText; 101 import org.eclipse.ui.forms.widgets.FormToolkit; 102 import org.eclipse.ui.forms.widgets.ILayoutExtension; 103 import org.eclipse.ui.forms.widgets.ScrolledForm; 104 105 public class ReusableHelpPart implements IHelpUIConstants, 106 IActivityManagerListener { 107 public static final int ALL_TOPICS = 1 << 1; 108 109 public static final int CONTEXT_HELP = 1 << 2; 110 111 public static final int SEARCH = 1 << 3; 112 113 public static final int BOOKMARKS = 1 << 4; 114 115 public static final int INDEX = 1 << 5; 116 117 public static final Collator SHARED_COLLATOR = Collator.getInstance(); 118 119 private static final String PROMPT_KEY = "askShowAll"; //$NON-NLS-1$ 120 121 private static final int STATE_START = 1; 122 123 private static final int STATE_LT = 2; 124 125 private static final int STATE_LT_B = 3; 126 127 private static final int STATE_LT_BR = 4; 128 129 /* 130 * Used as a bridge from live help actions back (e.g. breadcrumb links) 131 * to the originating help part. 132 */ 133 private static ReusableHelpPart lastActiveInstance; 134 135 private RoleFilter roleFilter; 136 137 private UAFilter uaFilter; 138 139 private ManagedForm mform; 140 141 private int verticalSpacing = 15; 142 143 private int bmargin = 5; 144 145 private String defaultContextHelpText; 146 147 private ArrayList<IHelpPartPage> pages; 148 149 private Action backAction; 150 151 private Action nextAction; 152 153 private CopyAction copyAction; 154 155 private Action openInfoCenterAction; 156 157 private OpenHrefAction openAction; 158 159 private OpenHrefAction openInHelpAction; 160 161 private OpenHrefAction bookmarkAction; 162 163 private Action showAllAction; 164 165 private ReusableHelpPartHistory history; 166 167 private HelpPartPage currentPage; 168 169 private int style; 170 171 private IMemento memento; 172 173 private boolean showDocumentsInPlace = true; 174 175 private int numberOfInPlaceHits = 8; 176 177 private IRunnableContext runnableContext; 178 179 private IToolBarManager toolBarManager; 180 181 private IStatusLineManager statusLineManager; 182 183 private IActionBars actionBars; 184 185 private EngineDescriptorManager engineManager; 186 187 public IMenuManager menuManager; 188 189 private abstract class BusyRunAction extends Action { BusyRunAction(String name)190 public BusyRunAction(String name) { 191 super(name); 192 } 193 194 @Override run()195 public void run() { 196 BusyIndicator.showWhile(getControl().getDisplay(), this::busyRun); 197 } 198 busyRun()199 protected abstract void busyRun(); 200 } 201 202 private abstract class OpenHrefAction extends BusyRunAction { 203 private Object target; 204 OpenHrefAction(String name)205 public OpenHrefAction(String name) { 206 super(name); 207 } 208 setTarget(Object target)209 public void setTarget(Object target) { 210 this.target = target; 211 } 212 getTarget()213 public Object getTarget() { 214 return target; 215 } 216 } 217 218 private class CopyAction extends Action implements FocusListener, 219 SelectionListener { 220 private FormText target; 221 CopyAction()222 public CopyAction() { 223 super("copy"); //$NON-NLS-1$ 224 } 225 hook(final FormText text)226 public void hook(final FormText text) { 227 text.addFocusListener(this); 228 } 229 unhook(FormText text)230 public void unhook(FormText text) { 231 text.removeFocusListener(this); 232 if (target == text) 233 setTarget(null); 234 } 235 236 @Override focusGained(FocusEvent e)237 public void focusGained(FocusEvent e) { 238 FormText text = (FormText) e.widget; 239 text.addSelectionListener(this); 240 setTarget(text); 241 } 242 243 @Override focusLost(FocusEvent e)244 public void focusLost(FocusEvent e) { 245 FormText text = (FormText) e.widget; 246 text.removeSelectionListener(this); 247 setTarget(null); 248 } 249 setTarget(FormText target)250 public void setTarget(FormText target) { 251 this.target = target; 252 updateState(); 253 } 254 updateState()255 private void updateState() { 256 setEnabled(target != null && target.canCopy()); 257 } 258 259 @Override run()260 public void run() { 261 if (target != null) 262 target.copy(); 263 } 264 265 @Override widgetSelected(SelectionEvent e)266 public void widgetSelected(SelectionEvent e) { 267 FormText text = (FormText) e.widget; 268 if (text == target) { 269 updateState(); 270 } 271 } 272 273 @Override widgetDefaultSelected(SelectionEvent e)274 public void widgetDefaultSelected(SelectionEvent e) { 275 } 276 } 277 278 private static class PartRec { 279 String id; 280 281 boolean flexible; 282 283 boolean grabVertical; 284 285 IHelpPart part; 286 PartRec(String id, boolean flexible, boolean grabVertical)287 PartRec(String id, boolean flexible, boolean grabVertical) { 288 this.id = id; 289 this.flexible = flexible; 290 this.grabVertical = grabVertical; 291 } 292 } 293 294 private class HelpPartPage implements IHelpPartPage { 295 private String id; 296 297 private String iconId; 298 299 Action pageAction; 300 301 private int vspacing = verticalSpacing; 302 303 private int horizontalMargin = 0; 304 305 private String text; 306 307 private SubActionBars bars; 308 309 private IToolBarManager subToolBarManager; 310 311 private IMenuManager subMenuManager; 312 313 protected ArrayList<PartRec> partRecs; 314 315 private int nflexible; 316 HelpPartPage(String id, String text)317 public HelpPartPage(String id, String text) { 318 this.id = id; 319 this.text = text; 320 partRecs = new ArrayList<>(); 321 if (ReusableHelpPart.this.actionBars != null) { 322 // Help View 323 bars = new SubActionBars(ReusableHelpPart.this.actionBars); 324 subToolBarManager = bars.getToolBarManager(); 325 subMenuManager = bars.getMenuManager(); 326 } else { 327 // Help Tray 328 subToolBarManager = new SubToolBarManager( 329 ReusableHelpPart.this.toolBarManager); 330 if (ReusableHelpPart.this.menuManager != null) { 331 subMenuManager = new SubMenuManager( 332 ReusableHelpPart.this.menuManager); 333 } else { 334 subMenuManager = null; 335 } 336 } 337 } 338 HelpPartPage(String id, String text, String iconId)339 public HelpPartPage(String id, String text, String iconId) { 340 this(id, text); 341 this.iconId = iconId; 342 } 343 344 @Override dispose()345 public void dispose() { 346 if (bars != null) { 347 bars.dispose(); 348 bars = null; 349 subToolBarManager = null; 350 subMenuManager = null; 351 } else { 352 try { 353 ((SubToolBarManager) subToolBarManager).disposeManager(); 354 if (subMenuManager != null) { 355 ((SubMenuManager)subMenuManager).disposeManager(); 356 } 357 } catch (RuntimeException e) { 358 // Bug 218079 359 } 360 } 361 partRecs = null; 362 } 363 364 @Override setVerticalSpacing(int value)365 public void setVerticalSpacing(int value) { 366 this.vspacing = value; 367 } 368 369 @Override getVerticalSpacing()370 public int getVerticalSpacing() { 371 return vspacing; 372 } 373 374 @Override setHorizontalMargin(int value)375 public void setHorizontalMargin(int value) { 376 this.horizontalMargin = value; 377 } 378 379 @Override getHorizontalMargin()380 public int getHorizontalMargin() { 381 return horizontalMargin; 382 } 383 384 @Override getToolBarManager()385 public IToolBarManager getToolBarManager() { 386 return subToolBarManager; 387 } 388 389 @Override getId()390 public String getId() { 391 return id; 392 } 393 394 @Override getText()395 public String getText() { 396 return text; 397 } 398 399 @Override getIconId()400 public String getIconId() { 401 return iconId; 402 } 403 404 @Override addPart(String id, boolean flexible)405 public void addPart(String id, boolean flexible) { 406 addPart(id, flexible, false); 407 } 408 409 @Override addPart(String id, boolean flexible, boolean grabVertical)410 public void addPart(String id, boolean flexible, boolean grabVertical) { 411 partRecs.add(new PartRec(id, flexible, grabVertical)); 412 if (flexible) 413 nflexible++; 414 } 415 getParts()416 public PartRec[] getParts() { 417 return partRecs.toArray(new PartRec[partRecs.size()]); 418 } 419 refreshPage()420 public void refreshPage() 421 { 422 PartRec parts[] = getParts(); 423 if (parts==null) 424 return; 425 426 for (int p=0;p<parts.length;p++) 427 if (parts[p]!=null && parts[p].part!=null && parts[p].part.isStale()) 428 parts[p].part.refresh(); 429 } 430 431 @Override getNumberOfFlexibleParts()432 public int getNumberOfFlexibleParts() { 433 return nflexible; 434 } 435 436 @Override canOpen()437 public boolean canOpen() { 438 for (int i = 0; i < partRecs.size(); i++) { 439 PartRec rec = partRecs.get(i); 440 441 if (rec.id.equals(IHelpUIConstants.HV_BROWSER)) { 442 // Try to create a browser and watch 443 // for 'no-handle' error - it means 444 // that the embedded browser is not 445 // available 446 try { 447 createRecPart(rec); 448 rec.part.setVisible(false); 449 } catch (SWTError error) { 450 // cannot create a browser 451 return false; 452 } 453 } 454 } 455 return true; 456 } 457 458 @Override stop()459 public void stop() { 460 for (int i = 0; i < partRecs.size(); i++) { 461 PartRec rec = partRecs.get(i); 462 if (rec.part!=null) 463 rec.part.stop(); 464 } 465 } 466 467 @Override saveState(IMemento memento)468 public void saveState(IMemento memento) { 469 for (int i = 0; i < partRecs.size(); i++) { 470 PartRec rec = partRecs.get(i); 471 if (rec.part!=null) 472 rec.part.saveState(memento); 473 } 474 } 475 476 @Override toggleRoleFilter()477 public void toggleRoleFilter() { 478 for (int i = 0; i < partRecs.size(); i++) { 479 PartRec rec = partRecs.get(i); 480 if (rec.part != null) 481 rec.part.toggleRoleFilter(); 482 } 483 } 484 485 @Override refilter()486 public void refilter() { 487 for (int i = 0; i < partRecs.size(); i++) { 488 PartRec rec = partRecs.get(i); 489 if (rec.part != null) 490 rec.part.refilter(); 491 } 492 } 493 494 @Override setVisible(boolean visible)495 public void setVisible(boolean visible) { 496 if (bars != null) 497 bars.clearGlobalActionHandlers(); 498 ArrayList<Control> tabList = new ArrayList<>(); 499 for (int i = 0; i < partRecs.size(); i++) { 500 PartRec rec = partRecs.get(i); 501 if (visible) { 502 createRecPart(rec); 503 hookGlobalAction(ActionFactory.PRINT.getId(), rec.part); 504 hookGlobalAction(ActionFactory.COPY.getId(), rec.part); 505 hookGlobalAction(ActionFactory.DELETE.getId(), rec.part); 506 tabList.add(rec.part.getControl()); 507 } 508 rec.part.setVisible(visible); 509 } 510 Composite parent = mform.getForm().getBody(); 511 parent.setTabList(tabList.toArray(new Control[tabList.size()])); 512 513 if (actionBars != null) { 514 actionBars.clearGlobalActionHandlers(); 515 if (visible) { 516 Map<String, IAction> handlers = bars.getGlobalActionHandlers(); 517 if (handlers != null) { 518 Set<String> keys = handlers.keySet(); 519 for (Iterator<String> iter = keys.iterator(); iter.hasNext();) { 520 String key = iter.next(); 521 actionBars.setGlobalActionHandler(key, handlers.get(key)); 522 } 523 } 524 } 525 if (pageAction != null) 526 pageAction.setChecked(visible); 527 } 528 529 if (bars != null) { 530 if (visible) 531 bars.activate(); 532 else 533 bars.deactivate(); 534 bars.updateActionBars(); 535 } else { 536 ((SubToolBarManager) subToolBarManager).setVisible(visible); 537 if (subMenuManager != null) { 538 ((SubMenuManager)subMenuManager).setVisible(visible); 539 } 540 ReusableHelpPart.this.toolBarManager.update(true); 541 getControl().getParent().layout(); 542 } 543 544 } 545 hookGlobalAction(String id, IHelpPart part)546 private void hookGlobalAction(String id, IHelpPart part) { 547 if (bars == null) 548 return; 549 IAction action = part.getGlobalAction(id); 550 if (action != null) 551 bars.setGlobalActionHandler(id, action); 552 } 553 createRecPart(PartRec rec)554 private void createRecPart(PartRec rec) throws SWTError { 555 if (rec.part == null) { 556 rec.part = createPart(rec.id, subToolBarManager, subMenuManager); 557 } 558 } 559 560 @Override findPart(String id)561 public IHelpPart findPart(String id) { 562 for (int i = 0; i < partRecs.size(); i++) { 563 PartRec rec = partRecs.get(i); 564 if (rec.id.equals(id)) 565 return rec.part; 566 } 567 return null; 568 } 569 570 @Override setFocus()571 public void setFocus() { 572 // Focus on the first part that is not the see also links or missing content link 573 for (int focusPart = 0; focusPart < partRecs.size(); focusPart++) { 574 PartRec rec = partRecs.get(focusPart); 575 String partId = rec.part.getId(); 576 if ( partId != IHelpUIConstants.HV_SEE_ALSO && partId != IHelpUIConstants.HV_MISSING_CONTENT) { 577 rec.part.setFocus(); 578 return; 579 } 580 } 581 } 582 583 } 584 585 class HelpPartLayout extends Layout implements ILayoutExtension { 586 587 @Override computeMaximumWidth(Composite parent, boolean changed)588 public int computeMaximumWidth(Composite parent, boolean changed) { 589 return computeSize(parent, SWT.DEFAULT, SWT.DEFAULT, changed).x; 590 } 591 592 @Override computeMinimumWidth(Composite parent, boolean changed)593 public int computeMinimumWidth(Composite parent, boolean changed) { 594 return computeSize(parent, 0, SWT.DEFAULT, changed).x; 595 } 596 597 @Override computeSize(Composite composite, int wHint, int hHint, boolean flushCache)598 protected Point computeSize(Composite composite, int wHint, int hHint, 599 boolean flushCache) { 600 if (currentPage == null) 601 return new Point(0, 0); 602 PartRec[] parts = currentPage.getParts(); 603 int hmargin = currentPage.getHorizontalMargin(); 604 int innerWhint = wHint != SWT.DEFAULT ? wHint - 2 * hmargin : wHint; 605 Point result = new Point(0, 0); 606 for (int i = 0; i < parts.length; i++) { 607 PartRec partRec = parts[i]; 608 if (!partRec.flexible) { 609 Control c = partRec.part.getControl(); 610 Point size = c.computeSize(innerWhint, SWT.DEFAULT, 611 flushCache); 612 result.x = Math.max(result.x, size.x); 613 result.y += size.y; 614 } 615 if (i < parts.length - 1) 616 result.y += currentPage.getVerticalSpacing(); 617 } 618 result.x += hmargin * 2; 619 result.y += bmargin; 620 return result; 621 } 622 623 @Override layout(Composite composite, boolean flushCache)624 protected void layout(Composite composite, boolean flushCache) { 625 if (currentPage == null) 626 return; 627 628 Rectangle clientArea = composite.getClientArea(); 629 630 PartRec[] parts = currentPage.getParts(); 631 int hmargin = currentPage.getHorizontalMargin(); 632 int nfixedParts = parts.length 633 - currentPage.getNumberOfFlexibleParts(); 634 Point[] fixedSizes = new Point[nfixedParts]; 635 int fixedHeight = 0; 636 int index = 0; 637 int innerWidth = clientArea.width - hmargin * 2; 638 for (int i = 0; i < parts.length; i++) { 639 PartRec partRec = parts[i]; 640 if (!partRec.flexible) { 641 Control c = partRec.part.getControl(); 642 Point size = c.computeSize(innerWidth, SWT.DEFAULT, false); 643 fixedSizes[index++] = size; 644 if (!partRec.grabVertical) 645 fixedHeight += size.y; 646 } 647 if (i < parts.length - 1) 648 fixedHeight += currentPage.getVerticalSpacing(); 649 } 650 fixedHeight += bmargin; 651 int flexHeight = clientArea.height - fixedHeight; 652 int flexPortion = 0; 653 if (currentPage.getNumberOfFlexibleParts() > 0) 654 flexPortion = flexHeight 655 / currentPage.getNumberOfFlexibleParts(); 656 657 int usedFlexHeight = 0; 658 int y = 0; 659 index = 0; 660 int nflexParts = 0; 661 for (int i = 0; i < parts.length; i++) { 662 PartRec partRec = parts[i]; 663 Control c = partRec.part.getControl(); 664 665 if (partRec.flexible) { 666 int height; 667 if (++nflexParts == currentPage.getNumberOfFlexibleParts()) 668 height = flexHeight - usedFlexHeight; 669 else { 670 height = flexPortion; 671 usedFlexHeight += height; 672 } 673 c.setBounds(0, y, clientArea.width, height); 674 } else { 675 Point fixedSize = fixedSizes[index++]; 676 if (fixedSize.y < flexHeight && partRec.grabVertical) 677 c.setBounds(hmargin, y, innerWidth, flexHeight); 678 else 679 c.setBounds(hmargin, y, innerWidth, fixedSize.y); 680 } 681 if (i < parts.length - 1) 682 y += c.getSize().y + currentPage.getVerticalSpacing(); 683 } 684 } 685 } 686 687 class RoleFilter extends ViewerFilter { 688 689 @Override select(Viewer viewer, Object parentElement, Object element)690 public boolean select(Viewer viewer, Object parentElement, 691 Object element) { 692 IHelpResource res = (IHelpResource) element; 693 String href = res.getHref(); 694 if (href == null) 695 return true; 696 return HelpBasePlugin.getActivitySupport().isEnabled(href); 697 } 698 } 699 700 class UAFilter extends ViewerFilter { 701 702 @Override select(Viewer viewer, Object parentElement, Object element)703 public boolean select(Viewer viewer, Object parentElement, 704 Object element) { 705 return !UAContentFilter.isFiltered(element, HelpEvaluationContext.getContext()); 706 } 707 } 708 ReusableHelpPart(IRunnableContext runnableContext)709 public ReusableHelpPart(IRunnableContext runnableContext) { 710 this(runnableContext, getDefaultStyle()); 711 } 712 ReusableHelpPart(IRunnableContext runnableContext, int style)713 public ReusableHelpPart(IRunnableContext runnableContext, int style) { 714 this.runnableContext = runnableContext; 715 history = new ReusableHelpPartHistory(); 716 this.style = style; 717 ensureHelpIndexed(); 718 PlatformUI.getWorkbench().getActivitySupport().getActivityManager() 719 .addActivityManagerListener(this); 720 } 721 722 /* 723 * Used as a bridge from live help actions back (e.g. breadcrumb links) 724 * to the originating help part. 725 */ getLastActiveInstance()726 public static ReusableHelpPart getLastActiveInstance() { 727 return lastActiveInstance; 728 } 729 ensureHelpIndexed()730 private void ensureHelpIndexed() { 731 // make sure we have the index but 732 // don't schedule the indexer job if one is 733 // already running 734 Job[] jobs = Job.getJobManager().find(IndexerJob.FAMILY); 735 if (jobs.length == 0) { 736 IndexerJob indexerJob = new IndexerJob(); 737 indexerJob.schedule(); 738 } 739 } 740 741 /** 742 * Adds the given page to this part. 743 * 744 * @param page the page to add 745 */ addPage(IHelpPartPage page)746 public void addPage(IHelpPartPage page) { 747 pages.add(page); 748 } 749 750 /** 751 * Adds the given part to this one. The part can then be used inside 752 * any page and referred to by id. 753 * 754 * @param id the part's unique id 755 * @param part the part to add 756 */ addPart(String id, IHelpPart part)757 public void addPart(String id, IHelpPart part) { 758 part.init(this, id, memento); 759 mform.addPart(part); 760 } 761 762 /** 763 * Creates a new page for this part. 764 * 765 * @param id the page's unique id 766 * @param text the page's heading, or null for none 767 * @param iconId the page's icon 768 * @return the newly created page 769 */ createPage(String id, String text, String iconId)770 public IHelpPartPage createPage(String id, String text, String iconId) { 771 return new HelpPartPage(id, text, iconId); 772 } 773 definePages()774 private void definePages() { 775 pages = new ArrayList<>(); 776 // federated search page 777 HelpPartPage page = new HelpPartPage(HV_FSEARCH_PAGE, 778 Messages.ReusableHelpPart_searchPage_name, 779 IHelpUIConstants.IMAGE_HELP_SEARCH); 780 page.setVerticalSpacing(0); 781 page.addPart(HV_SEE_ALSO, false); 782 page.addPart(HV_MISSING_CONTENT, false); 783 page.addPart(HV_FSEARCH, false); 784 page.addPart(HV_FSEARCH_RESULT, true); 785 pages.add(page); 786 787 // all topics page 788 page = new HelpPartPage(HV_ALL_TOPICS_PAGE, 789 Messages.ReusableHelpPart_allTopicsPage_name, 790 IHelpUIConstants.IMAGE_ALL_TOPICS); 791 page.setVerticalSpacing(0); 792 page.setHorizontalMargin(0); 793 page.addPart(HV_SEE_ALSO, false); 794 page.addPart(HV_MISSING_CONTENT, false); 795 page.addPart(HV_SCOPE_SELECT, false); 796 page.addPart(HV_TOPIC_TREE, true); 797 pages.add(page); 798 799 // bookmarks page 800 page = new HelpPartPage(HV_BOOKMARKS_PAGE, 801 Messages.ReusableHelpPart_bookmarksPage_name, 802 IHelpUIConstants.IMAGE_BOOKMARKS); 803 page.setVerticalSpacing(0); 804 page.setHorizontalMargin(0); 805 page.addPart(HV_SEE_ALSO, false); 806 page.addPart(HV_BOOKMARKS_HEADER, false); 807 page.addPart(HV_BOOKMARKS_TREE, true); 808 pages.add(page); 809 // browser page 810 page = new HelpPartPage(HV_BROWSER_PAGE, null); 811 page.setVerticalSpacing(0); 812 page.addPart(HV_SEE_ALSO, false); 813 page.addPart(HV_BROWSER, true); 814 pages.add(page); 815 816 // context help page 817 page = new HelpPartPage(HV_CONTEXT_HELP_PAGE, 818 Messages.ReusableHelpPart_contextHelpPage_name, 819 IHelpUIConstants.IMAGE_RELATED_TOPICS); 820 // page.addPart(HV_CONTEXT_HELP, false); 821 // page.addPart(HV_SEARCH_RESULT, false, true); 822 page.setVerticalSpacing(0); 823 page.setHorizontalMargin(0); 824 page.addPart(HV_SEE_ALSO, false); 825 page.addPart(HV_MISSING_CONTENT, false); 826 page.addPart(HV_RELATED_TOPICS, true); 827 pages.add(page); 828 829 // index page 830 page = new HelpPartPage(HV_INDEX_PAGE, 831 Messages.ReusableHelpPart_indexPage_name, 832 IHelpUIConstants.IMAGE_INDEX); 833 page.setVerticalSpacing(0); 834 page.addPart(HV_SEE_ALSO, false); 835 page.addPart(HV_MISSING_CONTENT, false); 836 page.addPart(HV_SCOPE_SELECT, false); 837 page.addPart(HV_INDEX_TYPEIN, false); 838 page.addPart(HV_INDEX, true); 839 pages.add(page); 840 } 841 init(IActionBars bars, IToolBarManager toolBarManager, IStatusLineManager statusLineManager, IMenuManager menuManager, IMemento memento)842 public void init(IActionBars bars, IToolBarManager toolBarManager, 843 IStatusLineManager statusLineManager, IMenuManager menuManager, IMemento memento) { 844 this.memento = memento; 845 this.actionBars = bars; 846 this.toolBarManager = toolBarManager; 847 this.menuManager = menuManager; 848 this.statusLineManager = statusLineManager; 849 definePages(); 850 makeActions(); 851 } 852 makeActions()853 private void makeActions() { 854 backAction = new Action("back") { //$NON-NLS-1$ 855 856 @Override 857 public void run() { 858 doBack(); 859 } 860 }; 861 backAction.setImageDescriptor(PlatformUI.getWorkbench() 862 .getSharedImages().getImageDescriptor( 863 ISharedImages.IMG_TOOL_BACK)); 864 backAction.setDisabledImageDescriptor(PlatformUI.getWorkbench() 865 .getSharedImages().getImageDescriptor( 866 ISharedImages.IMG_TOOL_BACK_DISABLED)); 867 backAction.setEnabled(false); 868 backAction.setText(Messages.ReusableHelpPart_back_label); 869 backAction.setToolTipText(Messages.ReusableHelpPart_back_tooltip); 870 backAction.setId("back"); //$NON-NLS-1$ 871 872 nextAction = new Action("next") { //$NON-NLS-1$ 873 874 @Override 875 public void run() { 876 doNext(); 877 } 878 }; 879 nextAction.setText(Messages.ReusableHelpPart_forward_label); 880 nextAction.setImageDescriptor(PlatformUI.getWorkbench() 881 .getSharedImages().getImageDescriptor( 882 ISharedImages.IMG_TOOL_FORWARD)); 883 nextAction.setDisabledImageDescriptor(PlatformUI.getWorkbench() 884 .getSharedImages().getImageDescriptor( 885 ISharedImages.IMG_TOOL_FORWARD_DISABLED)); 886 nextAction.setEnabled(false); 887 nextAction.setToolTipText(Messages.ReusableHelpPart_forward_tooltip); 888 nextAction.setId("next"); //$NON-NLS-1$ 889 toolBarManager.add(backAction); 890 toolBarManager.add(nextAction); 891 892 openInfoCenterAction = new BusyRunAction("openInfoCenter") { //$NON-NLS-1$ 893 894 @Override 895 protected void busyRun() { 896 PlatformUI.getWorkbench().getHelpSystem().displayHelp(); 897 } 898 }; 899 openInfoCenterAction 900 .setText(Messages.ReusableHelpPart_openInfoCenterAction_label); 901 openAction = new OpenHrefAction("open") { //$NON-NLS-1$ 902 903 @Override 904 protected void busyRun() { 905 doOpen(getTarget(), getShowDocumentsInPlace()); 906 } 907 }; 908 openAction.setText(Messages.ReusableHelpPart_openAction_label); 909 openInHelpAction = new OpenHrefAction("") {//$NON-NLS-1$ 910 911 @Override 912 protected void busyRun() { 913 doOpenInHelp(getTarget()); 914 } 915 }; 916 openInHelpAction 917 .setText(Messages.ReusableHelpPart_openInHelpContentsAction_label); 918 copyAction = new CopyAction(); 919 copyAction.setText(Messages.ReusableHelpPart_copyAction_label); 920 bookmarkAction = new OpenHrefAction("bookmark") { //$NON-NLS-1$ 921 922 @Override 923 protected void busyRun() { 924 doBookmark(getTarget()); 925 } 926 }; 927 bookmarkAction.setText(Messages.ReusableHelpPart_bookmarkAction_label); 928 bookmarkAction.setImageDescriptor(HelpUIResources 929 .getImageDescriptor(IHelpUIConstants.IMAGE_ADD_BOOKMARK)); 930 if (actionBars != null && actionBars.getMenuManager() != null) 931 contributeToDropDownMenu(actionBars.getMenuManager()); 932 933 roleFilter = new RoleFilter(); 934 uaFilter = new UAFilter(); 935 if (HelpBasePlugin.getActivitySupport().isUserCanToggleFiltering()) { 936 showAllAction = new Action() { 937 938 @Override 939 public void run() { 940 BusyIndicator.showWhile(getControl().getDisplay(), 941 () -> toggleShowAll(showAllAction.isChecked())); 942 } 943 }; 944 showAllAction.setImageDescriptor(HelpUIResources 945 .getImageDescriptor(IHelpUIConstants.IMAGE_SHOW_ALL)); 946 showAllAction 947 .setToolTipText(Messages.AllTopicsPart_showAll_tooltip); 948 toolBarManager.insertBefore("back", showAllAction); //$NON-NLS-1$ 949 toolBarManager.insertBefore("back", new Separator()); //$NON-NLS-1$ 950 showAllAction.setChecked(!HelpBasePlugin.getActivitySupport() 951 .isFilteringEnabled()); 952 } 953 } 954 getRoleFilter()955 ViewerFilter getRoleFilter() { 956 return roleFilter; 957 } 958 getUAFilter()959 ViewerFilter getUAFilter() { 960 return uaFilter; 961 } 962 963 @Override activityManagerChanged(ActivityManagerEvent activityManagerEvent)964 public void activityManagerChanged(ActivityManagerEvent activityManagerEvent) { 965 // pages is null when the activity manager listener is added, and is set to null 966 // prior to the activity manager listener being removed, so very short timeframes in 967 // logic where pages could equals null entering this method 968 if (pages != null){ 969 for (int i = 0; i < pages.size(); i++) { 970 HelpPartPage page = (HelpPartPage) pages.get(i); 971 page.refilter(); 972 } 973 } 974 } 975 isFilteredByRoles()976 boolean isFilteredByRoles() { 977 return HelpBasePlugin.getActivitySupport().isFilteringEnabled(); 978 } 979 doBack()980 private void doBack() { 981 String id = getCurrentPageId(); 982 if (id.equals(IHelpUIConstants.HV_BROWSER_PAGE)) { 983 // stop the browser 984 BrowserPart part = (BrowserPart) findPart(IHelpUIConstants.HV_BROWSER); 985 part.stop(); 986 } 987 HistoryEntry entry = history.prev(); 988 if (entry != null) 989 executeHistoryEntry(entry); 990 } 991 doNext()992 private void doNext() { 993 HistoryEntry entry = history.next(); 994 if (entry != null) 995 executeHistoryEntry(entry); 996 } 997 executeHistoryEntry(HistoryEntry entry)998 private void executeHistoryEntry(HistoryEntry entry) { 999 history.setBlocked(true); 1000 if (entry.getType() == HistoryEntry.PAGE) { 1001 showPage(entry.getTarget(), true); 1002 mform.setInput(entry.getData()); 1003 } else if (entry.getType() == HistoryEntry.URL) { 1004 String relativeUrl = (String) entry.getData(); 1005 showURL(relativeUrl != null ? relativeUrl : entry.getTarget(), true); 1006 } 1007 } 1008 createControl(Composite parent, FormToolkit toolkit)1009 public void createControl(Composite parent, FormToolkit toolkit) { 1010 ScrolledForm form = toolkit.createScrolledForm(parent); 1011 form.getBody().setLayout(new HelpPartLayout()); 1012 mform = new ManagedForm(toolkit, form); 1013 mform.getForm().setDelayedReflow(false); 1014 toolkit.decorateFormHeading(mform.getForm().getForm()); 1015 MenuManager manager = new MenuManager(); 1016 IMenuListener listener = this::contextMenuAboutToShow; 1017 manager.setRemoveAllWhenShown(true); 1018 manager.addMenuListener(listener); 1019 Menu contextMenu = manager.createContextMenu(form.getForm()); 1020 form.getForm().setMenu(contextMenu); 1021 form.addListener(SWT.Activate, event -> lastActiveInstance = ReusableHelpPart.this); 1022 //contributeToDropDownMenu(mform.getForm().getForm().getMenuManager()); 1023 } 1024 showPage(String id)1025 public HelpPartPage showPage(String id) { 1026 String currentPageId = currentPage == null ? null : currentPage.getId(); 1027 if (id.equals(currentPageId)) 1028 return currentPage; 1029 // If navigating away from the browser page clear 1030 // its contents 1031 if (IHelpUIConstants.HV_BROWSER_PAGE.equals(currentPageId)) { 1032 BrowserPart part = (BrowserPart) findPart(IHelpUIConstants.HV_BROWSER); 1033 part.clearBrowser(); 1034 } 1035 1036 HelpPartPage page = findPage(id); 1037 if (page != null) { 1038 page.refreshPage(); 1039 boolean success = flipPages(currentPage, page); 1040 return success ? page : null; 1041 } 1042 return null; 1043 } 1044 showPage(String id, boolean setFocus)1045 public HelpPartPage showPage(String id, boolean setFocus) { 1046 HelpPartPage page = this.showPage(id); 1047 if (page != null && setFocus) 1048 page.setFocus(); 1049 return page; 1050 } 1051 startSearch(String phrase)1052 public void startSearch(String phrase) { 1053 showPage(IHelpUIConstants.HV_FSEARCH_PAGE, true); 1054 SearchPart part = (SearchPart) findPart(IHelpUIConstants.HV_FSEARCH); 1055 if (part != null && phrase != null) 1056 part.startSearch(phrase); 1057 } 1058 showDynamicHelp(IWorkbenchPart wpart, Control c)1059 public void showDynamicHelp(IWorkbenchPart wpart, Control c) { 1060 showPage(IHelpUIConstants.HV_CONTEXT_HELP_PAGE, true); 1061 RelatedTopicsPart part = (RelatedTopicsPart) findPart(IHelpUIConstants.HV_RELATED_TOPICS); 1062 if (part != null) { 1063 part.handleActivation(c, wpart); 1064 } 1065 } 1066 flipPages(HelpPartPage oldPage, HelpPartPage newPage)1067 private boolean flipPages(HelpPartPage oldPage, HelpPartPage newPage) { 1068 if (newPage.canOpen() == false) 1069 return false; 1070 if (oldPage != null) { 1071 oldPage.stop(); 1072 oldPage.setVisible(false); 1073 } 1074 mform.getForm().setText(null); //(newPage.getText()); 1075 mform.getForm().getForm().setSeparatorVisible(newPage.getText()!=null); 1076 Image newImage=null; 1077 //String iconId = newPage.getIconId(); 1078 //if (iconId != null) 1079 //newImage = HelpUIResources.getImage(iconId); 1080 mform.getForm().setImage(newImage); 1081 newPage.setVisible(true); 1082 toolBarManager.update(true); 1083 currentPage = newPage; 1084 if (mform.isStale()) 1085 mform.refresh(); 1086 mform.getForm().getBody().layout(true); 1087 mform.reflow(true); 1088 if (newPage.getId().equals(IHelpUIConstants.HV_BROWSER_PAGE) == false) { 1089 if (!history.isBlocked()) { 1090 history.addEntry(new HistoryEntry(HistoryEntry.PAGE, newPage 1091 .getId(), null)); 1092 } 1093 updateNavigation(); 1094 } 1095 return true; 1096 } 1097 1098 /* 1099 * void addPageHistoryEntry(String id, Object data) { if 1100 * (!history.isBlocked()) { history.addEntry(new 1101 * HistoryEntry(HistoryEntry.PAGE, id, data)); } updateNavigation(); } 1102 */ getCurrentPage()1103 public HelpPartPage getCurrentPage() { 1104 return currentPage; 1105 } 1106 getCurrentPageId()1107 public String getCurrentPageId() { 1108 return currentPage != null ? currentPage.getId() : null; 1109 } 1110 browserChanged(String url)1111 void browserChanged(String url) { 1112 if (!history.isBlocked()) { 1113 try { 1114 history.addEntry(new HistoryEntry(HistoryEntry.URL, url, 1115 BaseHelpSystem.unresolve(new URL(url)))); 1116 } catch (MalformedURLException e) { 1117 // Do not add to history 1118 } 1119 } 1120 updateNavigation(); 1121 } 1122 updateNavigation()1123 private void updateNavigation() { 1124 backAction.setEnabled(history.hasPrev()); 1125 nextAction.setEnabled(history.hasNext()); 1126 history.setBlocked(false); 1127 } 1128 isMonitoringContextHelp()1129 public boolean isMonitoringContextHelp() { 1130 return currentPage != null && (currentPage.getId().equals(HV_CONTEXT_HELP_PAGE) 1131 || currentPage.getId().equals(HV_BROWSER_PAGE)); 1132 } 1133 getControl()1134 public Control getControl() { 1135 return mform.getForm(); 1136 } 1137 getForm()1138 public ManagedForm getForm() { 1139 return mform; 1140 } 1141 reflow()1142 public void reflow() { 1143 mform.getForm().getBody().layout(); 1144 mform.reflow(true); 1145 } 1146 dispose()1147 public void dispose() { 1148 if (lastActiveInstance == this) { 1149 lastActiveInstance = null; 1150 } 1151 for (int i = 0; i < pages.size(); i++) { 1152 HelpPartPage page = (HelpPartPage) pages.get(i); 1153 page.dispose(); 1154 } 1155 pages = null; 1156 if (mform != null) { 1157 mform.dispose(); 1158 mform = null; 1159 } 1160 PlatformUI.getWorkbench().getActivitySupport().getActivityManager() 1161 .removeActivityManagerListener(this); 1162 } 1163 1164 /* 1165 * (non-Javadoc) 1166 * 1167 * @see org.eclipse.ui.internal.intro.impl.parts.IStandbyContentPart#setFocus() 1168 */ setFocus()1169 public void setFocus() { 1170 if (currentPage != null) 1171 currentPage.setFocus(); 1172 else 1173 mform.setFocus(); 1174 } 1175 update(IWorkbenchPart part, Control control)1176 public void update(IWorkbenchPart part, Control control) { 1177 update(null, null, part, control, false); 1178 } 1179 1180 /** 1181 * Called to update the related topics page in response to a 1182 * @param provider 1183 * @param context 1184 * @param part 1185 * @param control 1186 * @param isExplicitRequest is true if this is the result of a direct user request such as 1187 * pressing F1 and false if it is in response to a focus change listener 1188 */ update(IContextProvider provider, IContext context, IWorkbenchPart part, Control control, boolean isExplicitRequest)1189 public void update(IContextProvider provider, IContext context, IWorkbenchPart part, Control control, 1190 boolean isExplicitRequest) { 1191 IContext realContext = context; 1192 if (provider != null) { 1193 realContext = provider.getContext(control); 1194 } 1195 if (realContext != null) { 1196 String contextText = realContext.getText(); 1197 IHelpResource[] topics = realContext.getRelatedTopics(); 1198 if (contextText == null && topics.length == 1) { 1199 showURL(topics[0].getHref()); 1200 return; 1201 } 1202 } 1203 // Ensure that context help is currently showing 1204 showPage(IHelpUIConstants.HV_CONTEXT_HELP_PAGE); 1205 mform.setInput(new ContextHelpProviderInput(provider, context, control, part, isExplicitRequest)); 1206 } 1207 createPart(String id, IToolBarManager tbm, IMenuManager menuManager)1208 private IHelpPart createPart(String id, IToolBarManager tbm, IMenuManager menuManager) { 1209 IHelpPart part = null; 1210 Composite parent = mform.getForm().getBody(); 1211 1212 part = findPart(id); 1213 if (part != null) 1214 return part; 1215 1216 if (id.equals(HV_TOPIC_TREE)) { 1217 part = new AllTopicsPart(parent, mform.getToolkit(), tbm); 1218 } else if (id.equals(HV_CONTEXT_HELP)) { 1219 part = new ContextHelpPart(parent, mform.getToolkit()); 1220 ((ContextHelpPart) part) 1221 .setDefaultText(getDefaultContextHelpText()); 1222 } else if (id.equals(HV_RELATED_TOPICS)) { 1223 part = new RelatedTopicsPart(parent, mform.getToolkit()); 1224 ((RelatedTopicsPart) part) 1225 .setDefaultText(getDefaultContextHelpText()); 1226 } else if (id.equals(HV_BROWSER)) { 1227 part = new BrowserPart(parent, mform.getToolkit(), tbm, menuManager); 1228 } else if (id.equals(HV_SEARCH_RESULT)) { 1229 part = new DynamicHelpPart(parent, mform.getToolkit()); 1230 } else if (id.equals(HV_FSEARCH_RESULT)) { 1231 part = new SearchResultsPart(parent, mform.getToolkit(), tbm); 1232 } else if (id.equals(HV_SCOPE_SELECT)) { 1233 part = new ScopeSelectPart(parent, mform.getToolkit()); 1234 } else if (id.equals(HV_SEE_ALSO)) { 1235 part = new SeeAlsoPart(parent, mform.getToolkit()); 1236 } else if (id.equals(HV_FSEARCH)) { 1237 part = new SearchPart(parent, mform.getToolkit()); 1238 } else if (id.equals(HV_BOOKMARKS_HEADER)) { 1239 part = new BookmarkHeaderPart(parent, mform.getToolkit()); 1240 } else if (id.equals(HV_BOOKMARKS_TREE)) { 1241 part = new BookmarksPart(parent, mform.getToolkit(), tbm); 1242 } else if (id.equals(HV_INDEX)) { 1243 part = new IndexPart(parent, mform.getToolkit(), tbm); 1244 } else if (id.equals(HV_INDEX_TYPEIN)) { 1245 part = new IndexTypeinPart(parent, mform.getToolkit(), tbm); 1246 } else if (id.equals(HV_MISSING_CONTENT)) { 1247 part = new MissingContentPart(parent, mform.getToolkit()); 1248 } 1249 if (part != null) { 1250 mform.addPart(part); 1251 part.init(this, id, memento); 1252 } 1253 return part; 1254 } 1255 1256 /** 1257 * @return Returns the runnableContext. 1258 */ getRunnableContext()1259 public IRunnableContext getRunnableContext() { 1260 return runnableContext; 1261 } 1262 isInWorkbenchWindow()1263 public boolean isInWorkbenchWindow() { 1264 return runnableContext instanceof IWorkbenchWindow; 1265 } 1266 1267 /** 1268 * @return Returns the defaultContextHelpText. 1269 */ getDefaultContextHelpText()1270 public String getDefaultContextHelpText() { 1271 return defaultContextHelpText; 1272 } 1273 1274 /** 1275 * @param defaultContextHelpText 1276 * The defaultContextHelpText to set. 1277 */ setDefaultContextHelpText(String defaultContextHelpText)1278 public void setDefaultContextHelpText(String defaultContextHelpText) { 1279 this.defaultContextHelpText = defaultContextHelpText; 1280 } 1281 showURL(final String url)1282 public void showURL(final String url) { 1283 BusyIndicator.showWhile(getControl().getDisplay(), () -> showURL(url, getShowDocumentsInPlace())); 1284 } 1285 showURL(String url, boolean replace)1286 public void showURL(String url, boolean replace) { 1287 if (url == null) 1288 return; 1289 if (url.startsWith("nw:")) { //$NON-NLS-1$ 1290 replace = false; 1291 url = url.substring(3); 1292 } 1293 else if (url.startsWith("open:")) { //$NON-NLS-1$ 1294 int col = url.indexOf(':'); 1295 int qloc = url.indexOf('?'); 1296 String engineId = url.substring(col+1, qloc); 1297 EngineDescriptor desc = getEngineManager().findEngine(engineId); 1298 if (desc==null) 1299 return; 1300 HashMap<String, Object> args = new HashMap<>(); 1301 HelpURLConnection.parseQuery(url.substring(qloc+1), args); 1302 ((ISearchEngine2)desc.getEngine()).open((String)args.get("id")); //$NON-NLS-1$ 1303 return; 1304 } 1305 if (replace) { 1306 if (openInternalBrowser(url)) 1307 return; 1308 } 1309 showExternalURL(url); 1310 } 1311 openInternalBrowser(String url)1312 private boolean openInternalBrowser(String url) { 1313 String openMode = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, 1314 IHelpBaseConstants.P_KEY_HELP_VIEW_OPEN_MODE, IHelpBaseConstants.P_IN_PLACE, null); 1315 boolean openInEditor = IHelpBaseConstants.P_IN_EDITOR.equals(openMode); 1316 boolean openInBrowser = IHelpBaseConstants.P_IN_BROWSER.equals(openMode); 1317 Shell windowShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 1318 Shell helpShell = mform.getForm().getShell(); 1319 boolean isDialog = (helpShell != windowShell); 1320 if (!isDialog && openInEditor) { 1321 return DefaultHelpUI.showInWorkbenchBrowser(url, true); 1322 } 1323 if (openInBrowser) { 1324 BaseHelpSystem.getHelpDisplay().displayHelpResource(url, false); 1325 return true; 1326 } 1327 showPage(IHelpUIConstants.HV_BROWSER_PAGE); 1328 BrowserPart bpart = (BrowserPart) findPart(IHelpUIConstants.HV_BROWSER); 1329 if (bpart != null) { 1330 bpart.showURL(BaseHelpSystem 1331 .resolve(url, "/help/ntopic").toString()); //$NON-NLS-1$ 1332 return true; 1333 } 1334 return false; 1335 } 1336 showExternalURL(String url)1337 public void showExternalURL(String url) { 1338 if (isHelpResource(url)) 1339 PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(url); 1340 else { 1341 try { 1342 String aurl = BaseHelpSystem.resolve(url, true).toString(); 1343 /* 1344 /* Previous code before fix for Bug 192750 1345 if (aurl.endsWith("&noframes=true") || aurl.endsWith("?noframes=true")) //$NON-NLS-1$ //$NON-NLS-2$ 1346 aurl = aurl.substring(0, aurl.length() - 14); 1347 DefaultHelpUI.showInWorkbenchBrowser(aurl, false); 1348 */ 1349 1350 PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(aurl); 1351 1352 } catch (Exception e) { 1353 Platform.getLog(getClass()).error("Error opening browser", e); //$NON-NLS-1$ 1354 } 1355 } 1356 } 1357 findPart(String id)1358 public IHelpPart findPart(String id) { 1359 if (mform == null) 1360 return null; 1361 IFormPart[] parts = mform.getParts(); 1362 for (int i = 0; i < parts.length; i++) { 1363 IHelpPart part = (IHelpPart) parts[i]; 1364 if (part.getId().equals(id)) 1365 return part; 1366 } 1367 return null; 1368 } 1369 isHelpResource(String url)1370 public boolean isHelpResource(String url) { 1371 if (url == null || !url.contains("://")) //$NON-NLS-1$ 1372 return true; 1373 return false; 1374 } 1375 contextMenuAboutToShow(IMenuManager manager)1376 private void contextMenuAboutToShow(IMenuManager manager) { 1377 IFormPart[] parts = mform.getParts(); 1378 boolean hasContext = false; 1379 Control focusControl = getControl().getDisplay().getFocusControl(); 1380 for (int i = 0; i < parts.length; i++) { 1381 IHelpPart part = (IHelpPart) parts[i]; 1382 if (part.hasFocusControl(focusControl)) { 1383 hasContext = part.fillContextMenu(manager); 1384 break; 1385 } 1386 } 1387 if (hasContext) 1388 manager.add(new Separator()); 1389 manager.add(backAction); 1390 manager.add(nextAction); 1391 manager.add(new Separator()); 1392 manager.add(openInfoCenterAction); 1393 } 1394 contributeToDropDownMenu(IMenuManager manager)1395 private void contributeToDropDownMenu(IMenuManager manager) { 1396 addPageAction(manager, IHelpUIConstants.HV_CONTEXT_HELP_PAGE); 1397 addPageAction(manager, IHelpUIConstants.HV_ALL_TOPICS_PAGE); 1398 addPageAction(manager, IHelpUIConstants.HV_INDEX_PAGE); 1399 addPageAction(manager, IHelpUIConstants.HV_FSEARCH_PAGE); 1400 addPageAction(manager, IHelpUIConstants.HV_BOOKMARKS_PAGE); 1401 } 1402 addPageAction(IMenuManager manager, final String pageId)1403 private void addPageAction(IMenuManager manager, final String pageId) { 1404 // String cid = getCurrentPageId(); 1405 HelpPartPage page = findPage(pageId); 1406 if (page == null) 1407 return; 1408 Action action = new Action(pageId, IAction.AS_CHECK_BOX) { 1409 1410 @Override 1411 public void run() { 1412 BusyIndicator.showWhile(mform.getForm().getDisplay(), 1413 () -> showPage(pageId)); 1414 } 1415 }; 1416 action.setText(page.getText()); 1417 String iconId = page.getIconId(); 1418 if (iconId != null) 1419 action.setImageDescriptor(HelpUIResources 1420 .getImageDescriptor(iconId)); 1421 manager.add(action); 1422 page.pageAction = action; 1423 } 1424 findPage(String id)1425 private HelpPartPage findPage(String id) { 1426 for (int i = 0; i < pages.size(); i++) { 1427 HelpPartPage page = (HelpPartPage) pages.get(i); 1428 if (page.getId().equals(id)) { 1429 return page; 1430 } 1431 } 1432 return null; 1433 } 1434 fillSelectionProviderMenu(ISelectionProvider provider, IMenuManager manager, boolean addBookmarks)1435 boolean fillSelectionProviderMenu(ISelectionProvider provider, 1436 IMenuManager manager, boolean addBookmarks) { 1437 boolean value = fillOpenActions(provider, manager); 1438 if (value && addBookmarks) { 1439 manager.add(new Separator()); 1440 bookmarkAction.setTarget(provider); 1441 manager.add(bookmarkAction); 1442 } 1443 return true; 1444 } 1445 fillOpenActions(Object target, IMenuManager manager)1446 private boolean fillOpenActions(Object target, IMenuManager manager) { 1447 String href = getHref(target); 1448 if (href != null && !href.startsWith("__")) { //$NON-NLS-1$ 1449 openAction.setTarget(target); 1450 manager.add(openAction); 1451 if (!href.startsWith("nw:") && !href.startsWith("open:")) { //$NON-NLS-1$ //$NON-NLS-2$ 1452 openInHelpAction.setTarget(target); 1453 manager.add(openInHelpAction); 1454 } 1455 return true; 1456 } 1457 return false; 1458 } 1459 hookFormText(FormText text)1460 void hookFormText(FormText text) { 1461 copyAction.hook(text); 1462 } 1463 unhookFormText(FormText text)1464 void unhookFormText(FormText text) { 1465 copyAction.unhook(text); 1466 } 1467 fillFormContextMenu(FormText text, IMenuManager manager)1468 boolean fillFormContextMenu(FormText text, IMenuManager manager) { 1469 if (fillOpenActions(text, manager)) 1470 manager.add(new Separator()); 1471 manager.add(copyAction); 1472 copyAction.setTarget(text); 1473 if (text.getSelectedLinkHref() != null) { 1474 manager.add(new Separator()); 1475 manager.add(bookmarkAction); 1476 bookmarkAction.setTarget(getResource(text)); 1477 } 1478 return true; 1479 } 1480 getCopyAction()1481 IAction getCopyAction() { 1482 return copyAction; 1483 } 1484 getHref(Object target)1485 private String getHref(Object target) { 1486 if (target instanceof ISelectionProvider) { 1487 ISelectionProvider provider = (ISelectionProvider) target; 1488 IStructuredSelection ssel = (IStructuredSelection) provider 1489 .getSelection(); 1490 Object obj = ssel.getFirstElement(); 1491 if (obj instanceof IToc) 1492 return null; 1493 if (obj instanceof IHelpResource) { 1494 IHelpResource res = (IHelpResource) obj; 1495 return res.getHref(); 1496 } 1497 if (obj instanceof IIndexEntry) { 1498 /* 1499 * if index entry has single topic 1500 * it represents the topic by itself 1501 */ 1502 IHelpResource[] topics = ((IIndexEntry) obj).getTopics(); 1503 if (topics.length == 1) 1504 return topics[0].getHref(); 1505 return null; 1506 } 1507 } else if (target instanceof FormText) { 1508 FormText text = (FormText) target; 1509 Object href = text.getSelectedLinkHref(); 1510 if (href != null) 1511 return href.toString(); 1512 } 1513 return null; 1514 } 1515 getResource(Object target)1516 private IHelpResource getResource(Object target) { 1517 if (target instanceof ISelectionProvider) { 1518 ISelectionProvider provider = (ISelectionProvider) target; 1519 IStructuredSelection ssel = (IStructuredSelection) provider 1520 .getSelection(); 1521 Object obj = ssel.getFirstElement(); 1522 if (obj instanceof ITopic) { 1523 return (ITopic) obj; 1524 } else if (obj instanceof IIndexEntry) { 1525 /* 1526 * if index entry has single topic 1527 * it represents the topic by itself 1528 */ 1529 IIndexEntry entry = (IIndexEntry) obj; 1530 IHelpResource[] topics = entry.getTopics(); 1531 if (topics.length == 1) { 1532 final String href = topics[0].getHref(); 1533 final String label = entry.getKeyword(); 1534 return new IHelpResource() { 1535 1536 @Override 1537 public String getHref() { 1538 return href; 1539 } 1540 1541 @Override 1542 public String getLabel() { 1543 return label; 1544 } 1545 }; 1546 } 1547 return null; 1548 } else if (obj instanceof IHelpResource) { 1549 return (IHelpResource) obj; 1550 } 1551 } else if (target instanceof FormText) { 1552 FormText text = (FormText) target; 1553 String rawHref = text.getSelectedLinkHref().toString(); 1554 final String href = rawHref.startsWith("open") ? rawHref : //$NON-NLS-1$ 1555 LinkUtil.stripParams(text.getSelectedLinkHref().toString()); 1556 final String label = text.getSelectedLinkText(); 1557 if (href != null) { 1558 return new IHelpResource() { 1559 1560 @Override 1561 public String getHref() { 1562 return href; 1563 } 1564 1565 @Override 1566 public String getLabel() { 1567 return label; 1568 } 1569 }; 1570 } 1571 } 1572 return null; 1573 } 1574 1575 private void doBookmark(Object target) { 1576 IHelpResource res = null; 1577 if (target instanceof IHelpResource) { 1578 res = (IHelpResource)target; 1579 } 1580 else { 1581 res = getResource(target); 1582 } 1583 if (res != null) { 1584 BaseHelpSystem.getBookmarkManager().addBookmark(res.getHref(), 1585 res.getLabel()); 1586 } 1587 } 1588 1589 /* 1590 * private void doOpen(Object target) { String href = getHref(target); if 1591 * (href != null) showURL(href, getShowDocumentsInPlace()); } 1592 */ 1593 1594 private void doOpen(Object target, boolean replace) { 1595 String href = getHref(target); 1596 if (href != null) 1597 showURL(href, replace); 1598 } 1599 1600 private void doOpenInHelp(Object target) { 1601 String href = getHref(target); 1602 if (href != null) 1603 // WorkbenchHelp.displayHelpResource(href); 1604 showURL(href, false); 1605 } 1606 1607 /** 1608 * @return Returns the statusLineManager. 1609 */ 1610 public IStatusLineManager getStatusLineManager() { 1611 return statusLineManager; 1612 } 1613 1614 /** 1615 * @return Returns the showDocumentsInPlace. 1616 */ 1617 public boolean getShowDocumentsInPlace() { 1618 return showDocumentsInPlace; 1619 } 1620 1621 /** 1622 * @param showDocumentsInPlace 1623 * The showDocumentsInPlace to set. 1624 */ 1625 public void setShowDocumentsInPlace(boolean showDocumentsInPlace) { 1626 this.showDocumentsInPlace = showDocumentsInPlace; 1627 } 1628 1629 /** 1630 * @return Returns the style. 1631 */ 1632 public int getStyle() { 1633 return style; 1634 } 1635 1636 public int getNumberOfInPlaceHits() { 1637 return numberOfInPlaceHits; 1638 } 1639 1640 public void setNumberOfInPlaceHits(int numberOfInPlaceHits) { 1641 this.numberOfInPlaceHits = numberOfInPlaceHits; 1642 } 1643 1644 void handleLinkEntered(HyperlinkEvent e) { 1645 IStatusLineManager mng = getRoot(getStatusLineManager()); 1646 if (mng != null) { 1647 String label = e.getLabel(); 1648 String href = (String) e.getHref(); 1649 if (href != null && href.startsWith("__")) //$NON-NLS-1$ 1650 href = null; 1651 if (href != null) { 1652 try { 1653 href = URLDecoder.decode(href, "UTF-8"); //$NON-NLS-1$ 1654 } catch (UnsupportedEncodingException ex) { 1655 } 1656 // Next line unnecessary following fix for Bug 78746 1657 //href = href.replaceAll("&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$ 1658 } 1659 if (label != null && href != null) { 1660 String message = NLS.bind(Messages.ReusableHelpPart_status, 1661 label, href); 1662 mng.setMessage(message); 1663 } else if (label != null) 1664 mng.setMessage(label); 1665 else 1666 mng.setMessage(href); 1667 } 1668 } 1669 1670 private IStatusLineManager getRoot(IStatusLineManager mng) { 1671 while (mng != null) { 1672 if (mng instanceof SubStatusLineManager) { 1673 SubStatusLineManager smng = (SubStatusLineManager) mng; 1674 IContributionManager parent = smng.getParent(); 1675 if (parent == null) 1676 return smng; 1677 if (!(parent instanceof IStatusLineManager)) 1678 return smng; 1679 mng = (IStatusLineManager) parent; 1680 } else 1681 break; 1682 } 1683 return mng; 1684 } 1685 1686 void handleLinkExited(HyperlinkEvent e) { 1687 IStatusLineManager mng = getRoot(getStatusLineManager()); 1688 if (mng != null) 1689 mng.setMessage(null); 1690 } 1691 1692 1693 1694 private void toggleShowAll(boolean checked) { 1695 if (checked) { 1696 IPreferenceStore store = HelpUIPlugin.getDefault() 1697 .getPreferenceStore(); 1698 String value = store.getString(PROMPT_KEY); 1699 if (value.length() == 0) { 1700 MessageDialogWithToggle dialog = MessageDialogWithToggle 1701 .openOkCancelConfirm(null, 1702 Messages.AskShowAll_dialogTitle, 1703 getShowAllMessage(), 1704 Messages.AskShowAll_toggleMessage, false, 1705 store, PROMPT_KEY); 1706 if (dialog.getReturnCode() != MessageDialogWithToggle.OK) { 1707 showAllAction.setChecked(false); 1708 return; 1709 } 1710 } 1711 } 1712 HelpBasePlugin.getActivitySupport().setFilteringEnabled(!checked); 1713 for (int i = 0; i < pages.size(); i++) { 1714 HelpPartPage page = (HelpPartPage) pages.get(i); 1715 page.toggleRoleFilter(); 1716 } 1717 } 1718 1719 public void saveState(IMemento memento) { 1720 for (int i = 0; i < pages.size(); i++) { 1721 HelpPartPage page = (HelpPartPage) pages.get(i); 1722 page.saveState(memento); 1723 } 1724 } 1725 1726 private String getShowAllMessage() { 1727 String message = HelpBasePlugin.getActivitySupport() 1728 .getShowAllMessage(); 1729 if (message == null) 1730 return Messages.AskShowAll_message; 1731 StringBuilder buff = new StringBuilder(); 1732 int state = STATE_START; 1733 1734 for (int i = 0; i < message.length(); i++) { 1735 char c = message.charAt(i); 1736 switch (state) { 1737 case STATE_START: 1738 if (c == '<') 1739 state = STATE_LT; 1740 else 1741 buff.append(c); 1742 break; 1743 case STATE_LT: 1744 if (c == 'b' || c == 'B') 1745 state = STATE_LT_B; 1746 break; 1747 case STATE_LT_B: 1748 if (c == 'r' || c == 'R') 1749 state = STATE_LT_BR; 1750 break; 1751 case STATE_LT_BR: 1752 if (c == '>') { 1753 buff.append('\n'); 1754 } 1755 state = STATE_START; 1756 break; 1757 default: 1758 buff.append(c); 1759 } 1760 } 1761 return buff.toString(); 1762 } 1763 1764 EngineDescriptorManager getEngineManager() { 1765 if (engineManager==null) { 1766 engineManager = new EngineDescriptorManager(); 1767 } 1768 return engineManager; 1769 } 1770 1771 static public int getDefaultStyle() { 1772 int style = ALL_TOPICS | CONTEXT_HELP | SEARCH; 1773 if (ProductPreferences.getBoolean(HelpBasePlugin.getDefault(), "indexView")) { //$NON-NLS-1$ 1774 style |= INDEX; 1775 } 1776 if (ProductPreferences.getBoolean(HelpBasePlugin.getDefault(), "bookmarksView")) { //$NON-NLS-1$ 1777 style |= BOOKMARKS; 1778 } 1779 return style; 1780 } 1781 1782 public void checkRemoteStatus() { 1783 clearBrowser(); 1784 showURL("/org.eclipse.help.webapp/" + MissingContentManager.REMOTE_STATUS_HELP_VIEW_HREF); //$NON-NLS-1$ 1785 updateStatusLinks(); 1786 } 1787 1788 public void checkPlaceholderStatus() { 1789 clearBrowser(); 1790 showURL("/org.eclipse.help.webapp/" + MissingContentManager.MISSING_BOOKS_HELP_VIEW_HREF); //$NON-NLS-1$ 1791 updateStatusLinks(); 1792 1793 } 1794 1795 private void clearBrowser() { 1796 IHelpPart part = findPart(HV_BROWSER); 1797 if ( part == null ) { 1798 return; 1799 } 1800 BrowserPart browserPart = (BrowserPart) part; 1801 browserPart.clearBrowser(); 1802 } 1803 1804 private void updateStatusLinks() { 1805 IHelpPart part = findPart(HV_MISSING_CONTENT); 1806 if ( part == null ) { 1807 return; 1808 } 1809 MissingContentPart mcPart = (MissingContentPart) part; 1810 mcPart.updateStatus(); 1811 } 1812 } 1813 1814