45
|
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
|
74
|
42 module browserapplication;
|
|
43
|
|
44
|
|
45 import qt.core.QBuffer;
|
|
46 import qt.core.QDir;
|
|
47 import qt.core.QLibraryInfo;
|
|
48 import qt.core.QSettings;
|
|
49 import qt.core.QTextStream;
|
|
50 import qt.core.QTranslator;
|
|
51 import qt.core.QUrl;
|
113
|
52 import qt.core.QTimer;
|
94
|
53 //import qt.core.QPointer;
|
45
|
54
|
74
|
55 import qt.gui.QApplication;
|
|
56 import qt.gui.QIcon;
|
|
57 import qt.gui.QDesktopServices;
|
|
58 import qt.gui.QFileOpenEvent;
|
|
59 import qt.gui.QMessageBox;
|
45
|
60
|
74
|
61 import qt.network.QLocalServer;
|
|
62 import qt.network.QLocalSocket;
|
|
63 import qt.network.QNetworkProxy;
|
|
64 import qt.network.QSslSocket;
|
45
|
65
|
94
|
66 import qt.webkit.QWebSettings;
|
74
|
67
|
94
|
68 //import qt.core.QDebug;
|
45
|
69
|
|
70 import bookmarks;
|
|
71 import browsermainwindow;
|
|
72 import cookiejar;
|
|
73 import downloadmanager;
|
|
74 import history;
|
|
75 import networkaccessmanager;
|
|
76 import tabwidget;
|
|
77 import webview;
|
|
78
|
|
79
|
|
80 class BrowserApplication : public QApplication
|
|
81 {
|
74
|
82 public:
|
|
83
|
113
|
84 this(string[] arguments)
|
74
|
85 {
|
113
|
86 super(arguments);
|
77
|
87 m_localServer = null;
|
80
|
88 QCoreApplication.setOrganizationName("Trolltech");
|
|
89 QCoreApplication.setApplicationName("demobrowser");
|
|
90 QCoreApplication.setApplicationVersion("0.1");
|
74
|
91 version(Q_WS_QWS)
|
|
92 {
|
|
93 // Use a different server name for QWS so we can run an X11
|
|
94 // browser and a QWS browser in parallel on the same machine for
|
|
95 // debugging
|
80
|
96 string serverName = QCoreApplication.applicationName() ~ "_qws";
|
74
|
97 } else {
|
77
|
98 string serverName = QCoreApplication.applicationName();
|
74
|
99 }
|
77
|
100 auto socket = new QLocalSocket;
|
74
|
101 socket.connectToServer(serverName);
|
|
102 if (socket.waitForConnected(500)) {
|
|
103 auto stream = new QTextStream(&socket);
|
77
|
104 string[] args = QCoreApplication.arguments();
|
94
|
105 if (args.length > 1)
|
113
|
106 stream.writeString(args[$-1]);
|
|
107 //else
|
|
108 // stream << "";
|
74
|
109 stream.flush();
|
|
110 socket.waitForBytesWritten();
|
|
111 return;
|
|
112 }
|
|
113
|
|
114 version(Q_WS_MAC) {
|
|
115 QApplication.setQuitOnLastWindowClosed(false);
|
|
116 } else {
|
|
117 QApplication.setQuitOnLastWindowClosed(true);
|
|
118 }
|
|
119
|
|
120 m_localServer = new QLocalServer(this);
|
|
121 m_localServer.newConnection.connect(&this.newLocalSocketConnection);
|
|
122 if (!m_localServer.listen(serverName)) {
|
|
123 if (m_localServer.serverError() == QAbstractSocket.AddressInUseError
|
|
124 && QFile.exists(m_localServer.serverName())) {
|
|
125 QFile.remove(m_localServer.serverName());
|
|
126 m_localServer.listen(serverName);
|
|
127 }
|
|
128 }
|
|
129
|
|
130 version(QT_NO_OPENSSL) {} else {
|
|
131 if (!QSslSocket.supportsSsl()) {
|
113
|
132 QMessageBox.information(null, "Demo Browser",
|
150
|
133 "This system does not support OpenSSL. SSL websites will not be available.");
|
74
|
134 }
|
|
135 }
|
|
136
|
150
|
137 QDesktopServices.setUrlHandler("http", &this.openUrl);
|
77
|
138 string localSysName = QLocale.system().name();
|
45
|
139
|
80
|
140 installTranslator("qt_" ~ localSysName);
|
74
|
141
|
113
|
142 auto settings = new QSettings;
|
80
|
143 settings.beginGroup("sessions");
|
|
144 m_lastSession = settings.value("lastSession").toByteArray();
|
74
|
145 settings.endGroup();
|
|
146
|
|
147 version(Q_WS_MAC) {
|
|
148 this.lastWindowClosed.connect(&this.lastWindowClosed);
|
|
149 }
|
|
150
|
|
151 QTimer.singleShot(0, this, SLOT(postLaunch()));
|
|
152 }
|
|
153
|
|
154 ~this()
|
|
155 {
|
|
156 delete s_downloadManager;
|
77
|
157 for (int i = 0; i < m_mainWindows.length; ++i) {
|
|
158 BrowserMainWindow window = m_mainWindows[i];
|
74
|
159 delete window;
|
|
160 }
|
|
161 delete s_networkAccessManager;
|
|
162 delete s_bookmarksManager;
|
|
163 }
|
|
164
|
|
165 static BrowserApplication instance()
|
|
166 {
|
|
167 return cast(BrowserApplication) QCoreApplication.instance();
|
|
168 }
|
|
169
|
|
170 void loadSettings()
|
|
171 {
|
150
|
172 QSettings settings = new QSettings;
|
80
|
173 settings.beginGroup("websettings");
|
74
|
174
|
|
175 QWebSettings defaultSettings = QWebSettings.globalSettings();
|
77
|
176 string standardFontFamily = defaultSettings.fontFamily(QWebSettings.StandardFont);
|
74
|
177 int standardFontSize = defaultSettings.fontSize(QWebSettings.DefaultFontSize);
|
113
|
178 QFont standardFont = new QFont(standardFontFamily, standardFontSize);
|
150
|
179 standardFont = QVariant.fromValue!(QFont)(settings.value("standardFont", standardFont));
|
74
|
180 defaultSettings.setFontFamily(QWebSettings.StandardFont, standardFont.family());
|
|
181 defaultSettings.setFontSize(QWebSettings.DefaultFontSize, standardFont.pointSize());
|
|
182
|
77
|
183 string fixedFontFamily = defaultSettings.fontFamily(QWebSettings.FixedFont);
|
74
|
184 int fixedFontSize = defaultSettings.fontSize(QWebSettings.DefaultFixedFontSize);
|
150
|
185 QFont fixedFont = new QFont(fixedFontFamily, fixedFontSize);
|
|
186 fixedFont = QVariant.fromValue!(QFont)(settings.value("fixedFont", fixedFont));
|
74
|
187 defaultSettings.setFontFamily(QWebSettings.FixedFont, fixedFont.family());
|
|
188 defaultSettings.setFontSize(QWebSettings.DefaultFixedFontSize, fixedFont.pointSize());
|
|
189
|
150
|
190 defaultSettings.setAttribute(QWebSettings.JavascriptEnabled, settings.value("enableJavascript", new QVariant(true)).toBool());
|
|
191 defaultSettings.setAttribute(QWebSettings.PluginsEnabled, settings.value("enablePlugins", new QVariant(true)).toBool());
|
74
|
192
|
80
|
193 QUrl url = settings.value("userStyleSheet").toUrl();
|
74
|
194 defaultSettings.setUserStyleSheetUrl(url);
|
|
195
|
|
196 settings.endGroup();
|
|
197 }
|
|
198
|
|
199 bool isTheOnlyBrowser()
|
45
|
200 {
|
150
|
201 return (m_localServer !is null);
|
74
|
202 }
|
|
203
|
|
204 BrowserMainWindow mainWindow()
|
|
205 {
|
|
206 clean();
|
94
|
207 if (m_mainWindows.length == 0)
|
74
|
208 newMainWindow();
|
|
209 return m_mainWindows[0];
|
|
210 }
|
|
211
|
|
212 BrowserMainWindow[] mainWindows()
|
|
213 {
|
|
214 clean();
|
|
215 BrowserMainWindow[] list;
|
77
|
216 for (int i = 0; i < m_mainWindows.length; ++i)
|
|
217 list ~= m_mainWindows[i];
|
74
|
218 return list;
|
|
219 }
|
|
220
|
|
221 QIcon icon(QUrl url)
|
|
222 {
|
|
223 QIcon icon = QWebSettings.iconForUrl(url);
|
|
224 if (!icon.isNull())
|
|
225 return icon.pixmap(16, 16);
|
|
226 if (m_defaultIcon.isNull())
|
80
|
227 m_defaultIcon = QIcon(":defaulticon.png");
|
74
|
228 return m_defaultIcon.pixmap(16, 16);
|
|
229 }
|
|
230
|
|
231 void saveSession()
|
|
232 {
|
|
233 QWebSettings globalSettings = QWebSettings.globalSettings();
|
|
234 if (globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled))
|
|
235 return;
|
|
236
|
|
237 clean();
|
|
238
|
150
|
239 QSettings settings = new QSettings;
|
80
|
240 settings.beginGroup("sessions");
|
74
|
241
|
150
|
242 QByteArray data = new QByteArray;
|
74
|
243 auto buffer = new QBuffer(&data);
|
|
244 auto stream = new QDataStream(&buffer);
|
|
245 buffer.open(QIODevice.ReadWrite);
|
|
246
|
150
|
247 stream.writeLong(m_mainWindows.length);
|
77
|
248 for (int i = 0; i < m_mainWindows.length; ++i)
|
|
249 stream << m_mainWindows[i].saveState();
|
80
|
250 settings.setValue("lastSession", data);
|
74
|
251 settings.endGroup();
|
|
252 }
|
|
253
|
|
254 bool canRestoreSession()
|
|
255 {
|
|
256 return !m_lastSession.isEmpty();
|
|
257 }
|
45
|
258
|
74
|
259 static HistoryManager historyManager()
|
|
260 {
|
|
261 if (!s_historyManager) {
|
|
262 s_historyManager = new HistoryManager();
|
|
263 QWebHistoryInterface.setDefaultInterface(s_historyManager);
|
|
264 }
|
|
265 return s_historyManager;
|
|
266 }
|
|
267
|
|
268 static CookieJar cookieJar()
|
|
269 {
|
|
270 return cast(CookieJar) networkAccessManager().cookieJar();
|
|
271 }
|
|
272
|
|
273 static DownloadManager downloadManager()
|
|
274 {
|
|
275 if (!s_downloadManager) {
|
|
276 s_downloadManager = new DownloadManager();
|
|
277 }
|
|
278 return s_downloadManager;
|
|
279 }
|
|
280
|
|
281 static NetworkAccessManager networkAccessManager()
|
|
282 {
|
|
283 if (!s_networkAccessManager) {
|
|
284 s_networkAccessManager = new NetworkAccessManager();
|
|
285 s_networkAccessManager.setCookieJar(new CookieJar);
|
|
286 }
|
|
287 return s_networkAccessManager;
|
|
288 }
|
|
289
|
45
|
290
|
74
|
291 static BookmarksManager bookmarksManager()
|
|
292 {
|
|
293 if (!s_bookmarksManager) {
|
|
294 s_bookmarksManager = new BookmarksManager;
|
|
295 }
|
|
296 return s_bookmarksManager;
|
|
297 }
|
|
298
|
45
|
299
|
74
|
300 version(Q_WS_MAC)
|
|
301 {
|
|
302 bool event(QEvent event)
|
|
303 {
|
|
304 switch (event.type()) {
|
|
305 case QEvent.ApplicationActivate: {
|
|
306 clean();
|
94
|
307 if (m_mainWindows.length) {
|
74
|
308 BrowserMainWindow mw = mainWindow();
|
|
309 if (mw && !mw.isMinimized()) {
|
|
310 mainWindow().show();
|
|
311 }
|
|
312 return true;
|
|
313 }
|
|
314 }
|
|
315 case QEvent.FileOpen:
|
94
|
316 if (m_mainWindows.length) {
|
74
|
317 mainWindow().loadPage(cast(QFileOpenEvent) event.file());
|
|
318 return true;
|
|
319 }
|
|
320 default:
|
|
321 break;
|
|
322 }
|
|
323 return QApplication.event(event);
|
|
324 }
|
45
|
325 }
|
|
326
|
74
|
327 public:
|
45
|
328
|
74
|
329 BrowserMainWindow newMainWindow()
|
|
330 {
|
|
331 BrowserMainWindow browser = new BrowserMainWindow();
|
94
|
332 m_mainWindows = [browser] ~ m_mainWindows;
|
74
|
333 browser.show();
|
|
334 return browser;
|
|
335 }
|
45
|
336
|
74
|
337 void restoreLastSession()
|
|
338 {
|
|
339 QByteArray[] windows;
|
|
340 auto buffer = new QBuffer(&m_lastSession);
|
|
341 auto stream = new QDataStream(&buffer);
|
|
342 buffer.open(QIODevice.ReadOnly);
|
|
343 int windowCount;
|
|
344 stream >> windowCount;
|
|
345 for (int i = 0; i < windowCount; ++i) {
|
|
346 QByteArray windowState;
|
|
347 stream >> windowState;
|
|
348 windows ~= windowState;
|
|
349 }
|
150
|
350 for (int i = 0; i < windows.length; ++i) {
|
74
|
351 BrowserMainWindow newWindow = 0;
|
94
|
352 if (m_mainWindows.length == 1 && mainWindow().tabWidget().count() == 1
|
|
353 && mainWindow().currentTab().getUrl() is null) {
|
74
|
354 newWindow = mainWindow();
|
|
355 } else {
|
|
356 newWindow = newMainWindow();
|
|
357 }
|
77
|
358 newWindow.restoreState(windows[i]);
|
74
|
359 }
|
|
360 }
|
45
|
361
|
|
362
|
74
|
363 version(Q_WS_MAC)
|
45
|
364 {
|
74
|
365 import qt.gui.QMessageBox;
|
|
366
|
|
367 void quitBrowser()
|
|
368 {
|
|
369 clean();
|
|
370 int tabCount = 0;
|
77
|
371 for (int i = 0; i < m_mainWindows.length; ++i) {
|
|
372 tabCount =+ m_mainWindows[i].tabWidget().count();
|
74
|
373 }
|
45
|
374
|
74
|
375 if (tabCount > 1) {
|
77
|
376 int ret = QMessageBox.warning(mainWindow(), null,
|
94
|
377 Format(tr("There are %1 windows and %2 tabs open\n"
|
|
378 "Do you want to quit anyway?"), m_mainWindows.length, tabCount),
|
74
|
379 QMessageBox.Yes | QMessageBox.No,
|
|
380 QMessageBox.No);
|
|
381 if (ret == QMessageBox.No)
|
|
382 return;
|
|
383 }
|
45
|
384
|
74
|
385 exit(0);
|
|
386 }
|
|
387
|
|
388 void lastWindowClosed()
|
|
389 {
|
|
390 clean();
|
|
391 BrowserMainWindow mw = new BrowserMainWindow;
|
|
392 mw.slotHome();
|
94
|
393 m_mainWindows = [mw] ~ m_mainWindows;
|
74
|
394 }
|
45
|
395 }
|
|
396
|
74
|
397 private:
|
45
|
398
|
74
|
399 /*!
|
|
400 Any actions that can be delayed until the window is visible
|
|
401 */
|
|
402 void postLaunch()
|
|
403 {
|
77
|
404 string directory = QDesktopServices.storageLocation(QDesktopServices.DataLocation);
|
74
|
405 if (directory.isEmpty())
|
80
|
406 directory = QDir.homePath() ~ "/." ~ QCoreApplication.applicationName();
|
74
|
407 QWebSettings.setIconDatabasePath(directory);
|
45
|
408
|
80
|
409 setWindowIcon(new QIcon(":browser.svg"));
|
45
|
410
|
74
|
411 loadSettings();
|
45
|
412
|
74
|
413 // newMainWindow() needs to be called in main() for this to happen
|
94
|
414 if (m_mainWindows.length > 0) {
|
77
|
415 string[] args = QCoreApplication.arguments();
|
150
|
416 if (args.length > 1)
|
74
|
417 mainWindow().loadPage(args.last());
|
|
418 else
|
|
419 mainWindow().slotHome();
|
|
420 }
|
|
421 BrowserApplication.historyManager();
|
|
422 }
|
45
|
423
|
150
|
424 void openUrl(QUrl url)
|
74
|
425 {
|
|
426 mainWindow().loadPage(url.toString());
|
|
427 }
|
45
|
428
|
74
|
429 void newLocalSocketConnection()
|
|
430 {
|
|
431 QLocalSocket socket = m_localServer.nextPendingConnection();
|
|
432 if (!socket)
|
|
433 return;
|
|
434 socket.waitForReadyRead(1000);
|
150
|
435 auto stream = new QTextStream(socket);
|
77
|
436 string url;
|
74
|
437 stream >> url;
|
150
|
438 if (url.length) {
|
74
|
439 QSettings settings;
|
80
|
440 settings.beginGroup("general");
|
150
|
441 int openLinksIn = settings.value("openLinksIn", new QVariant(0)).toInt();
|
74
|
442 settings.endGroup();
|
|
443 if (openLinksIn == 1)
|
|
444 newMainWindow();
|
|
445 else
|
|
446 mainWindow().tabWidget().newTab();
|
|
447 openUrl(url);
|
|
448 }
|
|
449 delete socket;
|
|
450 mainWindow().raise();
|
|
451 mainWindow().activateWindow();
|
|
452 }
|
45
|
453
|
|
454 private:
|
74
|
455
|
|
456 void clean()
|
|
457 {
|
|
458 // cleanup any deleted main windows first
|
77
|
459 for (int i = m_mainWindows.length - 1; i >= 0; --i)
|
150
|
460 if (m_mainWindows[i] is null)
|
74
|
461 m_mainWindows.removeAt(i);
|
|
462 }
|
45
|
463
|
77
|
464 void installTranslator(string name)
|
74
|
465 {
|
|
466 QTranslator translator = new QTranslator(this);
|
|
467 translator.load(name, QLibraryInfo.location(QLibraryInfo.TranslationsPath));
|
|
468 QApplication.installTranslator(translator);
|
|
469 }
|
|
470
|
|
471 static HistoryManager s_historyManager;
|
|
472 static DownloadManager s_downloadManager;
|
|
473 static NetworkAccessManager s_networkAccessManager;
|
|
474 static BookmarksManager s_bookmarksManager;
|
|
475
|
94
|
476 //QPointer!(BrowserMainWindow)[] m_mainWindows;
|
|
477 BrowserMainWindow[] m_mainWindows;
|
74
|
478 QLocalServer m_localServer;
|
|
479 QByteArray m_lastSession;
|
|
480 QIcon m_defaultIcon;
|
45
|
481 }
|