tools/assistant/tabbedbrowser.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the Qt Assistant of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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     // workaround for sgi style
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 * /*win*/)
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     // Make the classname in the title a bit more visible (otherwise
00307     // we just see the "Qt 4.0 : Q..." which isn't really helpful ;-)
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       // Return/Enter key events are not accepted by QLineEdit
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()) { // assume textbrowser
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 }

Generated on Thu Mar 15 12:00:58 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1