1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
#include "browser.h"
#include <QAction>
#include <QKeySequence>
#include <QLabel>
#include <QLineEdit>
#include <QProgressBar>
#include <QPushButton>
#include <QRegExp>
#include <QStatusBar>
#include <QStyle>
#include <QTabWidget>
#include <QToolBar>
#include <QWebView>
Browser::Browser(QWidget *parent)
: QMainWindow(parent), web(0)
{
// vytvoříme widgety:
// políčko pro URL
urlBar = new QLineEdit;
// rozhraní s taby
tabs = new QTabWidget;
// tlačítko napravo od tabů pro vytvoření nového
QPushButton* newTabBtn = new QPushButton(style()->standardIcon(QStyle::SP_FileDialogNewFolder), "", tabs);
// text ve stavovém řádku
statusLabel = new QLabel;
// průběh načítání stránky ve stavovém řádku
loading = new QProgressBar;
// panel nástrojů (obsahující ovládací prvky prohlížeče)
QToolBar* toolBar = addToolBar(tr("Controls"));
// přidáme akce do panelu nástrojů a rovnou je napojíme na sloty
toolBar->addAction(style()->standardIcon(QStyle::SP_ArrowBack), tr("Back"), this, SLOT(goBack()));
toolBar->addAction(style()->standardIcon(QStyle::SP_ArrowForward), tr("Forward"), this, SLOT(goForward()));
toolBar->addAction(style()->standardIcon(QStyle::SP_BrowserReload), tr("Reload"), this, SLOT(reload()));
toolBar->addAction(style()->standardIcon(QStyle::SP_BrowserStop), tr("Stop"), this, SLOT(stop()));
// uložíme si ukazatel akce pro vytvoření nového tabu
QAction* actionAddTab = toolBar->addAction(style()->standardIcon(QStyle::SP_FileDialogNewFolder),
tr("New tab"), this, SLOT(addNewTab()));
// a přiřadíme jí klávesovou zkratku
actionAddTab->setShortcut(QKeySequence("Ctrl+T"));
// přidáme adresní řádek
toolBar->addWidget(urlBar);
toolBar->addAction(style()->standardIcon(QStyle::SP_CommandLink), tr("Go"), this, SLOT(loadUrl()));
// propojíme tlačítko pro přidání tabů
connect(newTabBtn, SIGNAL(clicked()), this, SLOT(addNewTab()));
// reakce na změnu aktuálního tabu
connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
// reakce na zavření daného tabu
connect(tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
// reakce stisknutí Enteru v adresním řádku
connect(urlBar, SIGNAL(returnPressed()), this, SLOT(loadUrl()));
// přidáme tlačítko vedle tabů
tabs->setCornerWidget(newTabBtn);
// povolíme přesouvání tabů
tabs->setMovable(true);
// nastavíme pevnou šířku ukazateli průběhu
loading->setFixedWidth(100);
// nastavíme hlavnímu oknu:
// hlavní widget (rozhraní s taby)
setCentralWidget(tabs);
// a stavový řádek
setStatusBar(new QStatusBar);
// popisek ve stavovém řádku nebude zvětšovat okno
statusBar()->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
// přidáme do stavového řádku popisek
statusBar()->addWidget(statusLabel);
// a ukazatel průběhu
statusBar()->addPermanentWidget(loading);
// vytvoříme první tab
addNewTab();
// nastavíme do adresního řádku adresu abclinuxu
urlBar->setText("http://www.abclinuxu.cz");
// a stránku načteme
loadUrl();
// nastavíme výchozí velikost okna
resize(950, 700);
}
// vytvoří nový tab
void Browser::addNewTab()
{
// přidáme tab
int index = tabs->addTab(new QWebView, tr("New tab"));
// pokud máme víc než 1 tab,
if(tabs->count() > 1)
{
// přepneme se na tab nově vytvořený
tabs->setCurrentIndex(index);
// a povolíme zavírání tabů
tabs->setTabsClosable(true);
}
// vyprázdníme adresní řádek
urlBar->setText("");
// vynulujeme ukazatel průběhu načítání
loading->reset();
// nastavíme titulek okna
setWindowTitle("WebKit browser");
}
void Browser::tabChanged(int index)
{
// pokud si zavřeme poslední tab, dostaneme index o hodnotě -1
// a k tomu by nemělo dojít, takže v debug. verzi shodíme program
Q_ASSERT(index >= 0);
// v obyčejné verzi se problém pokusíme obejít přidáním nového tabu
if(index < 0)
{
addNewTab();
return;
}
if(web)
{
// odpojíme tab ze kterého přepínáme od GUI slotů (viz níže)
disconnect(web, SIGNAL(urlChanged(QUrl)), this, SLOT(setUrl(QUrl)));
disconnect(web, SIGNAL(titleChanged(QString)), this, SLOT(changeTitle(QString)));
disconnect(web, SIGNAL(loadProgress(int)), loading, SLOT(setValue(int)));
disconnect(web, SIGNAL(loadFinished(bool)), this, SLOT(setLoadingStatus(bool)));
disconnect(web->page(), SIGNAL(linkHovered(QString,QString,QString)), statusLabel, SLOT(setText(QString)));
}
// získáme prohlížeč aktuálního tabu
web = qobject_cast<QWebView*>( tabs->widget(index) );
// a napojíme jej na GUI:
// projeví změnu URL z prohlížeče do adresního řádku
connect(web, SIGNAL(urlChanged(QUrl)), this, SLOT(setUrl(QUrl)));
// nastaví titulek stránky jako titulek okna a tabu
connect(web, SIGNAL(titleChanged(QString)), this, SLOT(changeTitle(QString)));
// zobrazuje průběh načítání
connect(web, SIGNAL(loadProgress(int)), loading, SLOT(setValue(int)));
connect(web, SIGNAL(loadFinished(bool)), this, SLOT(setLoadingStatus(bool)));
// když kurzor najede na odkaz, zobrazíme jeho cíl ve stavovém řádku
connect(web->page(), SIGNAL(linkHovered(QString,QString,QString)), statusLabel, SLOT(setText(QString)));
// načteme správnou adresu do adresního řádku
setUrl(web->url());
// vyprázdníme text ve stavovém řádku
statusLabel->setText("");
// změníme titulek okna
setWindowTitle(tabs->tabText(tabs->currentIndex()));
}
// zavře tab s daným indexem
void Browser::closeTab(int index)
{
// v případě, že zavíráme aktuální tab, nastavíme web na 0, aby se tabChanged() nepokoušelo
// odpojovat neexistující widget
if(tabs->widget(index) == web)
web = 0;
// smazání widgetu zavře tab
delete tabs->widget(index);
// pokud po zavření akt. tabu zbyl už jen jeden, zakážeme jeho zavření
if(tabs->count() < 2)
tabs->setTabsClosable(false);
}
// informuje ve stavovém řádku o úspěšnosti načtení stránky
void Browser::setLoadingStatus(bool ok)
{
QString text = tr("OK");
if(!ok) text = tr("Loading failed");
statusLabel->setText(text);
}
// načte adresu zadanou v adresním řádku
void Browser::loadUrl()
{
QString url = urlBar->text();
// pokud daná adresa neobsahuje protokol, předpokládáme http://
if(!url.contains(QRegExp("^[a-z]+://")))
url.prepend("http://");
// načteme připravenou adresu
web->load(QUrl(url, QUrl::TolerantMode));
}
// nastaví dané URL do adresního řádku
void Browser::setUrl(QUrl url)
{
// z URL odstraníme přihlašovací informace
urlBar->setText(url.toString(QUrl::RemoveUserInfo));
}
// nastaví titulek okna a aktuálního tabu
void Browser::changeTitle(QString title)
{
if(title.isEmpty())
title = web->url().toString(QUrl::RemoveUserInfo);
setWindowTitle(title);
tabs->setTabText(tabs->currentIndex(), title);
}
// "Zpět" v prohlížeči
void Browser::goBack()
{
web->back();
}
// "Vpřed" v prohlížeči
void Browser::goForward()
{
web->forward();
}
// "Obnovit" v prohlížeči
void Browser::reload()
{
web->reload();
}
// "Stop" v prohlížeči
void Browser::stop()
{
web->stop();
}
|