Fix access to uninitialized memory
[qt-netbsd.git] / demos / browser / tabwidget.cpp
blob8ce5182ac8dd0331955549434a8fc8539428bff4
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (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 ** No Commercial Usage
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the Technology Preview License Agreement accompanying
13 ** this package.
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.
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.1, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include "tabwidget.h"
44 #include "browserapplication.h"
45 #include "browsermainwindow.h"
46 #include "history.h"
47 #include "urllineedit.h"
48 #include "webview.h"
50 #include <QtGui/QClipboard>
51 #include <QtGui/QCompleter>
52 #include <QtGui/QListView>
53 #include <QtGui/QMenu>
54 #include <QtGui/QMessageBox>
55 #include <QtGui/QMouseEvent>
56 #include <QtGui/QStackedWidget>
57 #include <QtGui/QStyle>
58 #include <QtGui/QToolButton>
60 #include <QtCore/QDebug>
62 TabBar::TabBar(QWidget *parent)
63 : QTabBar(parent)
65 setContextMenuPolicy(Qt::CustomContextMenu);
66 setAcceptDrops(true);
67 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
68 this, SLOT(contextMenuRequested(const QPoint &)));
70 QString alt = QLatin1String("Alt+%1");
71 for (int i = 1; i <= 10; ++i) {
72 int key = i;
73 if (key == 10)
74 key = 0;
75 QShortcut *shortCut = new QShortcut(alt.arg(key), this);
76 m_tabShortcuts.append(shortCut);
77 connect(shortCut, SIGNAL(activated()), this, SLOT(selectTabAction()));
79 setTabsClosable(true);
80 connect(this, SIGNAL(tabCloseRequested(int)),
81 this, SIGNAL(closeTab(int)));
82 setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
83 setMovable(true);
86 void TabBar::selectTabAction()
88 if (QShortcut *shortCut = qobject_cast<QShortcut*>(sender())) {
89 int index = m_tabShortcuts.indexOf(shortCut);
90 if (index == 0)
91 index = 10;
92 setCurrentIndex(index);
96 void TabBar::contextMenuRequested(const QPoint &position)
98 QMenu menu;
99 menu.addAction(tr("New &Tab"), this, SIGNAL(newTab()), QKeySequence::AddTab);
100 int index = tabAt(position);
101 if (-1 != index) {
102 QAction *action = menu.addAction(tr("Clone Tab"),
103 this, SLOT(cloneTab()));
104 action->setData(index);
106 menu.addSeparator();
108 action = menu.addAction(tr("&Close Tab"),
109 this, SLOT(closeTab()), QKeySequence::Close);
110 action->setData(index);
112 action = menu.addAction(tr("Close &Other Tabs"),
113 this, SLOT(closeOtherTabs()));
114 action->setData(index);
116 menu.addSeparator();
118 action = menu.addAction(tr("Reload Tab"),
119 this, SLOT(reloadTab()), QKeySequence::Refresh);
120 action->setData(index);
121 } else {
122 menu.addSeparator();
124 menu.addAction(tr("Reload All Tabs"), this, SIGNAL(reloadAllTabs()));
125 menu.exec(QCursor::pos());
128 void TabBar::cloneTab()
130 if (QAction *action = qobject_cast<QAction*>(sender())) {
131 int index = action->data().toInt();
132 emit cloneTab(index);
136 void TabBar::closeTab()
138 if (QAction *action = qobject_cast<QAction*>(sender())) {
139 int index = action->data().toInt();
140 emit closeTab(index);
144 void TabBar::closeOtherTabs()
146 if (QAction *action = qobject_cast<QAction*>(sender())) {
147 int index = action->data().toInt();
148 emit closeOtherTabs(index);
152 void TabBar::mousePressEvent(QMouseEvent *event)
154 if (event->button() == Qt::LeftButton)
155 m_dragStartPos = event->pos();
156 QTabBar::mousePressEvent(event);
159 void TabBar::mouseMoveEvent(QMouseEvent *event)
161 if (event->buttons() == Qt::LeftButton) {
162 int diffX = event->pos().x() - m_dragStartPos.x();
163 int diffY = event->pos().y() - m_dragStartPos.y();
164 if ((event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()
165 && diffX < 3 && diffX > -3
166 && diffY < -10) {
167 QDrag *drag = new QDrag(this);
168 QMimeData *mimeData = new QMimeData;
169 QList<QUrl> urls;
170 int index = tabAt(event->pos());
171 QUrl url = tabData(index).toUrl();
172 urls.append(url);
173 mimeData->setUrls(urls);
174 mimeData->setText(tabText(index));
175 mimeData->setData(QLatin1String("action"), "tab-reordering");
176 drag->setMimeData(mimeData);
177 drag->exec();
180 QTabBar::mouseMoveEvent(event);
183 // When index is -1 index chooses the current tab
184 void TabWidget::reloadTab(int index)
186 if (index < 0)
187 index = currentIndex();
188 if (index < 0 || index >= count())
189 return;
191 QWidget *widget = this->widget(index);
192 if (WebView *tab = qobject_cast<WebView*>(widget))
193 tab->reload();
196 void TabBar::reloadTab()
198 if (QAction *action = qobject_cast<QAction*>(sender())) {
199 int index = action->data().toInt();
200 emit reloadTab(index);
204 TabWidget::TabWidget(QWidget *parent)
205 : QTabWidget(parent)
206 , m_recentlyClosedTabsAction(0)
207 , m_newTabAction(0)
208 , m_closeTabAction(0)
209 , m_nextTabAction(0)
210 , m_previousTabAction(0)
211 , m_recentlyClosedTabsMenu(0)
212 , m_lineEditCompleter(0)
213 , m_lineEdits(0)
214 , m_tabBar(new TabBar(this))
216 setElideMode(Qt::ElideRight);
218 connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab()));
219 connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int)));
220 connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int)));
221 connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int)));
222 connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int)));
223 connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs()));
224 connect(m_tabBar, SIGNAL(tabMoved(int, int)), this, SLOT(moveTab(int, int)));
225 setTabBar(m_tabBar);
226 setDocumentMode(true);
228 // Actions
229 m_newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this);
230 m_newTabAction->setShortcuts(QKeySequence::AddTab);
231 m_newTabAction->setIconVisibleInMenu(false);
232 connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab()));
234 m_closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this);
235 m_closeTabAction->setShortcuts(QKeySequence::Close);
236 m_closeTabAction->setIconVisibleInMenu(false);
237 connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab()));
239 m_nextTabAction = new QAction(tr("Show Next Tab"), this);
240 QList<QKeySequence> shortcuts;
241 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight));
242 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown));
243 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight));
244 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less));
245 m_nextTabAction->setShortcuts(shortcuts);
246 connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab()));
248 m_previousTabAction = new QAction(tr("Show Previous Tab"), this);
249 shortcuts.clear();
250 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft));
251 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp));
252 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft));
253 shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater));
254 m_previousTabAction->setShortcuts(shortcuts);
255 connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab()));
257 m_recentlyClosedTabsMenu = new QMenu(this);
258 connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()),
259 this, SLOT(aboutToShowRecentTabsMenu()));
260 connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)),
261 this, SLOT(aboutToShowRecentTriggeredAction(QAction *)));
262 m_recentlyClosedTabsAction = new QAction(tr("Recently Closed Tabs"), this);
263 m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu);
264 m_recentlyClosedTabsAction->setEnabled(false);
266 connect(this, SIGNAL(currentChanged(int)),
267 this, SLOT(currentChanged(int)));
269 m_lineEdits = new QStackedWidget(this);
272 void TabWidget::clear()
274 // clear the recently closed tabs
275 m_recentlyClosedTabs.clear();
276 // clear the line edit history
277 for (int i = 0; i < m_lineEdits->count(); ++i) {
278 QLineEdit *qLineEdit = lineEdit(i);
279 qLineEdit->setText(qLineEdit->text());
283 void TabWidget::moveTab(int fromIndex, int toIndex)
285 QWidget *lineEdit = m_lineEdits->widget(fromIndex);
286 m_lineEdits->removeWidget(lineEdit);
287 m_lineEdits->insertWidget(toIndex, lineEdit);
290 void TabWidget::addWebAction(QAction *action, QWebPage::WebAction webAction)
292 if (!action)
293 return;
294 m_actions.append(new WebActionMapper(action, webAction, this));
297 void TabWidget::currentChanged(int index)
299 WebView *webView = this->webView(index);
300 if (!webView)
301 return;
303 Q_ASSERT(m_lineEdits->count() == count());
305 WebView *oldWebView = this->webView(m_lineEdits->currentIndex());
306 if (oldWebView) {
307 disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)),
308 this, SIGNAL(showStatusBarMessage(const QString&)));
309 disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
310 this, SIGNAL(linkHovered(const QString&)));
311 disconnect(oldWebView, SIGNAL(loadProgress(int)),
312 this, SIGNAL(loadProgress(int)));
315 connect(webView, SIGNAL(statusBarMessage(const QString&)),
316 this, SIGNAL(showStatusBarMessage(const QString&)));
317 connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
318 this, SIGNAL(linkHovered(const QString&)));
319 connect(webView, SIGNAL(loadProgress(int)),
320 this, SIGNAL(loadProgress(int)));
322 for (int i = 0; i < m_actions.count(); ++i) {
323 WebActionMapper *mapper = m_actions[i];
324 mapper->updateCurrent(webView->page());
326 emit setCurrentTitle(webView->title());
327 m_lineEdits->setCurrentIndex(index);
328 emit loadProgress(webView->progress());
329 emit showStatusBarMessage(webView->lastStatusBarText());
330 if (webView->url().isEmpty())
331 m_lineEdits->currentWidget()->setFocus();
332 else
333 webView->setFocus();
336 QAction *TabWidget::newTabAction() const
338 return m_newTabAction;
341 QAction *TabWidget::closeTabAction() const
343 return m_closeTabAction;
346 QAction *TabWidget::recentlyClosedTabsAction() const
348 return m_recentlyClosedTabsAction;
351 QAction *TabWidget::nextTabAction() const
353 return m_nextTabAction;
356 QAction *TabWidget::previousTabAction() const
358 return m_previousTabAction;
361 QWidget *TabWidget::lineEditStack() const
363 return m_lineEdits;
366 QLineEdit *TabWidget::currentLineEdit() const
368 return lineEdit(m_lineEdits->currentIndex());
371 WebView *TabWidget::currentWebView() const
373 return webView(currentIndex());
376 QLineEdit *TabWidget::lineEdit(int index) const
378 UrlLineEdit *urlLineEdit = qobject_cast<UrlLineEdit*>(m_lineEdits->widget(index));
379 if (urlLineEdit)
380 return urlLineEdit->lineEdit();
381 return 0;
384 WebView *TabWidget::webView(int index) const
386 QWidget *widget = this->widget(index);
387 if (WebView *webView = qobject_cast<WebView*>(widget)) {
388 return webView;
389 } else {
390 // optimization to delay creating the first webview
391 if (count() == 1) {
392 TabWidget *that = const_cast<TabWidget*>(this);
393 that->setUpdatesEnabled(false);
394 that->newTab();
395 that->closeTab(0);
396 that->setUpdatesEnabled(true);
397 return currentWebView();
400 return 0;
403 int TabWidget::webViewIndex(WebView *webView) const
405 int index = indexOf(webView);
406 return index;
409 WebView *TabWidget::newTab(bool makeCurrent)
411 // line edit
412 UrlLineEdit *urlLineEdit = new UrlLineEdit;
413 QLineEdit *lineEdit = urlLineEdit->lineEdit();
414 if (!m_lineEditCompleter && count() > 0) {
415 HistoryCompletionModel *completionModel = new HistoryCompletionModel(this);
416 completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel());
417 m_lineEditCompleter = new QCompleter(completionModel, this);
418 // Should this be in Qt by default?
419 QAbstractItemView *popup = m_lineEditCompleter->popup();
420 QListView *listView = qobject_cast<QListView*>(popup);
421 if (listView)
422 listView->setUniformItemSizes(true);
424 lineEdit->setCompleter(m_lineEditCompleter);
425 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed()));
426 m_lineEdits->addWidget(urlLineEdit);
427 m_lineEdits->setSizePolicy(lineEdit->sizePolicy());
429 // optimization to delay creating the more expensive WebView, history, etc
430 if (count() == 0) {
431 QWidget *emptyWidget = new QWidget;
432 QPalette p = emptyWidget->palette();
433 p.setColor(QPalette::Window, palette().color(QPalette::Base));
434 emptyWidget->setPalette(p);
435 emptyWidget->setAutoFillBackground(true);
436 disconnect(this, SIGNAL(currentChanged(int)),
437 this, SLOT(currentChanged(int)));
438 addTab(emptyWidget, tr("(Untitled)"));
439 connect(this, SIGNAL(currentChanged(int)),
440 this, SLOT(currentChanged(int)));
441 return 0;
444 // webview
445 WebView *webView = new WebView;
446 urlLineEdit->setWebView(webView);
447 connect(webView, SIGNAL(loadStarted()),
448 this, SLOT(webViewLoadStarted()));
449 connect(webView, SIGNAL(loadFinished(bool)),
450 this, SLOT(webViewIconChanged()));
451 connect(webView, SIGNAL(iconChanged()),
452 this, SLOT(webViewIconChanged()));
453 connect(webView, SIGNAL(titleChanged(const QString &)),
454 this, SLOT(webViewTitleChanged(const QString &)));
455 connect(webView, SIGNAL(urlChanged(const QUrl &)),
456 this, SLOT(webViewUrlChanged(const QUrl &)));
457 connect(webView->page(), SIGNAL(windowCloseRequested()),
458 this, SLOT(windowCloseRequested()));
459 connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)),
460 this, SIGNAL(geometryChangeRequested(const QRect &)));
461 connect(webView->page(), SIGNAL(printRequested(QWebFrame *)),
462 this, SIGNAL(printRequested(QWebFrame *)));
463 connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)),
464 this, SIGNAL(menuBarVisibilityChangeRequested(bool)));
465 connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)),
466 this, SIGNAL(statusBarVisibilityChangeRequested(bool)));
467 connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)),
468 this, SIGNAL(toolBarVisibilityChangeRequested(bool)));
469 addTab(webView, tr("(Untitled)"));
470 if (makeCurrent)
471 setCurrentWidget(webView);
473 // webview actions
474 for (int i = 0; i < m_actions.count(); ++i) {
475 WebActionMapper *mapper = m_actions[i];
476 mapper->addChild(webView->page()->action(mapper->webAction()));
479 if (count() == 1)
480 currentChanged(currentIndex());
481 emit tabsChanged();
482 return webView;
485 void TabWidget::reloadAllTabs()
487 for (int i = 0; i < count(); ++i) {
488 QWidget *tabWidget = widget(i);
489 if (WebView *tab = qobject_cast<WebView*>(tabWidget)) {
490 tab->reload();
495 void TabWidget::lineEditReturnPressed()
497 if (QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender())) {
498 emit loadPage(lineEdit->text());
499 if (m_lineEdits->currentWidget() == lineEdit)
500 currentWebView()->setFocus();
504 void TabWidget::windowCloseRequested()
506 WebPage *webPage = qobject_cast<WebPage*>(sender());
507 WebView *webView = qobject_cast<WebView*>(webPage->view());
508 int index = webViewIndex(webView);
509 if (index >= 0) {
510 if (count() == 1)
511 webView->webPage()->mainWindow()->close();
512 else
513 closeTab(index);
517 void TabWidget::closeOtherTabs(int index)
519 if (-1 == index)
520 return;
521 for (int i = count() - 1; i > index; --i)
522 closeTab(i);
523 for (int i = index - 1; i >= 0; --i)
524 closeTab(i);
527 // When index is -1 index chooses the current tab
528 void TabWidget::cloneTab(int index)
530 if (index < 0)
531 index = currentIndex();
532 if (index < 0 || index >= count())
533 return;
534 WebView *tab = newTab(false);
535 tab->setUrl(webView(index)->url());
538 // When index is -1 index chooses the current tab
539 void TabWidget::closeTab(int index)
541 if (index < 0)
542 index = currentIndex();
543 if (index < 0 || index >= count())
544 return;
546 bool hasFocus = false;
547 if (WebView *tab = webView(index)) {
548 if (tab->isModified()) {
549 QMessageBox closeConfirmation(tab);
550 closeConfirmation.setWindowFlags(Qt::Sheet);
551 closeConfirmation.setWindowTitle(tr("Do you really want to close this page?"));
552 closeConfirmation.setInformativeText(tr("You have modified this page and when closing it you would lose the modification.\n"
553 "Do you really want to close this page?\n"));
554 closeConfirmation.setIcon(QMessageBox::Question);
555 closeConfirmation.addButton(QMessageBox::Yes);
556 closeConfirmation.addButton(QMessageBox::No);
557 closeConfirmation.setEscapeButton(QMessageBox::No);
558 if (closeConfirmation.exec() == QMessageBox::No)
559 return;
561 hasFocus = tab->hasFocus();
563 m_recentlyClosedTabsAction->setEnabled(true);
564 m_recentlyClosedTabs.prepend(tab->url());
565 if (m_recentlyClosedTabs.size() >= TabWidget::m_recentlyClosedTabsSize)
566 m_recentlyClosedTabs.removeLast();
568 QWidget *lineEdit = m_lineEdits->widget(index);
569 m_lineEdits->removeWidget(lineEdit);
570 lineEdit->deleteLater();
571 QWidget *webView = widget(index);
572 removeTab(index);
573 webView->deleteLater();
574 emit tabsChanged();
575 if (hasFocus && count() > 0)
576 currentWebView()->setFocus();
577 if (count() == 0)
578 emit lastTabClosed();
581 void TabWidget::webViewLoadStarted()
583 WebView *webView = qobject_cast<WebView*>(sender());
584 int index = webViewIndex(webView);
585 if (-1 != index) {
586 QIcon icon(QLatin1String(":loading.gif"));
587 setTabIcon(index, icon);
591 void TabWidget::webViewIconChanged()
593 WebView *webView = qobject_cast<WebView*>(sender());
594 int index = webViewIndex(webView);
595 if (-1 != index) {
596 QIcon icon = BrowserApplication::instance()->icon(webView->url());
597 setTabIcon(index, icon);
601 void TabWidget::webViewTitleChanged(const QString &title)
603 WebView *webView = qobject_cast<WebView*>(sender());
604 int index = webViewIndex(webView);
605 if (-1 != index) {
606 setTabText(index, title);
608 if (currentIndex() == index)
609 emit setCurrentTitle(title);
610 BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title);
613 void TabWidget::webViewUrlChanged(const QUrl &url)
615 WebView *webView = qobject_cast<WebView*>(sender());
616 int index = webViewIndex(webView);
617 if (-1 != index) {
618 m_tabBar->setTabData(index, url);
620 emit tabsChanged();
623 void TabWidget::aboutToShowRecentTabsMenu()
625 m_recentlyClosedTabsMenu->clear();
626 for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) {
627 QAction *action = new QAction(m_recentlyClosedTabsMenu);
628 action->setData(m_recentlyClosedTabs.at(i));
629 QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i));
630 action->setIcon(icon);
631 action->setText(m_recentlyClosedTabs.at(i).toString());
632 m_recentlyClosedTabsMenu->addAction(action);
636 void TabWidget::aboutToShowRecentTriggeredAction(QAction *action)
638 QUrl url = action->data().toUrl();
639 loadUrlInCurrentTab(url);
642 void TabWidget::mouseDoubleClickEvent(QMouseEvent *event)
644 if (!childAt(event->pos())
645 // Remove the line below when QTabWidget does not have a one pixel frame
646 && event->pos().y() < (tabBar()->y() + tabBar()->height())) {
647 newTab();
648 return;
650 QTabWidget::mouseDoubleClickEvent(event);
653 void TabWidget::contextMenuEvent(QContextMenuEvent *event)
655 if (!childAt(event->pos())) {
656 m_tabBar->contextMenuRequested(event->pos());
657 return;
659 QTabWidget::contextMenuEvent(event);
662 void TabWidget::mouseReleaseEvent(QMouseEvent *event)
664 if (event->button() == Qt::MidButton && !childAt(event->pos())
665 // Remove the line below when QTabWidget does not have a one pixel frame
666 && event->pos().y() < (tabBar()->y() + tabBar()->height())) {
667 QUrl url(QApplication::clipboard()->text(QClipboard::Selection));
668 if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) {
669 WebView *webView = newTab();
670 webView->setUrl(url);
675 void TabWidget::loadUrlInCurrentTab(const QUrl &url)
677 WebView *webView = currentWebView();
678 if (webView) {
679 webView->loadUrl(url);
680 webView->setFocus();
684 void TabWidget::nextTab()
686 int next = currentIndex() + 1;
687 if (next == count())
688 next = 0;
689 setCurrentIndex(next);
692 void TabWidget::previousTab()
694 int next = currentIndex() - 1;
695 if (next < 0)
696 next = count() - 1;
697 setCurrentIndex(next);
700 static const qint32 TabWidgetMagic = 0xaa;
702 QByteArray TabWidget::saveState() const
704 int version = 1;
705 QByteArray data;
706 QDataStream stream(&data, QIODevice::WriteOnly);
708 stream << qint32(TabWidgetMagic);
709 stream << qint32(version);
711 QStringList tabs;
712 for (int i = 0; i < count(); ++i) {
713 if (WebView *tab = qobject_cast<WebView*>(widget(i))) {
714 tabs.append(tab->url().toString());
715 } else {
716 tabs.append(QString::null);
719 stream << tabs;
720 stream << currentIndex();
721 return data;
724 bool TabWidget::restoreState(const QByteArray &state)
726 int version = 1;
727 QByteArray sd = state;
728 QDataStream stream(&sd, QIODevice::ReadOnly);
729 if (stream.atEnd())
730 return false;
732 qint32 marker;
733 qint32 v;
734 stream >> marker;
735 stream >> v;
736 if (marker != TabWidgetMagic || v != version)
737 return false;
739 QStringList openTabs;
740 stream >> openTabs;
742 for (int i = 0; i < openTabs.count(); ++i) {
743 if (i != 0)
744 newTab();
745 loadPage(openTabs.at(i));
748 int currentTab;
749 stream >> currentTab;
750 setCurrentIndex(currentTab);
752 return true;
755 WebActionMapper::WebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent)
756 : QObject(parent)
757 , m_currentParent(0)
758 , m_root(root)
759 , m_webAction(webAction)
761 if (!m_root)
762 return;
763 connect(m_root, SIGNAL(triggered()), this, SLOT(rootTriggered()));
764 connect(root, SIGNAL(destroyed(QObject *)), this, SLOT(rootDestroyed()));
765 root->setEnabled(false);
768 void WebActionMapper::rootDestroyed()
770 m_root = 0;
773 void WebActionMapper::currentDestroyed()
775 updateCurrent(0);
778 void WebActionMapper::addChild(QAction *action)
780 if (!action)
781 return;
782 connect(action, SIGNAL(changed()), this, SLOT(childChanged()));
785 QWebPage::WebAction WebActionMapper::webAction() const
787 return m_webAction;
790 void WebActionMapper::rootTriggered()
792 if (m_currentParent) {
793 QAction *gotoAction = m_currentParent->action(m_webAction);
794 gotoAction->trigger();
798 void WebActionMapper::childChanged()
800 if (QAction *source = qobject_cast<QAction*>(sender())) {
801 if (m_root
802 && m_currentParent
803 && source->parent() == m_currentParent) {
804 m_root->setChecked(source->isChecked());
805 m_root->setEnabled(source->isEnabled());
810 void WebActionMapper::updateCurrent(QWebPage *currentParent)
812 if (m_currentParent)
813 disconnect(m_currentParent, SIGNAL(destroyed(QObject *)),
814 this, SLOT(currentDestroyed()));
816 m_currentParent = currentParent;
817 if (!m_root)
818 return;
819 if (!m_currentParent) {
820 m_root->setEnabled(false);
821 m_root->setChecked(false);
822 return;
824 QAction *source = m_currentParent->action(m_webAction);
825 m_root->setChecked(source->isChecked());
826 m_root->setEnabled(source->isEnabled());
827 connect(m_currentParent, SIGNAL(destroyed(QObject *)),
828 this, SLOT(currentDestroyed()));