launcherwindow.h revision 65f03d4f644ce73618e5f4f50dd694b26f55ae12
1db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block/*
2db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
4db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2006 George Staikos <staikos@kde.org>
5db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
6db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2006 Zack Rusin <zack@kde.org>
7db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
8db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *
9db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * All rights reserved.
10db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *
11db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Redistribution and use in source and binary forms, with or without
12db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * modification, are permitted provided that the following conditions
13db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * are met:
14db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * 1. Redistributions of source code must retain the above copyright
15db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *    notice, this list of conditions and the following disclaimer.
16db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * 2. Redistributions in binary form must reproduce the above copyright
17db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *    notice, this list of conditions and the following disclaimer in the
18db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *    documentation and/or other materials provided with the distribution.
19db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block *
20db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
21db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
24db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block */
32db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
33db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#ifndef launcherwindow_h
34db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#define launcherwindow_h
35db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
36db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QtGui>
37db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QtNetwork/QNetworkRequest>
38db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
39db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#if defined(QT_CONFIGURED_WITH_OPENGL)
40db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QtOpenGL/QGLWidget>
41db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
42db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
43db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#if !defined(QT_NO_PRINTER)
44db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QPrintPreviewDialog>
45db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
46db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
47db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#ifndef QT_NO_UITOOLS
48db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QtUiTools/QUiLoader>
49db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
50db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
51db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <QDebug>
52db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
53db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <cstdio>
54db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qevent.h>
55db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qwebelement.h>
56db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qwebframe.h>
57db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qwebinspector.h>
58db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qwebsettings.h>
59db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
60db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#ifdef Q_WS_MAEMO_5
61db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <qx11info_x11.h>
62db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
63db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
64db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "mainwindow.h"
65db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "urlloader.h"
66db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "utils.h"
67db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "webinspector.h"
68db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "webpage.h"
69db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "webview.h"
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "../../Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h"
71db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
72db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#ifdef Q_WS_MAEMO_5
73db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <X11/Xatom.h>
74db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include <X11/Xlib.h>
75db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#undef KeyPress
76db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
77db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass QPropertyAnimation;
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
80dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochclass WindowOptions {
81dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochpublic:
82dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    WindowOptions()
83dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        : useGraphicsView(false)
84dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useCompositing(true)
85dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useTiledBackingStore(false)
86dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useWebGL(false)
87f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN)
88dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useFrameFlattening(true)
89dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#else
90dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useFrameFlattening(false)
91dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif
92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        , useThreadedQnam(true)
93dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , cacheWebView(false)
94dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , showFrameRate(false)
95dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , resizesToContents(false)
96dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , viewportUpdateMode(QGraphicsView::MinimalViewportUpdate)
97dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#if defined(QT_CONFIGURED_WITH_OPENGL)
98dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        , useQGLWidgetViewport(false)
99dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif
100dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
101dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
102dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
103dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useGraphicsView;
104dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useCompositing;
105dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useTiledBackingStore;
106dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useWebGL;
107dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useFrameFlattening;
108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    bool useThreadedQnam;
109dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool cacheWebView;
110dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool showFrameRate;
111dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool resizesToContents;
112dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    QGraphicsView::ViewportUpdateMode viewportUpdateMode;
113dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#if defined(QT_CONFIGURED_WITH_OPENGL)
114dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool useQGLWidgetViewport;
115dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif
116dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    QUrl inspectorUrl;
117bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    quint16 remoteInspectorPort;
118dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch};
119dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
120db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockclass LauncherWindow : public MainWindow {
121db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    Q_OBJECT
122db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
123db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockpublic:
124dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    LauncherWindow(WindowOptions* data = 0, QGraphicsScene* sharedScene = 0);
125db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    virtual ~LauncherWindow();
126db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
127db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    virtual void keyPressEvent(QKeyEvent* event);
128db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void grabZoomKeys(bool grab);
129db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
130db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void sendTouchEvent();
131db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
132db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    bool eventFilter(QObject* obj, QEvent* event);
133db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
134db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockprotected slots:
135db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void loadStarted();
136db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void loadFinished();
137db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
138db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void showLinkHover(const QString &link, const QString &toolTip);
139db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
140db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void zoomIn();
141db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void zoomOut();
142db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void resetZoom();
143db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleZoomTextOnly(bool on);
144db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void zoomAnimationFinished();
145db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
146db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void print();
147db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void screenshot();
148db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
149db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void setEditable(bool on);
150db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
151db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    /* void dumpPlugins() */
152db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void dumpHtml();
153db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
154db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void setTouchMocking(bool on);
155f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void toggleWebView(bool graphicsBased);
156db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleAcceleratedCompositing(bool toggle);
157db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleTiledBackingStore(bool toggle);
158db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleResizesToContents(bool toggle);
159db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleWebGL(bool toggle);
160f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void toggleThreadedQnam(bool toggle);
161db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleSpatialNavigation(bool b);
162db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleFullScreenMode(bool enable);
163db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleFrameFlattening(bool toggle);
164db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleInterruptingJavaScriptEnabled(bool enable);
165db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleJavascriptCanOpenWindows(bool enable);
166db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
167db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#if defined(QT_CONFIGURED_WITH_OPENGL)
168db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void toggleQGLWidgetViewport(bool enable);
169db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
170db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
171db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void changeViewportUpdateMode(int mode);
172f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void animatedFlip();
173f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void animatedYFlip();
174db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void selectElements();
175db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void showFPS(bool enable);
176db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void showUserAgentDialog();
177db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
178db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockpublic slots:
179db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    LauncherWindow* newWindow();
180db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    LauncherWindow* cloneWindow();
181db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void updateFPS(int fps);
182db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
183db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blocksignals:
184db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void enteredFullScreenMode(bool on);
185db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
186db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockprivate:
187dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void init();
18868513a70bcd92384395513322f1b801e7bf9c729Steve Block    void initializeView();
189db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void createChrome();
190dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void applyPrefs();
191db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    void applyZoom();
192db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
19368513a70bcd92384395513322f1b801e7bf9c729Steve Block    bool isGraphicsBased() const;
19468513a70bcd92384395513322f1b801e7bf9c729Steve Block
195db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockprivate:
196dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    static QVector<int> m_zoomLevels;
197db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    int m_currentZoom;
198db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
199db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    QWidget* m_view;
200db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    WebInspector* m_inspector;
201db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
202dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    WindowOptions m_windowOptions;
203dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
204db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    QAction* m_formatMenuAction;
205db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
206db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    QPropertyAnimation* m_zoomAnimation;
207db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    QList<QTouchEvent::TouchPoint> m_touchPoints;
208db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    bool m_touchMocking;
209db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block};
210db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
211db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#endif
212