summaryrefslogtreecommitdiffstats
path: root/akregator/src/pageviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'akregator/src/pageviewer.cpp')
-rw-r--r--akregator/src/pageviewer.cpp514
1 files changed, 514 insertions, 0 deletions
diff --git a/akregator/src/pageviewer.cpp b/akregator/src/pageviewer.cpp
new file mode 100644
index 00000000..1a10b495
--- /dev/null
+++ b/akregator/src/pageviewer.cpp
@@ -0,0 +1,514 @@
+/*
+ This file is part of Akregator.
+
+ Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
+ 2005 Frank Osterfeld <frank.osterfeld at kdemail.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ As a special exception, permission is given to link this program
+ with any edition of Qt, and distribute the resulting executable,
+ without including the source code for Qt in the source distribution.
+*/
+
+#include "akregatorconfig.h"
+#include "akregator_run.h"
+#include "feediconmanager.h"
+#include "pageviewer.h"
+#include "viewer.h"
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kbookmark.h>
+#include <kbookmarkmanager.h>
+#include <kconfig.h>
+#include <kglobalsettings.h>
+#include <khtml_settings.h>
+#include <khtmlview.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kstandarddirs.h>
+#include <kstdaccel.h>
+#include <kparts/browserinterface.h>
+
+#include <qclipboard.h>
+#include <qcstring.h>
+#include <qdatastream.h>
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qmetaobject.h>
+#include <qscrollview.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <private/qucomextra_p.h>
+
+#include <cstdlib>
+using std::abs;
+
+namespace Akregator {
+
+
+// taken from KDevelop
+class PageViewer::HistoryEntry
+{
+ public:
+
+ KURL url;
+ QString title;
+ QByteArray state;
+ int id;
+
+ HistoryEntry() {}
+ HistoryEntry(const KURL& u, const QString& t=QString::null): url(u), title(t)
+ {
+ id = abs( QTime::currentTime().msecsTo( QTime() ) ); // nasty, but should provide a reasonably unique number
+ }
+
+};
+
+class PageViewer::PageViewerPrivate
+{
+ public:
+
+ QValueList<HistoryEntry> history;
+ QValueList<HistoryEntry>::Iterator current;
+
+ KToolBarPopupAction* backAction;
+ KToolBarPopupAction* forwardAction;
+ KAction* reloadAction;
+ KAction* stopAction;
+
+ QString caption;
+};
+
+
+PageViewer::PageViewer(QWidget *parent, const char *name)
+ : Viewer(parent, name), d(new PageViewerPrivate)
+{
+ // this hack is necessary since the part looks for []HTML Settings] in
+ // KGlobal::config() by default, which is wrong when running in Kontact
+ KHTMLSettings* s = const_cast<KHTMLSettings*> (settings());
+ s->init(Settings::self()->config());
+
+ setXMLFile(locate("data", "akregator/pageviewer.rc"), true);
+
+ QPair< KGuiItem, KGuiItem > backForward = KStdGuiItem::backAndForward();
+
+ d->backAction = new KToolBarPopupAction(backForward.first,
+ KStdAccel::shortcut(KStdAccel::Back), this,
+ SLOT(slotBack()), actionCollection(),
+ "pageviewer_back");
+
+ connect(d->backAction->popupMenu(), SIGNAL(aboutToShow()),
+ this, SLOT(slotBackAboutToShow()));
+ connect(d->backAction->popupMenu(), SIGNAL(activated(int)),
+ this, SLOT(slotPopupActivated(int)));
+
+
+ d->forwardAction = new KToolBarPopupAction(backForward.second,
+ KStdAccel::shortcut(KStdAccel::Forward),this,
+ SLOT(slotForward()), actionCollection(),
+ "pageviewer_forward");
+
+ connect(d->forwardAction->popupMenu(), SIGNAL(aboutToShow()),
+ this, SLOT(slotForwardAboutToShow()));
+ connect(d->forwardAction->popupMenu(), SIGNAL(activated(int)),
+ this, SLOT(slotPopupActivated(int)));
+
+ d->reloadAction = new KAction(i18n("Reload"), "reload", 0,
+ this, SLOT(slotReload()),
+ actionCollection(), "pageviewer_reload");
+ d->stopAction = new KAction(KStdGuiItem::guiItem(KStdGuiItem::Stop), 0,
+ this, SLOT(slotStop()),
+ actionCollection(), "pageviewer_stop");
+
+ //connect( this, SIGNAL(popupMenu(const QString &, const QPoint &)), this, SLOT(slotPopupMenu(const QString &, const QPoint &)));
+
+ d->backAction->setEnabled(false);
+ d->forwardAction->setEnabled(false);
+ d->stopAction->setEnabled(false);
+
+ connect( this, SIGNAL(setWindowCaption (const QString &)),
+ this, SLOT(slotSetCaption (const QString &)) );
+
+ connect(this, SIGNAL(started(KIO::Job *)), this, SLOT(slotStarted(KIO::Job* )));
+ connect(this, SIGNAL(completed()), this, SLOT(slotCompleted()));
+ connect(this, SIGNAL(canceled(const QString &)), this, SLOT(slotCancelled(const QString &)));
+
+ d->current = d->history.end();
+
+ // uncomment this to load konq plugins (doesn't work properly and clutters the GUI)
+ //loadPlugins( partObject(), this, instance() );
+
+}
+
+PageViewer::~PageViewer()
+{
+ delete d;
+ d = 0;
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::slotBack()
+{
+ if ( d->current != d->history.begin() )
+ {
+ QValueList<HistoryEntry>::Iterator tmp = d->current;
+ --tmp;
+ restoreHistoryEntry(tmp);
+ }
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::slotForward()
+{
+ if ( d->current != d->history.fromLast() && d->current != d->history.end() )
+ {
+ QValueList<HistoryEntry>::Iterator tmp = d->current;
+ ++tmp;
+ restoreHistoryEntry(tmp);
+ }
+}
+
+void PageViewer::slotBackAboutToShow()
+{
+ KPopupMenu *popup = d->backAction->popupMenu();
+ popup->clear();
+
+ if ( d->current == d->history.begin() )
+ return;
+
+ QValueList<HistoryEntry>::Iterator it = d->current;
+ --it;
+
+ int i = 0;
+ while( i < 10 )
+ {
+ if ( it == d->history.begin() )
+ {
+ popup->insertItem( (*it).title, (*it).id );
+ return;
+ }
+
+ popup->insertItem( (*it).title, (*it).id );
+ ++i;
+ --it;
+ }
+}
+
+void PageViewer::slotForwardAboutToShow()
+{
+ KPopupMenu *popup = d->forwardAction->popupMenu();
+ popup->clear();
+
+ if ( d->current == d->history.fromLast() )
+ return;
+
+ QValueList<HistoryEntry>::Iterator it = d->current;
+ ++it;
+
+ int i = 0;
+ while( i < 10 )
+ {
+ if ( it == d->history.fromLast() )
+ {
+ popup->insertItem( (*it).title, (*it).id );
+ return;
+ }
+
+ popup->insertItem( (*it).title, (*it).id );
+ ++i;
+ ++it;
+ }
+}
+
+
+void PageViewer::slotReload()
+{
+ openURL( url() );
+}
+
+void PageViewer::slotStop()
+{
+ closeURL();
+}
+
+bool PageViewer::openURL(const KURL& url)
+{
+ updateHistoryEntry(); // update old history entry before switching to the new one
+ emit started(0);
+
+ bool val = KHTMLPart::openURL(url);
+
+ addHistoryEntry(url); // add new URL to history
+
+ d->backAction->setEnabled( d->current != d->history.begin() );
+ d->forwardAction->setEnabled( d->current != d->history.fromLast() );
+
+ QString favicon = FeedIconManager::self()->iconLocation(url);
+ if (!favicon.isEmpty())
+ emit setTabIcon(QPixmap(KGlobal::dirs()->findResource("cache", favicon+".png")));
+ else
+ emit setTabIcon(SmallIcon("html"));
+
+ return val;
+}
+
+
+void PageViewer::slotOpenURLRequest(const KURL& url, const KParts::URLArgs& args)
+{
+ updateHistoryEntry();
+ if (args.doPost())
+ {
+ browserExtension()->setURLArgs(args);
+ openURL(url);
+ }
+
+}
+
+void PageViewer::slotPopupActivated( int id )
+{
+ QValueList<HistoryEntry>::Iterator it = d->history.begin();
+ while( it != d->history.end() )
+ {
+ if ( (*it).id == id )
+ {
+ restoreHistoryEntry(it);
+ return;
+ }
+ ++it;
+ }
+}
+
+void PageViewer::updateHistoryEntry()
+{
+ (*d->current).title = d->caption;
+ (*d->current).state = QByteArray(); // Start with empty buffer.
+ QDataStream stream( (*d->current).state, IO_WriteOnly);
+ browserExtension()->saveState(stream);
+}
+
+void PageViewer::restoreHistoryEntry(const QValueList<HistoryEntry>::Iterator& entry)
+{
+ updateHistoryEntry();
+
+ QDataStream stream( (*entry).state, IO_ReadOnly );
+ browserExtension()->restoreState( stream );
+ d->current = entry;
+ d->backAction->setEnabled( d->current != d->history.begin() );
+ d->forwardAction->setEnabled( d->current != d->history.fromLast() );
+ //openURL( entry.url ); // TODO read state
+
+
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::addHistoryEntry(const KURL& url)
+{
+ QValueList<HistoryEntry>::Iterator it = d->current;
+
+ // if We're not already the last entry, we truncate the list here before adding an entry
+ if ( it != d->history.end() && it != d->history.fromLast() )
+ {
+ d->history.erase( ++it, d->history.end() );
+ }
+ HistoryEntry newEntry( url, url.url() );
+
+ // Only save the new entry if it is different from the last
+ if ( newEntry.url != (*d->current).url )
+ {
+ d->history.append( newEntry );
+ d->current = d->history.fromLast();
+ }
+ updateHistoryEntry();
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::slotStarted( KIO::Job * )
+{
+ d->stopAction->setEnabled(true);
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::slotCompleted( )
+{
+ d->stopAction->setEnabled(false);
+}
+
+// Taken from KDevelop (lib/widgets/kdevhtmlpart.cpp)
+void PageViewer::slotCancelled( const QString & /*errMsg*/ )
+{
+ d->stopAction->setEnabled(false);
+}
+
+void PageViewer::urlSelected(const QString &url, int button, int state, const QString &_target, KParts::URLArgs args)
+{
+ if (url.startsWith(QString::fromLatin1( "javascript:" ), /*case-sensitive=*/false) )
+ {
+ KHTMLPart::urlSelected(url,button,state,_target,args);
+ }
+ else
+ {
+ if (button == LeftButton)
+ {
+ m_url = completeURL(url);
+ browserExtension()->setURLArgs(args);
+ slotOpenLinkInThisTab();
+ }
+ else
+ {
+ Viewer::urlSelected(url,button,state,_target,args);
+ }
+ }
+}
+
+void PageViewer::slotSetCaption(const QString& cap)
+{
+ d->caption = cap;
+ (*d->current).title = cap;
+}
+
+void PageViewer::slotPaletteOrFontChanged()
+{
+ kdDebug() << "PageViewer::slotPaletteOrFontChanged()" << endl;
+ // taken from KonqView (kdebase/konqueror/konq_view.cc)
+
+ QObject *obj = KParts::BrowserExtension::childObject(this);
+ if ( !obj ) // not all views have a browser extension !
+ return;
+
+ int id = obj->metaObject()->findSlot("reparseConfiguration()");
+ if (id == -1)
+ return;
+ QUObject o[1];
+
+ obj->qt_invoke(id, o);
+
+ // this hack is necessary since the part looks for []HTML Settings] in
+ // KGlobal::config() by default, which is wrong when running in Kontact
+ // NOTE: when running in Kontact, immediate updating doesn't work
+ KHTMLSettings* s = const_cast<KHTMLSettings*> (settings());
+ s->init(Settings::self()->config());
+}
+
+void PageViewer::slotGlobalBookmarkArticle()
+{
+ KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
+ KBookmarkGroup grp = mgr->root();
+ grp.addBookmark(mgr, d->caption, toplevelURL());
+ mgr->emitChanged(grp);
+ mgr->save();
+}
+
+
+void PageViewer::slotPopupMenu(KXMLGUIClient*, const QPoint& p, const KURL& kurl, const KParts::URLArgs&, KParts::BrowserExtension::PopupFlags kpf, mode_t)
+{
+ m_url = kurl;
+ QString url = kurl.url(); // maximal url confusion
+
+ const bool showReload = (kpf & KParts::BrowserExtension::ShowReload) != 0;
+ const bool showNavigationItems = (kpf & KParts::BrowserExtension::ShowNavigationItems) != 0;
+ const bool isLink = (kpf & (KParts::BrowserExtension::ShowNavigationItems | KParts::BrowserExtension::ShowTextSelectionItems)) == 0;
+ const bool isSelection = (kpf & KParts::BrowserExtension::ShowTextSelectionItems) != 0;
+
+ KPopupMenu popup(this->widget());
+
+ int idNewWindow = -2;
+ if (isLink)
+ {
+ idNewWindow = popup.insertItem(SmallIcon("tab_new"),i18n("Open Link in New &Tab"), this, SLOT(slotOpenLinkInForegroundTab()));
+ popup.setWhatsThis(idNewWindow, i18n("<b>Open Link in New Tab</b><p>Opens current link in a new tab."));
+ popup.insertItem(SmallIcon("window_new"), i18n("Open Link in External &Browser"), this, SLOT(slotOpenLinkInBrowser()));
+
+ popup.insertSeparator();
+ action("savelinkas")->plug(&popup);
+ KAction* copylinkaddress = action("copylinkaddress");
+ if (copylinkaddress)
+ {
+ copylinkaddress->plug( &popup);
+ //popup.insertSeparator();
+ }
+ }
+ else // we are not on a link
+ {
+ if (showNavigationItems)
+ {
+ d->backAction->plug( &popup );
+ d->forwardAction->plug( &popup );
+ }
+
+ if (showReload)
+ d->reloadAction->plug(&popup);
+
+ d->stopAction->plug(&popup);
+
+ popup.insertSeparator();
+
+ if (isSelection)
+ {
+ action("viewer_copy")->plug(&popup);
+ popup.insertSeparator();
+ }
+
+ KAction* incFontAction = this->action("incFontSizes");
+ KAction* decFontAction = this->action("decFontSizes");
+ if ( incFontAction && decFontAction )
+ {
+ incFontAction->plug( &popup );
+ decFontAction->plug( &popup );
+ popup.insertSeparator();
+ }
+
+ popup.insertItem(SmallIcon("window_new"), i18n("Open Page in External Browser"), this, SLOT(slotOpenLinkInBrowser()));
+
+ action("viewer_print")->plug(&popup);
+ popup.insertSeparator();
+
+ KAction *ac = action("setEncoding");
+ if (ac)
+ ac->plug(&popup);
+ popup.insertItem(SmallIcon("bookmark_add"),i18n("Add to Konqueror Bookmarks"), this, SLOT(slotGlobalBookmarkArticle()));
+ }
+
+ int r = popup.exec(p);
+
+ if (r == idNewWindow)
+ {
+ KURL kurl;
+ if (!KURL(url).path().startsWith("/"))
+ {
+ kdDebug() << "processing relative url: " << url << endl;
+ if (url.startsWith("#"))
+ {
+ kurl = KURL(PageViewer::url());
+ kurl.setRef(url.mid(1));
+ }
+ else
+ kurl = KURL(PageViewer::url().upURL().url(true)+url);
+ }
+ else
+ kurl = KURL(url);
+// kurl.addPath(url);
+ if (kurl.isValid()) {
+ //slotOpenInNewWindow(kurl);
+ }
+// ( kurl );
+ }
+}
+
+} // namespace Akregator
+
+#include "pageviewer.moc"