00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tabbedbrowser.h"
00025 #include "mainwindow.h"
00026 #include "helpwindow.h"
00027 #include "config.h"
00028
00029 #include <QStyleOptionTab>
00030 #include <QToolTip>
00031 #include <QFileInfo>
00032 #include <QToolButton>
00033 #include <QPixmap>
00034 #include <QIcon>
00035 #include <QStyle>
00036 #include <QTimer>
00037 #include <QStackedWidget>
00038 #include <QTimer>
00039 #include <QTextBlock>
00040 #include <QKeyEvent>
00041
00042 #ifdef Q_WS_MAC
00043 const QLatin1String ImageLocation(":trolltech/assistant/images/mac/");
00044 #else
00045 const QLatin1String ImageLocation(":trolltech/assistant/images/win/");
00046 #endif
00047
00048 TabbedBrowser::TabbedBrowser(MainWindow *parent)
00049 : QWidget(parent)
00050 {
00051 ui.setupUi(this);
00052 init();
00053
00054 QStackedWidget *stack = qFindChild<QStackedWidget*>(ui.tab);
00055 Q_ASSERT(stack);
00056 stack->setContentsMargins(0, 0, 0, 0);
00057 connect(stack, SIGNAL(currentChanged(int)), parent, SLOT(browserTabChanged()));
00058
00059 QPalette p = palette();
00060 p.setColor(QPalette::Inactive, QPalette::Highlight,
00061 p.color(QPalette::Active, QPalette::Highlight));
00062 p.setColor(QPalette::Inactive, QPalette::HighlightedText,
00063 p.color(QPalette::Active, QPalette::HighlightedText));
00064 setPalette(p);
00065 }
00066
00067 TabbedBrowser::~TabbedBrowser()
00068 {
00069 }
00070
00071 MainWindow *TabbedBrowser::mainWindow() const
00072 {
00073 return static_cast<MainWindow*>(parentWidget());
00074 }
00075
00076 void TabbedBrowser::forward()
00077 {
00078 currentBrowser()->forward();
00079 }
00080
00081 void TabbedBrowser::backward()
00082 {
00083 currentBrowser()->backward();
00084 }
00085
00086 void TabbedBrowser::setSource( const QString &ref )
00087 {
00088 HelpWindow * win = currentBrowser();
00089 win->setSource(ref);
00090 }
00091
00092 void TabbedBrowser::reload()
00093 {
00094 currentBrowser()->reload();
00095 }
00096
00097 void TabbedBrowser::home()
00098 {
00099 currentBrowser()->home();
00100 }
00101
00102 HelpWindow *TabbedBrowser::currentBrowser() const
00103 {
00104 return static_cast<HelpWindow*>(ui.tab->currentWidget());
00105 }
00106
00107 void TabbedBrowser::nextTab()
00108 {
00109 if(ui.tab->currentIndex()<=ui.tab->count()-1)
00110 ui.tab->setCurrentIndex(ui.tab->currentIndex()+1);
00111 }
00112
00113 void TabbedBrowser::previousTab()
00114 {
00115 int idx = ui.tab->currentIndex()-1;
00116 if(idx>=0)
00117 ui.tab->setCurrentIndex(idx);
00118 }
00119
00120 HelpWindow *TabbedBrowser::createHelpWindow()
00121 {
00122 MainWindow *mainWin = mainWindow();
00123 HelpWindow *win = new HelpWindow(mainWin, 0);
00124 win->setFrameStyle(QFrame::NoFrame);
00125 win->setPalette(palette());
00126 win->setSearchPaths(Config::configuration()->mimePaths());
00127 ui.tab->addTab(win, tr("..."));
00128 connect(win, SIGNAL(highlighted(QString)),
00129 (const QObject*) (mainWin->statusBar()), SLOT(showMessage(QString)));
00130 connect(win, SIGNAL(backwardAvailable(bool)),
00131 mainWin, SLOT(backwardAvailable(bool)));
00132 connect(win, SIGNAL(forwardAvailable(bool)),
00133 mainWin, SLOT(forwardAvailable(bool)));
00134 connect(win, SIGNAL(sourceChanged(QUrl)), this, SLOT(sourceChanged()));
00135
00136 ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
00137 win->installEventFilter(this);
00138 win->viewport()->installEventFilter(this);
00139 ui.editFind->installEventFilter(this);
00140 return win;
00141 }
00142
00143 HelpWindow *TabbedBrowser::newBackgroundTab()
00144 {
00145 HelpWindow *win = createHelpWindow();
00146 return win;
00147 }
00148
00149 void TabbedBrowser::newTab(const QString &lnk)
00150 {
00151 QString link(lnk);
00152 if(link.isNull()) {
00153 HelpWindow *w = currentBrowser();
00154 if(w)
00155 link = w->source().toString();
00156 }
00157 HelpWindow *win = createHelpWindow();
00158 ui.tab->setCurrentIndex(ui.tab->indexOf(win));
00159 if(!link.isNull()) {
00160 win->setSource(link);
00161 }
00162 }
00163
00164 void TabbedBrowser::zoomIn()
00165 {
00166 currentBrowser()->zoomIn();
00167 Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
00168 }
00169
00170 void TabbedBrowser::zoomOut()
00171 {
00172 currentBrowser()->zoomOut();
00173 Config::configuration()->setFontPointSize(currentBrowser()->font().pointSizeF());
00174 }
00175
00176 void TabbedBrowser::init()
00177 {
00178
00179 lastCurrentTab = 0;
00180 while(ui.tab->count()) {
00181 QWidget *page = ui.tab->widget(0);
00182 ui.tab->removeTab(0);
00183 delete page;
00184 }
00185
00186 connect(ui.tab, SIGNAL(currentChanged(int)),
00187 this, SLOT(transferFocus()));
00188
00189 QTabBar *tabBar = qFindChild<QTabBar*>(ui.tab);
00190 QStyleOptionTab opt;
00191 if (tabBar) {
00192 opt.init(tabBar);
00193 opt.shape = tabBar->shape();
00194 }
00195
00196
00197 QPalette pal = palette();
00198 pal.setColor(QPalette::Active, QPalette::Button, pal.color(QPalette::Active, QPalette::Window));
00199 pal.setColor(QPalette::Disabled, QPalette::Button, pal.color(QPalette::Disabled, QPalette::Window));
00200 pal.setColor(QPalette::Inactive, QPalette::Button, pal.color(QPalette::Inactive, QPalette::Window));
00201
00202 QToolButton *newTabButton = new QToolButton(this);
00203 ui.tab->setCornerWidget(newTabButton, Qt::TopLeftCorner);
00204 newTabButton->setCursor(Qt::ArrowCursor);
00205 newTabButton->setAutoRaise(true);
00206 newTabButton->setIcon(QIcon(ImageLocation + QLatin1String("addtab.png")));
00207 QObject::connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));
00208 newTabButton->setToolTip(tr("Add page"));
00209
00210 QToolButton *closeTabButton = new QToolButton(this);
00211 closeTabButton->setPalette(pal);
00212 ui.tab->setCornerWidget(closeTabButton, Qt::TopRightCorner);
00213 closeTabButton->setCursor(Qt::ArrowCursor);
00214 closeTabButton->setAutoRaise(true);
00215 closeTabButton->setIcon(QIcon(ImageLocation + QLatin1String("closetab.png")));
00216 QObject::connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeTab()));
00217 closeTabButton->setToolTip(tr("Close page"));
00218 closeTabButton->setEnabled(false);
00219
00220 QObject::connect(ui.toolClose, SIGNAL(clicked()), ui.frameFind, SLOT(hide()));
00221 QObject::connect(ui.toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
00222 QObject::connect(ui.toolNext, SIGNAL(clicked()), this, SLOT(findNext()));
00223 QObject::connect(ui.editFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
00224 QObject::connect(ui.editFind, SIGNAL(textEdited(const QString&)),
00225 this, SLOT(find(QString)));
00226 ui.frameFind->setVisible(false);
00227 ui.labelWrapped->setVisible(false);
00228 autoHideTimer = new QTimer(this);
00229 autoHideTimer->setInterval(5000);
00230 autoHideTimer->setSingleShot(true);
00231 QObject::connect(autoHideTimer, SIGNAL(timeout()), ui.frameFind, SLOT(hide()));
00232 }
00233
00234 void TabbedBrowser::updateTitle(const QString &title)
00235 {
00236 ui.tab->setTabText(ui.tab->indexOf(currentBrowser()), title);
00237 }
00238
00239 void TabbedBrowser::newTab()
00240 {
00241 newTab(QString());
00242 }
00243
00244 void TabbedBrowser::transferFocus()
00245 {
00246 if(currentBrowser()) {
00247 currentBrowser()->setFocus();
00248 }
00249 mainWindow()->setWindowTitle(Config::configuration()->title()
00250 + QLatin1String(" - ")
00251 + currentBrowser()->documentTitle());
00252 }
00253
00254 void TabbedBrowser::initHelpWindow(HelpWindow * )
00255 {
00256 }
00257
00258 void TabbedBrowser::setup()
00259 {
00260 newTab(QString());
00261 }
00262
00263 void TabbedBrowser::copy()
00264 {
00265 currentBrowser()->copy();
00266 }
00267
00268 void TabbedBrowser::closeTab()
00269 {
00270 if(ui.tab->count()==1)
00271 return;
00272 HelpWindow *win = currentBrowser();
00273 mainWindow()->removePendingBrowser(win);
00274 ui.tab->removeTab(ui.tab->indexOf(win));
00275 QTimer::singleShot(0, win, SLOT(deleteLater()));
00276 ui.tab->cornerWidget(Qt::TopRightCorner)->setEnabled(ui.tab->count() > 1);
00277 }
00278
00279 QStringList TabbedBrowser::sources() const
00280 {
00281 QStringList lst;
00282 int cnt = ui.tab->count();
00283 for(int i=0; i<cnt; i++) {
00284 lst.append(((QTextBrowser*) ui.tab->widget(i))->source().toString());
00285 }
00286 return lst;
00287 }
00288
00289 QList<HelpWindow*> TabbedBrowser::browsers() const
00290 {
00291 QList<HelpWindow*> list;
00292 for (int i=0; i<ui.tab->count(); ++i) {
00293 Q_ASSERT(::qobject_cast<HelpWindow*>(ui.tab->widget(i)));
00294 list.append(static_cast<HelpWindow*>(ui.tab->widget(i)));
00295 }
00296 return list;
00297 }
00298
00299 void TabbedBrowser::sourceChanged()
00300 {
00301 HelpWindow *win = ::qobject_cast<HelpWindow *>(QObject::sender());
00302 Q_ASSERT(win);
00303 QString docTitle(win->documentTitle());
00304 if (docTitle.isEmpty())
00305 docTitle = QLatin1String("...");
00306
00307
00308 QString qtTitle = "Qt " + QString::number( (QT_VERSION >> 16) & 0xff )
00309 + QLatin1String(".") + QString::number( (QT_VERSION >> 8) & 0xff )
00310 + ": ";
00311 if (docTitle.startsWith(qtTitle))
00312 docTitle = docTitle.mid(qtTitle.length());
00313 setTitle(win, docTitle);
00314 ui.frameFind->hide();
00315 ui.labelWrapped->hide();
00316 win->setTextCursor(win->cursorForPosition(QPoint(0, 0)));
00317 }
00318
00319 void TabbedBrowser::setTitle(HelpWindow *win, const QString &title)
00320 {
00321 ui.tab->setTabText(ui.tab->indexOf(win), title);
00322 if (win == currentBrowser())
00323 mainWindow()->setWindowTitle(Config::configuration()->title() + QLatin1String(" - ") + title);
00324 }
00325
00326 void TabbedBrowser::keyPressEvent(QKeyEvent *e)
00327 {
00328 int key = e->key();
00329 QString ttf = ui.editFind->text();
00330 QString text = e->text();
00331
00332 if (ui.frameFind->isVisible()) {
00333 switch (key) {
00334 case Qt::Key_Escape:
00335 ui.frameFind->hide();
00336 ui.labelWrapped->hide();
00337 return;
00338 case Qt::Key_Backspace:
00339 ttf.chop(1);
00340 break;
00341 case Qt::Key_Return:
00342 case Qt::Key_Enter:
00343
00344 return;
00345 default:
00346 if (text.isEmpty()) {
00347 QWidget::keyPressEvent(e);
00348 return;
00349 }
00350 ttf += text;
00351 }
00352 } else {
00353 if (text.isEmpty() || text[0].isSpace() || !text[0].isPrint()) {
00354 QWidget::keyPressEvent(e);
00355 return;
00356 }
00357 if (text.startsWith(QLatin1Char('/'))) {
00358 ui.editFind->clear();
00359 find();
00360 return;
00361 }
00362 ttf = text;
00363 ui.frameFind->show();
00364 }
00365
00366 ui.editFind->setText(ttf);
00367 find(ttf, false, false);
00368 }
00369
00370 void TabbedBrowser::findNext()
00371 {
00372 find(ui.editFind->text(), true, false);
00373 }
00374
00375 void TabbedBrowser::findPrevious()
00376 {
00377 find(ui.editFind->text(), false, true);
00378 }
00379
00380 void TabbedBrowser::find()
00381 {
00382 ui.frameFind->show();
00383 ui.editFind->setFocus(Qt::ShortcutFocusReason);
00384 ui.editFind->selectAll();
00385 autoHideTimer->stop();
00386 }
00387
00388 void TabbedBrowser::find(QString ttf, bool forward, bool backward)
00389 {
00390 HelpWindow *browser = currentBrowser();
00391 QTextDocument *doc = browser->document();
00392 QString oldText = ui.editFind->text();
00393 QTextCursor c = browser->textCursor();
00394 QTextDocument::FindFlags options;
00395 QPalette p = ui.editFind->palette();
00396 p.setColor(QPalette::Active, QPalette::Base, Qt::white);
00397
00398 if (c.hasSelection())
00399 c.setPosition(forward ? c.position() : c.anchor(), QTextCursor::MoveAnchor);
00400
00401 QTextCursor newCursor = c;
00402
00403 if (!ttf.isEmpty()) {
00404 if (backward)
00405 options |= QTextDocument::FindBackward;
00406
00407 if (ui.checkCase->isChecked())
00408 options |= QTextDocument::FindCaseSensitively;
00409
00410 if (ui.checkWholeWords->isChecked())
00411 options |= QTextDocument::FindWholeWords;
00412
00413 newCursor = doc->find(ttf, c, options);
00414 ui.labelWrapped->hide();
00415
00416 if (newCursor.isNull()) {
00417 QTextCursor ac(doc);
00418 ac.movePosition(options & QTextDocument::FindBackward
00419 ? QTextCursor::End : QTextCursor::Start);
00420 newCursor = doc->find(ttf, ac, options);
00421 if (newCursor.isNull()) {
00422 p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
00423 newCursor = c;
00424 } else
00425 ui.labelWrapped->show();
00426 }
00427 }
00428
00429 if (!ui.frameFind->isVisible())
00430 ui.frameFind->show();
00431 browser->setTextCursor(newCursor);
00432 ui.editFind->setPalette(p);
00433 if (!ui.editFind->hasFocus())
00434 autoHideTimer->start();
00435 }
00436
00437 bool TabbedBrowser::eventFilter(QObject *o, QEvent *e)
00438 {
00439 if (o == ui.editFind) {
00440 if (e->type() == QEvent::FocusIn && autoHideTimer->isActive())
00441 autoHideTimer->stop();
00442 } else if (e->type() == QEvent::KeyPress && ui.frameFind->isVisible()) {
00443 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
00444 if (ke->key() == Qt::Key_Space) {
00445 keyPressEvent(ke);
00446 return true;
00447 }
00448 }
00449
00450 return QWidget::eventFilter(o, e);
00451 }