--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ * Semantum Oy\r
+ *******************************************************************************/\r
+package org.simantics.workbench.internal.contributions.search;\r
+\r
+import java.net.URL;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.browser.Browser;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.layer0.request.ActiveModels;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextChangedListener;\r
+import org.simantics.db.management.SessionContextChangedEvent;\r
+import org.simantics.db.service.LifecycleSupport;\r
+import org.simantics.utils.ui.SWTUtils;\r
+import org.simantics.workbench.search.ISearchService;\r
+import org.simantics.workbench.search.ISearchService.ResultBrowser;\r
+import org.simantics.workbench.search.SearchQuery;\r
+\r
+/**\r
+ * A very non-configurable Web browser view for search trim.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class BrowserView extends ViewPart {\r
+\r
+ /**\r
+ * ID of this view's plug-in extension.\r
+ */\r
+ public static final String ID = "org.simantics.workbench.search.browser";\r
+\r
+ /**\r
+ * Used as a property of this view to keep track of the last search query\r
+ * performed with this view. This information is needed to know whether or\r
+ * not to initialize the view with default contents after it has been\r
+ * created. This depends on whether the creation was caused by a simple\r
+ * activation of the view or an actual search being performed.\r
+ */\r
+ public static final String LAST_QUERY_PROPERTY = "org.simantics.workbench.search.browser.lastQuery";\r
+\r
+ private Browser browser;\r
+ private boolean disposed;\r
+ private ActiveModelsListener currentListener;\r
+\r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ browser = new org.eclipse.swt.browser.Browser(parent, SWT.NONE);\r
+\r
+ // Ensure the view receives some browser content even when no searches\r
+ // have been performed yet.\r
+ scheduleInitializeViewContent(false);\r
+\r
+ // Make sure that the contents of the view are reset every time the set\r
+ // of active models changes. This must be because what is searchable depends\r
+ // completely on the active models. When there is no active model, the search\r
+ // will find nothing.\r
+ Simantics.getSessionContextProvider().addContextChangedListener(sessionListener);\r
+ trackActiveModels(Simantics.peekSession());\r
+ }\r
+\r
+ private ISessionContextChangedListener sessionListener = new ISessionContextChangedListener() {\r
+ @Override\r
+ public void sessionContextChanged(SessionContextChangedEvent event) {\r
+ ISessionContext ctx = event.getNewValue();\r
+ final Session newSession = ctx != null ? ctx.peekSession() : null;\r
+ // Synchronize session changes to the UI thread to keep threading more predictable.\r
+ SWTUtils.asyncExec(browser, new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (!disposed)\r
+ trackActiveModels(newSession);\r
+ }\r
+ });\r
+ }\r
+ };\r
+\r
+ private void trackActiveModels(Session session) {\r
+ if (currentListener != null) {\r
+ currentListener.dispose();\r
+ currentListener = null;\r
+ }\r
+ if (session != null) {\r
+ \r
+ LifecycleSupport lfs = session.peekService(LifecycleSupport.class);\r
+ if (lfs == null)\r
+ return;\r
+ if (lfs.isClosed())\r
+ return;\r
+ \r
+ ActiveModelsListener listener = new ActiveModelsListener(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ scheduleInitializeViewContent(true);\r
+ }\r
+ });\r
+ \r
+ // Make sure that the listener is disposed if the session is disposed.\r
+ session.registerService(ActiveModelsListener.class, listener);\r
+ session.asyncRequest(new ActiveModels(Simantics.getProjectResource()), listener);\r
+ this.currentListener = listener;\r
+ }\r
+ }\r
+\r
+ protected void scheduleInitializeViewContent(final boolean force) {\r
+ SWTUtils.asyncExec(browser, new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (disposed)\r
+ return;\r
+ // If SearchServiceImpl hasn't performed any queries yet,\r
+ // then we shall initialize the view contents at this point.\r
+ String lastQuery = getPartProperty(LAST_QUERY_PROPERTY);\r
+ if (force || lastQuery == null)\r
+ initializeViewContent();\r
+ }\r
+ });\r
+ }\r
+\r
+ protected void initializeViewContent() {\r
+ SearchQuery query = new SearchQuery("");\r
+ query.setSearchFlag("Name", "on");\r
+ query.setSearchFlag("Types", "on");\r
+ ISearchService searchService = (ISearchService) PlatformUI.getWorkbench().getService(ISearchService.class);\r
+ if (searchService != null)\r
+ searchService.performQuery(query, ResultBrowser.VIEW, false);\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ disposed = true;\r
+ super.dispose();\r
+ }\r
+\r
+ public boolean isDisposed() {\r
+ return disposed;\r
+ }\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ browser.setFocus();\r
+ }\r
+\r
+ public org.eclipse.swt.browser.Browser getBrowser() {\r
+ return browser;\r
+ }\r
+\r
+ public void setUrl(URL url) {\r
+ getBrowser().setUrl(url.toString());\r
+ }\r
+\r
+ @Override\r
+ public void setContentDescription(String description) {\r
+ super.setContentDescription(description);\r
+ }\r
+\r
+}\r