1 11 package org.eclipse.help.ui.internal.views; 12 13 import java.util.List ; 14 15 import org.eclipse.core.runtime.IProgressMonitor; 16 import org.eclipse.core.runtime.IStatus; 17 import org.eclipse.core.runtime.OperationCanceledException; 18 import org.eclipse.core.runtime.Platform; 19 import org.eclipse.core.runtime.Status; 20 import org.eclipse.core.runtime.jobs.IJobChangeEvent; 21 import org.eclipse.core.runtime.jobs.IJobChangeListener; 22 import org.eclipse.core.runtime.jobs.Job; 23 import org.eclipse.help.IContext; 24 import org.eclipse.help.IHelpResource; 25 import org.eclipse.help.internal.base.BaseHelpSystem; 26 import org.eclipse.help.internal.base.HelpBasePlugin; 27 import org.eclipse.help.internal.search.SearchHit; 28 import org.eclipse.help.internal.search.SearchQuery; 29 import org.eclipse.help.internal.search.SearchResults; 30 import org.eclipse.help.internal.search.federated.IndexerJob; 31 import org.eclipse.help.search.ISearchEngineResult2; 32 import org.eclipse.help.ui.internal.HelpUIResources; 33 import org.eclipse.help.ui.internal.IHelpUIConstants; 34 import org.eclipse.help.ui.internal.Messages; 35 import org.eclipse.jface.action.IAction; 36 import org.eclipse.jface.action.IMenuManager; 37 import org.eclipse.swt.widgets.Composite; 38 import org.eclipse.swt.widgets.Control; 39 import org.eclipse.ui.IMemento; 40 import org.eclipse.ui.PlatformUI; 41 import org.eclipse.ui.actions.ActionFactory; 42 import org.eclipse.ui.forms.IFormColors; 43 import org.eclipse.ui.forms.SectionPart; 44 import org.eclipse.ui.forms.events.ExpansionEvent; 45 import org.eclipse.ui.forms.events.HyperlinkEvent; 46 import org.eclipse.ui.forms.events.IExpansionListener; 47 import org.eclipse.ui.forms.events.IHyperlinkListener; 48 import org.eclipse.ui.forms.widgets.FormText; 49 import org.eclipse.ui.forms.widgets.FormToolkit; 50 import org.eclipse.ui.forms.widgets.Section; 51 52 public class DynamicHelpPart extends SectionPart implements IHelpPart { 53 private static final String CANCEL_HREF = "__cancel__"; 55 private static final String MORE_HREF = "__more__"; 57 private ReusableHelpPart parent; 58 59 private FormText searchResults; 60 61 private SorterByScore resultSorter; 62 63 private String id; 64 65 private String phrase; 66 67 private Job runningJob; 68 private IContext context; 69 70 private JobListener jobListener; 71 public static final int SHORT_COUNT = 8; 72 73 class JobListener implements IJobChangeListener { 74 public void aboutToRun(IJobChangeEvent event) { 75 } 76 77 public void awake(IJobChangeEvent event) { 78 } 79 80 public void done(IJobChangeEvent event) { 81 if (event.getJob() == runningJob) { 82 runningJob = null; 83 } 84 } 85 86 public void running(IJobChangeEvent event) { 87 } 88 89 public void scheduled(IJobChangeEvent event) { 90 } 91 92 public void sleeping(IJobChangeEvent event) { 93 } 94 } 95 96 101 public DynamicHelpPart(Composite parent, FormToolkit toolkit) { 102 super(parent, toolkit, Section.EXPANDED | Section.TWISTIE 103 | Section.TITLE_BAR); 104 Section section = getSection(); 106 section.setText(Messages.SearchPart_title); 107 section.marginWidth = 5; 108 section.addExpansionListener(new IExpansionListener() { 109 public void expansionStateChanging(ExpansionEvent e) { 110 } 111 public void expansionStateChanged(ExpansionEvent e) { 112 if (e.getState()) { 113 refilter(); 114 } 115 } 116 }); 117 133 resultSorter = new SorterByScore(); 134 searchResults = toolkit.createFormText(section, false); 135 section.setClient(searchResults); 136 searchResults.setColor(IFormColors.TITLE, toolkit.getColors().getColor( 137 IFormColors.TITLE)); 138 String topicKey = IHelpUIConstants.IMAGE_FILE_F1TOPIC; 139 String nwKey = IHelpUIConstants.IMAGE_NW; 140 String searchKey = IHelpUIConstants.IMAGE_HELP_SEARCH; 141 searchResults.setImage(topicKey, HelpUIResources.getImage(topicKey)); 142 searchResults.setImage(nwKey, HelpUIResources.getImage(nwKey)); 143 searchResults.setImage(searchKey, HelpUIResources.getImage(searchKey)); 144 searchResults.addHyperlinkListener(new IHyperlinkListener() { 145 public void linkActivated(HyperlinkEvent e) { 146 Object href = e.getHref(); 147 if (href.equals(CANCEL_HREF)) { 148 if (runningJob != null) { 149 runningJob.cancel(); 150 runningJob = null; 151 } 152 clearResults(); 153 } else if (href.equals(MORE_HREF)) { 154 doMore(); 155 } else 156 doOpenLink(e.getHref()); 157 } 158 public void linkEntered(HyperlinkEvent e) { 159 DynamicHelpPart.this.parent.handleLinkEntered(e); 160 } 161 public void linkExited(HyperlinkEvent e) { 162 DynamicHelpPart.this.parent.handleLinkExited(e); 163 } 164 }); 165 searchResults.setText("", false, false); jobListener = new JobListener(); 167 Job.getJobManager().addJobChangeListener(jobListener); 168 } 169 170 public void dispose() { 171 Job.getJobManager().removeJobChangeListener(jobListener); 172 stop(); 173 super.dispose(); 174 } 175 176 public void setFocus() { 177 if (searchResults!=null) 178 searchResults.setFocus(); 179 } 180 181 public void stop () { 182 if (runningJob!=null) { 183 runningJob.cancel(); 184 runningJob=null; 185 } 186 } 187 188 193 public Control getControl() { 194 return getSection(); 195 } 196 197 202 public void init(ReusableHelpPart parent, String id, IMemento memento) { 203 this.parent = parent; 204 this.id = id; 205 parent.hookFormText(searchResults); 206 } 207 208 public String getId() { 209 return id; 210 } 211 212 217 public void setVisible(boolean visible) { 218 getSection().setVisible(visible); 219 } 220 221 void clearResults() { 222 if (runningJob != null) { 223 runningJob.cancel(); 224 runningJob = null; 225 } 226 searchResults.setText("", false, false); getManagedForm().reflow(true); 228 } 229 230 public void startSearch(String newPhrase, IContext excludeContext) { 231 if (phrase!=null && phrase.equals(newPhrase)) 232 return; 233 this.phrase = newPhrase; 234 this.context = excludeContext; 235 if (getSection().isExpanded()) 236 startInPlaceSearch(phrase, excludeContext); 237 } 238 239 private void startInPlaceSearch(final String phrase, 240 final IContext excludeContext) { 241 Job job = new Job(Messages.SearchPart_dynamicJob) { 242 protected IStatus run(IProgressMonitor monitor) { 243 try { 244 try { 245 Job.getJobManager().join(IndexerJob.FAMILY, 246 monitor); 247 } catch (InterruptedException e) { 248 } 250 performSearch(phrase, excludeContext, monitor); 251 return Status.OK_STATUS; 252 } catch (OperationCanceledException e) { 253 return Status.OK_STATUS; 255 } 256 } 257 }; 258 job.setSystem(true); 259 scheduleSearch(job); 260 } 261 262 private void performSearch(String phrase, IContext excludeContext, 263 IProgressMonitor monitor) { 264 SearchQuery searchQuery = new SearchQuery(); 265 searchQuery.setSearchWord(phrase); 266 SearchResults localResults = new SearchResults(null, 267 DynamicHelpPart.SHORT_COUNT * 2, Platform.getNL()) { 268 public void addHits(List hits, String highlightTerms) { 269 super.addHits(hits, ""); } 272 }; 273 BaseHelpSystem.getSearchManager().search(searchQuery, localResults, 274 monitor); 275 SearchHit[] hits = localResults.getSearchHits(); 276 updateResults(phrase, excludeContext, new StringBuffer (), hits); 277 } 278 279 void scheduleSearch(Job job) { 280 if (runningJob != null) { 281 runningJob.cancel(); 282 } 283 StringBuffer buff = new StringBuffer (); 284 buff.append("<form>"); buff.append("<p><span color=\""); buff.append(IFormColors.TITLE); 287 buff.append("\">"); buff.append(Messages.SearchResultsPart_progress); 289 buff.append("</span>"); buff.append("<a HREF=\""); buff.append(CANCEL_HREF); 292 buff.append("\">"); buff.append(Messages.SearchResultsPart_cancel); 294 buff.append("</a></p>"); buff.append("</form>"); searchResults.setText(buff.toString(), true, false); 297 getManagedForm().reflow(true); 298 runningJob = job; 299 job.schedule(); 300 } 301 302 private void updateResults(final String phrase, 303 final IContext excludeContext, final StringBuffer buffer, 304 final SearchHit[] hits) { 305 if (getSection().isDisposed()) 306 return; 307 getSection().getDisplay().asyncExec(new Runnable () { 308 public void run() { 309 doUpdateResults(phrase, excludeContext, buffer, hits); 310 } 311 }); 312 } 313 314 private void doUpdateResults(String phrase, IContext excludeContext, StringBuffer buff, SearchHit[] hits) { 315 if (runningJob != null) { 316 runningJob.cancel(); 317 } 318 this.phrase = phrase; 319 buff.delete(0, buff.length()); 320 if (hits.length > 0) { 321 buff.append("<form>"); buff.append("<p><span color=\""); buff.append(IFormColors.TITLE); 324 buff.append("\">"); buff.append(Messages.SearchResultsPart_label); 326 buff.append("</span></p>"); resultSorter.sort(null, hits); 328 IHelpResource [] excludedTopics = excludeContext!=null?excludeContext.getRelatedTopics():null; 329 330 for (int i = 0; i < hits.length; i++) { 331 SearchHit hit = hits[i]; 332 if (isExcluded(hit.getHref(), excludedTopics)) 333 continue; 334 if (i==SHORT_COUNT) 335 break; 336 buff.append("<li indent=\"21\" style=\"image\" value=\""); buff.append(IHelpUIConstants.IMAGE_FILE_F1TOPIC); 338 buff.append("\">"); buff.append("<a HREF=\""); String href = hit.getHref(); 341 if (hit instanceof ISearchEngineResult2) { 342 ISearchEngineResult2 hit2 = (ISearchEngineResult2)hit; 343 if (((ISearchEngineResult2)hit).canOpen()) { 344 href = "open:" + IHelpUIConstants.INTERNAL_HELP_ID + "?id=" + hit2.getId(); } 346 } 347 buff.append(href); 348 buff.append("\""); if (hit.getToc()!=null && !Platform.getWS().equals(Platform.WS_GTK)) { 350 buff.append(" alt=\""); buff.append(parent.escapeSpecialChars(hit.getToc().getLabel())); 352 buff.append("\""); } 354 buff.append(">"); buff.append(parent.escapeSpecialChars(hit.getLabel())); 356 buff.append("</a>"); buff.append("</li>"); } 359 if (hits.length > 0) { 360 buff.append("<p><img HREF=\""); buff.append(IHelpUIConstants.IMAGE_HELP_SEARCH); 362 buff.append("\"/>"); buff.append(" <a HREF=\""); buff.append(MORE_HREF); 365 buff.append("\">"); buff.append(Messages.SearchResultsPart_moreResults); 367 buff.append("</a></p>"); } 369 buff.append("</form>"); if (!searchResults.isDisposed()) 371 searchResults.setText(buff.toString(), true, false); 372 } else 373 if (!searchResults.isDisposed()) 374 searchResults.setText("", false, false); if (!searchResults.isDisposed()) 376 getManagedForm().reflow(true); 377 } 378 379 private boolean isExcluded(String href, IHelpResource [] excludedTopics) { 380 if (excludedTopics==null) return false; 381 for (int i=0; i<excludedTopics.length; i++) { 382 if (href.startsWith(excludedTopics[i].getHref())) 383 return true; 384 if (parent.isFilteredByRoles()) { 385 if (!HelpBasePlugin.getActivitySupport().isEnabled(href)) 386 return true; 387 } 388 } 389 return false; 390 } 391 392 private void doMore() { 393 parent.startSearch(phrase); 394 } 395 396 private void doOpenLink(Object href) { 397 String url = (String ) href; 398 399 if (url.startsWith("nw:")) { PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(url.substring(3)); 401 } else 402 parent.showURL(url); 403 } 404 405 410 public boolean fillContextMenu(IMenuManager manager) { 411 return parent.fillFormContextMenu(searchResults, manager); 412 } 413 414 419 public boolean hasFocusControl(Control control) { 420 return searchResults.equals(control); 421 } 422 423 public IAction getGlobalAction(String id) { 424 if (id.equals(ActionFactory.COPY.getId())) 425 return parent.getCopyAction(); 426 return null; 427 } 428 429 public void toggleRoleFilter() { 430 refilter(); 431 } 432 433 public void refilter() { 434 if (phrase!=null && phrase.length() > 0) 435 startInPlaceSearch(phrase, context); 436 } 437 438 public void saveState(IMemento memento) { 439 } 440 } 441 | Popular Tags |