PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/demos/browser/browserapplication.d

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