1 /***************************************************************************
2 * Copyright (C) 2008 Marco Martin <notmart@gmail.com> *
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. *
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. *
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"
24 #include <QGraphicsLinearLayout>
25 #include <QGraphicsProxyWidget>
26 #include <QGraphicsSceneMouseEvent>
27 #include <QStandardItemModel>
28 #include <QModelIndex>
34 #include <QWebHistory>
37 #include <KCompletion>
38 #include <KBookmarkManager>
39 #include <KIconLoader>
40 #include <KUrlPixmapProvider>
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
),
60 m_verticalScrollValue(0),
61 m_horizontalScrollValue(0),
65 m_autoRefreshTimer(0),
69 setHasConfigurationInterface(true);
70 setAspectRatioMode(Plasma::IgnoreAspectRatio
);
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
);
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
);
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
);
171 m_autoRefresh
= cg
.readEntry("autoRefresh", false);
172 m_autoRefreshInterval
= qMax(2, cg
.readEntry("autoRefreshInterval", 5));
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()
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
);
232 void WebBrowser::bookmarksModelInit()
234 if (m_bookmarkModel
) {
235 m_bookmarkModel
->clear();
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);
252 KBookmarkGroup grp
= it
.toGroup();
253 fillGroup( bookmarkItem
, grp
);
258 parentItem
->appendRow(bookmarkItem
);
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
);
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
)
313 Plasma::DataEngine
*engine
= dataEngine( "favicons" );
315 //engine->disconnectSource( url.toString(), this );
316 engine
->connectSource( url
.toString(), this );
318 engine
->query( url
.toString() );
323 if (m_bookmarkModel
->match(m_bookmarkModel
->index(0,0), BookmarkItem::UrlRole
, m_url
.prettyUrl()).isEmpty()) {
324 m_addBookmark
->setAction(m_addBookmarkAction
);
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();
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
)
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
));
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,
381 KGuiItem(i18nc("@action:button", "Delete Bookmark"))
382 ) == KMessageBox::Continue
;
388 bookmark
.parentGroup().deleteBookmark(bookmark
);
389 m_bookmarkManager
->save();
392 if (item
&& item
->parent()) {
393 item
->parent()->removeRow(index
.row());
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);
417 m_browser
->setMaximumHeight(INT_MAX
);
419 m_bookmarksView
->show();
420 m_bookmarksView
->setMaximumHeight(INT_MAX
);
422 m_browser
->setMaximumHeight(0);
426 void WebBrowser::bookmarkClicked(const QModelIndex
&index
)
428 QStandardItem
*item
= m_bookmarkModel
->itemFromIndex(index
);
431 KUrl
url(item
->data(BookmarkItem::UrlRole
).value
<QString
>());
434 m_browser
->setUrl(url
);
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);
454 m_stop
->setMaximumWidth(0);
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
);
464 m_stop
->setMaximumWidth(INT_MAX
);
465 m_progress
->setMaximumWidth(INT_MAX
);
466 m_zoom
->setMaximumWidth(0);
468 m_statusbarLayout
->invalidate();
472 void WebBrowser::createConfigurationInterface(KConfigDialog
*parent
)
474 QWidget
*widget
= new QWidget();
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
);
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);
502 delete m_autoRefreshTimer
;
503 m_autoRefreshTimer
= 0;
506 emit
configNeedsSaving();
509 #include "webbrowser.moc"