not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / applets / webbrowser / webbrowser.cpp
blobfe65432bdc044c96a77856d4e13cdc8f81568d76
1 /***************************************************************************
2 * Copyright (C) 2008 Marco Martin <notmart@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
18 ***************************************************************************/
20 #include "webbrowser.h"
22 #include <limits.h>
24 #include <QGraphicsLinearLayout>
25 #include <QGraphicsProxyWidget>
26 #include <QGraphicsSceneMouseEvent>
27 #include <QStandardItemModel>
28 #include <QModelIndex>
29 #include <QAction>
30 #include <QTimer>
31 #include <QTreeView>
32 #include <QWebPage>
33 #include <QWebFrame>
34 #include <QWebHistory>
36 #include <KIcon>
37 #include <KCompletion>
38 #include <KBookmarkManager>
39 #include <KIconLoader>
40 #include <KUrlPixmapProvider>
41 #include <KUriFilter>
42 #include <KMessageBox>
43 #include <KConfigDialog>
44 #include <KHistoryComboBox>
46 #include <Plasma/IconWidget>
47 #include <Plasma/LineEdit>
48 #include <Plasma/Meter>
49 #include <Plasma/WebView>
50 #include <Plasma/TreeView>
51 #include <Plasma/Slider>
53 #include "historycombobox.h"
54 #include "bookmarksdelegate.h"
55 #include "bookmarkitem.h"
57 WebBrowser::WebBrowser(QObject *parent, const QVariantList &args)
58 : Plasma::PopupApplet(parent, args),
59 m_browser(0),
60 m_verticalScrollValue(0),
61 m_horizontalScrollValue(0),
62 m_completion(0),
63 m_bookmarkManager(0),
64 m_bookmarkModel(0),
65 m_autoRefreshTimer(0),
66 m_graphicsWidget(0),
67 m_historyCombo(0)
69 setHasConfigurationInterface(true);
70 setAspectRatioMode(Plasma::IgnoreAspectRatio);
72 m_layout = 0;
73 resize(500,500);
74 if (args.count() > 0) {
75 m_url = KUrl(args.value(0).toString());
77 setPopupIcon("konqueror");
80 QGraphicsWidget *WebBrowser::graphicsWidget()
82 if (m_graphicsWidget) {
83 return m_graphicsWidget;
86 KConfigGroup cg = config();
89 m_layout = new QGraphicsLinearLayout(Qt::Vertical);
90 m_toolbarLayout = new QGraphicsLinearLayout(Qt::Horizontal);
91 m_statusbarLayout = new QGraphicsLinearLayout(Qt::Horizontal);
93 m_back = addTool("go-previous", m_toolbarLayout);
94 m_forward = addTool("go-next", m_toolbarLayout);
96 m_historyCombo = new Plasma::HistoryComboBox(this);
97 m_historyCombo->setZValue(999);
98 m_historyCombo->setDuplicatesEnabled(false);
99 m_pixmapProvider = new KUrlPixmapProvider;
100 m_historyCombo->nativeWidget()->setPixmapProvider(m_pixmapProvider);
102 m_toolbarLayout->addItem(m_historyCombo);
103 m_go = addTool("go-jump-locationbar", m_toolbarLayout);
104 m_goAction = m_go->action();
105 m_reloadAction = new QAction(KIcon("view-refresh"), QString(), this);
107 m_layout->addItem(m_toolbarLayout);
110 m_browser = new Plasma::WebView(this);
111 m_browser->setPreferredSize(400, 400);
112 m_browser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
115 m_layout->addItem(m_browser);
117 //bookmarks
118 m_bookmarkManager = KBookmarkManager::userBookmarksManager();
119 connect(m_bookmarkManager, SIGNAL(changed(const QString, const QString)), this, SLOT(bookmarksModelInit()));
120 bookmarksModelInit();
122 m_bookmarksView = new Plasma::TreeView(this);
123 m_bookmarksView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
124 m_bookmarksView->setModel(m_bookmarkModel);
125 m_bookmarksView->nativeWidget()->setHeaderHidden(true);
126 //m_bookmarksView->nativeWidget()->viewport()->setAutoFillBackground(false);
127 m_bookmarksView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
128 m_bookmarksView->hide();
129 //FIXME: this is probably a Qt bug, QGraphicslayout always behaves as the hidden element is present, unlike QLayouts
130 m_bookmarksView->setMaximumHeight(0);
131 m_layout->addItem(m_bookmarksView);
133 m_bookmarksDelegate = new BookmarksDelegate(this);
134 m_bookmarksView->nativeWidget()->setItemDelegate(m_bookmarksDelegate);
136 connect(m_bookmarksDelegate, SIGNAL(destroyBookmark(const QModelIndex &)), this, SLOT(removeBookmark(const QModelIndex &)));
138 m_layout->addItem(m_statusbarLayout);
140 m_addBookmark = addTool("bookmark-new", m_statusbarLayout);
141 m_addBookmarkAction = m_addBookmark->action();
142 m_removeBookmarkAction = new QAction(KIcon("list-remove"), QString(), this);
143 m_organizeBookmarks = addTool("bookmarks-organize", m_statusbarLayout);
146 m_progress = new Plasma::Meter(this);
147 m_progress->setMeterType(Plasma::Meter::BarMeterHorizontal);
148 m_progress->setMinimum(0);
149 m_progress->setMaximum(100);
150 m_statusbarLayout->addItem(m_progress);
151 m_stop = addTool("process-stop", m_statusbarLayout);
153 m_zoom = new Plasma::Slider(this);
154 m_zoom->setMaximum(100);
155 m_zoom->setMinimum(0);
156 m_zoom->setValue(50);
157 m_zoom->setOrientation(Qt::Horizontal);
158 m_zoom->hide();
159 m_zoom->setMaximumWidth(0);
160 m_statusbarLayout->addItem(m_zoom);
161 connect(m_zoom, SIGNAL(valueChanged(int)), this, SLOT(zoom(int)));
163 if (!m_url.isValid()) {
164 m_url = KUrl(cg.readEntry("Url", "http://www.kde.org"));
165 m_verticalScrollValue = cg.readEntry("VerticalScrollValue", 0);
166 m_horizontalScrollValue = cg.readEntry("HorizontalScrollValue", 0);
168 m_browser->setUrl(m_url);
169 m_browser->update();
171 m_autoRefresh = cg.readEntry("autoRefresh", false);
172 m_autoRefreshInterval = qMax(2, cg.readEntry("autoRefreshInterval", 5));
174 if (m_autoRefresh) {
175 m_autoRefreshTimer = new QTimer(this);
176 m_autoRefreshTimer->start(m_autoRefreshInterval*60*1000);
177 connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(reload()));
180 connect(m_back->action(), SIGNAL(triggered()), this, SLOT(back()));
181 connect(m_forward->action(), SIGNAL(triggered()), this, SLOT(forward()));
182 connect(m_reloadAction, SIGNAL(triggered()), this, SLOT(reload()));
183 connect(m_goAction, SIGNAL(triggered()), this, SLOT(returnPressed()));
184 connect(m_stop->action(), SIGNAL(triggered()), m_browser->page()->action(QWebPage::Stop), SLOT(trigger()));
186 connect(m_historyCombo, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
187 connect(m_historyCombo, SIGNAL(activated(int)), this, SLOT(returnPressed()));
188 connect(m_historyCombo, SIGNAL(activated(const QString&)), this, SLOT(comboTextChanged(const QString&)));
189 connect(m_browser->page()->mainFrame(), SIGNAL(urlChanged(const QUrl &)), this, SLOT(urlChanged(const QUrl &)));
190 connect(m_browser, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int)));
192 connect(m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()));
193 connect(m_removeBookmarkAction, SIGNAL(triggered()), this, SLOT(removeBookmark()));
194 connect(m_organizeBookmarks->action(), SIGNAL(triggered()), this, SLOT(bookmarksToggle()));
195 connect(m_bookmarksView->nativeWidget(), SIGNAL(clicked(const QModelIndex &)), this, SLOT(bookmarkClicked(const QModelIndex &)));
197 //Autocompletion stuff
198 m_completion = new KCompletion();
199 m_historyCombo->nativeWidget()->setCompletionObject(m_completion);
201 QStringList list = cg.readEntry("History list", QStringList());
202 m_historyCombo->setHistoryItems(list);
204 m_graphicsWidget = new QGraphicsWidget(this);
205 m_graphicsWidget->setLayout(m_layout);
207 m_back->setEnabled(m_browser->page()->history()->canGoBack());
208 m_forward->setEnabled(m_browser->page()->history()->canGoForward());
211 return m_graphicsWidget;
214 WebBrowser::~WebBrowser()
216 delete m_completion;
217 delete m_bookmarkManager;
218 delete m_bookmarkModel;
221 Plasma::IconWidget *WebBrowser::addTool(const QString &iconString, QGraphicsLinearLayout *layout)
223 Plasma::IconWidget *icon = new Plasma::IconWidget(this);
224 QAction *action = new QAction(KIcon(iconString), QString(), this);
225 icon->setAction(action);
226 icon->setPreferredSize(icon->sizeFromIconSize(IconSize(KIconLoader::Toolbar)));
227 layout->addItem(icon);
229 return icon;
232 void WebBrowser::bookmarksModelInit()
234 if (m_bookmarkModel) {
235 m_bookmarkModel->clear();
236 } else {
237 m_bookmarkModel = new QStandardItemModel;
240 fillGroup(0, m_bookmarkManager->root());
243 void WebBrowser::fillGroup(BookmarkItem *parentItem, const KBookmarkGroup &group)
245 KBookmark it = group.first();
247 while (!it.isNull()) {
248 BookmarkItem *bookmarkItem = new BookmarkItem(it);
249 bookmarkItem->setEditable(false);
251 if (it.isGroup()) {
252 KBookmarkGroup grp = it.toGroup();
253 fillGroup( bookmarkItem, grp );
257 if (parentItem) {
258 parentItem->appendRow(bookmarkItem);
259 } else {
260 m_bookmarkModel->appendRow(bookmarkItem);
263 it = m_bookmarkManager->root().next(it);
267 void WebBrowser::saveState(KConfigGroup &cg) const
269 cg.writeEntry("Url", m_url.prettyUrl());
271 if (m_historyCombo) {
272 const QStringList list = m_historyCombo->historyItems();
273 cg.writeEntry("History list", list);
276 if (m_browser) {
277 cg.writeEntry("VerticalScrollValue", m_browser->page()->mainFrame()->scrollBarValue(Qt::Vertical));
278 cg.writeEntry("HorizontalScrollValue", m_browser->page()->mainFrame()->scrollBarValue(Qt::Horizontal));
282 void WebBrowser::back()
284 m_browser->page()->history()->back();
287 void WebBrowser::forward()
289 m_browser->page()->history()->forward();
292 void WebBrowser::reload()
294 m_browser->setUrl(m_url);
297 void WebBrowser::returnPressed()
299 KUrl url(m_historyCombo->currentText());
302 KUriFilter::self()->filterUri( url );
304 m_verticalScrollValue = 0;
305 m_horizontalScrollValue = 0;
306 m_browser->setUrl(url);
310 void WebBrowser::urlChanged(const QUrl &url)
312 //ask for a favicon
313 Plasma::DataEngine *engine = dataEngine( "favicons" );
314 if (engine) {
315 //engine->disconnectSource( url.toString(), this );
316 engine->connectSource( url.toString(), this );
318 engine->query( url.toString() );
321 m_url = KUrl(url);
323 if (m_bookmarkModel->match(m_bookmarkModel->index(0,0), BookmarkItem::UrlRole, m_url.prettyUrl()).isEmpty()) {
324 m_addBookmark->setAction(m_addBookmarkAction);
325 } else {
326 m_addBookmark->setAction(m_removeBookmarkAction);
329 m_historyCombo->addToHistory(m_url.prettyUrl());
330 m_historyCombo->nativeWidget()->setCurrentIndex(0);
332 m_go->setAction(m_reloadAction);
334 KConfigGroup cg = config();
335 saveState(cg);
337 m_back->setEnabled(m_browser->page()->history()->canGoBack());
338 m_forward->setEnabled(m_browser->page()->history()->canGoForward());
341 void WebBrowser::comboTextChanged(const QString &string)
343 Q_UNUSED(string)
345 m_go->setAction(m_goAction);
348 void WebBrowser::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data )
350 //TODO: find a way to update bookmarks and history combobox here, at the moment the data engine
351 // is only used to save the icon files
352 if (source == m_historyCombo->currentText()) {
353 QPixmap favicon(QPixmap::fromImage(data["Icon"].value<QImage>()));
354 m_historyCombo->nativeWidget()->setItemIcon(m_historyCombo->nativeWidget()->currentIndex(), QIcon(favicon));
355 setPopupIcon(QIcon(favicon));
359 void WebBrowser::addBookmark()
361 KBookmark bookmark = m_bookmarkManager->root().addBookmark(m_browser->page()->mainFrame()->title(), m_url);
362 m_bookmarkManager->save();
364 BookmarkItem *bookmarkItem = new BookmarkItem(bookmark);
365 m_bookmarkModel->appendRow(bookmarkItem);
367 m_addBookmark->setAction(m_removeBookmarkAction);
370 void WebBrowser::removeBookmark(const QModelIndex &index)
372 BookmarkItem *item = dynamic_cast<BookmarkItem *>(m_bookmarkModel->itemFromIndex(index));
374 if (item) {
375 KBookmark bookmark = item->bookmark();
377 const QString text(i18nc("@info", "Do you really want to remove the bookmark to %1?", bookmark.url().host()));
378 const bool del = KMessageBox::warningContinueCancel(0,
379 text,
380 QString(),
381 KGuiItem(i18nc("@action:button", "Delete Bookmark"))
382 ) == KMessageBox::Continue;
384 if (!del) {
385 return;
388 bookmark.parentGroup().deleteBookmark(bookmark);
389 m_bookmarkManager->save();
392 if (item && item->parent()) {
393 item->parent()->removeRow(index.row());
394 } else {
395 m_bookmarkModel->removeRow(index.row());
400 void WebBrowser::removeBookmark()
402 QModelIndexList list = m_bookmarkModel->match(m_bookmarkModel->index(0,0), BookmarkItem::UrlRole, m_url.prettyUrl());
404 if (!list.isEmpty()) {
405 removeBookmark(list.first());
408 m_addBookmark->setAction(m_addBookmarkAction);
411 void WebBrowser::bookmarksToggle()
413 if (m_bookmarksView->isVisible()) {
414 m_bookmarksView->hide();
415 m_bookmarksView->setMaximumHeight(0);
416 m_browser->show();
417 m_browser->setMaximumHeight(INT_MAX);
418 } else {
419 m_bookmarksView->show();
420 m_bookmarksView->setMaximumHeight(INT_MAX);
421 m_browser->hide();
422 m_browser->setMaximumHeight(0);
426 void WebBrowser::bookmarkClicked(const QModelIndex &index)
428 QStandardItem *item = m_bookmarkModel->itemFromIndex(index);
430 if (item) {
431 KUrl url(item->data(BookmarkItem::UrlRole).value<QString>());
433 if (url.isValid()) {
434 m_browser->setUrl(url);
435 bookmarksToggle();
440 void WebBrowser::zoom(int value)
442 m_browser->mainFrame()->setTextSizeMultiplier((qreal)0.2 + ((qreal)value/(qreal)50));
445 void WebBrowser::loadProgress(int progress)
447 m_progress->setValue(progress);
448 m_progress->update();
450 if (progress == 100) {
451 m_progress->setMaximumWidth(0);
452 m_progress->hide();
453 m_stop->hide();
454 m_stop->setMaximumWidth(0);
455 m_zoom->show();
456 m_zoom->setMaximumWidth(INT_MAX);
457 m_statusbarLayout->invalidate();
459 m_browser->page()->mainFrame()->setScrollBarValue(Qt::Vertical, m_verticalScrollValue);
460 m_browser->page()->mainFrame()->setScrollBarValue(Qt::Horizontal, m_horizontalScrollValue);
461 } else {
462 m_progress->show();
463 m_stop->show();
464 m_stop->setMaximumWidth(INT_MAX);
465 m_progress->setMaximumWidth(INT_MAX);
466 m_zoom->setMaximumWidth(0);
467 m_zoom->hide();
468 m_statusbarLayout->invalidate();
472 void WebBrowser::createConfigurationInterface(KConfigDialog *parent)
474 QWidget *widget = new QWidget();
475 ui.setupUi(widget);
476 parent->addPage(widget, i18n("General"), icon());
477 connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
478 connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
480 ui.autoRefresh->setChecked(m_autoRefresh);
481 ui.autoRefreshInterval->setValue(m_autoRefreshInterval);
484 void WebBrowser::configAccepted()
486 KConfigGroup cg = config();
488 m_autoRefresh = ui.autoRefresh->isChecked();
489 m_autoRefreshInterval = ui.autoRefreshInterval->value();
491 cg.writeEntry("autoRefresh", m_autoRefresh);
492 cg.writeEntry("autoRefreshInterval", m_autoRefreshInterval);
494 if (m_autoRefresh) {
495 if (!m_autoRefreshTimer) {
496 m_autoRefreshTimer = new QTimer(this);
497 connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(reload()));
500 m_autoRefreshTimer->start(m_autoRefreshInterval*60*1000);
501 } else {
502 delete m_autoRefreshTimer;
503 m_autoRefreshTimer = 0;
506 emit configNeedsSaving();
509 #include "webbrowser.moc"