Source Code Cross Referenced for Browser.java in  » Ajax » GWT » org » eclipse » swt » browser » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » GWT » org.eclipse.swt.browser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2003, 2006 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.swt.browser;
0011:
0012:        import org.eclipse.swt.*;
0013:        import org.eclipse.swt.graphics.*;
0014:        import org.eclipse.swt.internal.ole.win32.*;
0015:        import org.eclipse.swt.internal.win32.*;
0016:        import org.eclipse.swt.ole.win32.*;
0017:        import org.eclipse.swt.widgets.*;
0018:
0019:        /**
0020:         * Instances of this class implement the browser user interface
0021:         * metaphor.  It allows the user to visualize and navigate through
0022:         * HTML documents.
0023:         * <p>
0024:         * Note that although this class is a subclass of <code>Composite</code>,
0025:         * it does not make sense to set a layout on it.
0026:         * </p><p>
0027:         * IMPORTANT: This class is <em>not</em> intended to be subclassed.
0028:         * </p>
0029:         * 
0030:         * @since 3.0
0031:         */
0032:        public class Browser extends Composite {
0033:
0034:            OleFrame frame;
0035:            OleControlSite site;
0036:            OleAutomation auto;
0037:
0038:            boolean back, forward, navigate, delaySetText, ignoreDispose;
0039:            Point location;
0040:            Point size;
0041:            boolean addressBar = true, menuBar = true, statusBar = true,
0042:                    toolBar = true;
0043:            int info;
0044:
0045:            int globalDispatch;
0046:            String html;
0047:
0048:            /* External Listener management */
0049:            CloseWindowListener[] closeWindowListeners = new CloseWindowListener[0];
0050:            LocationListener[] locationListeners = new LocationListener[0];
0051:            OpenWindowListener[] openWindowListeners = new OpenWindowListener[0];
0052:            ProgressListener[] progressListeners = new ProgressListener[0];
0053:            StatusTextListener[] statusTextListeners = new StatusTextListener[0];
0054:            TitleListener[] titleListeners = new TitleListener[0];
0055:            VisibilityWindowListener[] visibilityWindowListeners = new VisibilityWindowListener[0];
0056:
0057:            static final int BeforeNavigate2 = 0xfa;
0058:            static final int CommandStateChange = 0x69;
0059:            static final int DocumentComplete = 0x103;
0060:            static final int NavigateComplete2 = 0xfc;
0061:            static final int NewWindow2 = 0xfb;
0062:            static final int OnMenuBar = 0x100;
0063:            static final int OnStatusBar = 0x101;
0064:            static final int OnToolBar = 0xff;
0065:            static final int OnVisible = 0xfe;
0066:            static final int ProgressChange = 0x6c;
0067:            static final int RegisterAsBrowser = 0x228;
0068:            static final int StatusTextChange = 0x66;
0069:            static final int TitleChange = 0x71;
0070:            static final int WindowClosing = 0x107;
0071:            static final int WindowSetHeight = 0x10b;
0072:            static final int WindowSetLeft = 0x108;
0073:            static final int WindowSetResizable = 0x106;
0074:            static final int WindowSetTop = 0x109;
0075:            static final int WindowSetWidth = 0x10a;
0076:
0077:            static final short CSC_NAVIGATEFORWARD = 1;
0078:            static final short CSC_NAVIGATEBACK = 2;
0079:            static final int INET_E_DEFAULT_ACTION = 0x800C0011;
0080:            static final int READYSTATE_COMPLETE = 4;
0081:            static final int URLPOLICY_ALLOW = 0x00;
0082:            static final int URLPOLICY_DISALLOW = 0x03;
0083:            static final int URLZONE_LOCAL_MACHINE = 0;
0084:            static final int URLZONE_INTRANET = 1;
0085:            static final int URLACTION_ACTIVEX_MIN = 0x00001200;
0086:            static final int URLACTION_ACTIVEX_MAX = 0x000013ff;
0087:            static final int URLACTION_ACTIVEX_RUN = 0x00001200;
0088:            static final int URLACTION_JAVA_MIN = 0x00001C00;
0089:            static final int URLPOLICY_JAVA_LOW = 0x00030000;
0090:            static final int URLACTION_JAVA_MAX = 0x00001Cff;
0091:
0092:            static final int DISPID_AMBIENT_DLCONTROL = -5512;
0093:            static final int DLCTL_DLIMAGES = 0x00000010;
0094:            static final int DLCTL_VIDEOS = 0x00000020;
0095:            static final int DLCTL_BGSOUNDS = 0x00000040;
0096:            static final int DLCTL_NO_SCRIPTS = 0x00000080;
0097:            static final int DLCTL_NO_JAVA = 0x00000100;
0098:            static final int DLCTL_NO_RUNACTIVEXCTLS = 0x00000200;
0099:            static final int DLCTL_NO_DLACTIVEXCTLS = 0x00000400;
0100:            static final int DLCTL_DOWNLOADONLY = 0x00000800;
0101:            static final int DLCTL_NO_FRAMEDOWNLOAD = 0x00001000;
0102:            static final int DLCTL_RESYNCHRONIZE = 0x00002000;
0103:            static final int DLCTL_PRAGMA_NO_CACHE = 0x00004000;
0104:            static final int DLCTL_FORCEOFFLINE = 0x10000000;
0105:            static final int DLCTL_NO_CLIENTPULL = 0x20000000;
0106:            static final int DLCTL_SILENT = 0x40000000;
0107:            static final int DOCHOSTUIFLAG_THEME = 0x00040000;
0108:            static final int DOCHOSTUIFLAG_NO3DBORDER = 0x0000004;
0109:            static final int DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000;
0110:
0111:            static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
0112:            static final String CLSID_SHELLEXPLORER1 = "{EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B}";
0113:            static final String URL_DIRECTOR = "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab"; //$NON-NLS-1$
0114:
0115:            /* Package Name */
0116:            static final String PACKAGE_PREFIX = "org.eclipse.swt.browser."; //$NON-NLS-1$
0117:
0118:            /**
0119:             * Constructs a new instance of this class given its parent
0120:             * and a style value describing its behavior and appearance.
0121:             * <p>
0122:             * The style value is either one of the style constants defined in
0123:             * class <code>SWT</code> which is applicable to instances of this
0124:             * class, or must be built by <em>bitwise OR</em>'ing together 
0125:             * (that is, using the <code>int</code> "|" operator) two or more
0126:             * of those <code>SWT</code> style constants. The class description
0127:             * lists the style constants that are applicable to the class.
0128:             * Style bits are also inherited from superclasses.
0129:             * </p>
0130:             *
0131:             * @param parent a widget which will be the parent of the new instance (cannot be null)
0132:             * @param style the style of widget to construct
0133:             *
0134:             * @exception IllegalArgumentException <ul>
0135:             *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
0136:             * </ul>
0137:             * @exception SWTException <ul>
0138:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0139:             * </ul>
0140:             * @exception SWTError <ul>
0141:             *    <li>ERROR_NO_HANDLES if a handle could not be obtained for browser creation</li>
0142:             * </ul>
0143:             * 
0144:             * @see Widget#getStyle
0145:             * 
0146:             * @since 3.0
0147:             */
0148:            public Browser(Composite parent, int style) {
0149:                super (parent, style & ~SWT.BORDER);
0150:                info = Browser.DOCHOSTUIFLAG_THEME;
0151:                if ((style & SWT.BORDER) == 0)
0152:                    info |= Browser.DOCHOSTUIFLAG_NO3DOUTERBORDER;
0153:                frame = new OleFrame(this , SWT.NONE);
0154:
0155:                /*
0156:                 * Registry entry HKEY_CLASSES_ROOT\Shell.Explorer\CLSID indicates which version of
0157:                 * Shell.Explorer to use by default.  We usually want to use this value because it
0158:                 * typically points at the newest one that is available.  However it is possible for
0159:                 * this registry entry to be changed by another application to point at some other
0160:                 * Shell.Explorer version.
0161:                 *
0162:                 * The Browser depends on the Shell.Explorer version being at least Shell.Explorer.2.
0163:                 * If it is detected in the registry to be Shell.Explorer.1 then change the progId that
0164:                 * will be embedded to explicitly specify Shell.Explorer.2.
0165:                 */
0166:                String progId = "Shell.Explorer"; //$NON-NLS-1$
0167:                TCHAR key = new TCHAR(0, "Shell.Explorer\\CLSID", true); //$NON-NLS-1$
0168:                int[] phkResult = new int[1];
0169:                if (OS.RegOpenKeyEx(OS.HKEY_CLASSES_ROOT, key, 0, OS.KEY_READ,
0170:                        phkResult) == 0) {
0171:                    int[] lpcbData = new int[1];
0172:                    int result = OS.RegQueryValueEx(phkResult[0], null, 0,
0173:                            null, (TCHAR) null, lpcbData);
0174:                    if (result == 0) {
0175:                        TCHAR lpData = new TCHAR(0, lpcbData[0] / TCHAR.sizeof);
0176:                        result = OS.RegQueryValueEx(phkResult[0], null, 0,
0177:                                null, lpData, lpcbData);
0178:                        if (result == 0) {
0179:                            String clsid = lpData.toString(0, lpData.strlen());
0180:                            if (clsid.equals(CLSID_SHELLEXPLORER1)) {
0181:                                /* Shell.Explorer.1 is the default, ensure that Shell.Explorer.2 is available */
0182:                                key = new TCHAR(0, "Shell.Explorer.2", true); //$NON-NLS-1$
0183:                                int[] phkResult2 = new int[1];
0184:                                if (OS.RegOpenKeyEx(OS.HKEY_CLASSES_ROOT, key,
0185:                                        0, OS.KEY_READ, phkResult2) == 0) {
0186:                                    /* specify that Shell.Explorer.2 is to be used */
0187:                                    OS.RegCloseKey(phkResult2[0]);
0188:                                    progId = "Shell.Explorer.2"; //$NON-NLS-1$
0189:                                }
0190:                            }
0191:                        }
0192:                    }
0193:                    OS.RegCloseKey(phkResult[0]);
0194:                }
0195:                try {
0196:                    site = new WebSite(frame, SWT.NONE, progId); //$NON-NLS-1$
0197:                } catch (SWTException e) {
0198:                    dispose();
0199:                    SWT.error(SWT.ERROR_NO_HANDLES);
0200:                }
0201:
0202:                site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
0203:                auto = new OleAutomation(site);
0204:
0205:                Listener listener = new Listener() {
0206:                    public void handleEvent(Event e) {
0207:                        switch (e.type) {
0208:                        case SWT.Dispose: {
0209:                            /* make this handler run after other dispose listeners */
0210:                            if (ignoreDispose) {
0211:                                ignoreDispose = false;
0212:                                break;
0213:                            }
0214:                            ignoreDispose = true;
0215:                            notifyListeners(e.type, e);
0216:                            e.type = SWT.NONE;
0217:                            if (auto != null)
0218:                                auto.dispose();
0219:                            auto = null;
0220:                            break;
0221:                        }
0222:                        case SWT.Resize: {
0223:                            frame.setBounds(getClientArea());
0224:                            break;
0225:                        }
0226:                        case SWT.KeyDown:
0227:                        case SWT.KeyUp: {
0228:                            notifyListeners(e.type, e);
0229:                            break;
0230:                        }
0231:                        }
0232:                    }
0233:                };
0234:                addListener(SWT.Dispose, listener);
0235:                addListener(SWT.Resize, listener);
0236:                site.addListener(SWT.KeyDown, listener);
0237:                site.addListener(SWT.KeyUp, listener);
0238:
0239:                OleListener oleListener = new OleListener() {
0240:                    public void handleEvent(OleEvent event) {
0241:                        if (auto == null)
0242:                            return; /* receiver was disposed, callback is asynchronous */
0243:                        switch (event.type) {
0244:                        case BeforeNavigate2: {
0245:                            Variant varResult = event.arguments[1];
0246:                            String url = varResult.getString();
0247:                            LocationEvent newEvent = new LocationEvent(
0248:                                    Browser.this );
0249:                            newEvent.display = getDisplay();
0250:                            newEvent.widget = Browser.this ;
0251:                            newEvent.location = url;
0252:                            newEvent.doit = true;
0253:                            for (int i = 0; i < locationListeners.length; i++) {
0254:                                locationListeners[i].changing(newEvent);
0255:                            }
0256:                            Variant cancel = event.arguments[6];
0257:                            if (cancel != null) {
0258:                                int pCancel = cancel.getByRef();
0259:                                COM
0260:                                        .MoveMemory(
0261:                                                pCancel,
0262:                                                new short[] { newEvent.doit ? COM.VARIANT_FALSE
0263:                                                        : COM.VARIANT_TRUE }, 2);
0264:                            }
0265:                            break;
0266:                        }
0267:                        case CommandStateChange: {
0268:                            boolean enabled = false;
0269:                            Variant varResult = event.arguments[0];
0270:                            int command = varResult.getInt();
0271:                            varResult = event.arguments[1];
0272:                            enabled = varResult.getBoolean();
0273:                            switch (command) {
0274:                            case CSC_NAVIGATEBACK:
0275:                                back = enabled;
0276:                                break;
0277:                            case CSC_NAVIGATEFORWARD:
0278:                                forward = enabled;
0279:                                break;
0280:                            }
0281:                            break;
0282:                        }
0283:                        case DocumentComplete: {
0284:                            Variant varResult = event.arguments[0];
0285:                            IDispatch dispatch = varResult.getDispatch();
0286:
0287:                            varResult = event.arguments[1];
0288:                            String url = varResult.getString();
0289:                            if (html != null && url.equals(ABOUT_BLANK)) {
0290:                                Runnable runnable = new Runnable() {
0291:                                    public void run() {
0292:                                        if (isDisposed() || html == null)
0293:                                            return;
0294:                                        int charCount = html.length();
0295:                                        char[] chars = new char[charCount];
0296:                                        html.getChars(0, charCount, chars, 0);
0297:                                        html = null;
0298:                                        int byteCount = OS.WideCharToMultiByte(
0299:                                                OS.CP_UTF8, 0, chars,
0300:                                                charCount, null, 0, null, null);
0301:                                        /*
0302:                                         * Note. Internet Explorer appears to treat the data loaded with 
0303:                                         * nsIPersistStreamInit.Load as if it were encoded using the default
0304:                                         * local charset.  There does not seem to be an API to set the
0305:                                         * desired charset explicitely in this case.  The fix is to
0306:                                         * prepend the UTF-8 Byte Order Mark signature to the data.
0307:                                         */
0308:                                        byte[] UTF8BOM = { (byte) 0xEF,
0309:                                                (byte) 0xBB, (byte) 0xBF };
0310:                                        int hGlobal = OS.GlobalAlloc(
0311:                                                OS.GMEM_FIXED
0312:                                                        | OS.GMEM_ZEROINIT,
0313:                                                UTF8BOM.length + byteCount);
0314:                                        if (hGlobal != 0) {
0315:                                            OS.MoveMemory(hGlobal, UTF8BOM,
0316:                                                    UTF8BOM.length);
0317:                                            OS.WideCharToMultiByte(OS.CP_UTF8,
0318:                                                    0, chars, charCount,
0319:                                                    hGlobal + UTF8BOM.length,
0320:                                                    byteCount, null, null);
0321:                                            int[] ppstm = new int[1];
0322:                                            /* 
0323:                                             * Note.  CreateStreamOnHGlobal is called with the flag fDeleteOnRelease.
0324:                                             * If the call succeeds the buffer hGlobal is freed automatically
0325:                                             * when the IStream object is released. If the call fails, free the buffer
0326:                                             * hGlobal.
0327:                                             */
0328:                                            if (OS.CreateStreamOnHGlobal(
0329:                                                    hGlobal, true, ppstm) == OS.S_OK) {
0330:                                                int[] rgdispid = auto
0331:                                                        .getIDsOfNames(new String[] { "Document" }); //$NON-NLS-1$
0332:                                                Variant pVarResult = auto
0333:                                                        .getProperty(rgdispid[0]);
0334:                                                IDispatch dispatchDocument = pVarResult
0335:                                                        .getDispatch();
0336:                                                int[] ppvObject = new int[1];
0337:                                                int result = dispatchDocument
0338:                                                        .QueryInterface(
0339:                                                                COM.IIDIPersistStreamInit,
0340:                                                                ppvObject);
0341:                                                if (result == OS.S_OK) {
0342:                                                    IPersistStreamInit persistStreamInit = new IPersistStreamInit(
0343:                                                            ppvObject[0]);
0344:                                                    if (persistStreamInit
0345:                                                            .InitNew() == OS.S_OK) {
0346:                                                        persistStreamInit
0347:                                                                .Load(ppstm[0]);
0348:                                                    }
0349:                                                    persistStreamInit.Release();
0350:                                                }
0351:                                                pVarResult.dispose();
0352:                                                /*
0353:                                                 * This code is intentionally commented.  The IDispatch obtained from a Variant
0354:                                                 * did not increase the reference count for the enclosed interface.
0355:                                                 */
0356:                                                //dispatchDocument.Release();
0357:                                                IUnknown stream = new IUnknown(
0358:                                                        ppstm[0]);
0359:                                                stream.Release();
0360:                                            } else {
0361:                                                OS.GlobalFree(hGlobal);
0362:                                            }
0363:                                        }
0364:                                    }
0365:                                };
0366:                                if (delaySetText) {
0367:                                    delaySetText = false;
0368:                                    getDisplay().asyncExec(runnable);
0369:                                } else {
0370:                                    runnable.run();
0371:                                }
0372:                            } else {
0373:                                Variant variant = new Variant(auto);
0374:                                IDispatch top = variant.getDispatch();
0375:                                LocationEvent locationEvent = new LocationEvent(
0376:                                        Browser.this );
0377:                                locationEvent.display = getDisplay();
0378:                                locationEvent.widget = Browser.this ;
0379:                                locationEvent.location = url;
0380:                                locationEvent.top = top.getAddress() == dispatch
0381:                                        .getAddress();
0382:                                for (int i = 0; i < locationListeners.length; i++) {
0383:                                    locationListeners[i].changed(locationEvent);
0384:                                }
0385:                                /*
0386:                                 * This code is intentionally commented.  A Variant constructed from an
0387:                                 * OleAutomation object does not increase its reference count.  The IDispatch
0388:                                 * obtained from this Variant did not increase the reference count for the
0389:                                 * OleAutomation instance either. 
0390:                                 */
0391:                                //top.Release();
0392:                                //variant.dispose();
0393:                                /*
0394:                                 * Note.  The completion of the page loading is detected as
0395:                                 * described in the MSDN article "Determine when a page is
0396:                                 * done loading in WebBrowser Control". 
0397:                                 */
0398:                                if (globalDispatch != 0
0399:                                        && dispatch.getAddress() == globalDispatch) {
0400:                                    /* final document complete */
0401:                                    globalDispatch = 0;
0402:                                    ProgressEvent progressEvent = new ProgressEvent(
0403:                                            Browser.this );
0404:                                    progressEvent.display = getDisplay();
0405:                                    progressEvent.widget = Browser.this ;
0406:                                    for (int i = 0; i < progressListeners.length; i++) {
0407:                                        progressListeners[i]
0408:                                                .completed(progressEvent);
0409:                                    }
0410:                                }
0411:                            }
0412:
0413:                            /*
0414:                             * This code is intentionally commented.  This IDispatch was received
0415:                             * as an argument from the OleEvent and it will be disposed along with
0416:                             * the other arguments.  
0417:                             */
0418:                            //dispatch.Release();
0419:                            break;
0420:                        }
0421:                        case NavigateComplete2: {
0422:                            Variant varResult = event.arguments[0];
0423:                            IDispatch dispatch = varResult.getDispatch();
0424:                            if (globalDispatch == 0)
0425:                                globalDispatch = dispatch.getAddress();
0426:                            break;
0427:                        }
0428:                        case NewWindow2: {
0429:                            Variant cancel = event.arguments[1];
0430:                            int pCancel = cancel.getByRef();
0431:                            WindowEvent newEvent = new WindowEvent(Browser.this );
0432:                            newEvent.display = getDisplay();
0433:                            newEvent.widget = Browser.this ;
0434:                            newEvent.required = false;
0435:                            for (int i = 0; i < openWindowListeners.length; i++) {
0436:                                openWindowListeners[i].open(newEvent);
0437:                            }
0438:                            Browser browser = newEvent.browser;
0439:                            boolean doit = browser != null
0440:                                    && !browser.isDisposed();
0441:                            if (doit) {
0442:                                Variant variant = new Variant(browser.auto);
0443:                                IDispatch iDispatch = variant.getDispatch();
0444:                                Variant ppDisp = event.arguments[0];
0445:                                int byref = ppDisp.getByRef();
0446:                                if (byref != 0)
0447:                                    COM.MoveMemory(byref, new int[] { iDispatch
0448:                                            .getAddress() }, 4);
0449:                                /*
0450:                                 * This code is intentionally commented.  A Variant constructed from an
0451:                                 * OleAutomation object does not increase its reference count.  The IDispatch
0452:                                 * obtained from this Variant did not increase the reference count for the
0453:                                 * OleAutomation instance either. 
0454:                                 */
0455:                                //variant.dispose();
0456:                                //iDispatch.Release();
0457:                            }
0458:                            if (newEvent.required) {
0459:                                COM.MoveMemory(pCancel,
0460:                                        new short[] { doit ? COM.VARIANT_FALSE
0461:                                                : COM.VARIANT_TRUE }, 2);
0462:                            }
0463:                            break;
0464:                        }
0465:                        case OnMenuBar: {
0466:                            Variant arg0 = event.arguments[0];
0467:                            menuBar = arg0.getBoolean();
0468:                            break;
0469:                        }
0470:                        case OnStatusBar: {
0471:                            Variant arg0 = event.arguments[0];
0472:                            statusBar = arg0.getBoolean();
0473:                            break;
0474:                        }
0475:                        case OnToolBar: {
0476:                            Variant arg0 = event.arguments[0];
0477:                            toolBar = arg0.getBoolean();
0478:                            /*
0479:                             * Feature in Internet Explorer.  OnToolBar FALSE is emitted 
0480:                             * when both tool bar, address bar and menu bar must not be visible.
0481:                             * OnToolBar TRUE is emitted when either of tool bar, address bar
0482:                             * or menu bar is visible.
0483:                             */
0484:                            if (!toolBar) {
0485:                                addressBar = false;
0486:                                menuBar = false;
0487:                            }
0488:                            break;
0489:                        }
0490:                        case OnVisible: {
0491:                            Variant arg1 = event.arguments[0];
0492:                            boolean visible = arg1.getBoolean();
0493:                            WindowEvent newEvent = new WindowEvent(Browser.this );
0494:                            newEvent.display = getDisplay();
0495:                            newEvent.widget = Browser.this ;
0496:                            if (visible) {
0497:                                if (addressBar) {
0498:                                    /*
0499:                                     * Bug in Internet Explorer.  There is no distinct notification for
0500:                                     * the address bar.  If neither address, menu or tool bars are visible,
0501:                                     * OnToolBar FALSE is emitted. For some reason, querying the value of
0502:                                     * AddressBar in this case returns true even though it should not be
0503:                                     * set visible.  The workaround is to only query the value of AddressBar
0504:                                     * when OnToolBar FALSE has not been emitted.
0505:                                     */
0506:                                    int[] rgdispid = auto
0507:                                            .getIDsOfNames(new String[] { "AddressBar" }); //$NON-NLS-1$
0508:                                    Variant pVarResult = auto
0509:                                            .getProperty(rgdispid[0]);
0510:                                    if (pVarResult != null
0511:                                            && pVarResult.getType() == OLE.VT_BOOL)
0512:                                        addressBar = pVarResult.getBoolean();
0513:                                }
0514:                                newEvent.addressBar = addressBar;
0515:                                newEvent.menuBar = menuBar;
0516:                                newEvent.statusBar = statusBar;
0517:                                newEvent.toolBar = toolBar;
0518:                                newEvent.location = location;
0519:                                newEvent.size = size;
0520:                                for (int i = 0; i < visibilityWindowListeners.length; i++) {
0521:                                    visibilityWindowListeners[i].show(newEvent);
0522:                                }
0523:                                location = null;
0524:                                size = null;
0525:                            } else {
0526:                                for (int i = 0; i < visibilityWindowListeners.length; i++) {
0527:                                    visibilityWindowListeners[i].hide(newEvent);
0528:                                }
0529:                            }
0530:                            break;
0531:                        }
0532:                        case ProgressChange: {
0533:                            Variant arg1 = event.arguments[0];
0534:                            int nProgress = arg1.getType() != OLE.VT_I4 ? 0
0535:                                    : arg1.getInt(); // may be -1
0536:                            Variant arg2 = event.arguments[1];
0537:                            int nProgressMax = arg2.getType() != OLE.VT_I4 ? 0
0538:                                    : arg2.getInt();
0539:                            ProgressEvent newEvent = new ProgressEvent(
0540:                                    Browser.this );
0541:                            newEvent.display = getDisplay();
0542:                            newEvent.widget = Browser.this ;
0543:                            newEvent.current = nProgress;
0544:                            newEvent.total = nProgressMax;
0545:                            if (nProgress != -1) {
0546:                                for (int i = 0; i < progressListeners.length; i++) {
0547:                                    progressListeners[i].changed(newEvent);
0548:                                }
0549:                            }
0550:                            break;
0551:                        }
0552:                        case StatusTextChange: {
0553:                            Variant arg1 = event.arguments[0];
0554:                            if (arg1.getType() == OLE.VT_BSTR) {
0555:                                String text = arg1.getString();
0556:                                StatusTextEvent newEvent = new StatusTextEvent(
0557:                                        Browser.this );
0558:                                newEvent.display = getDisplay();
0559:                                newEvent.widget = Browser.this ;
0560:                                newEvent.text = text;
0561:                                for (int i = 0; i < statusTextListeners.length; i++) {
0562:                                    statusTextListeners[i].changed(newEvent);
0563:                                }
0564:                            }
0565:                            break;
0566:                        }
0567:                        case TitleChange: {
0568:                            Variant arg1 = event.arguments[0];
0569:                            if (arg1.getType() == OLE.VT_BSTR) {
0570:                                String title = arg1.getString();
0571:                                TitleEvent newEvent = new TitleEvent(
0572:                                        Browser.this );
0573:                                newEvent.display = getDisplay();
0574:                                newEvent.widget = Browser.this ;
0575:                                newEvent.title = title;
0576:                                for (int i = 0; i < titleListeners.length; i++) {
0577:                                    titleListeners[i].changed(newEvent);
0578:                                }
0579:                            }
0580:                            break;
0581:                        }
0582:                        case WindowClosing: {
0583:                            WindowEvent newEvent = new WindowEvent(Browser.this );
0584:                            newEvent.display = getDisplay();
0585:                            newEvent.widget = Browser.this ;
0586:                            for (int i = 0; i < closeWindowListeners.length; i++) {
0587:                                closeWindowListeners[i].close(newEvent);
0588:                            }
0589:                            Variant cancel = event.arguments[1];
0590:                            int pCancel = cancel.getByRef();
0591:                            Variant arg1 = event.arguments[0];
0592:                            boolean isChildWindow = arg1.getBoolean();
0593:                            COM
0594:                                    .MoveMemory(
0595:                                            pCancel,
0596:                                            new short[] { isChildWindow ? COM.VARIANT_FALSE
0597:                                                    : COM.VARIANT_TRUE }, 2);
0598:                            dispose();
0599:                            break;
0600:                        }
0601:                        case WindowSetHeight: {
0602:                            if (size == null)
0603:                                size = new Point(0, 0);
0604:                            Variant arg1 = event.arguments[0];
0605:                            size.y = arg1.getInt();
0606:                            break;
0607:                        }
0608:                        case WindowSetLeft: {
0609:                            if (location == null)
0610:                                location = new Point(0, 0);
0611:                            Variant arg1 = event.arguments[0];
0612:                            location.x = arg1.getInt();
0613:                            break;
0614:                        }
0615:                        case WindowSetTop: {
0616:                            if (location == null)
0617:                                location = new Point(0, 0);
0618:                            Variant arg1 = event.arguments[0];
0619:                            location.y = arg1.getInt();
0620:                            break;
0621:                        }
0622:                        case WindowSetWidth: {
0623:                            if (size == null)
0624:                                size = new Point(0, 0);
0625:                            Variant arg1 = event.arguments[0];
0626:                            size.x = arg1.getInt();
0627:                            break;
0628:                        }
0629:                        }
0630:                        /*
0631:                         * Dispose all arguments passed in the OleEvent.  This must be
0632:                         * done to properly release any IDispatch reference that was
0633:                         * automatically addRef'ed when constructing the OleEvent.  
0634:                         */
0635:                        Variant[] arguments = event.arguments;
0636:                        for (int i = 0; i < arguments.length; i++)
0637:                            arguments[i].dispose();
0638:                    }
0639:                };
0640:                site.addEventListener(BeforeNavigate2, oleListener);
0641:                site.addEventListener(CommandStateChange, oleListener);
0642:                site.addEventListener(DocumentComplete, oleListener);
0643:                site.addEventListener(NavigateComplete2, oleListener);
0644:                site.addEventListener(NewWindow2, oleListener);
0645:                site.addEventListener(OnMenuBar, oleListener);
0646:                site.addEventListener(OnStatusBar, oleListener);
0647:                site.addEventListener(OnToolBar, oleListener);
0648:                site.addEventListener(OnVisible, oleListener);
0649:                site.addEventListener(ProgressChange, oleListener);
0650:                site.addEventListener(StatusTextChange, oleListener);
0651:                site.addEventListener(TitleChange, oleListener);
0652:                site.addEventListener(WindowClosing, oleListener);
0653:                site.addEventListener(WindowSetHeight, oleListener);
0654:                site.addEventListener(WindowSetLeft, oleListener);
0655:                site.addEventListener(WindowSetTop, oleListener);
0656:                site.addEventListener(WindowSetWidth, oleListener);
0657:
0658:                Variant variant = new Variant(true);
0659:                auto.setProperty(RegisterAsBrowser, variant);
0660:                variant.dispose();
0661:
0662:                variant = new Variant(false);
0663:                int[] rgdispid = auto
0664:                        .getIDsOfNames(new String[] { "RegisterAsDropTarget" }); //$NON-NLS-1$
0665:                if (rgdispid != null)
0666:                    auto.setProperty(rgdispid[0], variant);
0667:                variant.dispose();
0668:
0669:                // GOOGLE: Load Google Gears if we can.
0670:                ((WebSite) site).startGears();
0671:            }
0672:
0673:            /**
0674:             * Clears all session cookies from all current Browser instances.
0675:             * 
0676:             * @since 3.2
0677:             */
0678:            public static void clearSessions() {
0679:                OS.InternetSetOption(0, OS.INTERNET_OPTION_END_BROWSER_SESSION,
0680:                        0, 0);
0681:            }
0682:
0683:            /**	 
0684:             * Adds the listener to the collection of listeners who will be
0685:             * notified when the window hosting the receiver should be closed.
0686:             * <p>
0687:             * This notification occurs when a javascript command such as
0688:             * <code>window.close</code> gets executed by a <code>Browser</code>.
0689:             * </p>
0690:             *
0691:             * @param listener the listener which should be notified
0692:             *
0693:             * @exception IllegalArgumentException <ul>
0694:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0695:             * </ul>
0696:             * 
0697:             * @exception SWTException <ul>
0698:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0699:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0700:             * </ul>
0701:             *
0702:             * @since 3.0
0703:             */
0704:            public void addCloseWindowListener(CloseWindowListener listener) {
0705:                checkWidget();
0706:                if (listener == null)
0707:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0708:                CloseWindowListener[] newCloseWindowListeners = new CloseWindowListener[closeWindowListeners.length + 1];
0709:                System
0710:                        .arraycopy(closeWindowListeners, 0,
0711:                                newCloseWindowListeners, 0,
0712:                                closeWindowListeners.length);
0713:                closeWindowListeners = newCloseWindowListeners;
0714:                closeWindowListeners[closeWindowListeners.length - 1] = listener;
0715:            }
0716:
0717:            /**	 
0718:             * Adds the listener to the collection of listeners who will be
0719:             * notified when the current location has changed or is about to change.
0720:             * <p>
0721:             * This notification typically occurs when the application navigates
0722:             * to a new location with {@link #setUrl(String)} or when the user
0723:             * activates a hyperlink.
0724:             * </p>
0725:             *
0726:             * @param listener the listener which should be notified
0727:             *
0728:             * @exception IllegalArgumentException <ul>
0729:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0730:             * </ul>
0731:             * 
0732:             * @exception SWTException <ul>
0733:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0734:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0735:             * </ul>
0736:             *
0737:             * @since 3.0
0738:             */
0739:            public void addLocationListener(LocationListener listener) {
0740:                checkWidget();
0741:                if (listener == null)
0742:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0743:                LocationListener[] newLocationListeners = new LocationListener[locationListeners.length + 1];
0744:                System.arraycopy(locationListeners, 0, newLocationListeners, 0,
0745:                        locationListeners.length);
0746:                locationListeners = newLocationListeners;
0747:                locationListeners[locationListeners.length - 1] = listener;
0748:            }
0749:
0750:            /**	 
0751:             * Adds the listener to the collection of listeners who will be
0752:             * notified when a new window needs to be created.
0753:             * <p>
0754:             * This notification occurs when a javascript command such as
0755:             * <code>window.open</code> gets executed by a <code>Browser</code>.
0756:             * </p>
0757:             *
0758:             * @param listener the listener which should be notified
0759:             *
0760:             * @exception IllegalArgumentException <ul>
0761:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0762:             * </ul>
0763:             * 
0764:             * @exception SWTException <ul>
0765:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0766:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0767:             * </ul>
0768:             *
0769:             * @since 3.0
0770:             */
0771:            public void addOpenWindowListener(OpenWindowListener listener) {
0772:                checkWidget();
0773:                if (listener == null)
0774:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0775:                OpenWindowListener[] newOpenWindowListeners = new OpenWindowListener[openWindowListeners.length + 1];
0776:                System.arraycopy(openWindowListeners, 0,
0777:                        newOpenWindowListeners, 0, openWindowListeners.length);
0778:                openWindowListeners = newOpenWindowListeners;
0779:                openWindowListeners[openWindowListeners.length - 1] = listener;
0780:            }
0781:
0782:            /**	 
0783:             * Adds the listener to the collection of listeners who will be
0784:             * notified when a progress is made during the loading of the current 
0785:             * URL or when the loading of the current URL has been completed.
0786:             *
0787:             * @param listener the listener which should be notified
0788:             *
0789:             * @exception IllegalArgumentException <ul>
0790:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0791:             * </ul>
0792:             * 
0793:             * @exception SWTException <ul>
0794:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0795:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0796:             * </ul>
0797:             *
0798:             * @since 3.0
0799:             */
0800:            public void addProgressListener(ProgressListener listener) {
0801:                checkWidget();
0802:                if (listener == null)
0803:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0804:                ProgressListener[] newProgressListeners = new ProgressListener[progressListeners.length + 1];
0805:                System.arraycopy(progressListeners, 0, newProgressListeners, 0,
0806:                        progressListeners.length);
0807:                progressListeners = newProgressListeners;
0808:                progressListeners[progressListeners.length - 1] = listener;
0809:            }
0810:
0811:            /**	 
0812:             * Adds the listener to the collection of listeners who will be
0813:             * notified when the status text is changed.
0814:             * <p>
0815:             * The status text is typically displayed in the status bar of
0816:             * a browser application.
0817:             * </p>
0818:             *
0819:             * @param listener the listener which should be notified
0820:             *
0821:             * @exception IllegalArgumentException <ul>
0822:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0823:             * </ul>
0824:             * 
0825:             * @exception SWTException <ul>
0826:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0827:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0828:             * </ul>
0829:             *
0830:             * @since 3.0
0831:             */
0832:            public void addStatusTextListener(StatusTextListener listener) {
0833:                checkWidget();
0834:                if (listener == null)
0835:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0836:                StatusTextListener[] newStatusTextListeners = new StatusTextListener[statusTextListeners.length + 1];
0837:                System.arraycopy(statusTextListeners, 0,
0838:                        newStatusTextListeners, 0, statusTextListeners.length);
0839:                statusTextListeners = newStatusTextListeners;
0840:                statusTextListeners[statusTextListeners.length - 1] = listener;
0841:            }
0842:
0843:            /**	 
0844:             * Adds the listener to the collection of listeners who will be
0845:             * notified when the title of the current document is available
0846:             * or has changed.
0847:             *
0848:             * @param listener the listener which should be notified
0849:             *
0850:             * @exception IllegalArgumentException <ul>
0851:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0852:             * </ul>
0853:             * 
0854:             * @exception SWTException <ul>
0855:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0856:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0857:             * </ul>
0858:             *
0859:             * @since 3.0
0860:             */
0861:            public void addTitleListener(TitleListener listener) {
0862:                checkWidget();
0863:                if (listener == null)
0864:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0865:                TitleListener[] newTitleListeners = new TitleListener[titleListeners.length + 1];
0866:                System.arraycopy(titleListeners, 0, newTitleListeners, 0,
0867:                        titleListeners.length);
0868:                titleListeners = newTitleListeners;
0869:                titleListeners[titleListeners.length - 1] = listener;
0870:            }
0871:
0872:            /**	 
0873:             * Adds the listener to the collection of listeners who will be
0874:             * notified when a window hosting the receiver needs to be displayed
0875:             * or hidden.
0876:             *
0877:             * @param listener the listener which should be notified
0878:             *
0879:             * @exception IllegalArgumentException <ul>
0880:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0881:             * </ul>
0882:             * 
0883:             * @exception SWTException <ul>
0884:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0885:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0886:             * </ul>
0887:             *
0888:             * @since 3.0
0889:             */
0890:            public void addVisibilityWindowListener(
0891:                    VisibilityWindowListener listener) {
0892:                checkWidget();
0893:                if (listener == null)
0894:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0895:                VisibilityWindowListener[] newVisibilityWindowListeners = new VisibilityWindowListener[visibilityWindowListeners.length + 1];
0896:                System.arraycopy(visibilityWindowListeners, 0,
0897:                        newVisibilityWindowListeners, 0,
0898:                        visibilityWindowListeners.length);
0899:                visibilityWindowListeners = newVisibilityWindowListeners;
0900:                visibilityWindowListeners[visibilityWindowListeners.length - 1] = listener;
0901:            }
0902:
0903:            /**
0904:             * Navigate to the previous session history item.
0905:             *
0906:             * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
0907:             *
0908:             * @exception SWTException <ul>
0909:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0910:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0911:             * </ul>
0912:             *
0913:             * @see #forward
0914:             * 
0915:             * @since 3.0
0916:             */
0917:            public boolean back() {
0918:                checkWidget();
0919:                if (!back)
0920:                    return false;
0921:                int[] rgdispid = auto.getIDsOfNames(new String[] { "GoBack" }); //$NON-NLS-1$
0922:                Variant pVarResult = auto.invoke(rgdispid[0]);
0923:                return pVarResult != null
0924:                        && pVarResult.getType() == OLE.VT_EMPTY;
0925:            }
0926:
0927:            protected void checkSubclass() {
0928:                String name = getClass().getName();
0929:                int index = name.lastIndexOf('.');
0930:                if (!name.substring(0, index + 1).equals(PACKAGE_PREFIX)) {
0931:                    SWT.error(SWT.ERROR_INVALID_SUBCLASS);
0932:                }
0933:            }
0934:
0935:            /**
0936:             * Execute the specified script.
0937:             *
0938:             * <p>
0939:             * Execute a script containing javascript commands in the context of the current document. 
0940:             * 
0941:             * @param script the script with javascript commands
0942:             *  
0943:             * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
0944:             *
0945:             * @exception IllegalArgumentException <ul>
0946:             *    <li>ERROR_NULL_ARGUMENT - if the script is null</li>
0947:             * </ul>
0948:             * 
0949:             * @exception SWTException <ul>
0950:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
0951:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
0952:             * </ul>
0953:             *
0954:             * @since 3.1
0955:             */
0956:            public boolean execute(String script) {
0957:                checkWidget();
0958:                if (script == null)
0959:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
0960:
0961:                /* get IHTMLDocument2 */
0962:                int[] rgdispid = auto
0963:                        .getIDsOfNames(new String[] { "Document" }); //$NON-NLS-1$
0964:                int dispIdMember = rgdispid[0];
0965:                Variant pVarResult = auto.getProperty(dispIdMember);
0966:                if (pVarResult == null || pVarResult.getType() == COM.VT_EMPTY)
0967:                    return false;
0968:                OleAutomation document = pVarResult.getAutomation();
0969:                pVarResult.dispose();
0970:
0971:                /* get IHTMLWindow2 */
0972:                rgdispid = document
0973:                        .getIDsOfNames(new String[] { "parentWindow" }); //$NON-NLS-1$
0974:                if (rgdispid == null) {
0975:                    /* implies that browser's content is not a IHTMLDocument2 (eg.- acrobat reader) */
0976:                    document.dispose();
0977:                    return false;
0978:                }
0979:                dispIdMember = rgdispid[0];
0980:                pVarResult = document.getProperty(dispIdMember);
0981:                OleAutomation ihtmlWindow2 = pVarResult.getAutomation();
0982:                pVarResult.dispose();
0983:                document.dispose();
0984:
0985:                rgdispid = ihtmlWindow2.getIDsOfNames(new String[] {
0986:                        "execScript", "code" }); //$NON-NLS-1$  //$NON-NLS-2$
0987:                Variant[] rgvarg = new Variant[1];
0988:                rgvarg[0] = new Variant(script);
0989:                int[] rgdispidNamedArgs = new int[1];
0990:                rgdispidNamedArgs[0] = rgdispid[1];
0991:                pVarResult = ihtmlWindow2.invoke(rgdispid[0], rgvarg,
0992:                        rgdispidNamedArgs);
0993:                rgvarg[0].dispose();
0994:                ihtmlWindow2.dispose();
0995:                if (pVarResult == null)
0996:                    return false;
0997:                pVarResult.dispose();
0998:                return true;
0999:            }
1000:
1001:            /**
1002:             * Navigate to the next session history item.
1003:             *
1004:             * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
1005:             *
1006:             * @exception SWTException <ul>
1007:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1008:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1009:             * </ul>
1010:             * 
1011:             * @see #back
1012:             * 
1013:             * @since 3.0
1014:             */
1015:            public boolean forward() {
1016:                checkWidget();
1017:                if (!forward)
1018:                    return false;
1019:                int[] rgdispid = auto
1020:                        .getIDsOfNames(new String[] { "GoForward" }); //$NON-NLS-1$
1021:                Variant pVarResult = auto.invoke(rgdispid[0]);
1022:                return pVarResult != null
1023:                        && pVarResult.getType() == OLE.VT_EMPTY;
1024:            }
1025:
1026:            /**
1027:             * Returns <code>true</code> if the receiver can navigate to the 
1028:             * previous session history item, and <code>false</code> otherwise.
1029:             *
1030:             * @return the receiver's back command enabled state
1031:             *
1032:             * @exception SWTException <ul>
1033:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1034:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1035:             * </ul>
1036:             * 
1037:             * @see #back
1038:             */
1039:            public boolean isBackEnabled() {
1040:                checkWidget();
1041:                return back;
1042:            }
1043:
1044:            /**
1045:             * Returns <code>true</code> if the receiver can navigate to the 
1046:             * next session history item, and <code>false</code> otherwise.
1047:             *
1048:             * @return the receiver's forward command enabled state
1049:             *
1050:             * @exception SWTException <ul>
1051:             *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1052:             *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1053:             * </ul>
1054:             * 
1055:             * @see #forward
1056:             */
1057:            public boolean isForwardEnabled() {
1058:                checkWidget();
1059:                return forward;
1060:            }
1061:
1062:            /**
1063:             * Returns the current URL.
1064:             *
1065:             * @return the current URL or an empty <code>String</code> if there is no current URL
1066:             *
1067:             * @exception SWTException <ul>
1068:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1069:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1070:             * </ul>
1071:             *
1072:             * @see #setUrl
1073:             * 
1074:             * @since 3.0
1075:             */
1076:            public String getUrl() {
1077:                checkWidget();
1078:                int[] rgdispid = auto
1079:                        .getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
1080:                Variant pVarResult = auto.getProperty(rgdispid[0]);
1081:                if (pVarResult == null || pVarResult.getType() != OLE.VT_BSTR)
1082:                    return "";
1083:                String result = pVarResult.getString();
1084:                pVarResult.dispose();
1085:                return result;
1086:            }
1087:
1088:            public boolean isFocusControl() {
1089:                checkWidget();
1090:                if (site.isFocusControl() || frame.isFocusControl())
1091:                    return true;
1092:                return super .isFocusControl();
1093:            }
1094:
1095:            /**
1096:             * Refresh the current page.
1097:             *
1098:             * @exception SWTException <ul>
1099:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1100:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1101:             * </ul>
1102:             *
1103:             * @since 3.0
1104:             */
1105:            public void refresh() {
1106:                checkWidget();
1107:                int[] rgdispid = auto.getIDsOfNames(new String[] { "Refresh" }); //$NON-NLS-1$
1108:                auto.invoke(rgdispid[0]);
1109:            }
1110:
1111:            /**	 
1112:             * Removes the listener from the collection of listeners who will
1113:             * be notified when the window hosting the receiver should be closed.
1114:             *
1115:             * @param listener the listener which should no longer be notified
1116:             *
1117:             * @exception IllegalArgumentException <ul>
1118:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1119:             * </ul>
1120:             * 
1121:             * @exception SWTException <ul>
1122:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1123:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1124:             * </ul>
1125:             * 
1126:             * @since 3.0
1127:             */
1128:            public void removeCloseWindowListener(CloseWindowListener listener) {
1129:                checkWidget();
1130:                if (listener == null)
1131:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1132:                if (closeWindowListeners.length == 0)
1133:                    return;
1134:                int index = -1;
1135:                for (int i = 0; i < closeWindowListeners.length; i++) {
1136:                    if (listener == closeWindowListeners[i]) {
1137:                        index = i;
1138:                        break;
1139:                    }
1140:                }
1141:                if (index == -1)
1142:                    return;
1143:                if (closeWindowListeners.length == 1) {
1144:                    closeWindowListeners = new CloseWindowListener[0];
1145:                    return;
1146:                }
1147:                CloseWindowListener[] newCloseWindowListeners = new CloseWindowListener[closeWindowListeners.length - 1];
1148:                System.arraycopy(closeWindowListeners, 0,
1149:                        newCloseWindowListeners, 0, index);
1150:                System.arraycopy(closeWindowListeners, index + 1,
1151:                        newCloseWindowListeners, index,
1152:                        closeWindowListeners.length - index - 1);
1153:                closeWindowListeners = newCloseWindowListeners;
1154:            }
1155:
1156:            /**	 
1157:             * Removes the listener from the collection of listeners who will
1158:             * be notified when the current location is changed or about to be changed.
1159:             *
1160:             * @param listener the listener which should no longer be notified
1161:             *
1162:             * @exception IllegalArgumentException <ul>
1163:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1164:             * </ul>
1165:             * 
1166:             * @exception SWTException <ul>
1167:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1168:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1169:             * </ul>
1170:             * 
1171:             * @since 3.0
1172:             */
1173:            public void removeLocationListener(LocationListener listener) {
1174:                checkWidget();
1175:                if (listener == null)
1176:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1177:                if (locationListeners.length == 0)
1178:                    return;
1179:                int index = -1;
1180:                for (int i = 0; i < locationListeners.length; i++) {
1181:                    if (listener == locationListeners[i]) {
1182:                        index = i;
1183:                        break;
1184:                    }
1185:                }
1186:                if (index == -1)
1187:                    return;
1188:                if (locationListeners.length == 1) {
1189:                    locationListeners = new LocationListener[0];
1190:                    return;
1191:                }
1192:                LocationListener[] newLocationListeners = new LocationListener[locationListeners.length - 1];
1193:                System.arraycopy(locationListeners, 0, newLocationListeners, 0,
1194:                        index);
1195:                System.arraycopy(locationListeners, index + 1,
1196:                        newLocationListeners, index, locationListeners.length
1197:                                - index - 1);
1198:                locationListeners = newLocationListeners;
1199:            }
1200:
1201:            /**	 
1202:             * Removes the listener from the collection of listeners who will
1203:             * be notified when a new window needs to be created.
1204:             *
1205:             * @param listener the listener which should no longer be notified
1206:             *
1207:             * @exception IllegalArgumentException <ul>
1208:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1209:             * </ul>
1210:             * 
1211:             * @exception SWTException <ul>
1212:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1213:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1214:             * </ul>
1215:             * 
1216:             * @since 3.0
1217:             */
1218:            public void removeOpenWindowListener(OpenWindowListener listener) {
1219:                checkWidget();
1220:                if (listener == null)
1221:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1222:                if (openWindowListeners.length == 0)
1223:                    return;
1224:                int index = -1;
1225:                for (int i = 0; i < openWindowListeners.length; i++) {
1226:                    if (listener == openWindowListeners[i]) {
1227:                        index = i;
1228:                        break;
1229:                    }
1230:                }
1231:                if (index == -1)
1232:                    return;
1233:                if (openWindowListeners.length == 1) {
1234:                    openWindowListeners = new OpenWindowListener[0];
1235:                    return;
1236:                }
1237:                OpenWindowListener[] newOpenWindowListeners = new OpenWindowListener[openWindowListeners.length - 1];
1238:                System.arraycopy(openWindowListeners, 0,
1239:                        newOpenWindowListeners, 0, index);
1240:                System.arraycopy(openWindowListeners, index + 1,
1241:                        newOpenWindowListeners, index,
1242:                        openWindowListeners.length - index - 1);
1243:                openWindowListeners = newOpenWindowListeners;
1244:            }
1245:
1246:            /**	 
1247:             * Removes the listener from the collection of listeners who will
1248:             * be notified when a progress is made during the loading of the current 
1249:             * URL or when the loading of the current URL has been completed.
1250:             *
1251:             * @param listener the listener which should no longer be notified
1252:             *
1253:             * @exception IllegalArgumentException <ul>
1254:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1255:             * </ul>
1256:             * 
1257:             * @exception SWTException <ul>
1258:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1259:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1260:             * </ul>
1261:             * 
1262:             * @since 3.0
1263:             */
1264:            public void removeProgressListener(ProgressListener listener) {
1265:                checkWidget();
1266:                if (listener == null)
1267:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1268:                if (progressListeners.length == 0)
1269:                    return;
1270:                int index = -1;
1271:                for (int i = 0; i < progressListeners.length; i++) {
1272:                    if (listener == progressListeners[i]) {
1273:                        index = i;
1274:                        break;
1275:                    }
1276:                }
1277:                if (index == -1)
1278:                    return;
1279:                if (progressListeners.length == 1) {
1280:                    progressListeners = new ProgressListener[0];
1281:                    return;
1282:                }
1283:                ProgressListener[] newProgressListeners = new ProgressListener[progressListeners.length - 1];
1284:                System.arraycopy(progressListeners, 0, newProgressListeners, 0,
1285:                        index);
1286:                System.arraycopy(progressListeners, index + 1,
1287:                        newProgressListeners, index, progressListeners.length
1288:                                - index - 1);
1289:                progressListeners = newProgressListeners;
1290:            }
1291:
1292:            /**	 
1293:             * Removes the listener from the collection of listeners who will
1294:             * be notified when the status text is changed.
1295:             *
1296:             * @param listener the listener which should no longer be notified
1297:             *
1298:             * @exception IllegalArgumentException <ul>
1299:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1300:             * </ul>
1301:             * 
1302:             * @exception SWTException <ul>
1303:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1304:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1305:             * </ul>
1306:             * 
1307:             * @since 3.0
1308:             */
1309:            public void removeStatusTextListener(StatusTextListener listener) {
1310:                checkWidget();
1311:                if (listener == null)
1312:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1313:                if (statusTextListeners.length == 0)
1314:                    return;
1315:                int index = -1;
1316:                for (int i = 0; i < statusTextListeners.length; i++) {
1317:                    if (listener == statusTextListeners[i]) {
1318:                        index = i;
1319:                        break;
1320:                    }
1321:                }
1322:                if (index == -1)
1323:                    return;
1324:                if (statusTextListeners.length == 1) {
1325:                    statusTextListeners = new StatusTextListener[0];
1326:                    return;
1327:                }
1328:                StatusTextListener[] newStatusTextListeners = new StatusTextListener[statusTextListeners.length - 1];
1329:                System.arraycopy(statusTextListeners, 0,
1330:                        newStatusTextListeners, 0, index);
1331:                System.arraycopy(statusTextListeners, index + 1,
1332:                        newStatusTextListeners, index,
1333:                        statusTextListeners.length - index - 1);
1334:                statusTextListeners = newStatusTextListeners;
1335:            }
1336:
1337:            /**	 
1338:             * Removes the listener from the collection of listeners who will
1339:             * be notified when the title of the current document is available
1340:             * or has changed.
1341:             *
1342:             * @param listener the listener which should no longer be notified
1343:             *
1344:             * @exception IllegalArgumentException <ul>
1345:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1346:             * </ul>
1347:             * 
1348:             * @exception SWTException <ul>
1349:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1350:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1351:             * </ul>
1352:             * 
1353:             * @since 3.0
1354:             */
1355:            public void removeTitleListener(TitleListener listener) {
1356:                checkWidget();
1357:                if (listener == null)
1358:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1359:                if (titleListeners.length == 0)
1360:                    return;
1361:                int index = -1;
1362:                for (int i = 0; i < titleListeners.length; i++) {
1363:                    if (listener == titleListeners[i]) {
1364:                        index = i;
1365:                        break;
1366:                    }
1367:                }
1368:                if (index == -1)
1369:                    return;
1370:                if (titleListeners.length == 1) {
1371:                    titleListeners = new TitleListener[0];
1372:                    return;
1373:                }
1374:                TitleListener[] newTitleListeners = new TitleListener[titleListeners.length - 1];
1375:                System
1376:                        .arraycopy(titleListeners, 0, newTitleListeners, 0,
1377:                                index);
1378:                System.arraycopy(titleListeners, index + 1, newTitleListeners,
1379:                        index, titleListeners.length - index - 1);
1380:                titleListeners = newTitleListeners;
1381:            }
1382:
1383:            /**	 
1384:             * Removes the listener from the collection of listeners who will
1385:             * be notified when a window hosting the receiver needs to be displayed
1386:             * or hidden.
1387:             *
1388:             * @param listener the listener which should no longer be notified
1389:             *
1390:             * @exception IllegalArgumentException <ul>
1391:             *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1392:             * </ul>
1393:             * 
1394:             * @exception SWTException <ul>
1395:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1396:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1397:             * </ul>
1398:             * 
1399:             * @since 3.0
1400:             */
1401:            public void removeVisibilityWindowListener(
1402:                    VisibilityWindowListener listener) {
1403:                checkWidget();
1404:                if (listener == null)
1405:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1406:                if (visibilityWindowListeners.length == 0)
1407:                    return;
1408:                int index = -1;
1409:                for (int i = 0; i < visibilityWindowListeners.length; i++) {
1410:                    if (listener == visibilityWindowListeners[i]) {
1411:                        index = i;
1412:                        break;
1413:                    }
1414:                }
1415:                if (index == -1)
1416:                    return;
1417:                if (visibilityWindowListeners.length == 1) {
1418:                    visibilityWindowListeners = new VisibilityWindowListener[0];
1419:                    return;
1420:                }
1421:                VisibilityWindowListener[] newVisibilityWindowListeners = new VisibilityWindowListener[visibilityWindowListeners.length - 1];
1422:                System.arraycopy(visibilityWindowListeners, 0,
1423:                        newVisibilityWindowListeners, 0, index);
1424:                System.arraycopy(visibilityWindowListeners, index + 1,
1425:                        newVisibilityWindowListeners, index,
1426:                        visibilityWindowListeners.length - index - 1);
1427:                visibilityWindowListeners = newVisibilityWindowListeners;
1428:            }
1429:
1430:            /**
1431:             * Renders HTML.
1432:             * 
1433:             * <p>
1434:             * The html parameter is Unicode encoded since it is a java <code>String</code>.
1435:             * As a result, the HTML meta tag charset should not be set. The charset is implied
1436:             * by the <code>String</code> itself.
1437:             * 
1438:             * @param html the HTML content to be rendered
1439:             *
1440:             * @return true if the operation was successful and false otherwise.
1441:             *
1442:             * @exception IllegalArgumentException <ul>
1443:             *    <li>ERROR_NULL_ARGUMENT - if the html is null</li>
1444:             * </ul>
1445:             * 
1446:             * @exception SWTException <ul>
1447:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1448:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1449:             * </ul>
1450:             *  
1451:             * @see #setUrl
1452:             * 
1453:             * @since 3.0
1454:             */
1455:            public boolean setText(String html) {
1456:                checkWidget();
1457:                if (html == null)
1458:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1459:
1460:                /*
1461:                 * If the html field is non-null then the about:blank page is already being
1462:                 * loaded, so no Stop or Navigate is required.  Just set the html that is to
1463:                 * be shown.
1464:                 */
1465:                boolean blankLoading = this .html != null;
1466:                this .html = html;
1467:                if (blankLoading)
1468:                    return true;
1469:
1470:                /*
1471:                 * Navigate to the blank page and insert the given html when
1472:                 * receiving the next DocumentComplete notification.  See the
1473:                 * MSDN article "Loading HTML content from a Stream".
1474:                 * 
1475:                 * Note.  Stop any pending request.  This is required to avoid displaying a
1476:                 * blank page as a result of consecutive calls to setUrl and/or setText.  
1477:                 * The previous request would otherwise render the new html content and
1478:                 * reset the html field before the browser actually navigates to the blank
1479:                 * page as requested below.
1480:                 * 
1481:                 * Feature in Internet Explorer.  Stopping pending requests when no request
1482:                 * is pending causes a default page 'Action cancelled' to be displayed.  The
1483:                 * workaround is to not invoke 'stop' when no request has been set since
1484:                 * that instance was created.
1485:                 */
1486:                int[] rgdispid;
1487:                if (navigate) {
1488:                    /*
1489:                     * Stopping the loading of a page causes DocumentComplete events from previous
1490:                     * requests to be received before the DocumentComplete for this page.  In such
1491:                     * cases we must be sure to not set the html into the browser too soon, since
1492:                     * doing so could result in its page being cleared out by a subsequent
1493:                     * DocumentComplete.  The Browser's ReadyState can be used to determine whether
1494:                     * these extra events will be received or not.
1495:                     */
1496:                    rgdispid = auto
1497:                            .getIDsOfNames(new String[] { "ReadyState" }); //$NON-NLS-1$
1498:                    Variant pVarResult = auto.getProperty(rgdispid[0]);
1499:                    if (pVarResult == null)
1500:                        return false;
1501:                    delaySetText = pVarResult.getInt() != READYSTATE_COMPLETE;
1502:                    pVarResult.dispose();
1503:                    rgdispid = auto.getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
1504:                    auto.invoke(rgdispid[0]);
1505:                }
1506:                rgdispid = auto
1507:                        .getIDsOfNames(new String[] { "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
1508:                navigate = true;
1509:                Variant[] rgvarg = new Variant[1];
1510:                rgvarg[0] = new Variant(ABOUT_BLANK);
1511:                int[] rgdispidNamedArgs = new int[1];
1512:                rgdispidNamedArgs[0] = rgdispid[1];
1513:                Variant pVarResult = auto.invoke(rgdispid[0], rgvarg,
1514:                        rgdispidNamedArgs);
1515:                rgvarg[0].dispose();
1516:                if (pVarResult == null)
1517:                    return false;
1518:                boolean result = pVarResult.getType() == OLE.VT_EMPTY;
1519:                pVarResult.dispose();
1520:                return result;
1521:            }
1522:
1523:            /**
1524:             * Loads a URL.
1525:             * 
1526:             * @param url the URL to be loaded
1527:             *
1528:             * @return true if the operation was successful and false otherwise.
1529:             *
1530:             * @exception IllegalArgumentException <ul>
1531:             *    <li>ERROR_NULL_ARGUMENT - if the url is null</li>
1532:             * </ul>
1533:             * 
1534:             * @exception SWTException <ul>
1535:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1536:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1537:             * </ul>
1538:             *  
1539:             * @see #getUrl
1540:             * 
1541:             * @since 3.0
1542:             */
1543:            public boolean setUrl(String url) {
1544:                checkWidget();
1545:                if (url == null)
1546:                    SWT.error(SWT.ERROR_NULL_ARGUMENT);
1547:                html = null;
1548:
1549:                /*
1550:                 * Bug in Internet Explorer.  For some reason, Navigating to an xml document before
1551:                 * a previous Navigate has completed will leave the Browser in a bad state if the
1552:                 * Navigate to the xml document does not complete.  This bad state causes a GP when
1553:                 * the parent window is eventually disposed.  The workaround is to issue a Stop before
1554:                 * navigating to any xml document. 
1555:                 */
1556:                if (url.endsWith(".xml")) { //$NON-NLS-1$
1557:                    /*
1558:                     * Feature in Internet Explorer.  Stopping pending requests when no request has been
1559:                     * issued causes a default 'Action cancelled' page to be displayed.  Since Stop must
1560:                     * be issued here, the workaround is to first Navigate to the about:blank page before
1561:                     * issuing Stop so that the 'Action cancelled' page is not displayed.
1562:                     */
1563:                    if (!navigate) {
1564:                        int[] rgdispid = auto.getIDsOfNames(new String[] {
1565:                                "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
1566:                        Variant[] rgvarg = new Variant[1];
1567:                        rgvarg[0] = new Variant(ABOUT_BLANK);
1568:                        int[] rgdispidNamedArgs = new int[1];
1569:                        rgdispidNamedArgs[0] = rgdispid[1];
1570:                        auto.invoke(rgdispid[0], rgvarg, rgdispidNamedArgs);
1571:                        rgvarg[0].dispose();
1572:                    }
1573:                    int[] rgdispid = auto
1574:                            .getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
1575:                    auto.invoke(rgdispid[0]);
1576:                }
1577:
1578:                int[] rgdispid = auto.getIDsOfNames(new String[] {
1579:                        "Navigate", "URL" }); //$NON-NLS-1$ //$NON-NLS-2$
1580:                navigate = true;
1581:                Variant[] rgvarg = new Variant[1];
1582:                rgvarg[0] = new Variant(url);
1583:                int[] rgdispidNamedArgs = new int[1];
1584:                rgdispidNamedArgs[0] = rgdispid[1];
1585:                Variant pVarResult = auto.invoke(rgdispid[0], rgvarg,
1586:                        rgdispidNamedArgs);
1587:                rgvarg[0].dispose();
1588:                if (pVarResult == null)
1589:                    return false;
1590:                boolean result = pVarResult.getType() == OLE.VT_EMPTY;
1591:                pVarResult.dispose();
1592:                return result;
1593:            }
1594:
1595:            /**
1596:             * Stop any loading and rendering activity.
1597:             *
1598:             * @exception SWTException <ul>
1599:             *    <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
1600:             *    <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
1601:             * </ul>
1602:             *
1603:             * @since 3.0
1604:             */
1605:            public void stop() {
1606:                checkWidget();
1607:                int[] rgdispid = auto.getIDsOfNames(new String[] { "Stop" }); //$NON-NLS-1$
1608:                auto.invoke(rgdispid[0]);
1609:            }
1610:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.