1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** $QT_END_LICENSE$
31 **
32 ****************************************************************************/
33
34 #include "browsermainwindow.h"
35
36 #include "autosaver.h"
37 #include "bookmarks.h"
38 #include "browserapplication.h"
39 #include "chasewidget.h"
40 #include "downloadmanager.h"
41 #include "history.h"
42 #include "settings.h"
43 #include "tabwidget.h"
44 #include "toolbarsearch.h"
45 #include "ui_passworddialog.h"
46 #include "webview.h"
47
48 #include <QtCore/QSettings>
49
50 #include <QtWidgets/QDesktopWidget>
51 #include <QtWidgets/QFileDialog>
52 #include <QtWidgets/QPlainTextEdit>
53 #include <QtPrintSupport/QPrintDialog>
54 #include <QtPrintSupport/QPrintPreviewDialog>
55 #include <QtPrintSupport/QPrinter>
56 #include <QtWidgets/QMenuBar>
57 #include <QtWidgets/QMessageBox>
58 #include <QtWidgets/QStatusBar>
59 #include <QtWidgets/QToolBar>
60 #include <QtWidgets/QInputDialog>
61
62 #include <QWebFrame>
63 #include <QWebHistory>
64
65 #include <QtCore/QDebug>
66
BrowserMainWindow(QWidget * parent,Qt::WindowFlags flags)67 BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags)
68 : QMainWindow(parent, flags)
69 , m_tabWidget(new TabWidget(this))
70 , m_autoSaver(new AutoSaver(this))
71 , m_historyBack(0)
72 , m_historyForward(0)
73 , m_stop(0)
74 , m_reload(0)
75 {
76 setToolButtonStyle(Qt::ToolButtonFollowStyle);
77 setAttribute(Qt::WA_DeleteOnClose, true);
78 statusBar()->setSizeGripEnabled(true);
79 setupMenu();
80 setupToolBar();
81
82 QWidget *centralWidget = new QWidget(this);
83 BookmarksModel *boomarksModel = BrowserApplication::bookmarksManager()->bookmarksModel();
84 m_bookmarksToolbar = new BookmarksToolBar(boomarksModel, this);
85 connect(m_bookmarksToolbar, SIGNAL(openUrl(QUrl)),
86 m_tabWidget, SLOT(loadUrlInCurrentTab(QUrl)));
87 connect(m_bookmarksToolbar->toggleViewAction(), SIGNAL(toggled(bool)),
88 this, SLOT(updateBookmarksToolbarActionText(bool)));
89
90 QVBoxLayout *layout = new QVBoxLayout;
91 layout->setSpacing(0);
92 layout->setMargin(0);
93 #if defined(Q_OS_OSX)
94 layout->addWidget(m_bookmarksToolbar);
95 layout->addWidget(new QWidget); // <- OS X tab widget style bug
96 #else
97 addToolBarBreak();
98 addToolBar(m_bookmarksToolbar);
99 #endif
100 layout->addWidget(m_tabWidget);
101 centralWidget->setLayout(layout);
102 setCentralWidget(centralWidget);
103
104 connect(m_tabWidget, SIGNAL(loadPage(QString)),
105 this, SLOT(loadPage(QString)));
106 connect(m_tabWidget, SIGNAL(setCurrentTitle(QString)),
107 this, SLOT(slotUpdateWindowTitle(QString)));
108 connect(m_tabWidget, SIGNAL(showStatusBarMessage(QString)),
109 statusBar(), SLOT(showMessage(QString)));
110 connect(m_tabWidget, SIGNAL(linkHovered(QString)),
111 statusBar(), SLOT(showMessage(QString)));
112 connect(m_tabWidget, SIGNAL(loadProgress(int)),
113 this, SLOT(slotLoadProgress(int)));
114 connect(m_tabWidget, SIGNAL(tabsChanged()),
115 m_autoSaver, SLOT(changeOccurred()));
116 connect(m_tabWidget, SIGNAL(geometryChangeRequested(QRect)),
117 this, SLOT(geometryChangeRequested(QRect)));
118 connect(m_tabWidget, SIGNAL(printRequested(QWebFrame*)),
119 this, SLOT(printRequested(QWebFrame*)));
120 connect(m_tabWidget, SIGNAL(menuBarVisibilityChangeRequested(bool)),
121 menuBar(), SLOT(setVisible(bool)));
122 connect(m_tabWidget, SIGNAL(statusBarVisibilityChangeRequested(bool)),
123 statusBar(), SLOT(setVisible(bool)));
124 connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)),
125 m_navigationBar, SLOT(setVisible(bool)));
126 connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)),
127 m_bookmarksToolbar, SLOT(setVisible(bool)));
128 #if defined(Q_OS_OSX)
129 connect(m_tabWidget, SIGNAL(lastTabClosed()),
130 this, SLOT(close()));
131 #else
132 connect(m_tabWidget, SIGNAL(lastTabClosed()),
133 m_tabWidget, SLOT(newTab()));
134 #endif
135
136 slotUpdateWindowTitle();
137 loadDefaultState();
138 m_tabWidget->newTab();
139
140 int size = m_tabWidget->lineEditStack()->sizeHint().height();
141 m_navigationBar->setIconSize(QSize(size, size));
142
143 }
144
~BrowserMainWindow()145 BrowserMainWindow::~BrowserMainWindow()
146 {
147 m_autoSaver->changeOccurred();
148 m_autoSaver->saveIfNeccessary();
149 }
150
loadDefaultState()151 void BrowserMainWindow::loadDefaultState()
152 {
153 QSettings settings;
154 settings.beginGroup(QLatin1String("BrowserMainWindow"));
155 QByteArray data = settings.value(QLatin1String("defaultState")).toByteArray();
156 restoreState(data);
157 settings.endGroup();
158 }
159
sizeHint() const160 QSize BrowserMainWindow::sizeHint() const
161 {
162 QRect desktopRect = QApplication::desktop()->screenGeometry();
163 QSize size = desktopRect.size() * qreal(0.9);
164 return size;
165 }
166
save()167 void BrowserMainWindow::save()
168 {
169 BrowserApplication::instance()->saveSession();
170
171 QSettings settings;
172 settings.beginGroup(QLatin1String("BrowserMainWindow"));
173 QByteArray data = saveState(false);
174 settings.setValue(QLatin1String("defaultState"), data);
175 settings.endGroup();
176 }
177
178 static const qint32 BrowserMainWindowMagic = 0xba;
179
saveState(bool withTabs) const180 QByteArray BrowserMainWindow::saveState(bool withTabs) const
181 {
182 int version = 2;
183 QByteArray data;
184 QDataStream stream(&data, QIODevice::WriteOnly);
185
186 stream << qint32(BrowserMainWindowMagic);
187 stream << qint32(version);
188
189 stream << size();
190 stream << !m_navigationBar->isHidden();
191 stream << !m_bookmarksToolbar->isHidden();
192 stream << !statusBar()->isHidden();
193 if (withTabs)
194 stream << tabWidget()->saveState();
195 else
196 stream << QByteArray();
197 return data;
198 }
199
restoreState(const QByteArray & state)200 bool BrowserMainWindow::restoreState(const QByteArray &state)
201 {
202 int version = 2;
203 QByteArray sd = state;
204 QDataStream stream(&sd, QIODevice::ReadOnly);
205 if (stream.atEnd())
206 return false;
207
208 qint32 marker;
209 qint32 v;
210 stream >> marker;
211 stream >> v;
212 if (marker != BrowserMainWindowMagic || v != version)
213 return false;
214
215 QSize size;
216 bool showToolbar;
217 bool showBookmarksBar;
218 bool showStatusbar;
219 QByteArray tabState;
220
221 stream >> size;
222 stream >> showToolbar;
223 stream >> showBookmarksBar;
224 stream >> showStatusbar;
225 stream >> tabState;
226
227 resize(size);
228
229 m_navigationBar->setVisible(showToolbar);
230 updateToolbarActionText(showToolbar);
231
232 m_bookmarksToolbar->setVisible(showBookmarksBar);
233 updateBookmarksToolbarActionText(showBookmarksBar);
234
235 statusBar()->setVisible(showStatusbar);
236 updateStatusbarActionText(showStatusbar);
237
238 if (!tabWidget()->restoreState(tabState))
239 return false;
240
241 return true;
242 }
243
setupMenu()244 void BrowserMainWindow::setupMenu()
245 {
246 new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(slotSwapFocus()));
247
248 // File
249 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
250
251 fileMenu->addAction(tr("&New Window"), this, SLOT(slotFileNew()), QKeySequence::New);
252 fileMenu->addAction(m_tabWidget->newTabAction());
253 fileMenu->addAction(tr("&Open File..."), this, SLOT(slotFileOpen()), QKeySequence::Open);
254 fileMenu->addAction(tr("Open &Location..."), this,
255 SLOT(slotSelectLineEdit()), QKeySequence(Qt::ControlModifier + Qt::Key_L));
256 fileMenu->addSeparator();
257 fileMenu->addAction(m_tabWidget->closeTabAction());
258 fileMenu->addSeparator();
259 fileMenu->addAction(tr("&Save As..."), this,
260 SLOT(slotFileSaveAs()), QKeySequence(QKeySequence::Save));
261 fileMenu->addSeparator();
262 BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager();
263 fileMenu->addAction(tr("&Import Bookmarks..."), bookmarksManager, SLOT(importBookmarks()));
264 fileMenu->addAction(tr("&Export Bookmarks..."), bookmarksManager, SLOT(exportBookmarks()));
265 fileMenu->addSeparator();
266 fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview()));
267 fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print);
268 fileMenu->addSeparator();
269 QAction *action = fileMenu->addAction(tr("Private &Browsing..."), this, SLOT(slotPrivateBrowsing()));
270 action->setCheckable(true);
271 fileMenu->addSeparator();
272
273 #if defined(Q_OS_OSX)
274 fileMenu->addAction(tr("&Quit"), BrowserApplication::instance(), SLOT(quitBrowser()), QKeySequence(Qt::CTRL | Qt::Key_Q));
275 #else
276 fileMenu->addAction(tr("&Quit"), this, SLOT(close()), QKeySequence(Qt::CTRL | Qt::Key_Q));
277 #endif
278
279 // Edit
280 QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
281 QAction *m_undo = editMenu->addAction(tr("&Undo"));
282 m_undo->setShortcuts(QKeySequence::Undo);
283 m_tabWidget->addWebAction(m_undo, QWebPage::Undo);
284 QAction *m_redo = editMenu->addAction(tr("&Redo"));
285 m_redo->setShortcuts(QKeySequence::Redo);
286 m_tabWidget->addWebAction(m_redo, QWebPage::Redo);
287 editMenu->addSeparator();
288 QAction *m_cut = editMenu->addAction(tr("Cu&t"));
289 m_cut->setShortcuts(QKeySequence::Cut);
290 m_tabWidget->addWebAction(m_cut, QWebPage::Cut);
291 QAction *m_copy = editMenu->addAction(tr("&Copy"));
292 m_copy->setShortcuts(QKeySequence::Copy);
293 m_tabWidget->addWebAction(m_copy, QWebPage::Copy);
294 QAction *m_paste = editMenu->addAction(tr("&Paste"));
295 m_paste->setShortcuts(QKeySequence::Paste);
296 m_tabWidget->addWebAction(m_paste, QWebPage::Paste);
297 editMenu->addSeparator();
298
299 QAction *m_find = editMenu->addAction(tr("&Find"));
300 m_find->setShortcuts(QKeySequence::Find);
301 connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind()));
302 new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(slotEditFind()));
303
304 QAction *m_findNext = editMenu->addAction(tr("&Find Next"));
305 m_findNext->setShortcuts(QKeySequence::FindNext);
306 connect(m_findNext, SIGNAL(triggered()), this, SLOT(slotEditFindNext()));
307
308 QAction *m_findPrevious = editMenu->addAction(tr("&Find Previous"));
309 m_findPrevious->setShortcuts(QKeySequence::FindPrevious);
310 connect(m_findPrevious, SIGNAL(triggered()), this, SLOT(slotEditFindPrevious()));
311
312 editMenu->addSeparator();
313 editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,"));
314
315 // View
316 QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
317
318 m_viewBookmarkBar = new QAction(this);
319 updateBookmarksToolbarActionText(true);
320 m_viewBookmarkBar->setShortcut(tr("Shift+Ctrl+B"));
321 connect(m_viewBookmarkBar, SIGNAL(triggered()), this, SLOT(slotViewBookmarksBar()));
322 viewMenu->addAction(m_viewBookmarkBar);
323
324 m_viewToolbar = new QAction(this);
325 updateToolbarActionText(true);
326 m_viewToolbar->setShortcut(tr("Ctrl+|"));
327 connect(m_viewToolbar, SIGNAL(triggered()), this, SLOT(slotViewToolbar()));
328 viewMenu->addAction(m_viewToolbar);
329
330 m_viewStatusbar = new QAction(this);
331 updateStatusbarActionText(true);
332 m_viewStatusbar->setShortcut(tr("Ctrl+/"));
333 connect(m_viewStatusbar, SIGNAL(triggered()), this, SLOT(slotViewStatusbar()));
334 viewMenu->addAction(m_viewStatusbar);
335
336 viewMenu->addSeparator();
337
338 m_stop = viewMenu->addAction(tr("&Stop"));
339 QList<QKeySequence> shortcuts;
340 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period));
341 shortcuts.append(Qt::Key_Escape);
342 m_stop->setShortcuts(shortcuts);
343 m_tabWidget->addWebAction(m_stop, QWebPage::Stop);
344
345 m_reload = viewMenu->addAction(tr("Reload Page"));
346 m_reload->setShortcuts(QKeySequence::Refresh);
347 m_tabWidget->addWebAction(m_reload, QWebPage::Reload);
348
349 viewMenu->addAction(tr("Zoom &In"), this, SLOT(slotViewZoomIn()), QKeySequence(Qt::CTRL | Qt::Key_Plus));
350 viewMenu->addAction(tr("Zoom &Out"), this, SLOT(slotViewZoomOut()), QKeySequence(Qt::CTRL | Qt::Key_Minus));
351 viewMenu->addAction(tr("Reset &Zoom"), this, SLOT(slotViewResetZoom()), QKeySequence(Qt::CTRL | Qt::Key_0));
352 QAction *zoomTextOnlyAction = viewMenu->addAction(tr("Zoom &Text Only"));
353 connect(zoomTextOnlyAction, SIGNAL(toggled(bool)), this, SLOT(slotViewZoomTextOnly(bool)));
354 zoomTextOnlyAction->setCheckable(true);
355 zoomTextOnlyAction->setChecked(false);
356
357 viewMenu->addSeparator();
358 viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U"));
359 QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotViewFullScreen(bool)), Qt::Key_F11);
360 a->setCheckable(true);
361
362 // History
363 HistoryMenu *historyMenu = new HistoryMenu(this);
364 connect(historyMenu, SIGNAL(openUrl(QUrl)),
365 m_tabWidget, SLOT(loadUrlInCurrentTab(QUrl)));
366 connect(historyMenu, SIGNAL(hovered(QString)), this,
367 SLOT(slotUpdateStatusbar(QString)));
368 historyMenu->setTitle(tr("Hi&story"));
369 menuBar()->addMenu(historyMenu);
370 QList<QAction*> historyActions;
371
372 m_historyBack = new QAction(tr("Back"), this);
373 m_tabWidget->addWebAction(m_historyBack, QWebPage::Back);
374 m_historyBack->setShortcuts(QKeySequence::Back);
375 m_historyBack->setIconVisibleInMenu(false);
376
377 m_historyForward = new QAction(tr("Forward"), this);
378 m_tabWidget->addWebAction(m_historyForward, QWebPage::Forward);
379 m_historyForward->setShortcuts(QKeySequence::Forward);
380 m_historyForward->setIconVisibleInMenu(false);
381
382 QAction *m_historyHome = new QAction(tr("Home"), this);
383 connect(m_historyHome, SIGNAL(triggered()), this, SLOT(slotHome()));
384 m_historyHome->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H));
385
386 m_restoreLastSession = new QAction(tr("Restore Last Session"), this);
387 connect(m_restoreLastSession, SIGNAL(triggered()), BrowserApplication::instance(), SLOT(restoreLastSession()));
388 m_restoreLastSession->setEnabled(BrowserApplication::instance()->canRestoreSession());
389
390 historyActions.append(m_historyBack);
391 historyActions.append(m_historyForward);
392 historyActions.append(m_historyHome);
393 historyActions.append(m_tabWidget->recentlyClosedTabsAction());
394 historyActions.append(m_restoreLastSession);
395 historyMenu->setInitialActions(historyActions);
396
397 // Bookmarks
398 BookmarksMenu *bookmarksMenu = new BookmarksMenu(this);
399 connect(bookmarksMenu, SIGNAL(openUrl(QUrl)),
400 m_tabWidget, SLOT(loadUrlInCurrentTab(QUrl)));
401 connect(bookmarksMenu, SIGNAL(hovered(QString)),
402 this, SLOT(slotUpdateStatusbar(QString)));
403 bookmarksMenu->setTitle(tr("&Bookmarks"));
404 menuBar()->addMenu(bookmarksMenu);
405
406 QList<QAction*> bookmarksActions;
407
408 QAction *showAllBookmarksAction = new QAction(tr("Show All Bookmarks"), this);
409 connect(showAllBookmarksAction, SIGNAL(triggered()), this, SLOT(slotShowBookmarksDialog()));
410 m_addBookmark = new QAction(QIcon(QLatin1String(":addbookmark.png")), tr("Add Bookmark..."), this);
411 m_addBookmark->setIconVisibleInMenu(false);
412
413 connect(m_addBookmark, SIGNAL(triggered()), this, SLOT(slotAddBookmark()));
414 m_addBookmark->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
415
416 bookmarksActions.append(showAllBookmarksAction);
417 bookmarksActions.append(m_addBookmark);
418 bookmarksMenu->setInitialActions(bookmarksActions);
419
420 // Window
421 m_windowMenu = menuBar()->addMenu(tr("&Window"));
422 connect(m_windowMenu, SIGNAL(aboutToShow()),
423 this, SLOT(slotAboutToShowWindowMenu()));
424 slotAboutToShowWindowMenu();
425
426 QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools"));
427 toolsMenu->addAction(tr("Web &Search"), this, SLOT(slotWebSearch()), QKeySequence(tr("Ctrl+K", "Web Search")));
428 a = toolsMenu->addAction(tr("Enable Web &Inspector"), this, SLOT(slotToggleInspector(bool)));
429 a->setCheckable(true);
430
431 QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
432 helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
433 helpMenu->addAction(tr("About &Demo Browser"), this, SLOT(slotAboutApplication()));
434 }
435
setupToolBar()436 void BrowserMainWindow::setupToolBar()
437 {
438 setUnifiedTitleAndToolBarOnMac(true);
439 m_navigationBar = addToolBar(tr("Navigation"));
440 connect(m_navigationBar->toggleViewAction(), SIGNAL(toggled(bool)),
441 this, SLOT(updateToolbarActionText(bool)));
442
443 m_historyBack->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this));
444 m_historyBackMenu = new QMenu(this);
445 m_historyBack->setMenu(m_historyBackMenu);
446 connect(m_historyBackMenu, SIGNAL(aboutToShow()),
447 this, SLOT(slotAboutToShowBackMenu()));
448 connect(m_historyBackMenu, SIGNAL(triggered(QAction*)),
449 this, SLOT(slotOpenActionUrl(QAction*)));
450 m_navigationBar->addAction(m_historyBack);
451
452 m_historyForward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this));
453 m_historyForwardMenu = new QMenu(this);
454 connect(m_historyForwardMenu, SIGNAL(aboutToShow()),
455 this, SLOT(slotAboutToShowForwardMenu()));
456 connect(m_historyForwardMenu, SIGNAL(triggered(QAction*)),
457 this, SLOT(slotOpenActionUrl(QAction*)));
458 m_historyForward->setMenu(m_historyForwardMenu);
459 m_navigationBar->addAction(m_historyForward);
460
461 m_stopReload = new QAction(this);
462 m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload);
463 m_stopReload->setIcon(m_reloadIcon);
464
465 m_navigationBar->addAction(m_stopReload);
466
467 m_navigationBar->addWidget(m_tabWidget->lineEditStack());
468
469 m_toolbarSearch = new ToolbarSearch(m_navigationBar);
470 m_navigationBar->addWidget(m_toolbarSearch);
471 connect(m_toolbarSearch, SIGNAL(search(QUrl)), SLOT(loadUrl(QUrl)));
472
473 m_chaseWidget = new ChaseWidget(this);
474 m_navigationBar->addWidget(m_chaseWidget);
475 }
476
slotShowBookmarksDialog()477 void BrowserMainWindow::slotShowBookmarksDialog()
478 {
479 BookmarksDialog *dialog = new BookmarksDialog(this);
480 connect(dialog, SIGNAL(openUrl(QUrl)),
481 m_tabWidget, SLOT(loadUrlInCurrentTab(QUrl)));
482 dialog->show();
483 }
484
slotAddBookmark()485 void BrowserMainWindow::slotAddBookmark()
486 {
487 WebView *webView = currentTab();
488 QString url = webView->url().toString();
489 QString title = webView->title();
490 AddBookmarkDialog dialog(url, title);
491 dialog.exec();
492 }
493
slotViewToolbar()494 void BrowserMainWindow::slotViewToolbar()
495 {
496 if (m_navigationBar->isVisible()) {
497 updateToolbarActionText(false);
498 m_navigationBar->close();
499 } else {
500 updateToolbarActionText(true);
501 m_navigationBar->show();
502 }
503 m_autoSaver->changeOccurred();
504 }
505
slotViewBookmarksBar()506 void BrowserMainWindow::slotViewBookmarksBar()
507 {
508 if (m_bookmarksToolbar->isVisible()) {
509 updateBookmarksToolbarActionText(false);
510 m_bookmarksToolbar->close();
511 } else {
512 updateBookmarksToolbarActionText(true);
513 m_bookmarksToolbar->show();
514 }
515 m_autoSaver->changeOccurred();
516 }
517
updateStatusbarActionText(bool visible)518 void BrowserMainWindow::updateStatusbarActionText(bool visible)
519 {
520 m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar"));
521 }
522
updateToolbarActionText(bool visible)523 void BrowserMainWindow::updateToolbarActionText(bool visible)
524 {
525 m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar"));
526 }
527
updateBookmarksToolbarActionText(bool visible)528 void BrowserMainWindow::updateBookmarksToolbarActionText(bool visible)
529 {
530 m_viewBookmarkBar->setText(!visible ? tr("Show Bookmarks bar") : tr("Hide Bookmarks bar"));
531 }
532
slotViewStatusbar()533 void BrowserMainWindow::slotViewStatusbar()
534 {
535 if (statusBar()->isVisible()) {
536 updateStatusbarActionText(false);
537 statusBar()->close();
538 } else {
539 updateStatusbarActionText(true);
540 statusBar()->show();
541 }
542 m_autoSaver->changeOccurred();
543 }
544
loadUrl(const QUrl & url)545 void BrowserMainWindow::loadUrl(const QUrl &url)
546 {
547 if (!currentTab() || !url.isValid())
548 return;
549
550 m_tabWidget->currentLineEdit()->setText(QString::fromUtf8(url.toEncoded()));
551 m_tabWidget->loadUrlInCurrentTab(url);
552 }
553
slotDownloadManager()554 void BrowserMainWindow::slotDownloadManager()
555 {
556 BrowserApplication::downloadManager()->show();
557 }
558
slotSelectLineEdit()559 void BrowserMainWindow::slotSelectLineEdit()
560 {
561 m_tabWidget->currentLineEdit()->selectAll();
562 m_tabWidget->currentLineEdit()->setFocus();
563 }
564
slotFileSaveAs()565 void BrowserMainWindow::slotFileSaveAs()
566 {
567 BrowserApplication::downloadManager()->download(currentTab()->url(), true);
568 }
569
slotPreferences()570 void BrowserMainWindow::slotPreferences()
571 {
572 SettingsDialog *s = new SettingsDialog(this);
573 s->show();
574 }
575
slotUpdateStatusbar(const QString & string)576 void BrowserMainWindow::slotUpdateStatusbar(const QString &string)
577 {
578 statusBar()->showMessage(string, 2000);
579 }
580
slotUpdateWindowTitle(const QString & title)581 void BrowserMainWindow::slotUpdateWindowTitle(const QString &title)
582 {
583 if (title.isEmpty()) {
584 setWindowTitle(tr("Qt Demo Browser"));
585 } else {
586 #if defined(Q_OS_OSX)
587 setWindowTitle(title);
588 #else
589 setWindowTitle(tr("%1 - Qt Demo Browser", "Page title and Browser name").arg(title));
590 #endif
591 }
592 }
593
slotAboutApplication()594 void BrowserMainWindow::slotAboutApplication()
595 {
596 QMessageBox::about(this, tr("About"), tr(
597 "Version %1"
598 "<p>This demo demonstrates Qt's "
599 "webkit facilities in action, providing an example "
600 "browser for you to experiment with.<p>"
601 "<p>QtWebKit is based on the Open Source WebKit Project developed at <a href=\"http://webkit.org/\">http://webkit.org/</a>."
602 ).arg(QCoreApplication::applicationVersion()));
603 }
604
slotFileNew()605 void BrowserMainWindow::slotFileNew()
606 {
607 BrowserApplication::instance()->newMainWindow();
608 BrowserMainWindow *mw = BrowserApplication::instance()->mainWindow();
609 mw->slotHome();
610 }
611
slotFileOpen()612 void BrowserMainWindow::slotFileOpen()
613 {
614 QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(),
615 tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)"));
616
617 if (file.isEmpty())
618 return;
619
620 loadPage(file);
621 }
622
slotFilePrintPreview()623 void BrowserMainWindow::slotFilePrintPreview()
624 {
625 #ifndef QT_NO_PRINTPREVIEWDIALOG
626 if (!currentTab())
627 return;
628 QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this);
629 connect(dialog, SIGNAL(paintRequested(QPrinter*)),
630 currentTab(), SLOT(print(QPrinter*)));
631 dialog->exec();
632 #endif
633 }
634
slotFilePrint()635 void BrowserMainWindow::slotFilePrint()
636 {
637 if (!currentTab())
638 return;
639 printRequested(currentTab()->page()->mainFrame());
640 }
641
printRequested(QWebFrame * frame)642 void BrowserMainWindow::printRequested(QWebFrame *frame)
643 {
644 #ifndef QT_NO_PRINTDIALOG
645 QPrinter printer;
646 QPrintDialog *dialog = new QPrintDialog(&printer, this);
647 dialog->setWindowTitle(tr("Print Document"));
648 if (dialog->exec() != QDialog::Accepted)
649 return;
650 frame->print(&printer);
651 #endif
652 }
653
slotPrivateBrowsing()654 void BrowserMainWindow::slotPrivateBrowsing()
655 {
656 QWebSettings *settings = QWebSettings::globalSettings();
657 bool pb = settings->testAttribute(QWebSettings::PrivateBrowsingEnabled);
658 if (!pb) {
659 QString title = tr("Are you sure you want to turn on private browsing?");
660 QString text = tr("<b>%1</b><br><br>When private browsing in turned on,"
661 " webpages are not added to the history,"
662 " items are automatically removed from the Downloads window," \
663 " new cookies are not stored, current cookies can't be accessed," \
664 " site icons wont be stored, session wont be saved, " \
665 " and searches are not added to the pop-up menu in the Google search box." \
666 " Until you close the window, you can still click the Back and Forward buttons" \
667 " to return to the webpages you have opened.").arg(title);
668
669 QMessageBox::StandardButton button = QMessageBox::question(this, QString(), text,
670 QMessageBox::Ok | QMessageBox::Cancel,
671 QMessageBox::Ok);
672 if (button == QMessageBox::Ok) {
673 settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
674 }
675 } else {
676 settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false);
677
678 QList<BrowserMainWindow*> windows = BrowserApplication::instance()->mainWindows();
679 for (int i = 0; i < windows.count(); ++i) {
680 BrowserMainWindow *window = windows.at(i);
681 window->m_lastSearch = QString();
682 window->tabWidget()->clear();
683 }
684 }
685 }
686
closeEvent(QCloseEvent * event)687 void BrowserMainWindow::closeEvent(QCloseEvent *event)
688 {
689 if (m_tabWidget->count() > 1) {
690 int ret = QMessageBox::warning(this, QString(),
691 tr("Are you sure you want to close the window?"
692 " There are %1 tabs open").arg(m_tabWidget->count()),
693 QMessageBox::Yes | QMessageBox::No,
694 QMessageBox::No);
695 if (ret == QMessageBox::No) {
696 event->ignore();
697 return;
698 }
699 }
700 event->accept();
701 deleteLater();
702 }
703
slotEditFind()704 void BrowserMainWindow::slotEditFind()
705 {
706 if (!currentTab())
707 return;
708 bool ok;
709 QString search = QInputDialog::getText(this, tr("Find"),
710 tr("Text:"), QLineEdit::Normal,
711 m_lastSearch, &ok);
712 if (ok && !search.isEmpty()) {
713 m_lastSearch = search;
714 if (!currentTab()->findText(m_lastSearch))
715 slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch));
716 }
717 }
718
slotEditFindNext()719 void BrowserMainWindow::slotEditFindNext()
720 {
721 if (!currentTab() && !m_lastSearch.isEmpty())
722 return;
723 currentTab()->findText(m_lastSearch);
724 }
725
slotEditFindPrevious()726 void BrowserMainWindow::slotEditFindPrevious()
727 {
728 if (!currentTab() && !m_lastSearch.isEmpty())
729 return;
730 currentTab()->findText(m_lastSearch, QWebPage::FindBackward);
731 }
732
slotViewZoomIn()733 void BrowserMainWindow::slotViewZoomIn()
734 {
735 if (!currentTab())
736 return;
737 currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1);
738 }
739
slotViewZoomOut()740 void BrowserMainWindow::slotViewZoomOut()
741 {
742 if (!currentTab())
743 return;
744 currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1);
745 }
746
slotViewResetZoom()747 void BrowserMainWindow::slotViewResetZoom()
748 {
749 if (!currentTab())
750 return;
751 currentTab()->setZoomFactor(1.0);
752 }
753
slotViewZoomTextOnly(bool enable)754 void BrowserMainWindow::slotViewZoomTextOnly(bool enable)
755 {
756 if (!currentTab())
757 return;
758 currentTab()->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, enable);
759 }
760
slotViewFullScreen(bool makeFullScreen)761 void BrowserMainWindow::slotViewFullScreen(bool makeFullScreen)
762 {
763 if (makeFullScreen) {
764 showFullScreen();
765 } else {
766 if (isMinimized())
767 showMinimized();
768 else if (isMaximized())
769 showMaximized();
770 else showNormal();
771 }
772 }
773
slotViewPageSource()774 void BrowserMainWindow::slotViewPageSource()
775 {
776 if (!currentTab())
777 return;
778
779 QString markup = currentTab()->page()->mainFrame()->toHtml();
780 QPlainTextEdit *view = new QPlainTextEdit(markup);
781 view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title()));
782 view->setMinimumWidth(640);
783 view->setAttribute(Qt::WA_DeleteOnClose);
784 view->show();
785 }
786
slotHome()787 void BrowserMainWindow::slotHome()
788 {
789 QSettings settings;
790 settings.beginGroup(QLatin1String("MainWindow"));
791 QString home = settings.value(QLatin1String("home"), QLatin1String("http://qt-project.org/")).toString();
792 loadPage(home);
793 }
794
slotWebSearch()795 void BrowserMainWindow::slotWebSearch()
796 {
797 m_toolbarSearch->lineEdit()->selectAll();
798 m_toolbarSearch->lineEdit()->setFocus();
799 }
800
slotToggleInspector(bool enable)801 void BrowserMainWindow::slotToggleInspector(bool enable)
802 {
803 QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable);
804 if (enable) {
805 int result = QMessageBox::question(this, tr("Web Inspector"),
806 tr("The web inspector will only work correctly for pages that were loaded after enabling.\n"
807 "Do you want to reload all pages?"),
808 QMessageBox::Yes | QMessageBox::No);
809 if (result == QMessageBox::Yes) {
810 m_tabWidget->reloadAllTabs();
811 }
812 }
813 }
814
slotSwapFocus()815 void BrowserMainWindow::slotSwapFocus()
816 {
817 if (currentTab()->hasFocus())
818 m_tabWidget->currentLineEdit()->setFocus();
819 else
820 currentTab()->setFocus();
821 }
822
loadPage(const QString & page)823 void BrowserMainWindow::loadPage(const QString &page)
824 {
825 QUrl url = QUrl::fromUserInput(page);
826 loadUrl(url);
827 }
828
tabWidget() const829 TabWidget *BrowserMainWindow::tabWidget() const
830 {
831 return m_tabWidget;
832 }
833
currentTab() const834 WebView *BrowserMainWindow::currentTab() const
835 {
836 return m_tabWidget->currentWebView();
837 }
838
slotLoadProgress(int progress)839 void BrowserMainWindow::slotLoadProgress(int progress)
840 {
841 if (progress < 100 && progress > 0) {
842 m_chaseWidget->setAnimated(true);
843 disconnect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger()));
844 if (m_stopIcon.isNull())
845 m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop);
846 m_stopReload->setIcon(m_stopIcon);
847 connect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger()));
848 m_stopReload->setToolTip(tr("Stop loading the current page"));
849 } else {
850 m_chaseWidget->setAnimated(false);
851 disconnect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger()));
852 m_stopReload->setIcon(m_reloadIcon);
853 connect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger()));
854 m_stopReload->setToolTip(tr("Reload the current page"));
855 }
856 }
857
slotAboutToShowBackMenu()858 void BrowserMainWindow::slotAboutToShowBackMenu()
859 {
860 m_historyBackMenu->clear();
861 if (!currentTab())
862 return;
863 QWebHistory *history = currentTab()->history();
864 int historyCount = history->count();
865 for (int i = history->backItems(historyCount).count() - 1; i >= 0; --i) {
866 QWebHistoryItem item = history->backItems(history->count()).at(i);
867 QAction *action = new QAction(this);
868 action->setData(-1*(historyCount-i-1));
869 QIcon icon = BrowserApplication::instance()->icon(item.url());
870 action->setIcon(icon);
871 action->setText(item.title());
872 m_historyBackMenu->addAction(action);
873 }
874 }
875
slotAboutToShowForwardMenu()876 void BrowserMainWindow::slotAboutToShowForwardMenu()
877 {
878 m_historyForwardMenu->clear();
879 if (!currentTab())
880 return;
881 QWebHistory *history = currentTab()->history();
882 int historyCount = history->count();
883 for (int i = 0; i < history->forwardItems(history->count()).count(); ++i) {
884 QWebHistoryItem item = history->forwardItems(historyCount).at(i);
885 QAction *action = new QAction(this);
886 action->setData(historyCount-i);
887 QIcon icon = BrowserApplication::instance()->icon(item.url());
888 action->setIcon(icon);
889 action->setText(item.title());
890 m_historyForwardMenu->addAction(action);
891 }
892 }
893
slotAboutToShowWindowMenu()894 void BrowserMainWindow::slotAboutToShowWindowMenu()
895 {
896 m_windowMenu->clear();
897 m_windowMenu->addAction(m_tabWidget->nextTabAction());
898 m_windowMenu->addAction(m_tabWidget->previousTabAction());
899 m_windowMenu->addSeparator();
900 m_windowMenu->addAction(tr("Downloads"), this, SLOT(slotDownloadManager()), QKeySequence(tr("Alt+Ctrl+L", "Download Manager")));
901
902 m_windowMenu->addSeparator();
903 QList<BrowserMainWindow*> windows = BrowserApplication::instance()->mainWindows();
904 for (int i = 0; i < windows.count(); ++i) {
905 BrowserMainWindow *window = windows.at(i);
906 QAction *action = m_windowMenu->addAction(window->windowTitle(), this, SLOT(slotShowWindow()));
907 action->setData(i);
908 action->setCheckable(true);
909 if (window == this)
910 action->setChecked(true);
911 }
912 }
913
slotShowWindow()914 void BrowserMainWindow::slotShowWindow()
915 {
916 if (QAction *action = qobject_cast<QAction*>(sender())) {
917 QVariant v = action->data();
918 if (v.canConvert<int>()) {
919 int offset = qvariant_cast<int>(v);
920 QList<BrowserMainWindow*> windows = BrowserApplication::instance()->mainWindows();
921 windows.at(offset)->activateWindow();
922 windows.at(offset)->currentTab()->setFocus();
923 }
924 }
925 }
926
slotOpenActionUrl(QAction * action)927 void BrowserMainWindow::slotOpenActionUrl(QAction *action)
928 {
929 int offset = action->data().toInt();
930 QWebHistory *history = currentTab()->history();
931 if (offset < 0)
932 history->goToItem(history->backItems(-1*offset).first()); // back
933 else if (offset > 0)
934 history->goToItem(history->forwardItems(history->count() - offset + 1).back()); // forward
935 }
936
geometryChangeRequested(const QRect & geometry)937 void BrowserMainWindow::geometryChangeRequested(const QRect &geometry)
938 {
939 setGeometry(geometry);
940 }
941
942