tools/assistant/compat/tabbedbrowser.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Assistant of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "tabbedbrowser.h"
       
    43 #include "mainwindow.h"
       
    44 #include "helpwindow.h"
       
    45 #include "config.h"
       
    46 
       
    47 #include <QStyleOptionTab>
       
    48 #include <QToolTip>
       
    49 #include <QFileInfo>
       
    50 #include <QToolButton>
       
    51 #include <QPixmap>
       
    52 #include <QIcon>
       
    53 #include <QStyle>
       
    54 #include <QTimer>
       
    55 #include <QStackedWidget>
       
    56 #include <QTimer>
       
    57 #include <QTextBlock>
       
    58 #include <QKeyEvent>
       
    59 
       
    60 QT_BEGIN_NAMESPACE
       
    61 
       
    62 #ifdef Q_WS_MAC
       
    63 const QLatin1String ImageLocation(":trolltech/assistant/images/mac/");
       
    64 #else
       
    65 const QLatin1String ImageLocation(":trolltech/assistant/images/win/");
       
    66 #endif
       
    67 
       
    68 TabbedBrowser::TabbedBrowser(MainWindow *parent)
       
    69     : QWidget(parent)
       
    70 {
       
    71     ui.setupUi(this);
       
    72     init();
       
    73 
       
    74     QStackedWidget *stack = qFindChild<QStackedWidget*>(ui.tab);
       
    75     Q_ASSERT(stack);
       
    76     stack->setContentsMargins(0, 0, 0, 0);
       
    77     connect(stack, SIGNAL(currentChanged(int)), parent, SLOT(browserTabChanged()));
       
    78 
       
    79     QPalette p = palette();
       
    80     p.setColor(QPalette::Inactive, QPalette::Highlight,
       
    81         p.color(QPalette::Active, QPalette::Highlight));
       
    82     p.setColor(QPalette::Inactive, QPalette::HighlightedText,
       
    83         p.color(QPalette::Active, QPalette::HighlightedText));
       
    84     setPalette(p);
       
    85 }
       
    86 
       
    87 TabbedBrowser::~TabbedBrowser()
       
    88 {
       
    89 }
       
    90 
       
    91 MainWindow *TabbedBrowser::mainWindow() const
       
    92 {
       
    93     return static_cast<MainWindow*>(parentWidget());
       
    94 }
       
    95 
       
    96 void TabbedBrowser::forward()
       
    97 {
       
    98     currentBrowser()->forward();
       
    99     emit browserUrlChanged(currentBrowser()->source().toString());
       
   100 }
       
   101 
       
   102 void TabbedBrowser::backward()
       
   103 {
       
   104     currentBrowser()->backward();
       
   105     emit browserUrlChanged(currentBrowser()->source().toString());
       
   106 }
       
   107 
       
   108 void TabbedBrowser::setSource( const QString &ref )
       
   109 {
       
   110     HelpWindow * win = currentBrowser();
       
   111     win->setSource(ref);
       
   112 }
       
   113 
       
   114 void TabbedBrowser::reload()
       
   115 {
       
   116     currentBrowser()->reload();
       
   117 }
       
   118 
       
   119 void TabbedBrowser::home()
       
   120 {
       
   121     currentBrowser()->home();
       
   122 }
       
   123 
       
   124 HelpWindow *TabbedBrowser::currentBrowser() const
       
   125 {
       
   126     return static_cast<HelpWindow*>(ui.tab->currentWidget());
       
   127 }
       
   128 
       
   129 void TabbedBrowser::nextTab()
       
   130 {
       
   131     if(ui.tab->currentIndex()<=ui.tab->count()-1)
       
   132         ui.tab->setCurrentIndex(ui.tab->currentIndex()+1);
       
   133 }
       
   134 
       
   135 void TabbedBrowser::previousTab()
       
   136 {
       
   137     int idx = ui.tab->currentIndex()-1;
       
   138     if(idx>=0)
       
   139         ui.tab->setCurrentIndex(idx);
       
   140 }
       
   141 
       
   142 HelpWindow *TabbedBrowser::createHelpWindow()
       
   143 {
       
   144     MainWindow *mainWin = mainWindow();
       
   145     HelpWindow *win = new HelpWindow(mainWin, 0);
       
   146     win->setFrameStyle(QFrame::NoFrame);
       
   147     win->setPalette(palette());
       
   148     win->setSearchPaths(Config::configuration()->mimePaths());
       
   149     ui.tab->addTab(win, tr("..."));
       
   150     connect(win, SIGNAL(highlighted(QString)),
       
   151              (const QObject*) (mainWin->statusBar()), SLOT(showMessage(QString)));
       
   152     connect(win, SIGNAL(backwardAvailable(bool)),
       
   153              mainWin, SLOT(backwardAvailable(bool)));
       
   154     connect(win, SIGNAL(forwardAvailable(bool)),
       
   155              mainWin, SLOT(forwardAvailable(bool)));
       
   156     connect(win, SIGNAL(sourceChanged(QUrl)), this, SLOT(sourceChanged()));
       
   157 
       
   158     ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
       
   159 	win->installEventFilter(this);
       
   160 	win->viewport()->installEventFilter(this);
       
   161     ui.editFind->installEventFilter(this);
       
   162     return win;
       
   163 }
       
   164 
       
   165 HelpWindow *TabbedBrowser::newBackgroundTab()
       
   166 {
       
   167     HelpWindow *win = createHelpWindow();
       
   168     emit tabCountChanged(ui.tab->count());
       
   169     return win;
       
   170 }
       
   171 
       
   172 void TabbedBrowser::newTab(const QString &lnk)
       
   173 {
       
   174     QString link(lnk);
       
   175     if(link.isNull()) {
       
   176         HelpWindow *w = currentBrowser();
       
   177         if(w)
       
   178             link = w->source().toString();
       
   179     }
       
   180     HelpWindow *win = createHelpWindow();
       
   181     ui.tab->setCurrentIndex(ui.tab->indexOf(win));
       
   182     if(!link.isNull()) {
       
   183          win->setSource(link);
       
   184     }
       
   185 
       
   186     emit tabCountChanged(ui.tab->count());
       
   187 }
       
   188 
       
   189 void TabbedBrowser::zoomIn()
       
   190 {
       
   191     currentBrowser()->zoomIn();
       
   192     Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
       
   193 }
       
   194 
       
   195 void TabbedBrowser::zoomOut()
       
   196 {
       
   197     currentBrowser()->zoomOut();
       
   198     Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
       
   199 }
       
   200 
       
   201 void TabbedBrowser::init()
       
   202 {
       
   203 
       
   204     lastCurrentTab = 0;
       
   205     while(ui.tab->count()) {
       
   206         QWidget *page = ui.tab->widget(0);
       
   207         ui.tab->removeTab(0);
       
   208         delete page;
       
   209     }
       
   210 
       
   211     connect(ui.tab, SIGNAL(currentChanged(int)),
       
   212              this, SLOT(transferFocus()));
       
   213 
       
   214     QTabBar *tabBar = qFindChild<QTabBar*>(ui.tab);
       
   215     QStyleOptionTab opt;
       
   216     if (tabBar) {
       
   217         opt.init(tabBar);
       
   218         opt.shape = tabBar->shape();
       
   219         tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
       
   220         connect(tabBar, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(openTabMenu(const QPoint&)));
       
   221     }
       
   222 
       
   223     // workaround for sgi style
       
   224     QPalette pal = palette();
       
   225     pal.setColor(QPalette::Active, QPalette::Button, pal.color(QPalette::Active, QPalette::Window));
       
   226     pal.setColor(QPalette::Disabled, QPalette::Button, pal.color(QPalette::Disabled, QPalette::Window));
       
   227     pal.setColor(QPalette::Inactive, QPalette::Button, pal.color(QPalette::Inactive, QPalette::Window));
       
   228 
       
   229     QToolButton *newTabButton = new QToolButton(this);
       
   230     ui.tab->setCornerWidget(newTabButton, Qt::TopLeftCorner);
       
   231     newTabButton->setCursor(Qt::ArrowCursor);
       
   232     newTabButton->setAutoRaise(true);
       
   233     newTabButton->setIcon(QIcon(ImageLocation + QLatin1String("addtab.png")));
       
   234     QObject::connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));
       
   235     newTabButton->setToolTip(tr("Add page"));
       
   236 
       
   237     QToolButton *closeTabButton = new QToolButton(this);
       
   238     closeTabButton->setPalette(pal);
       
   239     ui.tab->setCornerWidget(closeTabButton, Qt::TopRightCorner);
       
   240     closeTabButton->setCursor(Qt::ArrowCursor);
       
   241     closeTabButton->setAutoRaise(true);
       
   242     closeTabButton->setIcon(QIcon(ImageLocation + QLatin1String("closetab.png")));
       
   243     QObject::connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeTab()));
       
   244     closeTabButton->setToolTip(tr("Close page"));
       
   245     closeTabButton->setEnabled(false);
       
   246 
       
   247 	QObject::connect(ui.toolClose, SIGNAL(clicked()), ui.frameFind, SLOT(hide()));
       
   248 	QObject::connect(ui.toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
       
   249 	QObject::connect(ui.toolNext, SIGNAL(clicked()), this, SLOT(findNext()));
       
   250 	QObject::connect(ui.editFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
       
   251 	QObject::connect(ui.editFind, SIGNAL(textEdited(const QString&)),
       
   252 				     this, SLOT(find(QString)));
       
   253 	ui.frameFind->setVisible(false);
       
   254 	ui.labelWrapped->setVisible(false);
       
   255 	autoHideTimer = new QTimer(this);
       
   256 	autoHideTimer->setInterval(5000);
       
   257 	autoHideTimer->setSingleShot(true);
       
   258 	QObject::connect(autoHideTimer, SIGNAL(timeout()), ui.frameFind, SLOT(hide()));
       
   259 }
       
   260 
       
   261 void TabbedBrowser::updateTitle(const QString &title)
       
   262 {
       
   263     ui.tab->setTabText(ui.tab->indexOf(currentBrowser()), title.trimmed());
       
   264 }
       
   265 
       
   266 void TabbedBrowser::newTab()
       
   267 {
       
   268     newTab(QString());
       
   269 }
       
   270 
       
   271 void TabbedBrowser::transferFocus()
       
   272 {
       
   273     if(currentBrowser()) {
       
   274         currentBrowser()->setFocus();
       
   275     }
       
   276     mainWindow()->setWindowTitle(Config::configuration()->title()
       
   277                              + QLatin1String(" - ")
       
   278                              + currentBrowser()->documentTitle());
       
   279 }
       
   280 
       
   281 void TabbedBrowser::initHelpWindow(HelpWindow * /*win*/)
       
   282 {
       
   283 }
       
   284 
       
   285 void TabbedBrowser::setup()
       
   286 {
       
   287     newTab(QString());
       
   288 }
       
   289 
       
   290 void TabbedBrowser::copy()
       
   291 {
       
   292     currentBrowser()->copy();
       
   293 }
       
   294 
       
   295 void TabbedBrowser::closeTab()
       
   296 {
       
   297     if(ui.tab->count()==1)
       
   298         return;
       
   299     HelpWindow *win = currentBrowser();
       
   300     mainWindow()->removePendingBrowser(win);
       
   301     ui.tab->removeTab(ui.tab->indexOf(win));
       
   302     QTimer::singleShot(0, win, SLOT(deleteLater()));
       
   303     ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
       
   304     emit tabCountChanged(ui.tab->count());
       
   305 }
       
   306 
       
   307 QStringList TabbedBrowser::sources() const
       
   308 {
       
   309     QStringList lst;
       
   310     int cnt = ui.tab->count();
       
   311     for(int i=0; i<cnt; i++) {
       
   312         lst.append(((QTextBrowser*) ui.tab->widget(i))->source().toString());
       
   313     }
       
   314     return lst;
       
   315 }
       
   316 
       
   317 QList<HelpWindow*> TabbedBrowser::browsers() const
       
   318 {
       
   319     QList<HelpWindow*> list;
       
   320     for (int i=0; i<ui.tab->count(); ++i) {
       
   321         Q_ASSERT(qobject_cast<HelpWindow*>(ui.tab->widget(i)));
       
   322         list.append(static_cast<HelpWindow*>(ui.tab->widget(i)));
       
   323     }
       
   324     return list;
       
   325 }
       
   326 
       
   327 void TabbedBrowser::sourceChanged()
       
   328 {
       
   329     HelpWindow *win = qobject_cast<HelpWindow *>(QObject::sender());
       
   330     Q_ASSERT(win);
       
   331     QString docTitle(win->documentTitle());
       
   332     if (docTitle.isEmpty())
       
   333         docTitle = QLatin1String("...");
       
   334     // Make the classname in the title a bit more visible (otherwise
       
   335     // we just see the "Qt 4.0 : Q..." which isn't really helpful ;-)
       
   336     QString qtTitle = QLatin1String("Qt ") + QString::number( (QT_VERSION >> 16) & 0xff )
       
   337         + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff )
       
   338         + QLatin1String(": ");
       
   339     if (docTitle.startsWith(qtTitle))
       
   340         docTitle = docTitle.mid(qtTitle.length());
       
   341     setTitle(win, docTitle);
       
   342 	ui.frameFind->hide();
       
   343     ui.labelWrapped->hide();
       
   344 	win->setTextCursor(win->cursorForPosition(QPoint(0, 0)));
       
   345 }
       
   346 
       
   347 void TabbedBrowser::setTitle(HelpWindow *win, const QString &title)
       
   348 {
       
   349     const QString tt = title.trimmed();
       
   350     ui.tab->setTabText(ui.tab->indexOf(win), tt);
       
   351     if (win == currentBrowser())
       
   352         mainWindow()->setWindowTitle(Config::configuration()->title() + QLatin1String(" - ") + tt);
       
   353 }
       
   354 
       
   355 void TabbedBrowser::keyPressEvent(QKeyEvent *e)
       
   356 {
       
   357 	int key = e->key();
       
   358 	QString ttf = ui.editFind->text();
       
   359 	QString text = e->text();
       
   360 
       
   361 	if (ui.frameFind->isVisible()) {
       
   362 		switch (key) {
       
   363 		case Qt::Key_Escape:
       
   364 			ui.frameFind->hide();
       
   365             ui.labelWrapped->hide();
       
   366 			return;
       
   367 		case Qt::Key_Backspace:
       
   368 			ttf.chop(1);
       
   369 			break;
       
   370 		case Qt::Key_Return:
       
   371         case Qt::Key_Enter:
       
   372 			// Return/Enter key events are not accepted by QLineEdit
       
   373 			return;
       
   374 		default:
       
   375 			if (text.isEmpty()) {
       
   376 				QWidget::keyPressEvent(e);
       
   377                                 return;
       
   378                         }
       
   379 			ttf += text;
       
   380 		}
       
   381 	} else {
       
   382 		if (text.isEmpty() || text[0].isSpace() || !text[0].isPrint()) {
       
   383 			QWidget::keyPressEvent(e);
       
   384                         return;
       
   385                 }
       
   386         if (text.startsWith(QLatin1Char('/'))) {
       
   387             ui.editFind->clear();
       
   388             find();
       
   389             return;
       
   390         }
       
   391 		ttf = text;
       
   392 		ui.frameFind->show();
       
   393 	}
       
   394 
       
   395 	ui.editFind->setText(ttf);
       
   396 	find(ttf, false, false);
       
   397 }
       
   398 
       
   399 void TabbedBrowser::findNext()
       
   400 {
       
   401 	find(ui.editFind->text(), true, false);
       
   402 }
       
   403 
       
   404 void TabbedBrowser::findPrevious()
       
   405 {
       
   406 	find(ui.editFind->text(), false, true);
       
   407 }
       
   408 
       
   409 void TabbedBrowser::find()
       
   410 {
       
   411 	ui.frameFind->show();
       
   412 	ui.editFind->setFocus(Qt::ShortcutFocusReason);
       
   413 	ui.editFind->selectAll();
       
   414 	autoHideTimer->stop();
       
   415 }
       
   416 
       
   417 void TabbedBrowser::find(QString ttf, bool forward, bool backward)
       
   418 {
       
   419 	HelpWindow *browser = currentBrowser();
       
   420 	QTextDocument *doc = browser->document();
       
   421 	QString oldText = ui.editFind->text();
       
   422 	QTextCursor c = browser->textCursor();
       
   423 	QTextDocument::FindFlags options;
       
   424 	QPalette p = ui.editFind->palette();
       
   425 	p.setColor(QPalette::Active, QPalette::Base, Qt::white);
       
   426 
       
   427 	if (c.hasSelection())
       
   428 		c.setPosition(forward ? c.position() : c.anchor(), QTextCursor::MoveAnchor);
       
   429 
       
   430 	QTextCursor newCursor = c;
       
   431 
       
   432 	if (!ttf.isEmpty()) {
       
   433 		if (backward)
       
   434 			options |= QTextDocument::FindBackward;
       
   435 
       
   436 		if (ui.checkCase->isChecked())
       
   437 			options |= QTextDocument::FindCaseSensitively;
       
   438 
       
   439 		if (ui.checkWholeWords->isChecked())
       
   440 			options |= QTextDocument::FindWholeWords;
       
   441 
       
   442 		newCursor = doc->find(ttf, c, options);
       
   443 		ui.labelWrapped->hide();
       
   444 
       
   445 		if (newCursor.isNull()) {
       
   446 			QTextCursor ac(doc);
       
   447 			ac.movePosition(options & QTextDocument::FindBackward
       
   448 							? QTextCursor::End : QTextCursor::Start);
       
   449 			newCursor = doc->find(ttf, ac, options);
       
   450 			if (newCursor.isNull()) {
       
   451 				p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
       
   452 				newCursor = c;
       
   453 			} else
       
   454 				ui.labelWrapped->show();
       
   455 		}
       
   456 	}
       
   457 
       
   458 	if (!ui.frameFind->isVisible())
       
   459 		ui.frameFind->show();
       
   460 	browser->setTextCursor(newCursor);
       
   461 	ui.editFind->setPalette(p);
       
   462 	if (!ui.editFind->hasFocus())
       
   463 		autoHideTimer->start();
       
   464 }
       
   465 
       
   466 bool TabbedBrowser::eventFilter(QObject *o, QEvent *e)
       
   467 {
       
   468     if (o == ui.editFind) {
       
   469         if (e->type() == QEvent::FocusIn && autoHideTimer->isActive())
       
   470             autoHideTimer->stop();
       
   471     } else if (e->type() == QEvent::KeyPress && ui.frameFind->isVisible()) { // assume textbrowser
       
   472 		QKeyEvent *ke = static_cast<QKeyEvent *>(e);
       
   473 		if (ke->key() == Qt::Key_Space) {
       
   474 			keyPressEvent(ke);
       
   475 			return true;
       
   476 		}
       
   477 	}
       
   478 
       
   479 	return QWidget::eventFilter(o, e);
       
   480 }
       
   481 
       
   482 void TabbedBrowser::openTabMenu(const QPoint& pos)
       
   483 {
       
   484     QTabBar *tabBar = qFindChild<QTabBar*>(ui.tab);
       
   485     
       
   486     QMenu m(QLatin1String(""), tabBar);
       
   487     QAction *new_action = m.addAction(tr("New Tab"));
       
   488     QAction *close_action = m.addAction(tr("Close Tab"));
       
   489     QAction *close_others_action = m.addAction(tr("Close Other Tabs"));
       
   490 
       
   491     if (tabBar->count() == 1) {
       
   492         close_action->setEnabled(false);
       
   493         close_others_action->setEnabled(false);
       
   494     }
       
   495     
       
   496     QAction *action_picked = m.exec(tabBar->mapToGlobal(pos));
       
   497     if (!action_picked)
       
   498         return;
       
   499 
       
   500     if (action_picked == new_action) {
       
   501         newTab();
       
   502         return;
       
   503     } 
       
   504 
       
   505     QList<HelpWindow*> windowList = browsers();
       
   506     for (int i = 0; i < tabBar->count(); ++i) {
       
   507         if (tabBar->tabRect(i).contains(pos)) {
       
   508             HelpWindow *win = static_cast<HelpWindow*>(ui.tab->widget(i));
       
   509             if (action_picked == close_action) {
       
   510                 mainWindow()->removePendingBrowser(win);
       
   511                 QTimer::singleShot(0, win, SLOT(deleteLater()));
       
   512             }
       
   513             windowList.removeOne(win);
       
   514             break;
       
   515         }
       
   516     }
       
   517 
       
   518     if (action_picked == close_others_action) {
       
   519         foreach (HelpWindow* win, windowList) {
       
   520             mainWindow()->removePendingBrowser(win);
       
   521             QTimer::singleShot(0, win, SLOT(deleteLater()));
       
   522             windowList.removeOne(win);
       
   523         }
       
   524     }
       
   525 
       
   526     ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(windowList.count() > 1);
       
   527     emit tabCountChanged(windowList.count());
       
   528 }
       
   529 
       
   530 QT_END_NAMESPACE