2 * Copyright (C) 2008 Trolltech ASA
3 * Copyright (C) 2006 George Staikos <staikos@kde.org>
4 * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
5 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
6 * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <qwebframe.h>
35 #include <qwebsettings.h>
39 #if QT_VERSION >= 0x040400 && !defined(QT_NO_PRINTER)
40 #include <QPrintPreviewDialog>
43 #include <QtUiTools/QUiLoader>
45 class WebPage : public QWebPage
48 WebPage(QWidget *parent) : QWebPage(parent) {}
50 virtual QWebPage *createWindow(QWebPage::WebWindowType);
51 virtual QObject* createPlugin(const QString&, const QUrl&, const QStringList&, const QStringList&);
54 class MainWindow : public QMainWindow
58 MainWindow(const QString& url = QString()): currentZoom(100) {
59 view = new QWebView(this);
60 setCentralWidget(view);
62 view->setPage(new WebPage(view));
64 connect(view, SIGNAL(loadFinished(bool)),
65 this, SLOT(loadFinished()));
66 connect(view, SIGNAL(titleChanged(const QString&)),
67 this, SLOT(setWindowTitle(const QString&)));
68 connect(view->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString &)),
69 this, SLOT(showLinkHover(const QString&, const QString&)));
70 connect(view->page(), SIGNAL(windowCloseRequested()), this, SLOT(deleteLater()));
74 QUrl qurl = guessUrlFromString(url);
76 urlEdit->setText(qurl.toString());
79 // the zoom values are chosen to be like in Mozilla Firefox 3
80 zoomLevels << 30 << 50 << 67 << 80 << 90;
82 zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
86 QWebPage *webPage() const {
92 void changeLocation() {
93 QUrl url = guessUrlFromString(urlEdit->text());
94 urlEdit->setText(url.toString());
96 view->setFocus(Qt::OtherFocusReason);
100 urlEdit->setText(view->url().toString());
102 QUrl::FormattingOptions opts;
103 opts |= QUrl::RemoveScheme;
104 opts |= QUrl::RemoveUserInfo;
105 opts |= QUrl::StripTrailingSlash;
106 QString s = view->url().toString(opts);
111 if (!urlList.contains(s))
113 urlModel.setStringList(urlList);
116 void showLinkHover(const QString &link, const QString &toolTip) {
117 statusBar()->showMessage(link);
118 #ifndef QT_NO_TOOLTIP
119 if (!toolTip.isEmpty())
120 QToolTip::showText(QCursor::pos(), toolTip);
125 MainWindow *mw = new MainWindow;
130 int i = zoomLevels.indexOf(currentZoom);
132 if (i < zoomLevels.count() - 1)
133 currentZoom = zoomLevels[i + 1];
135 view->setZoomFactor(qreal(currentZoom)/100.0);
139 int i = zoomLevels.indexOf(currentZoom);
142 currentZoom = zoomLevels[i - 1];
144 view->setZoomFactor(qreal(currentZoom)/100.0);
150 view->setZoomFactor(1.0);
153 void toggleZoomTextOnly(bool b)
155 view->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, b);
159 #if QT_VERSION >= 0x040400 && !defined(QT_NO_PRINTER)
160 QPrintPreviewDialog dlg(this);
161 connect(&dlg, SIGNAL(paintRequested(QPrinter *)),
162 view, SLOT(print(QPrinter *)));
167 void setEditable(bool on) {
168 view->page()->setEditable(on);
169 formatMenuAction->setVisible(on);
173 qDebug() << "HTML: " << view->page()->mainFrame()->toHtml();
177 QVector<int> zoomLevels;
180 // create the status bar, tool bar & menu
182 progress = new QProgressBar(this);
183 progress->setRange(0, 100);
184 progress->setMinimumSize(100, 20);
185 progress->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
187 statusBar()->addPermanentWidget(progress);
189 connect(view, SIGNAL(loadProgress(int)), progress, SLOT(show()));
190 connect(view, SIGNAL(loadProgress(int)), progress, SLOT(setValue(int)));
191 connect(view, SIGNAL(loadFinished(bool)), progress, SLOT(hide()));
193 urlEdit = new QLineEdit(this);
194 urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy());
195 connect(urlEdit, SIGNAL(returnPressed()),
196 SLOT(changeLocation()));
197 QCompleter *completer = new QCompleter(this);
198 urlEdit->setCompleter(completer);
199 completer->setModel(&urlModel);
201 QToolBar *bar = addToolBar("Navigation");
202 bar->addAction(view->pageAction(QWebPage::Back));
203 bar->addAction(view->pageAction(QWebPage::Forward));
204 bar->addAction(view->pageAction(QWebPage::Reload));
205 bar->addAction(view->pageAction(QWebPage::Stop));
206 bar->addWidget(urlEdit);
208 QMenu *fileMenu = menuBar()->addMenu("&File");
209 QAction *newWindow = fileMenu->addAction("New Window", this, SLOT(newWindow()));
210 #if QT_VERSION >= 0x040400
211 fileMenu->addAction(tr("Print"), this, SLOT(print()));
213 fileMenu->addAction("Close", this, SLOT(close()));
215 QMenu *editMenu = menuBar()->addMenu("&Edit");
216 editMenu->addAction(view->pageAction(QWebPage::Undo));
217 editMenu->addAction(view->pageAction(QWebPage::Redo));
218 editMenu->addSeparator();
219 editMenu->addAction(view->pageAction(QWebPage::Cut));
220 editMenu->addAction(view->pageAction(QWebPage::Copy));
221 editMenu->addAction(view->pageAction(QWebPage::Paste));
222 editMenu->addSeparator();
223 QAction *setEditable = editMenu->addAction("Set Editable", this, SLOT(setEditable(bool)));
224 setEditable->setCheckable(true);
226 QMenu *viewMenu = menuBar()->addMenu("&View");
227 viewMenu->addAction(view->pageAction(QWebPage::Stop));
228 viewMenu->addAction(view->pageAction(QWebPage::Reload));
229 viewMenu->addSeparator();
230 QAction *zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn()));
231 QAction *zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut()));
232 QAction *resetZoom = viewMenu->addAction("Reset Zoom", this, SLOT(resetZoom()));
233 QAction *zoomTextOnly = viewMenu->addAction("Zoom Text Only", this, SLOT(toggleZoomTextOnly(bool)));
234 zoomTextOnly->setCheckable(true);
235 zoomTextOnly->setChecked(false);
236 viewMenu->addSeparator();
237 viewMenu->addAction("Dump HTML", this, SLOT(dumpHtml()));
239 QMenu *formatMenu = new QMenu("F&ormat");
240 formatMenuAction = menuBar()->addMenu(formatMenu);
241 formatMenuAction->setVisible(false);
242 formatMenu->addAction(view->pageAction(QWebPage::ToggleBold));
243 formatMenu->addAction(view->pageAction(QWebPage::ToggleItalic));
244 formatMenu->addAction(view->pageAction(QWebPage::ToggleUnderline));
245 QMenu *writingMenu = formatMenu->addMenu(tr("Writing Direction"));
246 writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionDefault));
247 writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionLeftToRight));
248 writingMenu->addAction(view->pageAction(QWebPage::SetTextDirectionRightToLeft));
250 newWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
251 view->pageAction(QWebPage::Back)->setShortcut(QKeySequence::Back);
252 view->pageAction(QWebPage::Stop)->setShortcut(Qt::Key_Escape);
253 view->pageAction(QWebPage::Forward)->setShortcut(QKeySequence::Forward);
254 view->pageAction(QWebPage::Reload)->setShortcut(QKeySequence::Refresh);
255 view->pageAction(QWebPage::Undo)->setShortcut(QKeySequence::Undo);
256 view->pageAction(QWebPage::Redo)->setShortcut(QKeySequence::Redo);
257 view->pageAction(QWebPage::Cut)->setShortcut(QKeySequence::Cut);
258 view->pageAction(QWebPage::Copy)->setShortcut(QKeySequence::Copy);
259 view->pageAction(QWebPage::Paste)->setShortcut(QKeySequence::Paste);
260 zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
261 zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
262 resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
263 view->pageAction(QWebPage::ToggleBold)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
264 view->pageAction(QWebPage::ToggleItalic)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
265 view->pageAction(QWebPage::ToggleUnderline)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U));
268 QUrl guessUrlFromString(const QString &string) {
269 QString urlStr = string.trimmed();
270 QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*"));
272 // Check if it looks like a qualified URL. Try parsing it and see.
273 bool hasSchema = test.exactMatch(urlStr);
275 QUrl url(urlStr, QUrl::TolerantMode);
281 if (QFile::exists(urlStr))
282 return QUrl::fromLocalFile(urlStr);
284 // Might be a shorturl - try to detect the schema.
286 int dotIndex = urlStr.indexOf(QLatin1Char('.'));
287 if (dotIndex != -1) {
288 QString prefix = urlStr.left(dotIndex).toLower();
289 QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http");
290 QUrl url(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode);
296 // Fall back to QUrl's own tolerant parser.
297 return QUrl(string, QUrl::TolerantMode);
302 QProgressBar *progress;
304 QAction *formatMenuAction;
307 QStringListModel urlModel;
310 QWebPage *WebPage::createWindow(QWebPage::WebWindowType)
312 MainWindow *mw = new MainWindow;
313 return mw->webPage();
316 QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
319 Q_UNUSED(paramNames);
320 Q_UNUSED(paramValues);
322 return loader.createWidget(classId, view());
327 int main(int argc, char **argv)
329 QApplication app(argc, argv);
330 QString url = QString("%1/%2").arg(QDir::homePath()).arg(QLatin1String("index.html"));
332 QWebSettings::setMaximumPagesInCache(4);
334 app.setApplicationName("QtLauncher");
335 #if QT_VERSION >= 0x040400
336 app.setApplicationVersion("0.1");
339 QWebSettings::setObjectCacheCapacities((16*1024*1024) / 8, (16*1024*1024) / 8, 16*1024*1024);
341 QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true);
342 QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
344 const QStringList args = app.arguments();
345 if (args.count() > 1)
348 MainWindow window(url);