/* This file is part of Akregator. Copyright (C) 2004 Sashmit Bhaduri 2005 Frank Osterfeld 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 TQt, and distribute the resulting executable, without including the source code for TQt in the source distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "aboutdata.h" #include "akregator_run.h" #include "akregatorconfig.h" #include "articleviewer.h" #include "feed.h" #include "folder.h" #include "article.h" #include "treenode.h" #include "treenodevisitor.h" #include "tagnode.h" #include "utils.h" namespace Akregator { // from kmail::headerstyle.cpp static inline TQString directionOf(const TQString &str) { return str.isRightToLeft() ? "rtl" : "ltr" ; } class ArticleViewer::ShowSummaryVisitor : public TreeNodeVisitor { public: ShowSummaryVisitor(ArticleViewer* view) : m_view(view) {} virtual bool visitFeed(Feed* node) { m_view->m_link = TQString(); TQString text; text = TQString("
\n").arg(TQApplication::reverseLayout() ? "rtl" : "ltr"); text += TQString("
").arg(directionOf(Utils::stripTags(node->title()))); text += node->title(); if(node->unread() == 0) text += i18n(" (no unread articles)"); else text += i18n(" (1 unread article)", " (%n unread articles)", node->unread()); text += "
\n"; // headertitle text += "
\n"; // /headerbox if (!node->image().isNull()) // image { text += TQString("
"); TQString url=node->xmlUrl(); TQString file = url.tqreplace("/", "_").tqreplace(":", "_"); KURL u(m_view->m_imageDir); u.setFileName(file); text += TQString("\n").arg(node->htmlUrl()).arg(u.url()); } else text += "
"; if( !node->description().isEmpty() ) { text += TQString("
").arg(Utils::stripTags(directionOf(node->description()))); text += i18n("Description: %1

").arg(node->description()); text += "
\n"; // /description } if ( !node->htmlUrl().isEmpty() ) { text += TQString("
").arg(directionOf(node->htmlUrl())); text += i18n("Homepage: %2").arg(node->htmlUrl()).arg(node->htmlUrl()); text += "
\n"; // / link } //text += i18n("Unread articles: %1").arg(node->unread()); text += "
"; // /body m_view->renderContent(text); return true; } virtual bool visitFolder(Folder* node) { m_view->m_link = TQString(); TQString text; text = TQString("
\n").arg(TQApplication::reverseLayout() ? "rtl" : "ltr"); text += TQString("
%2").arg(directionOf(Utils::stripTags(node->title()))).arg(node->title()); if(node->unread() == 0) text += i18n(" (no unread articles)"); else text += i18n(" (1 unread article)", " (%n unread articles)", node->unread()); text += TQString("
\n"); text += "
\n"; // /headerbox m_view->renderContent(text); return true; } virtual bool visitTagNode(TagNode* node) { m_view->m_link = TQString(); TQString text; text = TQString("
\n").arg(TQApplication::reverseLayout() ? "rtl" : "ltr"); text += TQString("
%2").arg(directionOf(Utils::stripTags(node->title()))).arg(node->title()); if(node->unread() == 0) text += i18n(" (no unread articles)"); else text += i18n(" (1 unread article)", " (%n unread articles)", node->unread()); text += TQString("
\n"); text += "
\n"; // /headerbox m_view->renderContent(text); return true; } private: ArticleViewer* m_view; }; ArticleViewer::ArticleViewer(TQWidget *tqparent, const char *name) : Viewer(tqparent, name), m_htmlFooter(), m_currentText(), m_node(0), m_viewMode(NormalView) { setJScriptEnabled(false); setJavaEnabled(false); setPluginsEnabled(false); m_showSummaryVisitor = new ShowSummaryVisitor(this); setXMLFile(locate("data", "akregator/articleviewer.rc"), true); generateNormalModeCSS(); generateCombinedModeCSS(); new KAction( i18n("&Scroll Up"), TQString(), "Up", this, TQT_SLOT(slotScrollUp()), actionCollection(), "articleviewer_scroll_up" ); new KAction( i18n("&Scroll Down"), TQString(), "Down", this, TQT_SLOT(slotScrollDown()), actionCollection(), "articleviewer_scroll_down" ); connect(this, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotSelectionChanged())); connect(kapp, TQT_SIGNAL(kdisplayPaletteChanged()), this, TQT_SLOT(slotPaletteOrFontChanged()) ); connect(kapp, TQT_SIGNAL(kdisplayFontChanged()), this, TQT_SLOT(slotPaletteOrFontChanged()) ); m_imageDir.setPath(KGlobal::dirs()->saveLocation("cache", "akregator/Media/")); m_htmlFooter = ""; } ArticleViewer::~ArticleViewer() { delete m_showSummaryVisitor; } void ArticleViewer::generateNormalModeCSS() { const TQColorGroup & cg = TQApplication::palette().active(); // from kmail::headerstyle.cpp m_normalModeCSS = TQString( "@media screen, print {" "body {\n" " font-family: \"%1\" ! important;\n" " font-size: %2 ! important;\n" " color: %3 ! important;\n" " background: %4 ! important;\n" "}\n\n").arg(Settings::standardFont()) .arg(TQString::number(pointsToPixel(Settings::mediumFontSize()))+"px") .arg(cg.text().name()) .arg(cg.base().name()); m_normalModeCSS += TQString( "a {\n" + TQString(" color: %1 ! important;\n") + TQString(!Settings::underlineLinks() ? " text-decoration: none ! important;\n" : "") + "}\n\n" +".headerbox {\n" +" background: %2 ! important;\n" +" color: %3 ! important;\n" +" border:1px solid #000;\n" +" margin-bottom: 10pt;\n" // +" width: 99%;\n" + "}\n\n") .arg(cg.link().name()) .arg(cg.background().name()) .arg(cg.text().name()); m_normalModeCSS += TQString(".headertitle a:link { color: %1 ! important; }\n" ".headertitle a:visited { color: %2 ! important; }\n" ".headertitle a:hover{ color: %3 ! important; }\n" ".headertitle a:active { color: %4 ! important; }\n") .arg(cg.highlightedText().name()) .arg(cg.highlightedText().name()) .arg(cg.highlightedText().name()) .arg(cg.highlightedText().name()); m_normalModeCSS += TQString( ".headertitle {\n" " background: %1 ! important;\n" " padding:2px;\n" " color: %2 ! important;\n" " font-weight: bold;\n" "}\n\n" ".header {\n" " font-weight: bold;\n" " padding:2px;\n" " margin-right: 5px;\n" "}\n\n" ".headertext {\n" "}\n\n" ".headimage {\n" " float: right;\n" " margin-left: 5px;\n" "}\n\n").arg(cg.highlight().name()) .arg(cg.highlightedText().name()); m_normalModeCSS += TQString( "body { clear: none; }\n\n" ".content {\n" " display: block;\n" " margin-bottom: 6px;\n" "}\n\n" // these rules make sure that there is no leading space between the header and the first of the text ".content > P:first-child {\n margin-top: 1px; }\n" ".content > DIV:first-child {\n margin-top: 1px; }\n" ".content > BR:first-child {\n display: none; }\n" "iframe {display: none !important; }\n" "frame {display: none !important; }\n" "frameset {display: none !important; }\n" "object {display: none !important; }\n" "applet {display: none !important; }\n" "}\n\n"); // @media screen, print } void ArticleViewer::generateCombinedModeCSS() { const TQColorGroup & cg = TQApplication::palette().active(); // from kmail::headerstyle.cpp m_combinedModeCSS = TQString ( // "