1 11 12 package org.eclipse.help.ui.internal.search; 13 14 import java.io.BufferedReader ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.io.InputStreamReader ; 18 import java.io.Reader ; 19 import java.net.MalformedURLException ; 20 import java.net.URL ; 21 import java.net.URLConnection ; 22 import java.util.ArrayList ; 23 import java.util.StringTokenizer ; 24 25 import javax.xml.parsers.DocumentBuilder ; 26 import javax.xml.parsers.DocumentBuilderFactory ; 27 import javax.xml.parsers.ParserConfigurationException ; 28 29 import org.eclipse.core.expressions.IEvaluationContext; 30 import org.eclipse.core.runtime.IAdaptable; 31 import org.eclipse.help.IToc; 32 import org.eclipse.help.ITopic; 33 import org.eclipse.help.IUAElement; 34 import org.eclipse.help.internal.workingset.AdaptableHelpResource; 35 import org.eclipse.help.internal.workingset.AdaptableTocsArray; 36 import org.eclipse.help.internal.workingset.WorkingSet; 37 import org.eclipse.help.ui.RootScopePage; 38 import org.eclipse.help.ui.internal.HelpUIPlugin; 39 import org.eclipse.help.ui.internal.Messages; 40 import org.eclipse.jface.preference.IPreferenceStore; 41 import org.eclipse.jface.viewers.CheckStateChangedEvent; 42 import org.eclipse.jface.viewers.CheckboxTreeViewer; 43 import org.eclipse.jface.viewers.ICheckStateListener; 44 import org.eclipse.jface.viewers.ILabelProvider; 45 import org.eclipse.jface.viewers.ITreeContentProvider; 46 import org.eclipse.jface.viewers.ITreeViewerListener; 47 import org.eclipse.jface.viewers.TreeExpansionEvent; 48 import org.eclipse.swt.SWT; 49 import org.eclipse.swt.custom.BusyIndicator; 50 import org.eclipse.swt.events.ModifyEvent; 51 import org.eclipse.swt.events.ModifyListener; 52 import org.eclipse.swt.events.SelectionAdapter; 53 import org.eclipse.swt.events.SelectionEvent; 54 import org.eclipse.swt.graphics.Font; 55 import org.eclipse.swt.layout.GridData; 56 import org.eclipse.swt.widgets.Button; 57 import org.eclipse.swt.widgets.Composite; 58 import org.eclipse.swt.widgets.Label; 59 import org.eclipse.swt.widgets.Text; 60 import org.w3c.dom.Document ; 61 import org.w3c.dom.Element ; 62 import org.w3c.dom.Node ; 63 import org.w3c.dom.NodeList ; 64 import org.xml.sax.InputSource ; 65 import org.xml.sax.SAXException ; 66 67 70 public class InfoCenterPage extends RootScopePage { 71 private Text urlText; 72 73 private Button searchAll; 74 75 private Button searchSelected; 76 77 private CheckboxTreeViewer tree; 78 79 private ITreeContentProvider treeContentProvider; 80 81 private ILabelProvider elementLabelProvider; 82 83 private AdaptableTocsArray remoteTocs; 84 85 87 private RemoteWorkingSet workingSet; 88 89 private boolean tocStale; 90 91 class RemoteWorkingSet extends WorkingSet { 92 public RemoteWorkingSet() { 93 super("InfoCenter"); } 95 96 public void load(IPreferenceStore store) { 97 String elements = store.getString(getKey(InfoCenterSearchScopeFactory.P_TOCS)); 98 StringTokenizer stok = new StringTokenizer (elements, InfoCenterSearchScopeFactory.TOC_SEPARATOR); 99 ArrayList list = new ArrayList (); 100 while (stok.hasMoreTokens()) { 101 final String url = stok.nextToken(); 102 AdaptableHelpResource res = find(url); 103 if (res != null) 104 list.add(res); 105 } 106 setElements((AdaptableHelpResource[]) list 107 .toArray(new AdaptableHelpResource[list.size()])); 108 } 109 110 private AdaptableHelpResource find(String url) { 111 if (remoteTocs == null) 112 return null; 113 IAdaptable[] children = remoteTocs.getChildren(); 114 for (int i = 0; i < children.length; i++) { 115 IAdaptable child = children[i]; 116 if (child instanceof AdaptableHelpResource) { 117 AdaptableHelpResource res = (AdaptableHelpResource) child; 118 if (res.getHref().equals(url)) 119 return res; 120 } 121 } 122 return null; 123 } 124 125 public void store(IPreferenceStore store) { 126 StringBuffer buf = new StringBuffer (); 127 AdaptableHelpResource[] elements = getElements(); 128 129 for (int i = 0; i < elements.length; i++) { 130 if (i > 0) 131 buf.append(InfoCenterSearchScopeFactory.TOC_SEPARATOR); 132 buf.append(elements[i].getHref()); 133 } 134 store.setValue(getKey(InfoCenterSearchScopeFactory.P_TOCS), buf.toString()); 135 } 136 } 137 138 141 public InfoCenterPage() { 142 } 144 145 150 protected int createScopeContents(Composite parent) { 151 Font font = parent.getFont(); 152 initializeDialogUnits(parent); 153 154 Label label = new Label(parent, SWT.NULL); 155 label.setText(Messages.InfoCenterPage_url); 156 157 urlText = new Text(parent, SWT.BORDER); 158 urlText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 159 urlText.setEditable(getEngineDescriptor().isUserDefined()); 160 161 searchAll = new Button(parent, SWT.RADIO); 162 searchAll.setText(Messages.selectAll); 163 GridData gd = new GridData(); 164 gd.horizontalSpan = 2; 165 searchAll.setLayoutData(gd); 166 searchAll.addSelectionListener(new SelectionAdapter() { 167 public void widgetSelected(SelectionEvent e) { 168 if (searchAll.getSelection()) 169 tree.getTree().setEnabled(false); 170 } 171 }); 172 173 searchSelected = new Button(parent, SWT.RADIO); 174 searchSelected.setText(Messages.selectWorkingSet); 175 gd = new GridData(); 176 gd.horizontalSpan = 2; 177 searchSelected.setLayoutData(gd); 178 searchSelected.addSelectionListener(new SelectionAdapter() { 179 public void widgetSelected(SelectionEvent e) { 180 if (searchSelected.getSelection()) { 181 tree.getTree().setEnabled(true); 182 if (tocStale) 183 updateTocs(); 184 } 185 } 186 }); 187 188 label = new Label(parent, SWT.WRAP); 189 label.setFont(font); 190 label.setText(Messages.WorkingSetContent); 191 gd = new GridData(GridData.GRAB_HORIZONTAL 192 | GridData.HORIZONTAL_ALIGN_FILL 193 | GridData.VERTICAL_ALIGN_CENTER); 194 gd.horizontalSpan = 2; 195 label.setLayoutData(gd); 196 197 tree = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.H_SCROLL 198 | SWT.V_SCROLL); 199 gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); 200 gd.heightHint = convertHeightInCharsToPixels(15); 201 gd.horizontalSpan = 2; 202 tree.getControl().setLayoutData(gd); 203 tree.getControl().setFont(font); 204 205 treeContentProvider = new HelpWorkingSetTreeContentProvider(); 206 tree.setContentProvider(treeContentProvider); 207 208 elementLabelProvider = new HelpWorkingSetElementLabelProvider(); 209 tree.setLabelProvider(elementLabelProvider); 210 211 tree.setUseHashlookup(true); 212 213 initializeControls(); 214 215 tree.addCheckStateListener(new ICheckStateListener() { 216 public void checkStateChanged(CheckStateChangedEvent event) { 217 handleCheckStateChange(event); 218 } 219 }); 220 221 tree.addTreeListener(new ITreeViewerListener() { 222 public void treeCollapsed(TreeExpansionEvent event) { 223 } 224 225 public void treeExpanded(TreeExpansionEvent event) { 226 final Object element = event.getElement(); 227 if (tree.getGrayed(element) == false) 228 BusyIndicator.showWhile(getShell().getDisplay(), 229 new Runnable () { 230 public void run() { 231 setSubtreeChecked(element, tree 232 .getChecked(element), false); 233 } 234 }); 235 } 236 }); 237 238 applyDialogFont(parent); 239 240 return 2; 243 } 244 245 private void loadTocs(String urlName) { 246 InputStream is = null; 247 if (urlName==null || urlName.length()==0) { 248 resetRemoteTocs(); 249 return; 250 } 251 try { 252 URL url = new URL (urlName); 253 url = new URL (url, "toc/"); URLConnection connection = url.openConnection(); 255 is = connection.getInputStream(); 256 BufferedReader reader = new BufferedReader (new InputStreamReader ( 257 is, "utf-8")); load(reader); 259 reader.close(); 260 } catch (MalformedURLException e) { 261 HelpUIPlugin.logError(Messages.InfoCenterPage_invalidURL, e, false, true); 262 resetRemoteTocs(); 263 } catch (IOException e) { 264 HelpUIPlugin.logError(Messages.InfoCenterPage_tocError, e, false, true); 265 resetRemoteTocs(); 266 } finally { 267 if (is != null) { 268 try { 269 is.close(); 270 } catch (IOException e) { 271 } 272 } 273 } 274 } 275 276 private void resetRemoteTocs() { 277 remoteTocs = new AdaptableTocsArray(new IToc[0]); 278 } 279 280 private void load(Reader r) { 281 Document document = null; 282 try { 283 DocumentBuilder parser = DocumentBuilderFactory.newInstance() 284 .newDocumentBuilder(); 285 document = parser.parse(new InputSource (r)); 287 288 Node root = document.getFirstChild(); 290 while (root.getNodeType() == Node.COMMENT_NODE) { 291 document.removeChild(root); 292 root = document.getFirstChild(); 293 } 294 load(document, (Element) root); 295 } catch (ParserConfigurationException e) { 296 } catch (IOException e) { 298 } catch (SAXException e) { 300 } 302 } 303 304 private void load(Document doc, Element root) { 305 ArrayList list = new ArrayList (); 306 NodeList engines = root.getElementsByTagName("toc"); for (int i = 0; i < engines.getLength(); i++) { 308 final Node node = engines.item(i); 309 IToc toc = new IToc() { 310 public ITopic[] getTopics() { 311 return new ITopic[0]; 312 } 313 public ITopic getTopic(String href) { 314 return null; 315 } 316 public String getHref() { 317 return node.getAttributes().getNamedItem("href") .getNodeValue(); 319 } 320 public String getLabel() { 321 return node.getAttributes().getNamedItem("label") .getNodeValue(); 323 } 324 public IUAElement[] getChildren() { 325 return new IUAElement[0]; 326 } 327 public boolean isEnabled(IEvaluationContext context) { 328 return true; 329 } 330 }; 331 list.add(toc); 332 } 333 IToc[] tocs = (IToc[]) list.toArray(new IToc[list.size()]); 334 remoteTocs = new AdaptableTocsArray(tocs); 335 } 336 337 private void initializeControls() { 338 IPreferenceStore store = getPreferenceStore(); 339 String url = store 340 .getString(getKey(InfoCenterSearchScopeFactory.P_URL)); 341 if (url.length() == 0) { 342 url = (String ) getEngineDescriptor().getParameters().get( 343 InfoCenterSearchScopeFactory.P_URL); 344 if (url == null) 345 url = ""; } 347 urlText.setText(url); 348 busyLoadTocs(url); 349 workingSet = new RemoteWorkingSet(); 350 workingSet.load(store); 351 urlText.addModifyListener(new ModifyListener() { 352 public void modifyText(ModifyEvent e) { 353 tocStale=true; 354 } 355 }); 356 tree.setInput(remoteTocs); 357 boolean selected = store 358 .getBoolean(getKey(InfoCenterSearchScopeFactory.P_SEARCH_SELECTED)); 359 searchAll.setSelection(!selected); 360 searchSelected.setSelection(selected); 361 tree.getTree().setEnabled(selected); 362 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable () { 363 public void run() { 364 Object [] elements = workingSet.getElements(); 365 tree.setCheckedElements(elements); 366 for (int i = 0; i < elements.length; i++) { 367 Object element = elements[i]; 368 if (isExpandable(element)) 369 setSubtreeChecked(element, true, true); 370 updateParentState(element, true); 371 } 372 } 373 }); 374 } 375 376 private void updateTocs() { 377 String url = urlText.getText(); 378 busyLoadTocs(url); 379 tocStale=false; 380 tree.setInput(remoteTocs); 381 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable () { 382 public void run() { 383 Object [] elements = workingSet.getElements(); 384 tree.setCheckedElements(elements); 385 for (int i = 0; i < elements.length; i++) { 386 Object element = elements[i]; 387 if (isExpandable(element)) 388 setSubtreeChecked(element, true, true); 389 updateParentState(element, true); 390 } 391 } 392 }); 393 } 394 395 private void busyLoadTocs(final String url) { 396 BusyIndicator.showWhile(urlText.getDisplay(), new Runnable () { 397 public void run() { 398 loadTocs(url); 399 } 400 }); 401 } 402 403 boolean isExpandable(Object element) { 404 return treeContentProvider.hasChildren(element); 405 } 406 407 void updateParentState(Object child, boolean baseChildState) { 408 if (child == null) 409 return; 410 411 Object parent = treeContentProvider.getParent(child); 412 if (parent == null) 413 return; 414 415 boolean allSameState = true; 416 Object [] children = null; 417 children = treeContentProvider.getChildren(parent); 418 419 for (int i = children.length - 1; i >= 0; i--) { 420 if (tree.getChecked(children[i]) != baseChildState 421 || tree.getGrayed(children[i])) { 422 allSameState = false; 423 break; 424 } 425 } 426 427 tree.setGrayed(parent, !allSameState); 428 tree.setChecked(parent, !allSameState || baseChildState); 429 430 updateParentState(parent, baseChildState); 431 } 432 433 void setSubtreeChecked(Object parent, boolean state, 434 boolean checkExpandedState) { 435 436 Object [] children = treeContentProvider.getChildren(parent); 437 for (int i = children.length - 1; i >= 0; i--) { 438 Object element = children[i]; 439 if (state) { 440 tree.setChecked(element, true); 441 tree.setGrayed(element, false); 442 } else 443 tree.setGrayChecked(element, false); 444 if (isExpandable(element)) 445 setSubtreeChecked(element, state, checkExpandedState); 446 } 447 } 448 449 private void findCheckedElements(java.util.List checkedResources, 450 Object parent) { 451 Object [] children = treeContentProvider.getChildren(parent); 452 for (int i = 0; i < children.length; i++) { 453 if (tree.getGrayed(children[i])) 454 findCheckedElements(checkedResources, children[i]); 455 else if (tree.getChecked(children[i])) 456 checkedResources.add(children[i]); 457 } 458 } 459 460 void handleCheckStateChange(final CheckStateChangedEvent event) { 461 BusyIndicator.showWhile(getShell().getDisplay(), new Runnable () { 462 public void run() { 463 Object element = event.getElement(); 464 boolean state = event.getChecked(); 465 tree.setGrayed(element, false); 466 if (isExpandable(element)) 467 setSubtreeChecked(element, state, state); 468 470 updateParentState(element, state); 471 } 473 }); 474 } 475 476 public void updateWorkingSet() { 477 ArrayList elements = new ArrayList (10); 478 findCheckedElements(elements, tree.getInput()); 479 workingSet.setElements((AdaptableHelpResource[]) elements 480 .toArray(new AdaptableHelpResource[elements.size()])); 481 } 482 483 488 public boolean performOk() { 489 IPreferenceStore store = getPreferenceStore(); 490 if (getEngineDescriptor().isUserDefined()) 491 store.setValue(getKey(InfoCenterSearchScopeFactory.P_URL), urlText 492 .getText()); 493 updateWorkingSet(); 494 workingSet.store(store); 495 store.setValue(getKey(InfoCenterSearchScopeFactory.P_SEARCH_SELECTED), 496 searchSelected.getSelection()); 497 return super.performOk(); 498 } 499 500 private String getKey(String key) { 501 return getEngineDescriptor().getId() + "." + key; } 503 } 504 | Popular Tags |