source: gs3-extensions/atlas-src/trunk/src/org/greenstone/atlas/client/GS3MapLibrary.java@ 23906

Last change on this file since 23906 was 23906, checked in by sjm84, 13 years ago

Committing most recent version of ATLAS

File size: 81.8 KB
Line 
1package org.greenstone.client;
2
3import com.google.gwt.core.client.EntryPoint;
4import com.google.gwt.core.client.GWT;
5import com.google.gwt.core.client.JsArray;
6import com.google.gwt.user.client.DOM;
7import com.google.gwt.user.client.Element;
8import com.google.gwt.user.client.Window;
9import com.google.gwt.event.dom.client.ChangeEvent;
10import com.google.gwt.event.dom.client.ChangeHandler;
11import com.google.gwt.event.dom.client.ClickEvent;
12import com.google.gwt.event.dom.client.ClickHandler;
13import com.google.gwt.event.dom.client.MouseMoveEvent;
14import com.google.gwt.event.dom.client.MouseMoveHandler;
15import com.google.gwt.event.dom.client.MouseOutEvent;
16import com.google.gwt.event.dom.client.MouseOutHandler;
17import com.google.gwt.event.dom.client.MouseOverEvent;
18import com.google.gwt.event.dom.client.MouseOverHandler;
19import com.google.gwt.event.dom.client.MouseUpEvent;
20import com.google.gwt.event.dom.client.MouseUpHandler;
21import com.google.gwt.event.logical.shared.ValueChangeEvent;
22import com.google.gwt.event.logical.shared.ValueChangeHandler;
23import com.google.gwt.event.shared.HandlerRegistration;
24import com.google.gwt.http.client.Request;
25import com.google.gwt.http.client.Response;
26import com.google.gwt.http.client.RequestBuilder;
27import com.google.gwt.http.client.RequestCallback;
28import com.google.gwt.maps.client.InfoWindow;
29import com.google.gwt.maps.client.InfoWindowContent;
30import com.google.gwt.maps.client.MapWidget;
31import com.google.gwt.maps.client.control.ControlAnchor;
32import com.google.gwt.maps.client.control.ControlPosition;
33import com.google.gwt.maps.client.control.LargeMapControl;
34import com.google.gwt.maps.client.control.MapTypeControl;
35import com.google.gwt.maps.client.control.Control.CustomControl;
36import com.google.gwt.maps.client.event.MapClickHandler;
37import com.google.gwt.maps.client.event.MapMoveHandler;
38import com.google.gwt.maps.client.event.PolygonClickHandler;
39import com.google.gwt.maps.client.geocode.Geocoder;
40import com.google.gwt.maps.client.geocode.LatLngCallback;
41import com.google.gwt.maps.client.geom.LatLng;
42import com.google.gwt.maps.client.overlay.Marker;
43import com.google.gwt.maps.client.overlay.MarkerOptions;
44import com.google.gwt.maps.client.overlay.Polygon;
45import com.google.gwt.maps.client.overlay.Polyline;
46import com.google.gwt.maps.client.overlay.PolylineOptions;
47import com.google.gwt.user.client.Timer;
48import com.google.gwt.user.client.rpc.AsyncCallback;
49import com.google.gwt.user.client.rpc.ServiceDefTarget;
50import com.google.gwt.user.client.ui.Button;
51import com.google.gwt.user.client.ui.CheckBox;
52import com.google.gwt.user.client.ui.FlowPanel;
53import com.google.gwt.user.client.ui.FormPanel;
54import com.google.gwt.user.client.ui.HTML;
55import com.google.gwt.user.client.ui.Hidden;
56import com.google.gwt.user.client.ui.HorizontalPanel;
57import com.google.gwt.user.client.ui.Label;
58import com.google.gwt.user.client.ui.ListBox;
59import com.google.gwt.user.client.ui.RootPanel;
60import com.google.gwt.user.client.ui.VerticalPanel;
61import com.google.gwt.user.client.ui.Widget;
62import com.google.gwt.xml.client.NamedNodeMap;
63import com.google.gwt.dom.client.Document;
64import com.google.gwt.dom.client.FormElement;
65import com.google.gwt.dom.client.InputElement;
66import com.google.gwt.dom.client.NativeEvent;
67import com.google.gwt.dom.client.Node;
68import com.google.gwt.dom.client.NodeCollection;
69import com.google.gwt.dom.client.NodeList;
70import com.google.gwt.dom.client.OptionElement;
71import com.google.gwt.dom.client.SelectElement;
72import com.google.gwt.dom.client.TextAreaElement;
73
74import java.util.ArrayList;
75import java.util.HashMap;
76
77public class GS3MapLibrary implements EntryPoint
78{
79 protected MapWidget _map;
80
81 protected VerticalPanel _containerPanel = new VerticalPanel();
82 protected VerticalPanel _scoreAdjustPanel = new VerticalPanel();
83 protected VerticalPanel _headerDiv = new VerticalPanel();
84 protected HorizontalPanel _viewPanel = new HorizontalPanel();
85
86 protected StatusBar _statusBar = null;
87
88 protected HTML _gsPanel = new HTML();
89 protected HTML _columnViewBox = new HTML();
90
91 protected HorizontalPanel _contentDiv = new HorizontalPanel();
92 protected HorizontalPanel _footerDiv = new HorizontalPanel();
93
94 protected Menu _currentDocumentMenu = null;
95 protected Menu _lastCreatedPlaceMenu = null;
96
97 protected FlowPanel _radioPanel = new FlowPanel();
98 protected FlowPanel _checkBoxPanel = new FlowPanel();
99
100 protected Label _loadingBox = new Label("");
101 protected Label _mapLoadingLabel = new Label("Loading map content");
102
103 protected ListBox _textViewSelector = new ListBox();
104
105 protected Button _geoQueryButton = new Button("Specify Search Square");
106
107 protected Timer _loadingTimer = null;
108 protected Timer _resizeCheckTimer = null;
109 protected Timer _scrollCheckTimer = null;
110 protected Timer _placeMouseOverTimer = null;
111 protected Timer _documentMouseOverTimer = null;
112 protected Timer _menuOverTimer = null;
113 protected Timer _menuOutTimer = null;
114
115 protected Geocoder _geocoder = null;
116
117 protected static FindPlaceServiceAsync _findPlaceService = GWT.create(FindPlaceService.class);
118
119 protected ArrayList<Place> _currentPlaces = null;
120 protected ArrayList<String> _highlightedPlaces = new ArrayList<String>();
121 protected ArrayList<String> _highlightedTextPlaces = new ArrayList<String>();
122 protected ArrayList<Boolean> _visiblePlaceSets = new ArrayList<Boolean>();
123 protected ArrayList<LatLng> _areaPoints = new ArrayList<LatLng>();
124 protected ArrayList<String> _removedPlaces = new ArrayList<String>();
125
126 protected ArrayList<ArrayList<Place>> _currentMultiPlaces = null;
127
128 protected HashMap<String, Place> _chosenPlaces = new HashMap<String, Place>();
129
130 protected HandlerRegistration _fishEyeHandlerReg = null;
131 protected HandlerRegistration _columnViewHandlerReg = null;
132
133 protected MapMoveHandler _mapMoveHandler = null;
134 protected MapClickHandler _spatialSearchClickHandler = null;
135 protected SpatialSearchControls _searchControls = null;
136
137 protected final int _MAXVISIBLEMARKERS = 500;
138 protected int _currentZoomLevel = 2;
139 protected int _loadingCount = 0;
140 protected int _currentBrowserPixelWidth = 0;
141 protected int _currentBrowserPixelHeight = 0;
142 protected int _currentScrollTopValue = 0;
143
144 protected boolean _updatingMap = false;
145 protected boolean _gazetteerLoaded = false;
146 protected boolean _redraw = false;
147 protected boolean _resize = false;
148 protected boolean _mapVisible = false;
149 protected boolean _gsVisible = true;
150 protected boolean _frameLoaded = false;
151 protected boolean _initialised = false;
152 protected boolean _showAllPlaces = false;
153 protected boolean _mouseEventPause = false;
154 protected boolean _mapMoveHandlerOn = true;
155 protected boolean _searchResultsPage = false;
156
157 protected String _selectedPlaceName = "";
158 protected String _currentCollection = "";
159 protected String _currentURL = "";
160 protected final String _GREENSTONEURL = "http://taniwha.resnet.scms.waikato.ac.nz:8080/greenstone3";
161 //protected final String _GREENSTONEURL = "http://www.nzdl.org/atlasgreenstone3";
162 protected final String _GREENSTONEDEVURL = _GREENSTONEURL + "/dev";
163
164 protected com.google.gwt.xml.client.Document _currentNewPageDoc;
165
166 /**
167 * GWT module entry point
168 */
169 public void onModuleLoad()
170 {
171 _statusBar = new StatusBar(this);
172 //Make the Firebug console so that browsers that don't have it don't break
173 setUpConsole();
174
175 //Get a Google geocoder to help find places that the Gazetteer does not know the coordinates for
176 _geocoder = new Geocoder();
177
178 ((ServiceDefTarget) _findPlaceService).setServiceEntryPoint("http://taniwha.resnet.scms.waikato.ac.nz:8080/ATLAS/findPlace");
179 //((ServiceDefTarget) _findPlaceService).setServiceEntryPoint("http://www.nzdl.org/ATLAS/findPlace");
180
181 //Setup native Javascript functions
182 setUpLoadPageFromUrl(this);
183 setUpLoadPageFromForm(this);
184 setUpLoadSpatialSearchPage(this);
185
186 //Setup the map
187 setUpMap();
188
189 //Set up the list box that stores the text view options
190 setUpTextViewSelector();
191
192 //Load the Greenstone home page
193 loadPageFromUrl("http://taniwha.resnet.scms.waikato.ac.nz:8080/greenstone3/dev?a=p&sa=home");
194 }
195
196 /**
197 * Adds the three options to the text view selector
198 */
199 public void setUpTextViewSelector()
200 {
201 _textViewSelector.addItem("Normal");
202 _textViewSelector.addItem("Fisheye");
203 _textViewSelector.addItem("Column");
204 }
205
206 /**
207 * Loads the page at the given URL
208 * @param url is the url to load
209 */
210 public void loadPageFromUrl(String url)
211 {
212 //Make sure a url was given
213 if(url == null)
214 {
215 return;
216 }
217
218 //Save the given url for later use
219 _currentURL = url;
220
221 //Set Greenstone to be visible
222 _gsVisible = true;
223
224 //Clear the map
225 _map.clearOverlays();
226
227 updateHandlers();
228 clearStatusUpdates();
229
230 //Check if the page being loaded is a search page
231 if (url.contains("s1.query="))
232 {
233 //Load the search page
234 loadSearchPageFromUrl(url);
235 }
236 else
237 {
238 //This page is not a search page
239 _searchResultsPage = false;
240 }
241
242 //If the url contains a collection name
243 if (url.contains("&c="))
244 {
245 //Store the collection name
246 _currentCollection = getCollectionFromURL(url);
247 }
248
249 //Add the "Page loading" update to the status bar"
250 _statusBar.addUpdate("Loading new page", "LoadPage");
251
252 getNewPage(url);
253 }
254
255 public void loadPageWithoutUrl()
256 {
257 //Set the current url to be empty
258 _currentURL = "";
259
260 //Set Greenstone to be visible
261 _gsVisible = true;
262
263 //Clear the map
264 _map.clearOverlays();
265
266 updateHandlers();
267 clearStatusUpdates();
268
269 //Add the "Page loading" update to the status bar"
270 _statusBar.addUpdate("Loading new page", "LoadPage");
271 }
272
273 public void getNewPage(String url)
274 {
275 RequestBuilder newPageRequest = new RequestBuilder(RequestBuilder.GET, url.contains("?") ? (url + "&excerpttag=body") : (url + "?excerpttag=body"));
276 try{
277 newPageRequest.sendRequest(null, new RequestCallback()
278 {
279 public void onResponseReceived(Request request, Response response)
280 {
281 if(response.getStatusCode() == Response.SC_OK)
282 {
283 HTML newPage = new HTML(response.getText());
284 newPage.getElement().setId("newpage");
285 Element oldNewPage = (Element) Document.get().getElementById("newpage");
286 if(oldNewPage != null)
287 {
288 oldNewPage.removeFromParent();
289 }
290 getElementsByTagName("body").get(0).appendChild(newPage.getElement());
291 newPage.setVisible(false);
292
293 showLoadedPage();
294 }
295 }
296
297 public void onError(Request request, Throwable exception)
298 {
299 alert("Problem loading new page -> " + exception.getMessage());
300 }
301 });
302 }
303 catch(Exception ex)
304 {
305 alert("Exception while creating the new page request -> " + ex.getMessage());
306 }
307 }
308
309 /**
310 * Clears several of the status updates that should not persist across pages
311 */
312 public void clearStatusUpdates()
313 {
314 _statusBar.removeUpdate("DisPlaces");
315 _statusBar.removeUpdate("SearchLoad");
316 _statusBar.removeUpdate("TextSearch");
317 }
318
319 /**
320 * Gets a collection name from a given url
321 * @param url the url to search for a collection in
322 * @return the collection name
323 */
324 public String getCollectionFromURL(String url)
325 {
326 int start = (url.indexOf("&c=") + 3);
327 int end = -1;
328 if (url.indexOf("&", (url.indexOf("&c=") + 1)) == -1)
329 {
330 end = url.length();
331 }
332 else
333 {
334 end = url.indexOf("&", (url.indexOf("&c=") + 1));
335 }
336 return url.substring(start, end);
337 }
338
339 /**
340 * Sets up various handlers for a new page
341 */
342 public void updateHandlers()
343 {
344 if (_fishEyeHandlerReg != null)
345 {
346 _fishEyeHandlerReg.removeHandler();
347 _fishEyeHandlerReg = null;
348 }
349
350 if (!_mapMoveHandlerOn)
351 {
352 _mapMoveHandlerOn = true;
353 _map.addMapMoveHandler(_mapMoveHandler);
354 }
355
356 if (_searchControls != null)
357 {
358 _map.removeControl(_searchControls);
359 _searchControls = null;
360 }
361
362 if (_spatialSearchClickHandler != null)
363 {
364 _map.removeMapClickHandler(_spatialSearchClickHandler);
365 _spatialSearchClickHandler = null;
366 }
367 }
368
369 /**
370 * Moves the loaded page from the temporary frame to the main page
371 */
372 private void showLoadedPage()
373 {
374 //If ATLAS has not yet been initialised then do so
375 if (!_initialised)
376 {
377 //Fix webpage elements so that they point to the correct address
378 fixForms();
379 fixAnchors();
380 fixImages();
381
382 initialiseATLAS();
383
384 //Add <link> and <script> elements to <head>
385 //changeCSSLinksAndScripts();
386 }
387 else
388 {
389 //Add <link> and <script> elements to <head>
390 //changeCSSLinksAndScripts();
391
392 //Fix webpage elements so that they point to the correct address
393 fixForms();
394 fixAnchors();
395 fixImages();
396
397 Element newPageElem = getElementById("newpage");
398 NodeList<com.google.gwt.dom.client.Element> divs = newPageElem.getElementsByTagName("div");
399
400 Element newBanner = null;
401 Element newContent = null;
402
403 for(int i = 0; i < divs.getLength(); i++)
404 {
405 if(divs.getItem(i).getId().equals("gs_banner"))
406 {
407 newBanner = (Element) divs.getItem(i);
408 }
409 else if(divs.getItem(i).getId().equals("gs_content"))
410 {
411 newContent = (Element) divs.getItem(i);
412 }
413 }
414
415 //Swap the current banner with the new banner
416 Element oldBanner = getElementById("gs_banner");
417 oldBanner.getParentElement().removeChild(oldBanner);
418 _headerDiv.insert(HTML.wrap(newBanner), 0);
419
420 //If the content div was in column view mode then reset it
421 if (_contentDiv.getWidget(0).getElement().getId().equals("columnBox"))
422 {
423 _contentDiv.clear();
424 _contentDiv.add(_gsPanel);
425 _contentDiv.add(_map);
426 }
427
428 //Swap the current Greenstone content with the new Greenstone content
429 _gsPanel.setHTML(HTML.wrap(newContent).getHTML());
430 }
431
432 //If the page is a collection home page then add spatial search to the list of options
433 if (_currentURL.contains("sa=about"))
434 {
435 addSpatialSearchLinkToAboutPage();
436 }
437
438 //The page has now finished being updated
439 _statusBar.removeUpdate("LoadPage");
440
441 //Check the document's text for places
442 checkDocText();
443 }
444
445 /**
446 * Add a link to spatial searching on the current page
447 */
448 private void addSpatialSearchLinkToAboutPage()
449 {
450 //Get the list to add the link to
451 Element list = getElementById("servicelist");
452
453 //If the list does not exist then stop
454 if(list == null)
455 {
456 return;
457 }
458
459 //Create the div for the link and explanation
460 Element linkLabel = DOM.createDiv();
461 list.appendChild(linkLabel);
462 linkLabel.setClassName("paramLabel");
463
464 //Create the link and append it to the div
465 Element spatialLink = DOM.createAnchor();
466 linkLabel.appendChild(spatialLink);
467 spatialLink.setAttribute("href", "javascript:loadSpatialSearchPageJS()");
468 spatialLink.setInnerText("Spatial Search");
469
470 //Create the explanation div and add to the parent div
471 Element explainationDiv = DOM.createDiv();
472 list.appendChild(explainationDiv);
473 explainationDiv.setClassName("paramLabel");
474 explainationDiv.setInnerText("Search for documents mentioning places from a certain area");
475
476 Element br = DOM.createElement("br");
477 list.appendChild(br);
478 br.setClassName("clear");
479 }
480
481 /**
482 * Initialise the webpage elements for ATLAS
483 */
484 public void initialiseATLAS()
485 {
486 //Reload the page when the view type is changed
487 _textViewSelector.addChangeHandler(new ChangeHandler()
488 {
489 public void onChange(ChangeEvent event)
490 {
491 if (getDocTextElement() != null)
492 {
493 loadPageFromUrl(_currentURL);
494 }
495 }
496 });
497
498 //Set up content
499 _containerPanel.add(_headerDiv);
500 _containerPanel.add(_statusBar.getStatusBarDiv());
501 _containerPanel.add(_contentDiv);
502 _containerPanel.add(_footerDiv);
503
504 _viewPanel.add(new Label("View: "));
505 _viewPanel.add(_textViewSelector);
506 _viewPanel.setVisible(false);
507
508 Element newPageElem = getElementById("newpage");
509 NodeList<com.google.gwt.dom.client.Element> divs = newPageElem.getElementsByTagName("div");
510
511 Element headerElem = null;
512 Element bodyElem = null;
513 Element footerElem = null;
514
515 for(int i = 0; i < divs.getLength(); i++)
516 {
517 if(divs.getItem(i).getId().equals("gs_banner"))
518 {
519 headerElem = (Element) divs.getItem(i);
520 }
521 else if(divs.getItem(i).getId().equals("gs_content"))
522 {
523 bodyElem = (Element) divs.getItem(i);
524 }
525 else if(divs.getItem(i).getId().equals("gs_footer"))
526 {
527 footerElem = (Element) divs.getItem(i);
528 }
529 }
530
531 if(headerElem == null)
532 {
533 alert("header is null");
534 }
535 if(bodyElem == null)
536 {
537 alert("body is null");
538 }
539 if(footerElem == null)
540 {
541 alert("footer is null");
542 }
543
544 // Add header
545 //Node newHeader = importNode(newPage, tempFrameGetElementById("banner"), true);
546 _headerDiv.add(HTML.wrap(headerElem));
547 _headerDiv.add(_viewPanel);
548 _headerDiv.setWidth("100%");
549 _headerDiv.getElement().setId("GSHeader");
550
551 _gsPanel.getElement().getStyle().setProperty("overflow", "auto");
552
553 _contentDiv.setWidth("100%");
554 _contentDiv.getElement().getStyle().setProperty("backgroundColor", "#FFFFFF");
555 _contentDiv.getElement().setId("GSContent");
556
557 // Add content
558 //Node newContent = importNode(Document.get(), tempFrameGetElementById("content"), true);
559 _gsPanel = HTML.wrap(bodyElem);
560 _contentDiv.add(_gsPanel);
561 _contentDiv.add(_map);
562
563 // Add footer
564 //Node newFooter = importNode(Document.get(), tempFrameGetElementById("footer"), true);
565 _footerDiv.add(HTML.wrap(footerElem));
566 _footerDiv.setWidth("100%");
567 _footerDiv.getElement().setId("GSFooter");
568
569 RootPanel.get("mainFrame").add(_containerPanel);
570
571 setUpBrowserResizeCheckTimer();
572
573 // Make the call to check if the Gazetteer is loaded
574 _findPlaceService.isGazetteerLoaded(setUpCheckGazetteerCallback());
575 _initialised = true;
576 }
577
578 /**
579 * Loads a Greenstone search page from a url
580 * @param url is the url to load
581 */
582 public void loadSearchPageFromUrl(String url)
583 {
584 _searchResultsPage = true;
585
586 //Set up the request to get returned documents from the xml
587 RequestBuilder xmlRequest = new RequestBuilder(RequestBuilder.GET, url);
588 try
589 {
590 //Make the request
591 xmlRequest.sendRequest(null, new RequestCallback()
592 {
593 public void onError(Request request, Throwable exception)
594 {
595 logToConsole("xml Request Error -> " + exception.getMessage());
596 }
597
598 public void onResponseReceived(Request request, Response response)
599 {
600 processResponse(response);
601 }
602 });
603 }
604 catch (Exception ex)
605 {
606 ex.printStackTrace();
607 }
608 }
609
610 public void processResponse(Response response)
611 {
612 //If the status code is not the page loaded code then stop
613 if(response.getStatusCode() != 200)
614 {
615 return;
616 }
617
618 //Add the status update that indicates that the system is searching for places in the result document
619 _statusBar.addUpdate("Finding places in result documents", "SearchLoad");
620
621 //Get the response text
622 String text = response.getText();
623
624 //Get the hash codes for the documents
625 final ArrayList<String> docURLs = getDocURLsFromResponse(text);
626 final String[] texts = new String[docURLs.size()];
627
628 for(int i = 0; i < texts.length; i++)
629 {
630 texts[i] = null;
631 }
632
633 for(int i = 0; i < docURLs.size(); i++)
634 {
635 String url = docURLs.get(i);
636 RequestBuilder xmlRequest = new RequestBuilder(RequestBuilder.GET, _GREENSTONEURL + "/" + (url.contains("?") ? (url + "&excerptid=gs-document-text") : (url + "?excerptid=gs-document-text")));
637 try
638 {
639 final int index = i;
640 xmlRequest.sendRequest(null, new RequestCallback()
641 {
642 public void onResponseReceived(Request request, Response response)
643 {
644 if(response.getStatusCode() == Response.SC_OK)
645 {
646 texts[index] = response.getText();
647 }
648 }
649
650 public void onError(Request request, Throwable exception)
651 {
652 alert("Exception requesting new page -> " + exception.getMessage());
653 texts[index] = "";
654 }
655 });
656 }
657 catch(Exception ex)
658 {
659 alert("Exception requesting " + url + " -> " + ex.getMessage());
660 }
661 }
662
663 Timer checkDoneTimer = new Timer()
664 {
665 int _count = 0;
666
667 public void run()
668 {
669 boolean done = true;
670 if(_count < 20)
671 {
672 for(int i = 0; i < texts.length; i++)
673 {
674 if(texts[i] == null)
675 {
676 done = false;
677 break;
678 }
679 }
680 }
681 _count++;
682
683 if(done)
684 {
685 this.cancel();
686 findPlacesInTexts(texts);
687 }
688 }
689 };
690 checkDoneTimer.scheduleRepeating(500);
691 }
692
693 /**
694 * Makes a call to the server to look through multiple places for places
695 * @param texts is a list of texts from different documents
696 */
697 private void findPlacesInTexts(String[] texts)
698 {
699 logToConsole("Finished gettings doc text and gazetteer loaded!");
700
701 //Make the call to the server that finds the places
702 _findPlaceService.findPlacesInMultipleTexts(texts, setUpFindMultiplePlacesCallback());
703
704 //Set up the map for viewing multiple places
705 _map.clearOverlays();
706 _mapVisible = true;
707 _map.setVisible(true);
708 _contentDiv.add(_mapLoadingLabel);
709
710 _mapLoadingLabel.getElement().getStyle().setProperty("left", ((int) (_headerDiv.getOffsetWidth() * (3.0 / 4.0) - _mapLoadingLabel.getOffsetWidth() / 2)) + "px");
711 _mapLoadingLabel.getElement().getStyle().setProperty("top", (_headerDiv.getOffsetHeight() + _contentDiv.getOffsetHeight() / 3) + "px");
712
713 _map.getElement().getStyle().setProperty("left", (Window.getClientWidth() / 2 + 8) + "px");
714 _map.getElement().getStyle().setProperty("top", (_headerDiv.getOffsetHeight() + 28 + Window.getScrollTop()) + "px");
715
716 _resize = true;
717 }
718
719 /**
720 * Takes Greenstone search response xml text and extracts the document hashes from it
721 * @param text is the xml to use
722 * @return a list of document hashes
723 */
724 private ArrayList<String> getDocURLsFromResponse(String text)
725 {
726 ArrayList<String> docURLs = new ArrayList<String>();
727
728 int index = text.indexOf("<ul id=\"results\"");
729 int endIndex = text.indexOf("</ul>", index);
730 while ((index = text.indexOf("<a href=\"", index)) != -1 && index < endIndex)
731 {
732 int urlStart = index + "<a href=\"".length();
733 int urlEnd = text.indexOf("\"", urlStart + 1);
734
735 docURLs.add(text.substring(urlStart, urlEnd));
736
737 index++;
738 }
739
740 return docURLs;
741 }
742
743 /**
744 * Creates and shows a spatial search page
745 */
746 public void loadSpatialSearchPage()
747 {
748 //Clear the Greenstone panel
749 _gsPanel.setHTML((new HTML()).getHTML());
750
751 //Turn off the map move handler if it is on
752 if (_mapMoveHandlerOn)
753 {
754 _mapMoveHandlerOn = false;
755 _map.removeMapMoveHandler(_mapMoveHandler);
756 }
757
758 //Set up the page
759 _map.clearOverlays();
760 _mapVisible = true;
761 _gsVisible = false;
762 _map.setVisible(true);
763
764 //Create a new list that will store the points that the user clicks on
765 _areaPoints = new ArrayList<LatLng>();
766
767 //If the map does not currently have a spatial search handler
768 if (_spatialSearchClickHandler == null)
769 {
770 //Create a new map spatial search handler
771 _spatialSearchClickHandler = new MapClickHandler()
772 {
773 public void onClick(MapClickEvent event)
774 {
775 //Take the point that has been clicked and add it to the list
776 LatLng point = event.getLatLng();
777 _areaPoints.add(point);
778
779 //Create a marker at the clicked point
780 MarkerOptions mo = MarkerOptions.newInstance();
781 mo.setClickable(false);
782 Marker marker = new Marker(point, mo);
783 _map.addOverlay(marker);
784
785 //If this is not the first point then add a line between this and the previous point
786 if (_areaPoints.size() > 1)
787 {
788 PolylineOptions po = PolylineOptions.newInstance();
789 po.setClickable(false);
790
791 Polyline line = new Polyline(new LatLng[] { point, _areaPoints.get(_areaPoints.size() - 2) }, "#FFFFFF", 3, 1, po);
792 _map.addOverlay(line);
793 }
794 }
795 };
796 }
797 _map.addMapClickHandler(_spatialSearchClickHandler);
798
799 //If the map does not have search controls then add them
800 if (_searchControls == null)
801 {
802 _searchControls = new SpatialSearchControls(new ControlPosition(ControlAnchor.BOTTOM_RIGHT, 0, 0));
803 }
804 _map.addControl(_searchControls);
805
806 _resize = true;
807 }
808
809 /**
810 * Takes an HTML form element and loads a page using its content
811 * @param form is the form to use
812 */
813 public void loadPageFromForm(Element form)
814 {
815 //Get the top level url
816 StringBuilder url = new StringBuilder(_GREENSTONEDEVURL);
817
818 //Get the elements from the form
819 FormElement formElement = FormElement.as(form);
820 NodeCollection<com.google.gwt.dom.client.Element> elements = formElement.getElements();
821
822 //Go through each element
823 for (int i = 0; i < elements.getLength(); i++)
824 {
825 Element currentItem = (Element) elements.getItem(i);
826
827 //If the element is an input element
828 if (currentItem.getTagName().equals("INPUT"))
829 {
830 InputElement input = InputElement.as(currentItem);
831
832 //If the element is a text or hidden element
833 if (input.getType().equals("text") || input.getType().equals("hidden"))
834 {
835 //Append the name and value of this element to the url
836 url.append("&" + input.getName() + "=" + input.getValue());
837 }
838 //If the element is a radio or checkbox element
839 else if (input.getType().equals("radio") || input.getType().equals("checkbox"))
840 {
841 //If the element has been checked
842 if (input.isChecked())
843 {
844 //Append the name and value of this element to the url
845 url.append("&" + input.getName() + "=" + input.getAttribute("value"));
846 }
847 }
848 }
849 //If the element is a select element (drop down box)
850 else if (currentItem.getTagName().equals("SELECT"))
851 {
852 SelectElement select = SelectElement.as(currentItem);
853 NodeList<OptionElement> options = select.getOptions();
854
855 //Append the name of the element and the value of the currently selected index to the url
856 url.append("&" + select.getName() + "=" + options.getItem(select.getSelectedIndex()).getAttribute("value"));
857 }
858 //If the element is a text area element
859 else if (currentItem.getTagName().equals("TEXTAREA"))
860 {
861 TextAreaElement text = TextAreaElement.as(currentItem);
862
863 //Append the name and value of the text area to the url
864 url.append("&" + text.getName() + "=" + text.getValue());
865 }
866 }
867 //Replace the first & with a ?
868 url.replace(url.indexOf("&"), url.indexOf("&") + 1, "?");
869
870 //Load the page with the created url
871 loadPageFromUrl(url.toString());
872 }
873
874 /**
875 * Remove old CSS links from the page and add new ones, the href attributes are also corrected
876 */
877 public void changeCSSLinksAndScripts()
878 {
879 //Get the head section of the HTML page
880 Element head = getDocumentHead();
881
882 //Get all of the <link> elements from the HTML header
883 NodeList<com.google.gwt.dom.client.Element> currentLinks = head.getElementsByTagName("link");
884
885 //Get all of the <script> elements from the HTML header
886 NodeList<com.google.gwt.dom.client.Element> currentScripts = head.getElementsByTagName("script");
887
888 //Add the new links
889 com.google.gwt.xml.client.NodeList newLinks = _currentNewPageDoc.getElementsByTagName("link");
890 for (int i = 0; i < newLinks.getLength(); i++)
891 {
892 com.google.gwt.xml.client.Element e = (com.google.gwt.xml.client.Element) newLinks.item(i);
893 boolean found = false;
894 for(int j = 0; j < currentLinks.getLength(); j++)
895 {
896 Element elem = (Element) currentLinks.getItem(j);
897 if(e.getAttribute("href").equals(elem.getAttribute("href"))
898 && e.getAttribute("type").equals(elem.getAttribute("type"))
899 && e.getAttribute("rel").equals(elem.getAttribute("rel")))
900 {
901 found = true;
902 }
903 }
904
905 if(!found)
906 {
907 Element newElem = DOM.createElement("link");
908
909 NamedNodeMap map = e.getAttributes();
910 for(int k = 0; k < e.getAttributes().getLength(); k++)
911 {
912 newElem.setAttribute(map.item(k).getNodeName(), map.item(k).getNodeValue());
913 }
914
915 if(!newElem.getAttribute("href").startsWith("http://"))
916 {
917 newElem.setAttribute("href", _GREENSTONEURL + "/" + newElem.getAttribute("href"));
918 }
919 head.appendChild(newElem);
920 }
921 }
922
923 //Add the new scripts on the page
924 com.google.gwt.xml.client.NodeList newScripts = _currentNewPageDoc.getElementsByTagName("script");
925 for (int i = 0; i < newScripts.getLength(); i++)
926 {
927 com.google.gwt.xml.client.Element e = (com.google.gwt.xml.client.Element) newScripts.item(i);
928 boolean found = false;
929 for(int j = 0; j < currentScripts.getLength(); j++)
930 {
931 Element elem = (Element) currentLinks.getItem(j);
932 if(e.getAttribute("src").equals(elem.getAttribute("src"))
933 && e.getAttribute("type").equals(elem.getAttribute("type"))
934 && e.getAttribute("charset").equals(elem.getAttribute("charset")))
935 {
936 found = true;
937 }
938 }
939
940 if(!found)
941 {
942 Element newElem = DOM.createElement("link");
943
944 NamedNodeMap map = e.getAttributes();
945 for(int k = 0; k < e.getAttributes().getLength(); k++)
946 {
947 newElem.setAttribute(map.item(k).getNodeName(), map.item(k).getNodeValue());
948 }
949
950
951 if(!e.getAttribute("src").startsWith("http://"))
952 {
953 e.setAttribute("src", _GREENSTONEURL + "/" + e.getAttribute("src"));
954 }
955 head.appendChild(newElem);
956 }
957 }
958 }
959
960 /**
961 * Go through each form on the page and add a javascript function in place of its action attribute
962 */
963 public void fixForms()
964 {
965 NodeList<com.google.gwt.dom.client.Element> forms = getElementById("newpage").getElementsByTagName("form");
966 for (int i = 0; i < forms.getLength(); i++)
967 {
968 Element e = (Element)forms.getItem(i);
969 e.setAttribute("id", "form" + i);
970
971 if(e.getAttribute("action").isEmpty())
972 {
973 continue;
974 }
975 if (!e.getAttribute("action").startsWith("http://") && !e.getAttribute("action").startsWith("/"))
976 {
977 e.setAttribute("action", "javascript:loadPageFromFormJS(document.getElementById('form" + i + "'))");
978 }
979 }
980 }
981
982 /**
983 * Go through each anchor on the page and add a javascript function in place of the href attribute
984 */
985 public void fixAnchors()
986 {
987 NodeList<com.google.gwt.dom.client.Element> anchors = getElementById("newpage").getElementsByTagName("a");
988 for (int i = 0; i < anchors.getLength(); i++)
989 {
990 Element e = (Element)anchors.getItem(i);
991 if(e.getAttribute("href").isEmpty())
992 {
993 continue;
994 }
995 if (!e.getAttribute("href").startsWith("http://") && !e.getAttribute("href").startsWith("/"))
996 {
997 e.setAttribute("href", _GREENSTONEURL + "/" + e.getAttribute("href"));
998 }
999 //e.setAttribute("onClick", "loadPageFromUrlJS('" + e.getAttribute("href") + "'); return false;");
1000 e.setAttribute("href", "javascript:loadPageFromUrlJS('" + e.getAttribute("href") + "');");
1001 }
1002 }
1003
1004 /**
1005 * Go through each image on the page and correct its src attribute
1006 */
1007 public void fixImages()
1008 {
1009 NodeList<com.google.gwt.dom.client.Element> images = getElementById("newpage").getElementsByTagName("img");
1010 for (int i = 0; i < images.getLength(); i++)
1011 {
1012 Element e = (Element)images.getItem(i);
1013
1014 if(e.getAttribute("src").isEmpty())
1015 {
1016 continue;
1017 }
1018
1019 if (!e.getAttribute("src").startsWith("http://") && !e.getAttribute("src").startsWith("/"))
1020 {
1021 e.setAttribute("src", _GREENSTONEURL + "/" + e.getAttribute("src"));
1022 }
1023 }
1024 }
1025
1026 /**
1027 * Makes calls to console.log harmless on browsers that do not have Firebug
1028 */
1029 public static native void setUpConsole()
1030 /*-{
1031 if (! ("console" in $wnd) || !("firebug" in console))
1032 {
1033 var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
1034 $wnd.console = {};
1035 for (var i = 0; i < names.length; ++i) $wnd.console[names[i]] = function() {};
1036 }
1037 }-*/;
1038
1039 /**
1040 * Creates the javascript function that calls the loadPageFromForm GWT function
1041 * @param ml is the instance of the GS3MapLibrary class that you wish to attach this function to
1042 */
1043 public static native void setUpLoadPageFromForm(GS3MapLibrary ml)
1044 /*-{
1045 $wnd.loadPageFromFormJS = function(form)
1046 {
1047 [email protected]::loadPageFromForm(Lcom/google/gwt/user/client/Element;) (form);
1048 };
1049 }-*/;
1050
1051 /**
1052 * Creates the javascript function that calls the loadPageFromURL GWT function
1053 * @param ml is the instance of the GS3MapLibrary class that you wish to attach this function to
1054 */
1055 public static native void setUpLoadPageFromUrl(GS3MapLibrary ml)
1056 /*-{
1057 $wnd.loadPageFromUrlJS = function(url)
1058 {
1059 [email protected]::loadPageFromUrl(Ljava/lang/String;) (url);
1060 };
1061 }-*/;
1062
1063 /**
1064 * Creates the javascript function that calls the loadSpatialSearchPage GWT function
1065 * @param ml is the instance of the GS3MapLibrary class that you wish to attach this function to
1066 */
1067 public static native void setUpLoadSpatialSearchPage(GS3MapLibrary ml)
1068 /*-{
1069 $wnd.loadSpatialSearchPageJS = function()
1070 {
1071 [email protected]::loadSpatialSearchPage() ();
1072 };
1073 }-*/;
1074
1075 /**
1076 * Gets all of the specified type of element in the given frame
1077 * @param frameIndex is the index of the frame to search in
1078 * @param tagname is the specific tag type to get
1079 * @return the list of elements with that tag name
1080 */
1081 public static native JsArray<Element> tempFrameGetElementsByTagName(int frameIndex, String tagname)
1082 /*-{
1083 return $wnd.frames[frameIndex].document.getElementsByTagName(tagname);
1084 }-*/;
1085
1086 /**
1087 * Gets a element specifed by a given id in the specified frame
1088 * @param frameIndex is the index of the frame to search in
1089 * @param id is the id of the element to find
1090 * @return the specified element
1091 */
1092 public static native Element tempFrameGetElementById(int frameIndex, String id)
1093 /*-{
1094 return $wnd.frames[frameIndex].document.getElementById(id);
1095 }-*/;
1096
1097 /**
1098 * Gets the total number of frames in the webpage
1099 * @return the total number of frames
1100 */
1101 public static native int getNumberOfFrames()
1102 /*-{
1103 return $wnd.frames.length;
1104 }-*/;
1105
1106 /**
1107 * Gets an element specified the given id in the intermediate frame
1108 * @param id is the id of the element to find
1109 * @return the specified element
1110 */
1111 public static native Element tempFrameGetElementById(String id)
1112 /*-{
1113 return $wnd.frames[2].document.getElementById(id);
1114 }-*/;
1115
1116 /**
1117 * Gets all of the specified type of element in the intermediate frame
1118 * @param tagname is the specific tag type to get
1119 * @return the list of elements with that tag name
1120 */
1121 public static native JsArray<Element> tempFrameGetElementsByTagName(String tagname)
1122 /*-{
1123 return $wnd.frames[2].document.getElementsByTagName(tagname);
1124 }-*/;
1125
1126 /**
1127 * Prints a given message to screen in a window
1128 * @param msg is the message to print
1129 */
1130 public static native void alert(String msg)
1131 /*-{
1132 alert(msg);
1133 }-*/;
1134
1135 /**
1136 * Prints a given message to the Firebug console
1137 * @param msg is the message to print
1138 */
1139 public static native void logToConsole(String msg)
1140 /*-{
1141 //alert(msg);
1142 //console.log(msg);
1143 }-*/;
1144
1145 /**
1146 * Gets the <head> element of the <html>
1147 * @return the head element
1148 */
1149 public static native Element getDocumentHead()
1150 /*-{
1151 return $doc.getElementsByTagName("head")[0];
1152 }-*/;
1153
1154 /**
1155 * Patch GWT Document.importNode, which fails to return the imported nodes
1156 */
1157 public static final native Node importNode(Document doc, Node node, boolean deep) /*-{
1158 return doc.importNode(node, deep);
1159 }-*/;
1160
1161
1162 /**
1163 * Gets an element specified by the given id in the document
1164 * @param id the id of the element to find
1165 * @return the specified element
1166 */
1167 public static native Element getElementById(String id)
1168 /*-{
1169 return $doc.getElementById(id);
1170 }-*/;
1171
1172 /**
1173 * Gets all of the elements specified by the given tag name
1174 * @param tagName is the tag name of the elements to find
1175 * @return the list of elements specified by the given tag name
1176 */
1177 public static native JsArray<Element> getElementsByTagName(String tagName)
1178 /*-{
1179 return $doc.getElementsByTagName(tagName);
1180 }-*/;
1181
1182 /**
1183 * Calls the method the initialises the fisheye viewing
1184 */
1185 public static native void setUpFishEye()
1186 /*-{
1187 console.log("Fish eye set up");
1188 $wnd.fishEyeSetUp();
1189 }-*/;
1190
1191 /**
1192 * Passes the mouse y coordinates from the GWT handler to the fisheye handler
1193 * @param y is the mouse y coordinate
1194 */
1195 public static native void passMouseCoordsToFishEye(int y)
1196 /*-{
1197 $wnd.checkMousePos(y);
1198 }-*/;
1199
1200 /**
1201 * Sets up the timer that checks periodically whether or not the elements in the page need to be resized
1202 */
1203 public void setUpBrowserResizeCheckTimer()
1204 {
1205 _resizeCheckTimer = new Timer()
1206 {
1207 public void run()
1208 {
1209 if (_currentBrowserPixelHeight != Window.getClientHeight() || _currentBrowserPixelWidth != Window.getClientWidth() || _resize)
1210 {
1211 _resize = false;
1212 resizeElements();
1213 _currentBrowserPixelHeight = Window.getClientHeight();
1214 _currentBrowserPixelWidth = Window.getClientWidth();
1215 }
1216 }
1217 };
1218 _resizeCheckTimer.scheduleRepeating(500);
1219 }
1220
1221 /**
1222 * Resizes elements based on the current width and height of the browser window
1223 */
1224 public void resizeElements()
1225 {
1226 //Get the width and height we want to use for the content div
1227 int cwidth = Window.getClientWidth() - 45;
1228 int cheight = (int) (Window.getClientHeight() - _headerDiv.getOffsetHeight() - _footerDiv.getOffsetHeight() - _statusBar.getStatusBarDiv().getOffsetHeight() - 50);
1229
1230 //If the height is less than 300 then set it to 300
1231 if (cheight < 200)
1232 {
1233 cheight = 200;
1234 }
1235
1236 //Set the widths of the header and footer divs
1237 _headerDiv.setWidth(cwidth + "px");
1238 _footerDiv.setWidth(cwidth + "px");
1239
1240 //Set the size of the content div
1241 _contentDiv.setSize(cwidth + "px", cheight + "px");
1242
1243 //Set up the style of the Greenstone panel
1244 _gsPanel.getElement().getStyle().setProperty("position", "absolute");
1245 _gsPanel.getElement().getStyle().setProperty("overflow", "auto");
1246
1247 //Set up the style of the Map panel
1248 _map.getElement().getStyle().setProperty("position", "absolute");
1249 _map.getElement().getStyle().setProperty("top", _contentDiv.getAbsoluteTop() + "px");
1250
1251 //If the map is visible and the Greenstone panel is visible
1252 if (_mapVisible && _gsVisible)
1253 {
1254 _map.setSize((cwidth / 2 - 60) + "px", (cheight - 25) + "px");
1255 _map.getElement().getStyle().setProperty("left", (cwidth / 2 + 50) + "px");
1256 _gsPanel.setSize((cwidth / 2) + "px", (cheight - 25) + "px");
1257 }
1258
1259 //If the map is visible and the Greenstone panel is not visible
1260 if (_mapVisible && !_gsVisible)
1261 {
1262 _gsPanel.setSize("0px", "0px");
1263 _map.setSize((cwidth - 40) + "px", cheight + "px");
1264 _map.getElement().getStyle().setProperty("left", _gsPanel.getAbsoluteLeft() + "px");
1265 }
1266
1267 //If the map is not visible and the Greenstone panel is visible
1268 if (!_mapVisible && _gsVisible)
1269 {
1270 _gsPanel.setSize(cwidth + "px", cheight + "px");
1271 _map.setSize("0px", "0px");
1272 }
1273
1274 //If neither panel is visible
1275 if (!_mapVisible && !_gsVisible)
1276 {
1277 _gsPanel.setSize("0px", "0px");
1278 _map.setSize("0px", "0px");
1279 }
1280 }
1281
1282 /**
1283 * Initialises the Google Map view
1284 */
1285 public void setUpMap()
1286 {
1287 //Set up the map size, style, starting point and zoom level
1288 LatLng startPoint = LatLng.newInstance(0, 0);
1289 _map = new MapWidget(startPoint, _currentZoomLevel);
1290 _map.setSize(Window.getClientWidth() / 2 + "px", "600px");
1291 _map.getElement().getStyle().setProperty("margin", "5px");
1292 _map.setStyleName("map");
1293
1294 //Store the default map move handler
1295 _mapMoveHandler = new MapMoveHandler()
1296 {
1297 public void onMove(MapMoveEvent event)
1298 {
1299 if (_map.getZoomLevel() != _currentZoomLevel)
1300 {
1301 _currentZoomLevel = _map.getZoomLevel();
1302 _map.clearOverlays();
1303
1304 //If this is not a search page then there is only one place set
1305 if(!_searchResultsPage)
1306 {
1307 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", _searchResultsPage);
1308 }
1309 //If this is a search page then there are likely to be multiple place sets
1310 else
1311 {
1312 displayMultiplePlaceSets();
1313 }
1314 }
1315 }
1316 };
1317 _map.addMapMoveHandler(_mapMoveHandler);
1318
1319 // Add some controls for the zoom level
1320 _map.addControl(new LargeMapControl());
1321 _map.addControl(new MapTypeControl());
1322
1323 //Add the map loading label
1324 _mapLoadingLabel.setStyleName("mapLoadingLabel");
1325 _mapLoadingLabel.getElement().getStyle().setProperty("left", ((int) (_headerDiv.getOffsetWidth() * (3.0 / 4.0) - _mapLoadingLabel.getOffsetWidth() / 2)) + "px");
1326 _mapLoadingLabel.getElement().getStyle().setProperty("top", (_headerDiv.getOffsetHeight() + _contentDiv.getOffsetHeight() / 3) + "px");
1327
1328 //Make the map initially invisible
1329 _map.setVisible(false);
1330 }
1331
1332 /**
1333 * Creates a marker at the given point
1334 * @param p is the place to create a marker for
1335 * @param point is the point to place the marker at (if this is null the place will be used to provide the coordinates)
1336 * @param borderColour is the colour of the border to use
1337 * @param fillColour is the colour to use to fill the marker
1338 * @param colourInfo stores whether or not to show a coloured rectangle in the information box that is shown when the marker is clicked
1339 * @return the marker
1340 */
1341 public Polygon createMarkerAtPoint(Place p, LatLng point, String borderColour, String fillColour, Boolean colourInfo)
1342 {
1343 float lat = 0.0f;
1344 float lng = 0.0f;
1345
1346 //Get the coordinates
1347 if (point == null)
1348 {
1349 lat = p.getLatitude();
1350 lng = p.getLongitude();
1351 }
1352 else
1353 {
1354 lat = (float) point.getLatitude();
1355 lng = (float) point.getLongitude();
1356 }
1357
1358 LatLng newPoint = ((point == null) ? LatLng.newInstance(lat, lng) : point);
1359
1360 //Work out the size of the new marker based on the current zoom level
1361 double zoomLevel = _map.getZoomLevel();
1362 double size = (8.0 * Math.pow(2.0, -zoomLevel)) + (0.05 * (zoomLevel / 20.0));
1363
1364 //Work out the transparency of the new marker based on the current zoom level
1365 double transparency = 0.8 * ((20.0 - zoomLevel) / 20.0);
1366
1367 //Create the corner of the polygon
1368 LatLng tl = LatLng.newInstance(lat - size, lng + size);
1369 LatLng tr = LatLng.newInstance(lat + size, lng + size);
1370 LatLng br = LatLng.newInstance(lat + size, lng - size);
1371 LatLng bl = LatLng.newInstance(lat - size, lng - size);
1372
1373 //If the user has chosen to highlight this place then make the marker red
1374 Polygon newMarker = null;
1375 if (_highlightedPlaces.contains(p.getName()))
1376 {
1377 newMarker = new Polygon(new LatLng[] { tl, tr, br, bl, tl }, borderColour, 1, 1, "#FF7F27", transparency);
1378 }
1379 //Otherwise make it the normal colour
1380 else
1381 {
1382 newMarker = new Polygon(new LatLng[] { tl, tr, br, bl, tl }, borderColour, 1, 1, fillColour, transparency);
1383 }
1384
1385 // When the marker is clicked it will show its address in a info box
1386 newMarker.addPolygonClickHandler(new MarkerClickHandler(fillColour, p, newPoint, colourInfo));
1387
1388 return newMarker;
1389 }
1390
1391 /**
1392 * Shows an info box above the marker when the marker is clicked
1393 */
1394 public class MarkerClickHandler implements PolygonClickHandler
1395 {
1396 String _fillColour = "";
1397 Boolean _colourInfo = false;
1398 LatLng _point = null;
1399 Place _place = null;
1400
1401 public MarkerClickHandler(String fillColour, Place place, LatLng point, Boolean colourInfo)
1402 {
1403 _fillColour = fillColour;
1404 _place = place;
1405 _point = point;
1406 _colourInfo = colourInfo;
1407 }
1408
1409 public void onClick(PolygonClickEvent event)
1410 {
1411 InfoWindow info = _map.getInfoWindow();
1412 if (_colourInfo)
1413 {
1414 info.open(_point, new InfoWindowContent(createPlaceInformationString(_place)));
1415 }
1416 else
1417 {
1418 info.open(_point, new InfoWindowContent("<span style=\"background: " + _fillColour + "; color: " + _fillColour + ";\">...</span> " + createPlaceInformationString(_place)));
1419 }
1420 }
1421 }
1422
1423 /**
1424 * Takes a place object and creates a string with information about that place
1425 * @param p is the place to make an information string from
1426 * @return the information string
1427 */
1428 public String createPlaceInformationString(Place p)
1429 {
1430 //If we do not have a valid place then stop
1431 if(p == null)
1432 {
1433 return null;
1434 }
1435
1436 //Add the place name to the string
1437 StringBuilder s = new StringBuilder(p.getName());
1438
1439 //Add the full parent name to the string
1440 if (p.getParentPlaceName() != null)
1441 {
1442 s.append(" in " + p.getParentPlaceName());
1443 }
1444
1445 //If we have population information then add it to the string
1446 if (p.getPopulation() > 0)
1447 {
1448 StringBuilder pop = new StringBuilder(Long.toString(p.getPopulation()));
1449
1450 //Insert commas into long numbers
1451 for (int i = pop.length() - 3; i > 0; i -= 3)
1452 {
1453 pop.insert(i, ',');
1454 }
1455
1456 s.append("<br/>Population: " + pop);
1457 }
1458
1459 //If we have coordinates then add those to the string as well
1460 if (p.getLongitude() != null && p.getLatitude() != null)
1461 {
1462 StringBuilder lat = new StringBuilder(Float.toString(p.getLatitude()));
1463 StringBuilder lng = new StringBuilder(Float.toString(p.getLongitude()));
1464
1465 //Shorten coordinates to 3 decimal places
1466 int i = 0;
1467 while (lat.charAt(i++) != '.');
1468 int j = 0;
1469 while (lng.charAt(j++) != '.');
1470
1471 if ((i + 3) < lat.length())
1472 {
1473 lat.delete(i + 3, lat.length());
1474 }
1475
1476 if ((j + 3) < lng.length())
1477 {
1478 lng.delete(j + 3, lng.length());
1479 }
1480
1481 s.append("<br/>Coordinates: " + lat + ", " + lng);
1482 }
1483
1484 return s.toString();
1485 }
1486
1487 /**
1488 * Make a call to the server that gets places that match the given criteria
1489 */
1490 public void updateCurrentPlaces()
1491 {
1492 _findPlaceService.getPlaces(0, 100, 0, true, true, true, _MAXVISIBLEMARKERS, setUpGetPlacesCallback());
1493 }
1494
1495 /**
1496 * Displays all of the place sets created from a text search
1497 */
1498 public void displayMultiplePlaceSets()
1499 {
1500 //Clear the map
1501 _map.clearOverlays();
1502
1503 //Go through each place set and if it has been marked visible then add it
1504 for (int j = 0; j < _currentMultiPlaces.size(); j++)
1505 {
1506 logToConsole("Adding set " + j + " to the map");
1507 if (_visiblePlaceSets.get(j))
1508 {
1509 addPlacesToMap(_currentMultiPlaces.get(j), "#FFFFFF", numToColour(j, _currentMultiPlaces.size(), 100, 255), true);
1510 }
1511 }
1512 _statusBar.removeUpdate("DisPlaces");
1513 }
1514
1515 /**
1516 * Creates a colour from the given parameters
1517 * @param num is the specified index
1518 * @param max is the total number of indexes
1519 * @param cmin is the minimum colour
1520 * @param cmax is the maximum colour
1521 * @return the colour string (e.g. #F35A22)
1522 */
1523 public String numToColour(int num, int max, int cmin, int cmax)
1524 {
1525 logToConsole("num = " + num + ", max = " + max + ", cmin = " + cmin + ", cmax = " + cmax);
1526 //Make sure num and max are good numbers
1527 if(num < 0){num = 0;}
1528 if(max <= 0){return "#000000";}
1529 if(max > 255){max = 255;}
1530 if(num > max){num = max;}
1531
1532 //Work out where this colour will lie in the spectrum
1533 int colourNum = (int) ((((float) num) / ((float) max)) * ((cmax - cmin) * 8));
1534
1535 String red = null;
1536 String green = null;
1537 String blue = null;
1538
1539 //If the colour is in the first section then make it a mix between red and green
1540 if (colourNum <= (cmax - cmin) * 2)
1541 {
1542 if (colourNum <= (cmax - cmin))
1543 {
1544 red = Integer.toHexString(colourNum + cmin);
1545 green = "00";
1546 blue = "00";
1547 }
1548 else
1549 {
1550 colourNum -= (cmax - cmin);
1551 red = Integer.toHexString(cmax);
1552 green = Integer.toHexString(colourNum + cmin);
1553 blue = "00";
1554 }
1555 }
1556 //If the colour is in the second section then make it a mix between green and blue
1557 else if (colourNum <= (cmax - cmin) * 4)
1558 {
1559 colourNum -= ((cmax - cmin) * 2);
1560 if (colourNum <= (cmax - cmin))
1561 {
1562 red = "00";
1563 green = Integer.toHexString(colourNum + cmin);
1564 blue = "00";
1565 }
1566 else
1567 {
1568 colourNum -= (cmax - cmin);
1569 red = "00";
1570 green = Integer.toHexString(cmax);
1571 blue = Integer.toHexString(colourNum + cmin);
1572 }
1573 }
1574 //If the colour is in the third section then make it a mix between red and blue
1575 else if (colourNum <= (cmax - cmin) * 6)
1576 {
1577 colourNum -= ((cmax - cmin) * 4);
1578 if (colourNum <= (cmax - cmin))
1579 {
1580 red = "00";
1581 green = "00";
1582 blue = Integer.toHexString(colourNum + cmin);
1583 }
1584 else
1585 {
1586 colourNum -= (cmax - cmin);
1587 red = Integer.toHexString(colourNum + cmin);
1588 green = "00";
1589 blue = Integer.toHexString(cmax);
1590 }
1591 }
1592 //If the colour is in the fourth section then make it a mix between all colours
1593 else
1594 {
1595 colourNum -= ((cmax - cmin) * 6);
1596 colourNum /= 2;
1597
1598 red = Integer.toHexString(colourNum + cmin);
1599 green = Integer.toHexString(colourNum + cmin);
1600 blue = Integer.toHexString(colourNum + cmin);
1601 }
1602
1603 //If the hex strings are only one character long then add a zero the the front
1604 if (red.length() < 2){red = "0" + red;}
1605 if (green.length() < 2){green = "0" + green;}
1606 if (blue.length() < 2){blue = "0" + blue;}
1607
1608 logToConsole("#" + red + green + blue);
1609 return "#" + red + green + blue;
1610 }
1611
1612 /**
1613 * Takes an array of places and displays them on the map
1614 * @param places is the list of places to display
1615 * @param borderColour is the colour of the marker borders
1616 * @param fillColour is the main colour of the marker
1617 * @param colourInfo is whether or not to display a coloured box in the information box of the marker
1618 */
1619 public void addPlacesToMap(ArrayList<Place> places, String borderColour, String fillColour, boolean colourInfo)
1620 {
1621 //If we do not have a valid set of places then stop
1622 if(places == null || places.size() == 0)
1623 {
1624 return;
1625 }
1626
1627 ArrayList<Place> placesSeen = new ArrayList<Place>();
1628
1629 // Make the best places visible
1630 for (Place p : places)
1631 {
1632 if (!_showAllPlaces)
1633 {
1634 //If the place is not directly referenced then don't use it
1635 if (!p.isDirectlyReferenced())
1636 {
1637 continue;
1638 }
1639
1640 //If a different place with this name has been chosen then don't use it
1641 if (_removedPlaces.contains(p.getName()) || (_chosenPlaces.containsKey(p.getName()) && !_chosenPlaces.get(p.getName()).equals(p)))
1642 {
1643 continue;
1644 }
1645
1646 //Make sure we only add the place once
1647 boolean found = false;
1648 for (Place q : placesSeen)
1649 {
1650 if (p.getName().equals(q.getName()))
1651 {
1652 found = true;
1653 }
1654 }
1655
1656 if (found)
1657 {
1658 continue;
1659 }
1660 placesSeen.add(p);
1661 }
1662
1663 // If there is no latitude and longitude provided for this place
1664 if (p.getLatitude() == null)
1665 {
1666 // Use Google's geocoder to find the place
1667 findAndMarkAddress(p, borderColour, fillColour, colourInfo);
1668 }
1669 // Latitude and longitude are provided in the address
1670 else
1671 {
1672 Polygon marker = createMarkerAtPoint(p, null, borderColour, fillColour, colourInfo);
1673 // Add the marker to the map
1674 _map.addOverlay(marker);
1675 }
1676 }
1677 }
1678
1679 /**
1680 * Finds and puts a marker at the given address using Google's geocoder service
1681 * @param address is the address to find and mark (e.g. Hamilton, Waikato, New Zealand)
1682 * @param index is where in the list of place locations this is to be added
1683 */
1684 private void findAndMarkAddress(final Place place, final String borderColour, final String fillColour, final boolean colourInfo)
1685 {
1686 String address = null;
1687
1688 if (place.getParentPlaceName() != null)
1689 {
1690 address = place.getName() + ", " + place.getParentPlaceName();
1691 }
1692 else
1693 {
1694 address = place.getName();
1695 }
1696
1697 // Make the call to the geocoder service
1698 _geocoder.getLatLng(address, new LatLngCallback()
1699 {
1700 // Ignore the place if it is not valid
1701 public void onFailure()
1702 {
1703 // LogToConsole("Failed");
1704 }
1705
1706 // If the geocoder service found the place
1707 public void onSuccess(final LatLng point)
1708 {
1709 // LogToConsole("Found");
1710 Polygon marker = createMarkerAtPoint(place, point, borderColour, fillColour, colourInfo);
1711
1712 place.setLatitude((float) point.getLatitude());
1713 place.setLongitude((float) point.getLongitude());
1714
1715 // Add the marker to the map
1716 _map.addOverlay(marker);
1717 }
1718 });
1719 }
1720
1721 public AsyncCallback<ArrayList<Place>> setUpGetPlacesCallback()
1722 {
1723 AsyncCallback<ArrayList<Place>> callback = new AsyncCallback<ArrayList<Place>>()
1724 {
1725 public void onFailure(Throwable caught)
1726 {
1727 logToConsole("Get Places FAIL" + caught.getMessage());
1728 }
1729
1730 // This is called when a successful call to findAllPlaces() is
1731 // completed
1732 public void onSuccess(ArrayList<Place> places)
1733 {
1734 logToConsole("Get Places Success!");
1735 _currentPlaces = places;
1736
1737 addPlacesToMap(places, "#FFFFFF", "#00FF00", _searchResultsPage);
1738 _updatingMap = false;
1739 }
1740 };
1741
1742 return callback;
1743 }
1744
1745 /**
1746 * Creates the callback object that is used when the call to the server returns
1747 * @return the callback object
1748 */
1749 public AsyncCallback<Boolean> setUpFindPlacesCallback()
1750 {
1751 return new AsyncCallback<Boolean>()
1752 {
1753 /**
1754 * This is called when the call to the server fails
1755 */
1756 public void onFailure(Throwable caught)
1757 {
1758 _statusBar.removeUpdate("TextSearch");
1759 logToConsole("Find places fail" + caught.getMessage());
1760 }
1761
1762 /**
1763 * This is called when the call to the server succeeds
1764 * @param result is a dummy variable that does not do anything
1765 */
1766 public void onSuccess(Boolean result)
1767 {
1768 //Remove the "searching for places" status bar message
1769 _statusBar.removeUpdate("TextSearch");
1770
1771 logToConsole("Find Places success!");
1772
1773 //Get the marked up text from the server
1774 _findPlaceService.getMarkedUpText(setUpGetMarkedUpTextCallback());
1775
1776 //Get the found places from the server
1777 updateCurrentPlaces();
1778
1779 //Clear the map
1780 _map.clearOverlays();
1781
1782 //Add the new places to the map
1783 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", _searchResultsPage);
1784
1785 //Remove the "map loading" message from the map
1786 _mapLoadingLabel.removeFromParent();
1787 }
1788 };
1789 }
1790
1791 public AsyncCallback<ArrayList<ArrayList<Place>>> setUpFindMultiplePlacesCallback()
1792 {
1793 AsyncCallback<ArrayList<ArrayList<Place>>> callback = new AsyncCallback<ArrayList<ArrayList<Place>>>()
1794 {
1795 public void onFailure(Throwable caught)
1796 {
1797 alert("Find multi places fail" + caught.getMessage());
1798 }
1799
1800 public void onSuccess(ArrayList<ArrayList<Place>> places)
1801 {
1802 _statusBar.removeUpdate("SearchLoad");
1803 _statusBar.addUpdate("Displaying places", "DisPlaces");
1804
1805 _currentMultiPlaces = places;
1806 _visiblePlaceSets = new ArrayList<Boolean>();
1807 for (int i = 0; i < _currentMultiPlaces.size(); i++)
1808 {
1809 _visiblePlaceSets.add(true);
1810 }
1811
1812 _mapLoadingLabel.removeFromParent();
1813 displayMultiplePlaceSets();
1814 addElementsToSearchResults(places);
1815 }
1816 };
1817 return callback;
1818 }
1819
1820 public AsyncCallback<Boolean> setUpCheckGazetteerCallback()
1821 {
1822 AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>()
1823 {
1824 public void onFailure(Throwable caught)
1825 {
1826 logToConsole("Check Gazetteer fail " + caught.getMessage());
1827 }
1828
1829 public void onSuccess(Boolean result)
1830 {
1831 if (!result)
1832 {
1833 _statusBar.addUpdate("Server is loading gazetteer", "GazLoad");
1834
1835 _findPlaceService.loadGazetteer(setUpLoadGazetteerCallback());
1836 }
1837 else
1838 {
1839 logToConsole("Gazetteer Already Loaded!");
1840 _gazetteerLoaded = true;
1841 }
1842 }
1843 };
1844 return callback;
1845 }
1846
1847 /**
1848 * Checks to see if the current page has text from a document so that it can be checked for places
1849 */
1850 public void checkDocText()
1851 {
1852 //Get the document text element if it exists
1853 Element documentText = getDocTextElement();
1854
1855 //If it does not exist then stop
1856 if (documentText == null)
1857 {
1858 logToConsole("document text div not found");
1859 if (_mapVisible)
1860 {
1861 _map.setVisible(false);
1862 _mapVisible = false;
1863 }
1864 _viewPanel.setVisible(false);
1865 return;
1866 }
1867
1868 logToConsole("Document text found!");
1869
1870 //Allow the user to change the method they wish to use view the text
1871 _viewPanel.setVisible(true);
1872
1873 //If the view type is not set to normal then remove the TOC
1874 if (_textViewSelector.getSelectedIndex() > 0)
1875 {
1876 HTML.wrap(getElementById("rightSidebar")).setVisible(false);
1877 }
1878
1879 //Create the document menu if we have not already done so
1880 if (_currentDocumentMenu == null)
1881 {
1882 createDocumentMenu();
1883 }
1884
1885 //Create the timer that closes the document menu when it is not in focus
1886 _menuOutTimer = new Timer()
1887 {
1888 public void run()
1889 {
1890 _currentDocumentMenu.hideMenu();
1891 }
1892 };
1893
1894 //Let the user know that the system is searching for places
1895 _statusBar.addUpdate("Searching text for places", "TextSearch");
1896
1897 //Clear the map
1898 _map.clearOverlays();
1899
1900 //Make the map visible
1901 _mapVisible = true;
1902 _map.setVisible(true);
1903
1904 //Add the "Loading" message to the map
1905 _contentDiv.add(_mapLoadingLabel);
1906
1907 _mapLoadingLabel.getElement().getStyle().setProperty("left", ((int) (_headerDiv.getOffsetWidth() * (3.0 / 4.0) - _mapLoadingLabel.getOffsetWidth() / 2)) + "px");
1908 _mapLoadingLabel.getElement().getStyle().setProperty("top", (_headerDiv.getOffsetHeight() + _contentDiv.getOffsetHeight() / 3) + "px");
1909
1910 //Resize the page elemens
1911 _resize = true;
1912
1913 //Send the document text to the server to be checked for places
1914 final Element finalDocumentText = documentText;
1915 Timer checkLoadTimer = new Timer()
1916 {
1917 public void run()
1918 {
1919 if (_gazetteerLoaded)
1920 {
1921 this.cancel();
1922 _findPlaceService.findPlacesInText(finalDocumentText.getInnerText(), finalDocumentText.getInnerHTML(), setUpFindPlacesCallback());
1923 }
1924 }
1925 };
1926 checkLoadTimer.scheduleRepeating(1000);
1927 }
1928
1929 /**
1930 * Creates and returns the callback object used when the call to the server returns
1931 * @return the callback object
1932 */
1933 public AsyncCallback<String> setUpGetMarkedUpTextCallback()
1934 {
1935 return new AsyncCallback<String>()
1936 {
1937 /**
1938 * This is called when the call to the server fails
1939 */
1940 public void onFailure(Throwable caught)
1941 {
1942 logToConsole("Mark up text failed -> " + caught.getMessage());
1943 }
1944
1945 /**
1946 * This is called when the call the to server succeeds
1947 * @param markedUpText is the text (marked up with place names) returned from the server
1948 */
1949 public void onSuccess(String markedUpText)
1950 {
1951 logToConsole("Mark up text success");
1952
1953 //Get the unmodified document text element from the web page
1954 Element documentText = getDocTextElement();
1955
1956 //Set the document text HTML to be the marked up text
1957 documentText.setInnerHTML(markedUpText);
1958
1959 //Get the spans in the marked up text that are place names
1960 JsArray<Element> textPlaces = getElementsByTagName("span");
1961 ArrayList<Element> placeElements = new ArrayList<Element>();
1962
1963 //Add the place spans to the array
1964 for (int j = 0; j < textPlaces.length(); j++)
1965 {
1966 if (textPlaces.get(j).getAttribute("class").equals("place"))
1967 {
1968 placeElements.add(textPlaces.get(j));
1969 }
1970 }
1971
1972 logToConsole("Adding events to " + placeElements.size() + " place spans");
1973
1974 //Add mouse over and mouse out handlers to each span
1975 for (Element e : placeElements)
1976 {
1977 Label newLabel = Label.wrap(e);
1978 newLabel.addMouseOverHandler(new PlaceMouseOverHandler());
1979 newLabel.addMouseOutHandler(new PlaceMouseOutHandler());
1980 newLabel.addMouseUpHandler(new PlaceMouseUpHandler());
1981 }
1982
1983 //If Fisheye view is selected in the list box then use it
1984 if (_textViewSelector.getSelectedIndex() == 1)
1985 {
1986 _statusBar.addUpdate("Loading fisheye view", "FishLoad");
1987 setUpFishEye();
1988 _statusBar.removeUpdate("FishLoad");
1989 _fishEyeHandlerReg = _gsPanel.addMouseMoveHandler(new FishEyeMouseMoveHandler());
1990 }
1991
1992 //If Column view is selected in the list box then use it
1993 if (_textViewSelector.getSelectedIndex() == 2)
1994 {
1995 setUpColumnView(documentText);
1996 }
1997 }
1998 };
1999 }
2000
2001 public void setUpColumnView(Element documentText)
2002 {
2003 _statusBar.addUpdate("Loading column view", "ColLoad");
2004
2005 logToConsole("Wrapping doc text");
2006 HTML docText = HTML.wrap(documentText);
2007 int width = docText.getOffsetWidth();
2008 String html = docText.getHTML();
2009 ArrayList<String> words = new ArrayList<String>();
2010
2011 int inTag = 0;
2012 boolean inWord = false;
2013
2014 StringBuilder currentWord = new StringBuilder();
2015
2016 for (int i = 0; i < html.length(); i++)
2017 {
2018 boolean add = true;
2019 char c = html.charAt(i);
2020
2021 if (inTag > 0 && c == '>')
2022 {
2023 inTag--;
2024
2025 if (inTag == 0)
2026 {
2027 words.add(currentWord.toString() + ">");
2028 currentWord = new StringBuilder();
2029 add = false;
2030 }
2031 }
2032 else if (c == '<')
2033 {
2034 inTag++;
2035
2036 if (inWord)
2037 {
2038 inWord = false;
2039 words.add(currentWord.toString());
2040 currentWord = new StringBuilder();
2041 }
2042 }
2043 else if (("" + c).matches("\\s"))
2044 {
2045 if (inTag == 0)
2046 {
2047 add = false;
2048 }
2049
2050 if (inWord)
2051 {
2052 inWord = false;
2053 words.add(currentWord.toString());
2054 currentWord = new StringBuilder();
2055 }
2056 }
2057 else
2058 {
2059 if (inTag == 0 && !inWord)
2060 {
2061 inWord = true;
2062 }
2063 }
2064
2065 if (add)
2066 {
2067 currentWord.append(c);
2068 }
2069 }
2070
2071 docText.setHTML("");
2072
2073 HorizontalPanel columns = new HorizontalPanel();
2074 ArrayList<Label> labels = new ArrayList<Label>();
2075 logToConsole("Adding columns to panel");
2076
2077 if (_contentDiv.getWidget(0).getElement().getId() == "gs_content")
2078 {
2079 VerticalPanel newDocTextPanel = new VerticalPanel();
2080 newDocTextPanel.add(columns);
2081 newDocTextPanel.add(_contentDiv.getWidget(0));
2082 newDocTextPanel.getElement().setId("columnBox");
2083 _contentDiv.insert(newDocTextPanel, 0);
2084 }
2085 else
2086 {
2087 ((VerticalPanel) (_contentDiv.getWidget(0))).remove(0);
2088 ((VerticalPanel) (_contentDiv.getWidget(0))).insert(columns, 0);
2089 }
2090
2091 float fontSize = 12;
2092 do
2093 {
2094 logToConsole("Looping");
2095 Label l = new Label();
2096 labels.add(l);
2097 columns.add(l);
2098
2099 for (int j = 0; j < labels.size(); j++)
2100 {
2101 StringBuilder labelText = new StringBuilder();
2102 for (int i = (words.size() / labels.size()) * j; i < ((j < (labels.size() - 1)) ? (((words.size() / labels.size()) * (j + 1)) - 1) : (words.size())); i++)
2103 {
2104 labelText.append(words.get(i) + " ");
2105 }
2106
2107 labels.get(j).getElement().setInnerHTML(labelText.toString());
2108 labels.get(j).setWidth((width / labels.size()) + "px");
2109 labels.get(j).getElement().getStyle().setProperty("fontSize", fontSize + "px");
2110 }
2111 fontSize *= 0.85;
2112
2113 logToConsole("Font size = " + fontSize);
2114 } while (columns.getOffsetHeight() > (Window.getClientHeight() - _headerDiv.getOffsetHeight() - _footerDiv.getOffsetHeight() - 70));
2115
2116 for (int i = 0; i < labels.size(); i++)
2117 {
2118 ArrayList<String> subList = new ArrayList<String>();
2119 for (int j = (words.size() / labels.size()) * i; j < ((i < (labels.size() - 1)) ? (((words.size() / labels.size()) * (i + 1)) - 1) : (words.size())); j++)
2120 {
2121 subList.add(words.get(j));
2122 }
2123 labels.get(i).addMouseMoveHandler(new ColumnViewMouseMoveHandler(labels.get(i), subList));
2124 }
2125
2126 columns.add(_columnViewBox);
2127 _columnViewBox.getElement().getStyle().setProperty("position", "absolute");
2128 _columnViewBox.getElement().getStyle().setProperty("border", "2px solid");
2129 _columnViewBox.getElement().getStyle().setProperty("background", "#FFFFFF");
2130 _columnViewBox.getElement().getStyle().setProperty("fontSize", "10px");
2131 _columnViewBox.setPixelSize(250, 100);
2132 _columnViewBox.setVisible(false);
2133
2134 _statusBar.removeUpdate("ColLoad");
2135 }
2136
2137 class ColumnViewMouseMoveHandler implements MouseMoveHandler
2138 {
2139 Label _label = null;
2140 ArrayList<String> _words = null;
2141
2142 public ColumnViewMouseMoveHandler(Label label, ArrayList<String> words)
2143 {
2144 _label = label;
2145 _words = words;
2146 }
2147
2148 public void onMouseOut(MouseOutEvent event)
2149 {
2150 _columnViewBox.setVisible(false);
2151 }
2152
2153 public void onMouseOver(MouseOverEvent event)
2154 {
2155 _columnViewBox.setVisible(true);
2156 }
2157
2158 public void onMouseMove(MouseMoveEvent event)
2159 {
2160 _columnViewBox.setVisible(true);
2161
2162 JsArray<Element> divs = getElementsByTagName("div");
2163 Element documentText = null;
2164 for (int i = 0; i < divs.length(); i++)
2165 {
2166 if (divs.get(i).getAttribute("class").equals("documenttext"))
2167 {
2168 documentText = divs.get(i);
2169 break;
2170 }
2171 }
2172
2173 if (event.getY() < 125)
2174 {
2175 _columnViewBox.getElement().getStyle().setProperty("top", (event.getY() + _label.getAbsoluteTop() + 25) + "px");
2176 }
2177 else
2178 {
2179 _columnViewBox.getElement().getStyle().setProperty("top", (event.getY() + _label.getAbsoluteTop() - 125) + "px");
2180 }
2181
2182 if (event.getX() + _label.getAbsoluteLeft() - 125 < documentText.getAbsoluteLeft())
2183 {
2184 _columnViewBox.getElement().getStyle().setProperty("left", documentText.getAbsoluteLeft() + "px");
2185 }
2186 else if (event.getX() + _label.getAbsoluteLeft() + 125 > documentText.getOffsetWidth() + documentText.getAbsoluteLeft())
2187 {
2188 _columnViewBox.getElement().getStyle().setProperty("left", documentText.getOffsetWidth() + documentText.getAbsoluteLeft() - 250 + "px");
2189 }
2190 else
2191 {
2192 _columnViewBox.getElement().getStyle().setProperty("left", (event.getX() + _label.getAbsoluteLeft() - 125) + "px");
2193 }
2194
2195 int midWordIndex = (int) (((float) (event.getY()) / ((_label.getAbsoluteTop() + _label.getOffsetHeight()) - _label.getAbsoluteTop())) * _words.size());
2196 int topWord = midWordIndex - 25;
2197 int botWord = midWordIndex + 25;
2198
2199 if (_words.size() < 50)
2200 {
2201 topWord = 0;
2202 botWord = _words.size();
2203 }
2204 else
2205 {
2206 if (topWord < 0)
2207 {
2208 topWord = 0;
2209 }
2210 else if (topWord > _words.size() - 50)
2211 {
2212 topWord = _words.size() - 50;
2213 }
2214
2215 if (botWord > _words.size())
2216 {
2217 botWord = _words.size();
2218 }
2219 else if (botWord < 50)
2220 {
2221 botWord = 50;
2222 }
2223 }
2224
2225 StringBuilder s = new StringBuilder();
2226
2227 for (int i = topWord; i < botWord; i++)
2228 {
2229 s.append(_words.get(i) + " ");
2230 }
2231
2232 _columnViewBox.getElement().setInnerHTML(s.toString());
2233 }
2234 }
2235
2236 public AsyncCallback<Boolean> setUpLoadGazetteerCallback()
2237 {
2238 AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>()
2239 {
2240 public void onFailure(Throwable caught)
2241 {
2242 logToConsole("Loading Gazetteer failed ->" + caught.getMessage());
2243 }
2244
2245 public void onSuccess(Boolean success)
2246 {
2247 logToConsole("Loading Gazetteer success!");
2248 _statusBar.removeUpdate("GazLoad");
2249 _gazetteerLoaded = true;
2250 }
2251 };
2252
2253 return callback;
2254 }
2255
2256 public void createDocumentMenu()
2257 {
2258 // Menu
2259 final Menu documentMenu = new Menu(_footerDiv.getElement(), new MouseOverHandler()
2260 {
2261 public void onMouseOver(MouseOverEvent event)
2262 {
2263 if(_menuOverTimer != null)
2264 {
2265 _menuOverTimer.cancel();
2266 _menuOverTimer = null;
2267 }
2268 Label item = (Label) event.getSource();
2269 item.getElement().getStyle().setProperty("background", "#0000FF");
2270 item.getElement().getStyle().setProperty("color", "#FFFFFF");
2271 item.getElement().getStyle().setProperty("border", "1px solid");
2272 if (_menuOutTimer != null)
2273 {
2274 _menuOutTimer.cancel();
2275 _menuOutTimer = null;
2276 }
2277 }
2278 }, new MouseOutHandler()
2279 {
2280 public void onMouseOut(MouseOutEvent event)
2281 {
2282 // logToConsole("MENU OUT!");
2283 Label item = (Label) event.getSource();
2284 item.getElement().getStyle().setProperty("background", "#FFFFFF");
2285 item.getElement().getStyle().setProperty("color", "#000000");
2286 item.getElement().getStyle().setProperty("border", "1px solid");
2287
2288 _menuOutTimer = new Timer()
2289 {
2290 public void run()
2291 {
2292 _currentDocumentMenu.hideMenu();
2293 }
2294 };
2295
2296 _menuOutTimer.schedule(500);
2297 }
2298 });
2299
2300 // Menu items
2301 ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();
2302 menuItems.add(new MenuItem("Centre this place on the map", new ClickHandler()
2303 {
2304 public void onClick(ClickEvent event)
2305 {
2306 Place place = null;
2307
2308 logToConsole("Center clicked, selected place name = " + _selectedPlaceName);
2309
2310 if ((place = _chosenPlaces.get(_selectedPlaceName)) == null)
2311 {
2312 for (int i = 0; i < _currentPlaces.size(); i++)
2313 {
2314 if (_currentPlaces.get(i).getName().equals(_selectedPlaceName))
2315 {
2316 place = _currentPlaces.get(i);
2317 break;
2318 }
2319 }
2320 }
2321
2322 if (place != null && place.getLatitude() != null && place.getLongitude() != null)
2323 {
2324 logToConsole("Centering map");
2325 _map.setCenter(LatLng.newInstance(place.getLatitude(), place.getLongitude()));
2326 }
2327
2328 _currentDocumentMenu.hideMenu();
2329 }
2330 }));
2331
2332 menuItems.add(new MenuItem("Highlight this place on the map", new ClickHandler()
2333 {
2334 public void onClick(ClickEvent event)
2335 {
2336 _highlightedPlaces.add(_selectedPlaceName);
2337 _map.clearOverlays();
2338 logToConsole("Overlays cleared");
2339 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", false);
2340 logToConsole("Places added");
2341
2342 _currentDocumentMenu.hideMenu();
2343 }
2344 }));
2345
2346 menuItems.add(new MenuItem("Highlight this place in the text", new ClickHandler()
2347 {
2348 public void onClick(ClickEvent event)
2349 {
2350 _highlightedTextPlaces.add(_selectedPlaceName);
2351
2352 JsArray<Element> places = getElementsByTagName("span");
2353
2354 for (int i = 0; i < places.length(); i++)
2355 {
2356 Element e = places.get(i);
2357
2358 if (e.getClassName() == "place" && e.getInnerText() == _selectedPlaceName)
2359 {
2360 e.getStyle().setProperty("background", "#FF0000");
2361 }
2362 }
2363
2364 _currentDocumentMenu.hideMenu();
2365 }
2366 }));
2367
2368 menuItems.add(new MenuItem("Remove all highlights", new ClickHandler()
2369 {
2370 public void onClick(ClickEvent event)
2371 {
2372 _highlightedPlaces.clear();
2373
2374 _map.clearOverlays();
2375 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", false);
2376
2377 JsArray<Element> places = getElementsByTagName("span");
2378
2379 for (int i = 0; i < places.length(); i++)
2380 {
2381 Element e = places.get(i);
2382
2383 if (e.getClassName() == "place" && _highlightedTextPlaces.contains(e.getInnerText()))
2384 {
2385 e.getStyle().setProperty("background", "#FFFF00");
2386 }
2387 }
2388 _highlightedTextPlaces.clear();
2389
2390 _currentDocumentMenu.hideMenu();
2391 }
2392 }));
2393
2394 final MenuItem prevMenuItem = new MenuItem("Remove this place", new ClickHandler()
2395 {
2396 public void onClick(ClickEvent event)
2397 {
2398 _removedPlaces.add(_selectedPlaceName);
2399 _currentDocumentMenu.hideMenu();
2400
2401 JsArray<Element> textPlaces = getElementsByTagName("span");
2402
2403 //Add the place spans to the array
2404 for (int j = 0; j < textPlaces.length(); j++)
2405 {
2406 Element e = textPlaces.get(j);
2407 if (e.getAttribute("class").equals("place") && e.getInnerText().equals(_selectedPlaceName))
2408 {
2409 e.getParentElement().insertBefore(e.getFirstChild(), e);
2410 }
2411 }
2412
2413 _map.clearOverlays();
2414 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", false);
2415 }
2416 });
2417 menuItems.add(prevMenuItem);
2418
2419 menuItems.add(new MenuItem("Choose correct place >", new ClickHandler()
2420 {
2421 public void onClick(ClickEvent event)
2422 {
2423 logToConsole("MARKER!");
2424 ArrayList<MenuItem> places = new ArrayList<MenuItem>();
2425
2426 ArrayList<Place> matchingPlaces = new ArrayList<Place>();
2427
2428 for (Place p : _currentPlaces)
2429 {
2430 if (p.getName().equals(_selectedPlaceName))
2431 {
2432 matchingPlaces.add(p);
2433 }
2434 }
2435
2436 for (final Place p : matchingPlaces)
2437 {
2438 places.add(new MenuItem(p.getName() + ((p.getParentPlaceName() != null) ? (", " + p.getParentPlaceName()) : (" (Country)")), new ClickHandler()
2439 {
2440 public void onClick(ClickEvent e)
2441 {
2442 _chosenPlaces.put(_selectedPlaceName, p);
2443
2444 _map.clearOverlays();
2445 logToConsole("Chose a new place!!!");
2446 addPlacesToMap(_currentPlaces, "#FFFFFF", "#00FF00", false);
2447 logToConsole("Places added!!!");
2448
2449 _currentDocumentMenu.hideMenu();
2450 }
2451 }));
2452 }
2453
2454 Menu placeMenu = new Menu(_footerDiv.getElement(), new MouseOverHandler()
2455 {
2456 public void onMouseOver(MouseOverEvent event)
2457 {
2458 Label item = (Label) event.getSource();
2459 item.getElement().getStyle().setProperty("background", "#0000FF");
2460 item.getElement().getStyle().setProperty("color", "#FFFFFF");
2461 if (_menuOutTimer != null)
2462 {
2463 _menuOutTimer.cancel();
2464 _menuOutTimer = null;
2465 }
2466 }
2467 }, new MouseOutHandler()
2468 {
2469 public void onMouseOut(MouseOutEvent event)
2470 {
2471 Label item = (Label) event.getSource();
2472 item.getElement().getStyle().setProperty("background", "#FFFFFF");
2473 item.getElement().getStyle().setProperty("color", "#000000");
2474
2475 _menuOutTimer = new Timer()
2476 {
2477 public void run()
2478 {
2479 _currentDocumentMenu.hideMenu();
2480 }
2481 };
2482
2483 _menuOutTimer.schedule(500);
2484 }
2485 });
2486
2487 documentMenu.addChildMenu(placeMenu);
2488 placeMenu.addMenuItems(places);
2489 placeMenu.moveMenu(_currentDocumentMenu.getMenuDiv().getAbsoluteLeft() + _currentDocumentMenu.getMenuDiv().getOffsetWidth(), prevMenuItem.getMenuElement().getAbsoluteTop() + prevMenuItem.getMenuElement().getOffsetHeight() - 2);
2490 placeMenu.showMenu();
2491 }
2492 }){
2493 public boolean condition()
2494 {
2495 ArrayList<Place> matchingPlaces = new ArrayList<Place>();
2496
2497 if(_currentPlaces == null || _currentPlaces.size() == 0)
2498 {
2499 return false;
2500 }
2501
2502 for (Place p : _currentPlaces)
2503 {
2504 if (p.getName().equals(_selectedPlaceName))
2505 {
2506 matchingPlaces.add(p);
2507 }
2508 }
2509
2510 if(matchingPlaces.size() > 1)
2511 {
2512 return true;
2513 }
2514 return false;
2515 }
2516 });
2517
2518 documentMenu.addMenuItems(menuItems);
2519 documentMenu.hideMenu();
2520 _currentDocumentMenu = documentMenu;
2521 }
2522
2523 public void startDocumentMouseOverTimer(final int x, final int y)
2524 {
2525 _documentMouseOverTimer = new Timer()
2526 {
2527 public void run()
2528 {
2529 _currentDocumentMenu.moveMenu(x, y);
2530 _currentDocumentMenu.showMenu();
2531
2532 _documentMouseOverTimer = null;
2533 }
2534 };
2535
2536 _documentMouseOverTimer.schedule(1000);
2537 }
2538
2539 /**
2540 * Gets the document text element from the web page
2541 * @return the document text element
2542 */
2543 public Element getDocTextElement()
2544 {
2545 JsArray<Element> divs = getElementsByTagName("div");
2546
2547 Element documentText = null;
2548 for (int i = 0; i < divs.length(); i++)
2549 {
2550 if (divs.get(i).getAttribute("class").equals("documenttext"))
2551 {
2552 documentText = divs.get(i);
2553 break;
2554 }
2555 }
2556
2557 return documentText;
2558 }
2559
2560 public void addElementsToSearchResults(ArrayList<ArrayList<Place>> places)
2561 {
2562 JsArray<Element> elements = getElementsByTagName("li");
2563 ArrayList<Element> listElements = new ArrayList<Element>();
2564
2565 for (int i = 0; i < elements.length(); i++)
2566 {
2567 if (elements.get(i).getAttribute("class").equals("document"))
2568 {
2569 listElements.add(elements.get(i));
2570 }
2571 }
2572
2573 for (int i = 0; i < listElements.size(); i++)
2574 {
2575 Element span = DOM.createSpan();
2576 listElements.get(i).insertBefore(span, listElements.get(i).getFirstChild());
2577 span.getStyle().setBackgroundColor(numToColour(i, listElements.size(), 100, 255));
2578 span.getStyle().setColor(numToColour(i, listElements.size(), 100, 255));
2579 span.setInnerText("...");
2580
2581 Element checkBoxSpan = DOM.createSpan();
2582 listElements.get(i).insertBefore(checkBoxSpan, listElements.get(i).getFirstChild());
2583 checkBoxSpan.setId("Result" + i);
2584
2585 CheckBox c = new CheckBox();
2586 c.setValue(true);
2587 c.addValueChangeHandler(new SearchResultsCheckBoxChangeHandler(i));
2588 RootPanel.get("Result" + i).add(c);
2589 }
2590 }
2591
2592 public class SearchResultsCheckBoxChangeHandler implements ValueChangeHandler<Boolean>
2593 {
2594 int _index = -1;
2595
2596 public SearchResultsCheckBoxChangeHandler(int index)
2597 {
2598 _index = index;
2599 }
2600
2601 public void onValueChange(ValueChangeEvent<Boolean> event)
2602 {
2603 if (event.getValue())
2604 {
2605 _visiblePlaceSets.set(_index, true);
2606 }
2607 else
2608 {
2609 _visiblePlaceSets.set(_index, false);
2610 }
2611
2612 _map.clearOverlays();
2613 displayMultiplePlaceSets();
2614 }
2615 }
2616
2617 public class DocumentOverHandler implements MouseOverHandler
2618 {
2619 int _index = -1;
2620
2621 public DocumentOverHandler(int index)
2622 {
2623 _index = index;
2624 }
2625
2626 public void onMouseOver(MouseOverEvent event)
2627 {
2628 Label currentLabel = (Label) event.getSource();
2629 currentLabel.setStyleName("placeOver");
2630
2631 startDocumentMouseOverTimer(event.getX() + currentLabel.getAbsoluteLeft(), event.getY() + currentLabel.getAbsoluteTop());
2632 }
2633 }
2634
2635 public class PlaceMouseOverHandler implements MouseOverHandler
2636 {
2637 public void onMouseOver(MouseOverEvent event)
2638 {
2639 Label currentLabel = (Label) event.getSource();
2640 currentLabel.setStyleName("placeOver");
2641
2642 _selectedPlaceName = currentLabel.getElement().getInnerText();
2643
2644 startPlaceMouseOverTimer(event.getX() + currentLabel.getAbsoluteLeft(), event.getY() + currentLabel.getAbsoluteTop());
2645 }
2646 }
2647
2648 public class PlaceMouseOutHandler implements MouseOutHandler
2649 {
2650 public void onMouseOut(MouseOutEvent event)
2651 {
2652 Label currentLabel = (Label) event.getSource();
2653 currentLabel.setStyleName("place");
2654
2655 if (_placeMouseOverTimer != null)
2656 {
2657 _placeMouseOverTimer.cancel();
2658 _placeMouseOverTimer = null;
2659 }
2660 }
2661 }
2662
2663 public class PlaceMouseUpHandler implements MouseUpHandler
2664 {
2665 public void onMouseUp(MouseUpEvent event)
2666 {
2667 Label currentLabel = (Label) event.getSource();
2668 currentLabel.setStyleName("place");
2669 if(event.getNativeButton() == NativeEvent.BUTTON_LEFT)
2670 {
2671 String placeName = currentLabel.getText();
2672 Place place = _chosenPlaces.get(placeName);
2673
2674 if(place == null)
2675 {
2676 for(Place p : _currentPlaces)
2677 {
2678 if(p.getName().equals(placeName))
2679 {
2680 place = p;
2681 break;
2682 }
2683 }
2684 }
2685
2686 if(place != null && place.getLatitude() != null && place.getLongitude() != null)
2687 {
2688 _map.setCenter(LatLng.newInstance(place.getLatitude(), place.getLongitude()));
2689 }
2690 }
2691 /*
2692 else if(event.getNativeButton() == NativeEvent.BUTTON_RIGHT)
2693 {
2694 _currentDocumentMenu.moveMenu(event.getX() + currentLabel.getAbsoluteLeft(), event.getY() + currentLabel.getAbsoluteTop());
2695 _currentDocumentMenu.showMenu();
2696 }
2697 */
2698 }
2699 }
2700
2701 public void startPlaceMouseOverTimer(final int x, final int y)
2702 {
2703 _placeMouseOverTimer = new Timer()
2704 {
2705 public void run()
2706 {
2707 _currentDocumentMenu.refreshMenu();
2708 _currentDocumentMenu.moveMenu(x, y);
2709 _currentDocumentMenu.showMenu();
2710
2711 _menuOverTimer = new Timer()
2712 {
2713 public void run()
2714 {
2715 _menuOverTimer = null;
2716 _currentDocumentMenu.hideMenu();
2717 }
2718 };
2719 _menuOverTimer.schedule(4000);
2720
2721 _placeMouseOverTimer = null;
2722 }
2723 };
2724
2725 _placeMouseOverTimer.schedule(1000);
2726 }
2727
2728 public class FishEyeMouseMoveHandler implements MouseMoveHandler
2729 {
2730 public void onMouseMove(MouseMoveEvent e)
2731 {
2732 if (!_mouseEventPause)
2733 {
2734 _mouseEventPause = true;
2735 passMouseCoordsToFishEye(e.getY());
2736 Timer pauseTimer = new Timer()
2737 {
2738 public void run()
2739 {
2740 _mouseEventPause = false;
2741 }
2742 };
2743 pauseTimer.schedule(50);
2744 }
2745 }
2746 }
2747
2748 /**
2749 * This class contains methods that initialise and control the spatial search controls present on the map during a spatial search
2750 */
2751 public class SpatialSearchControls extends CustomControl
2752 {
2753 /**
2754 * Inherited parent constructor
2755 */
2756 protected SpatialSearchControls(ControlPosition arg0)
2757 {
2758 super(arg0);
2759 }
2760
2761 /**
2762 * Second inherited parent constructor
2763 */
2764 protected SpatialSearchControls(ControlPosition arg0, boolean arg1, boolean arg2)
2765 {
2766 super(arg0, arg1, arg2);
2767 }
2768
2769 /**
2770 * Initialises the control buttons
2771 */
2772 protected Widget initialize(MapWidget map)
2773 {
2774 //Create the panel to store the buttons
2775 HorizontalPanel panel = new HorizontalPanel();
2776
2777 //Create the button that clears the user's currently created points
2778 Button clearButton = new Button("Clear Points", new ClickHandler()
2779 {
2780 public void onClick(ClickEvent event)
2781 {
2782 _areaPoints.clear();
2783 _map.clearOverlays();
2784 }
2785 });
2786
2787 //Create the button the performs the spatial search
2788 Button performSearch = new Button("Search Area", new ClickHandler()
2789 {
2790 public void onClick(ClickEvent event)
2791 {
2792 //If the users has marked less than 3 points on the map then we cannot perform a spatial search
2793 if (_areaPoints.size() < 3)
2794 {
2795 //Show an error message on the status bar
2796 _statusBar.removeUpdate("SpatialWarn");
2797 _statusBar.addUpdate("A minimum of 3 points is needed on the map to perform a spatial search", "SpatialWarn");
2798
2799 //Remove the message after 5 seconds
2800 Timer warningRemoveTimer = new Timer()
2801 {
2802 public void run()
2803 {
2804 _statusBar.removeUpdate("SpatialWarn");
2805 }
2806 };
2807 warningRemoveTimer.schedule(5000);
2808
2809 return;
2810 }
2811
2812 ArrayList<Float[]> points = new ArrayList<Float[]>();
2813
2814 //Turn the points into a list of float arrays
2815 for (LatLng point : _areaPoints)
2816 {
2817 points.add(new Float[] { (float) point.getLatitude(), (float) point.getLongitude() });
2818 }
2819
2820 //Ask the server to perform the spatial search
2821 _findPlaceService.spatialSearch(points, getSpatialSearchCallback());
2822 }
2823 });
2824
2825 //Add the two buttons to the panel
2826 panel.add(clearButton);
2827 panel.add(performSearch);
2828
2829 return panel;
2830 }
2831
2832 /**
2833 * Creates and returns the callback necessary to perform a spatial search on the server
2834 * @return the callback object
2835 */
2836 public AsyncCallback<ArrayList<String>> getSpatialSearchCallback()
2837 {
2838 return new AsyncCallback<ArrayList<String>>()
2839 {
2840 /**
2841 * If the call to the server failed then this is called
2842 * @see com.google.gwt.user.client.rpc.AsyncCallback#onFailure(java.lang.Throwable)
2843 */
2844 public void onFailure(Throwable arg0)
2845 {
2846 logToConsole("Spatial search FAIL!");
2847 }
2848
2849 /**
2850 * If the call to the server succeeded then this is called
2851 * @param placeNames is the places found within the spatial search polygon
2852 */
2853 public void onSuccess(ArrayList<String> placeNames)
2854 {
2855 logToConsole("Spatial search Success!");
2856
2857 //Create the query to pass to Greenstone
2858 StringBuffer query = new StringBuffer();
2859 for (int j = 0; j < placeNames.size() && j < 20; j++)
2860 {
2861 if (j == 0)
2862 {
2863 query.append(placeNames.get(j).replaceAll(" ", "+").replaceAll("-", "+"));
2864 }
2865 else
2866 {
2867 query.append("+" + placeNames.get(j).replaceAll(" ", "+").replaceAll("-", "+"));
2868 }
2869 }
2870
2871 logToConsole("Query -> " + query);
2872 logToConsole("Collection -> " + _currentCollection);
2873
2874 //Create an invisible form
2875 FormPanel form = new FormPanel();
2876 form.setAction(_GREENSTONEDEVURL);
2877 form.setMethod(FormPanel.METHOD_POST);
2878 form.getElement().setAttribute("target", "_self");
2879
2880 VerticalPanel tempForm = new VerticalPanel();
2881 form.setWidget(tempForm);
2882
2883 getElementsByTagName("body").get(0).appendChild(form.getElement());
2884
2885 logToConsole("Adding hidden form elements");
2886
2887 Hidden a = new Hidden("a", "q");
2888 tempForm.add(a);
2889 Hidden sa = new Hidden("sa");
2890 tempForm.add(sa);
2891 Hidden rt = new Hidden("rt", "rd");
2892 tempForm.add(rt);
2893 Hidden s = new Hidden("s", "TextQuery");
2894 tempForm.add(s);
2895 Hidden c = new Hidden("c", _currentCollection);
2896 tempForm.add(c);
2897 Hidden startPage = new Hidden("startPage", "1");
2898 tempForm.add(startPage);
2899 Hidden s1level = new Hidden("s1.level", "Sec");
2900 tempForm.add(s1level);
2901 Hidden s1case = new Hidden("s1.case", "1");
2902 tempForm.add(s1case);
2903 Hidden s1stem = new Hidden("s1.stem", "0");
2904 tempForm.add(s1stem);
2905 Hidden s1accent = new Hidden("s1.accent", "0");
2906 tempForm.add(s1accent);
2907 Hidden s1matchMode = new Hidden("s1.matchMode", "some");
2908 tempForm.add(s1matchMode);
2909 Hidden s1sort = new Hidden("s1.sortBy", "1");
2910 tempForm.add(s1sort);
2911 Hidden s1index = new Hidden("s1.index", "ZZ");
2912 tempForm.add(s1index);
2913 Hidden s1maxDocs = new Hidden("s1.maxDocs", "100");
2914 tempForm.add(s1maxDocs);
2915 Hidden s1query = new Hidden("s1.query", query.toString());
2916 tempForm.add(s1query);
2917
2918 logToConsole("Submitting");
2919
2920 form.submit();
2921
2922 logToConsole("Loading results page");
2923
2924 loadPageWithoutUrl();
2925 }
2926 };
2927 }
2928
2929 public boolean isSelectable()
2930 {
2931 return false;
2932 }
2933 }
2934
2935 public static FindPlaceServiceAsync getServerConnection()
2936 {
2937 return _findPlaceService;
2938 }
2939}
Note: See TracBrowser for help on using the repository browser.