comparison demos/browser/browserapplication.d @ 45:71b382c10ef6

add coarse and incomplete QT browser port
author mandel
date Sun, 17 May 2009 18:49:59 +0000
parents
children 37caa90ce503
comparison
equal deleted inserted replaced
44:3cb15c92ac28 45:71b382c10ef6
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Qt Software Information (qt-info@nokia.com)
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at qt-sales@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 import QtGui.QApplication;
43
44 import QtCore.QUrl;
45 import QtCore.QPointer;
46
47 import QtGui.QIcon;
48
49 import browserapplication;
50
51 import bookmarks;
52 import browsermainwindow;
53 import cookiejar;
54 import downloadmanager;
55 import history;
56 import networkaccessmanager;
57 import tabwidget;
58 import webview;
59
60 import QtCore.QBuffer;
61 import QtCore.QDir;
62 import QtCore.QLibraryInfo;
63 import QtCore.QSettings;
64 import QtCore.QTextStream;
65 import QtCore.QTranslator;
66
67 import QtGui.QDesktopServices;
68 import QtGui.QFileOpenEvent;
69 import QtGui.QMessageBox;
70
71 import QtNetwork.QLocalServer;
72 import QtNetwork.QLocalSocket;
73 import QtNetwork.QNetworkProxy;
74 import QtNetwork.QSslSocket;
75
76 import QtWebKit.QWebSettings;
77
78 import QtCore.QDebug;
79
80 DownloadManager *BrowserApplication::s_downloadManager = 0;
81 HistoryManager *BrowserApplication::s_historyManager = 0;
82 NetworkAccessManager *BrowserApplication::s_networkAccessManager = 0;
83 BookmarksManager *BrowserApplication::s_bookmarksManager = 0;
84
85
86 /*
87 QT_BEGIN_NAMESPACE
88 class QLocalServer;
89 QT_END_NAMESPACE
90
91 class BookmarksManager;
92 class BrowserMainWindow;
93 class CookieJar;
94 class DownloadManager;
95 class HistoryManager;
96 class NetworkAccessManager;
97 */
98
99 class BrowserApplication : public QApplication
100 {
101 Q_OBJECT
102
103 public:
104 this(char[] args)
105 {
106 super(args);
107 m_localServer = 0;
108 QCoreApplication::setOrganizationName(QLatin1String("Trolltech"));
109 QCoreApplication::setApplicationName(QLatin1String("demobrowser"));
110 QCoreApplication::setApplicationVersion(QLatin1String("0.1"));
111 version(Q_WS_QWS)
112 {
113 // Use a different server name for QWS so we can run an X11
114 // browser and a QWS browser in parallel on the same machine for
115 // debugging
116 QString serverName = QCoreApplication::applicationName() + QLatin1String("_qws");
117 } else {
118 QString serverName = QCoreApplication::applicationName();
119 }
120 QLocalSocket socket;
121 socket.connectToServer(serverName);
122 if (socket.waitForConnected(500)) {
123 QTextStream stream(&socket);
124 QStringList args = QCoreApplication::arguments();
125 if (args.count() > 1)
126 stream << args.last();
127 else
128 stream << QString();
129 stream.flush();
130 socket.waitForBytesWritten();
131 return;
132 }
133
134 version(Q_WS_MAC) {
135 QApplication::setQuitOnLastWindowClosed(false);
136 } else {
137 QApplication::setQuitOnLastWindowClosed(true);
138 }
139
140 m_localServer = new QLocalServer(this);
141 connect(m_localServer, SIGNAL(newConnection()),
142 this, SLOT(newLocalSocketConnection()));
143 if (!m_localServer->listen(serverName)) {
144 if (m_localServer->serverError() == QAbstractSocket::AddressInUseError
145 && QFile::exists(m_localServer->serverName())) {
146 QFile::remove(m_localServer->serverName());
147 m_localServer->listen(serverName);
148 }
149 }
150
151 #ifndef QT_NO_OPENSSL
152 if (!QSslSocket::supportsSsl()) {
153 QMessageBox::information(0, "Demo Browser",
154 "This system does not support OpenSSL. SSL websites will not be available.");
155 }
156 }
157
158 QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl");
159 QString localSysName = QLocale::system().name();
160
161 installTranslator(QLatin1String("qt_") + localSysName);
162
163 QSettings settings;
164 settings.beginGroup(QLatin1String("sessions"));
165 m_lastSession = settings.value(QLatin1String("lastSession")).toByteArray();
166 settings.endGroup();
167
168 version(Q_WS_MAC) {
169 connect(this, SIGNAL(lastWindowClosed()),
170 this, SLOT(lastWindowClosed()));
171 }
172
173 QTimer::singleShot(0, this, SLOT(postLaunch()));
174 }
175
176 ~this()
177 {
178 delete s_downloadManager;
179 for (int i = 0; i < m_mainWindows.size(); ++i) {
180 BrowserMainWindow *window = m_mainWindows.at(i);
181 delete window;
182 }
183 delete s_networkAccessManager;
184 delete s_bookmarksManager;
185 }
186
187 static BrowserApplication *instance()
188 {
189 return (static_cast<BrowserApplication *>(QCoreApplication::instance()));
190 }
191
192
193
194 void loadSettings()
195 {
196 QSettings settings;
197 settings.beginGroup(QLatin1String("websettings"));
198
199 QWebSettings *defaultSettings = QWebSettings::globalSettings();
200 QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont);
201 int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize);
202 QFont standardFont = QFont(standardFontFamily, standardFontSize);
203 standardFont = qVariantValue<QFont>(settings.value(QLatin1String("standardFont"), standardFont));
204 defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family());
205 defaultSettings->setFontSize(QWebSettings::DefaultFontSize, standardFont.pointSize());
206
207 QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont);
208 int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize);
209 QFont fixedFont = QFont(fixedFontFamily, fixedFontSize);
210 fixedFont = qVariantValue<QFont>(settings.value(QLatin1String("fixedFont"), fixedFont));
211 defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family());
212 defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fixedFont.pointSize());
213
214 defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool());
215 defaultSettings->setAttribute(QWebSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool());
216
217 QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl();
218 defaultSettings->setUserStyleSheetUrl(url);
219
220 settings.endGroup();
221 }
222
223 bool isTheOnlyBrowser() const
224 {
225 return (m_localServer != 0);
226 }
227
228 BrowserMainWindow *mainWindow()
229 {
230 clean();
231 if (m_mainWindows.isEmpty())
232 newMainWindow();
233 return m_mainWindows[0];
234 }
235
236 QList<BrowserMainWindow*> mainWindows()
237 {
238 clean();
239 QList<BrowserMainWindow*> list;
240 for (int i = 0; i < m_mainWindows.count(); ++i)
241 list.append(m_mainWindows.at(i));
242 return list;
243 }
244
245
246 QIcon icon(const QUrl &url) const
247 {
248 QIcon icon = QWebSettings::iconForUrl(url);
249 if (!icon.isNull())
250 return icon.pixmap(16, 16);
251 if (m_defaultIcon.isNull())
252 m_defaultIcon = QIcon(QLatin1String(":defaulticon.png"));
253 return m_defaultIcon.pixmap(16, 16);
254 }
255
256 void saveSession()
257 {
258 QWebSettings *globalSettings = QWebSettings::globalSettings();
259 if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
260 return;
261
262 clean();
263
264 QSettings settings;
265 settings.beginGroup(QLatin1String("sessions"));
266
267 QByteArray data;
268 QBuffer buffer(&data);
269 QDataStream stream(&buffer);
270 buffer.open(QIODevice::ReadWrite);
271
272 stream << m_mainWindows.count();
273 for (int i = 0; i < m_mainWindows.count(); ++i)
274 stream << m_mainWindows.at(i)->saveState();
275 settings.setValue(QLatin1String("lastSession"), data);
276 settings.endGroup();
277 }
278
279 bool canRestoreSession() const
280 {
281 return !m_lastSession.isEmpty();
282 }
283
284 static HistoryManager *historyManager()
285 {
286 if (!s_historyManager) {
287 s_historyManager = new HistoryManager();
288 QWebHistoryInterface::setDefaultInterface(s_historyManager);
289 }
290 return s_historyManager;
291 }
292
293 static CookieJar *cookieJar()
294 {
295 return (CookieJar*)networkAccessManager()->cookieJar();
296 }
297 static DownloadManager *downloadManager()
298 {
299 if (!s_downloadManager) {
300 s_downloadManager = new DownloadManager();
301 }
302 return s_downloadManager;
303 }
304
305
306 static NetworkAccessManager *networkAccessManager()
307 {
308 if (!s_networkAccessManager) {
309 s_networkAccessManager = new NetworkAccessManager();
310 s_networkAccessManager->setCookieJar(new CookieJar);
311 }
312 return s_networkAccessManager;
313 }
314
315
316 static BookmarksManager *bookmarksManager()
317 {
318 if (!s_bookmarksManager) {
319 s_bookmarksManager = new BookmarksManager;
320 }
321 return s_bookmarksManager;
322 }
323
324
325 version(Q_WS_MAC) {
326 bool event(QEvent* event)
327 {
328 switch (event->type()) {
329 case QEvent::ApplicationActivate: {
330 clean();
331 if (!m_mainWindows.isEmpty()) {
332 BrowserMainWindow *mw = mainWindow();
333 if (mw && !mw->isMinimized()) {
334 mainWindow()->show();
335 }
336 return true;
337 }
338 }
339 case QEvent::FileOpen:
340 if (!m_mainWindows.isEmpty()) {
341 mainWindow()->loadPage(static_cast<QFileOpenEvent *>(event)->file());
342 return true;
343 }
344 default:
345 break;
346 }
347 return QApplication::event(event);
348 }
349 }
350
351 public slots:
352 BrowserMainWindow *newMainWindow()
353 {
354 BrowserMainWindow *browser = new BrowserMainWindow();
355 m_mainWindows.prepend(browser);
356 browser->show();
357 return browser;
358 }
359
360 void restoreLastSession()
361 {
362 QList<QByteArray> windows;
363 QBuffer buffer(&m_lastSession);
364 QDataStream stream(&buffer);
365 buffer.open(QIODevice::ReadOnly);
366 int windowCount;
367 stream >> windowCount;
368 for (int i = 0; i < windowCount; ++i) {
369 QByteArray windowState;
370 stream >> windowState;
371 windows.append(windowState);
372 }
373 for (int i = 0; i < windows.count(); ++i) {
374 BrowserMainWindow *newWindow = 0;
375 if (m_mainWindows.count() == 1
376 && mainWindow()->tabWidget()->count() == 1
377 && mainWindow()->currentTab()->url() == QUrl()) {
378 newWindow = mainWindow();
379 } else {
380 newWindow = newMainWindow();
381 }
382 newWindow->restoreState(windows.at(i));
383 }
384 }
385
386
387 version(Q_WS_MAC) {
388 import QtGui.QMessageBox;
389 void BrowserApplication::quitBrowser()
390 {
391 clean();
392 int tabCount = 0;
393 for (int i = 0; i < m_mainWindows.count(); ++i) {
394 tabCount =+ m_mainWindows.at(i)->tabWidget()->count();
395 }
396
397 if (tabCount > 1) {
398 int ret = QMessageBox::warning(mainWindow(), QString(),
399 tr("There are %1 windows and %2 tabs open\n"
400 "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount),
401 QMessageBox::Yes | QMessageBox::No,
402 QMessageBox::No);
403 if (ret == QMessageBox::No)
404 return;
405 }
406
407 exit(0);
408 }
409 }
410
411 version(Q_WS_MAC) {
412 void lastWindowClosed()
413 {
414 clean();
415 BrowserMainWindow *mw = new BrowserMainWindow;
416 mw->slotHome();
417 m_mainWindows.prepend(mw);
418 }
419 }
420
421
422 private slots:
423
424 /*!
425 Any actions that can be delayed until the window is visible
426 */
427 void postLaunch()
428 {
429 QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
430 if (directory.isEmpty())
431 directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName();
432 QWebSettings::setIconDatabasePath(directory);
433
434 setWindowIcon(QIcon(QLatin1String(":browser.svg")));
435
436 loadSettings();
437
438 // newMainWindow() needs to be called in main() for this to happen
439 if (m_mainWindows.count() > 0) {
440 QStringList args = QCoreApplication::arguments();
441 if (args.count() > 1)
442 mainWindow()->loadPage(args.last());
443 else
444 mainWindow()->slotHome();
445 }
446 BrowserApplication::historyManager();
447 }
448
449 void openUrl(const QUrl &url)
450 {
451 mainWindow()->loadPage(url.toString());
452 }
453
454 void newLocalSocketConnection();
455 {
456 QLocalSocket *socket = m_localServer->nextPendingConnection();
457 if (!socket)
458 return;
459 socket->waitForReadyRead(1000);
460 QTextStream stream(socket);
461 QString url;
462 stream >> url;
463 if (!url.isEmpty()) {
464 QSettings settings;
465 settings.beginGroup(QLatin1String("general"));
466 int openLinksIn = settings.value(QLatin1String("openLinksIn"), 0).toInt();
467 settings.endGroup();
468 if (openLinksIn == 1)
469 newMainWindow();
470 else
471 mainWindow()->tabWidget()->newTab();
472 openUrl(url);
473 }
474 delete socket;
475 mainWindow()->raise();
476 mainWindow()->activateWindow();
477 }
478
479 private:
480 void clean()
481 {
482 // cleanup any deleted main windows first
483 for (int i = m_mainWindows.count() - 1; i >= 0; --i)
484 if (m_mainWindows.at(i).isNull())
485 m_mainWindows.removeAt(i);
486 }
487
488 void installTranslator(const QString &name)
489 {
490 QTranslator *translator = new QTranslator(this);
491 translator->load(name, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
492 QApplication::installTranslator(translator);
493 }
494
495 static HistoryManager *s_historyManager;
496 static DownloadManager *s_downloadManager;
497 static NetworkAccessManager *s_networkAccessManager;
498 static BookmarksManager *s_bookmarksManager;
499
500 QList<QPointer<BrowserMainWindow> > m_mainWindows;
501 QLocalServer *m_localServer;
502 QByteArray m_lastSession;
503 mutable QIcon m_defaultIcon;
504 };
505
506 }
507