001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.shell;
017:
018: import com.google.gwt.core.ext.TreeLogger;
019: import com.google.gwt.core.ext.UnableToCompleteException;
020: import com.google.gwt.dev.GWTShell;
021: import com.google.gwt.dev.util.Util;
022: import com.google.gwt.dev.util.log.AbstractTreeLogger;
023: import com.google.gwt.dev.util.log.TreeLoggerWidget;
024:
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.events.DisposeEvent;
027: import org.eclipse.swt.events.DisposeListener;
028: import org.eclipse.swt.events.SelectionAdapter;
029: import org.eclipse.swt.events.SelectionEvent;
030: import org.eclipse.swt.events.ShellEvent;
031: import org.eclipse.swt.events.ShellListener;
032: import org.eclipse.swt.graphics.Color;
033: import org.eclipse.swt.layout.FillLayout;
034: import org.eclipse.swt.layout.GridData;
035: import org.eclipse.swt.layout.GridLayout;
036: import org.eclipse.swt.widgets.Composite;
037: import org.eclipse.swt.widgets.Shell;
038: import org.eclipse.swt.widgets.ToolItem;
039:
040: /**
041: * Implements the GWTShell's main window control.
042: */
043: public class ShellMainWindow extends Composite implements
044: DisposeListener, ShellListener {
045:
046: private class Toolbar extends HeaderBarBase {
047:
048: private ToolItem about;
049:
050: private ToolItem clearLog;
051: private ToolItem collapseAll;
052: private ToolItem expandAll;
053: private ToolItem newWindow;
054:
055: public Toolbar(Composite parent) {
056: super (parent);
057:
058: newWindow = newItem("new-window.gif", "&Hosted Browser",
059: "Opens a new hosted mode browser window for debugging");
060: newWindow.addSelectionListener(new SelectionAdapter() {
061: @Override
062: public void widgetSelected(SelectionEvent event) {
063: String startupUrl = serverWindow.normalizeURL("/");
064: try {
065: BrowserWidget bw = serverWindow
066: .openNewBrowserWindow();
067: bw.go(startupUrl);
068: } catch (UnableToCompleteException e) {
069: getLogger()
070: .log(
071: TreeLogger.ERROR,
072: "Unable to open a new hosted browser window",
073: e);
074: }
075: }
076: });
077:
078: newSeparator();
079:
080: collapseAll = newItem("collapse.gif", "&Collapse All",
081: "Collapses all log entries");
082: collapseAll.addSelectionListener(new SelectionAdapter() {
083: @Override
084: public void widgetSelected(SelectionEvent e) {
085: logPane.collapseAll();
086: }
087: });
088:
089: expandAll = newItem("expand.gif", "&Expand All",
090: "Expands all log entries");
091: expandAll.addSelectionListener(new SelectionAdapter() {
092: @Override
093: public void widgetSelected(SelectionEvent e) {
094: logPane.expandAll();
095: }
096: });
097:
098: clearLog = newItem("clear-log.gif", "Clear &Log",
099: "Removes all log entries");
100: clearLog.addSelectionListener(new SelectionAdapter() {
101: @Override
102: public void widgetSelected(SelectionEvent e) {
103: logPane.removeAll();
104: }
105: });
106:
107: newSeparator();
108:
109: about = newItem("about.gif", " &About ", "About...");
110: about.addSelectionListener(new SelectionAdapter() {
111: @Override
112: public void widgetSelected(SelectionEvent e) {
113: String aboutHtml = Util
114: .getFileFromInstallPath("about.html");
115: if (aboutHtml != null) {
116: String serial = verify("TwysxNpVumPBvFyBoxzLy");
117: StringBuffer sb = new StringBuffer();
118: sb
119: .append("<div style='overflow:hidden;width:100%;white-space:nowrap;font-size:1px'><br/><br/><br/><br/><font style='background-color:gray;color:lightgrey'>");
120: for (int i = 0; i < 100; ++i) {
121: sb.append(serial);
122: }
123: sb.append("</font></div>");
124: serial = sb.toString();
125: int pos;
126: while ((pos = aboutHtml.indexOf("<hr/>")) >= 0) {
127: aboutHtml = aboutHtml.substring(0, pos)
128: + serial
129: + aboutHtml.substring(pos + 5);
130: }
131: while ((pos = aboutHtml.indexOf("<body>")) >= 0) {
132: aboutHtml = aboutHtml.substring(0, pos)
133: + "<body oncontextmenu='return false'>"
134: + aboutHtml.substring(pos + 6);
135: }
136: } else {
137: aboutHtml = "Could not locate 'about.html' in installation directory.";
138: }
139: BrowserDialog browserDialog = new BrowserDialog(
140: getShell(), getLogger(), aboutHtml);
141: browserDialog.open(true);
142: }
143: });
144: }
145: }
146:
147: private static String verify(String hash) {
148: char[] in = hash.toCharArray();
149: char[] ou = new char[in.length];
150: for (int i = 0, c = 0; i < in.length; ++i) {
151: if (in[i] < 'a') {
152: c += in[i] - 'A';
153: } else {
154: c += in[i] - 'a' - 26;
155: }
156:
157: if (c == 0) {
158: ou[i] = ' ';
159: } else {
160: ou[i] = (char) ('@' + c);
161: }
162: }
163: return String.valueOf(ou);
164: }
165:
166: private Color colorWhite;
167:
168: private TreeLoggerWidget logPane;
169:
170: private GWTShell serverWindow;
171:
172: private Toolbar toolbar;
173:
174: public ShellMainWindow(GWTShell serverWindow, final Shell parent,
175: int serverPort, boolean checkForUpdates) {
176: super (parent, SWT.NONE);
177:
178: this .serverWindow = serverWindow;
179:
180: colorWhite = new Color(null, 255, 255, 255);
181:
182: addDisposeListener(this );
183: parent.addShellListener(this );
184:
185: setLayout(new FillLayout());
186: if (serverPort > 0) {
187: parent
188: .setText("Google Web Toolkit Development Shell / Port "
189: + serverPort);
190: } else {
191: parent.setText("Google Web Toolkit Development Shell");
192: }
193:
194: GridLayout gridLayout = new GridLayout(1, true);
195: gridLayout.marginWidth = 0;
196: gridLayout.marginHeight = 0;
197: gridLayout.horizontalSpacing = 0;
198: gridLayout.verticalSpacing = 0;
199: setLayout(gridLayout);
200:
201: // Create the toolbar.
202: //
203: {
204: toolbar = new Toolbar(this );
205: GridData data = new GridData();
206: data.grabExcessHorizontalSpace = true;
207: data.horizontalAlignment = GridData.FILL;
208: toolbar.setLayoutData(data);
209: }
210:
211: // Create the log pane.
212: //
213: {
214: logPane = new TreeLoggerWidget(this );
215: GridData data = new GridData();
216: data.grabExcessHorizontalSpace = true;
217: data.grabExcessVerticalSpace = true;
218: data.horizontalAlignment = GridData.FILL;
219: data.verticalAlignment = GridData.FILL;
220: logPane.setLayoutData(data);
221: }
222:
223: // check for updates
224: if (checkForUpdates) {
225: try {
226: final CheckForUpdates updateChecker = PlatformSpecific
227: .createUpdateChecker();
228: if (updateChecker != null) {
229: final CheckForUpdates.UpdateAvailableCallback callback = new CheckForUpdates.UpdateAvailableCallback() {
230: public void onUpdateAvailable(final String html) {
231: // Do this on the main thread.
232: //
233: parent.getDisplay().asyncExec(
234: new Runnable() {
235: public void run() {
236: new BrowserDialog(parent,
237: getLogger(), html)
238: .open(true);
239: }
240:
241: });
242: }
243: };
244:
245: // Run the update checker on a background thread.
246: //
247: Thread checkerThread = new Thread() {
248: @Override
249: public void run() {
250: updateChecker.check(callback);
251: }
252: };
253:
254: checkerThread.setDaemon(true);
255: checkerThread.start();
256: }
257: } catch (Throwable e) {
258: // Always silently ignore any errors.
259: }
260: }
261: }
262:
263: public AbstractTreeLogger getLogger() {
264: return logPane.getLogger();
265: }
266:
267: public void shellActivated(ShellEvent e) {
268: }
269:
270: public void shellClosed(ShellEvent e) {
271: if (serverWindow.hasBrowserWindowsOpen()) {
272: boolean closeWindows = true;
273: if (System.getProperty("gwt.shell.endquick") == null) {
274: closeWindows = DialogBase
275: .confirmAction(
276: (Shell) e.widget,
277: "Closing the development shell will close "
278: + "all hosted mode browsers. Continue?",
279: "Confirm close");
280: }
281:
282: if (closeWindows) {
283: serverWindow.closeAllBrowserWindows();
284: e.doit = true;
285: } else {
286: e.doit = false;
287: }
288: }
289: }
290:
291: public void shellDeactivated(ShellEvent e) {
292: }
293:
294: public void shellDeiconified(ShellEvent e) {
295: }
296:
297: public void shellIconified(ShellEvent e) {
298: }
299:
300: public void widgetDisposed(DisposeEvent e) {
301: colorWhite.dispose();
302: }
303: }
|