diff options
Diffstat (limited to 'src/parsers')
-rw-r--r-- | src/parsers/Makefile.am | 7 | ||||
-rw-r--r-- | src/parsers/filesearch.cpp | 52 | ||||
-rw-r--r-- | src/parsers/list.cpp | 69 | ||||
-rw-r--r-- | src/parsers/parsers.cpp | 64 | ||||
-rw-r--r-- | src/parsers/parsers.h | 91 | ||||
-rw-r--r-- | src/parsers/policy.cpp | 202 | ||||
-rw-r--r-- | src/parsers/qhtmlstream.h | 286 | ||||
-rw-r--r-- | src/parsers/search.cpp | 76 | ||||
-rw-r--r-- | src/parsers/show.cpp | 194 |
9 files changed, 1041 insertions, 0 deletions
diff --git a/src/parsers/Makefile.am b/src/parsers/Makefile.am new file mode 100644 index 0000000..9893dd4 --- /dev/null +++ b/src/parsers/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = $(all_includes) +METASOURCES = AUTO +libparsers_la_LDFLAGS = -avoid-version $(all_libraries) +noinst_LTLIBRARIES = libparsers.la +noinst_HEADERS = parsers.h qhtmlstream.h +libparsers_la_SOURCES = list.cpp search.cpp policy.cpp show.cpp parsers.cpp filesearch.cpp +libparsers_la_LIBADD = $(LIB_KIO) diff --git a/src/parsers/filesearch.cpp b/src/parsers/filesearch.cpp new file mode 100644 index 0000000..c0a7a36 --- /dev/null +++ b/src/parsers/filesearch.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ +#include "parsers.h" +#include "../apt.h" + +static QString + html_dpkgs_line_begin("<tr><td class=\"file\">%1</td><td>\n\t"), + html_dpkgs_line_end("\n</td></tr>\n"); + +namespace Parsers +{ + +void FileSearch::operator() (AptProtocol* slave, const QString & tag, const QString & value ) +{ + static QString buffer; + if (tag == "begin") + { + m_result_count = 0; + } + else if (tag == "error") + { + *slave << "<div class=\"error\">" + value + "</div>"; + } + else if (tag == "file") + { + if (m_result_count) + *slave << buffer + html_dpkgs_line_end; + + *slave << html_dpkgs_line_begin.arg(value); + ++m_result_count; + buffer = ""; + } + else if (tag == "package") + { + if (!buffer.isEmpty()) buffer = buffer + ", "; + buffer += "<a href=\"apt:/show?" + value + "\">" + value + "</a>"; + } + else if (tag == "end") + { + *slave << buffer + html_dpkgs_line_end; + buffer=""; + } +} + +} diff --git a/src/parsers/list.cpp b/src/parsers/list.cpp new file mode 100644 index 0000000..afaac7f --- /dev/null +++ b/src/parsers/list.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#include "parsers.h" +#include "../apt.h" + +#include <kio/slavebase.h> +#include <klocale.h> +#include <qregexp.h> +#include <kurl.h> + +namespace Parsers +{ + List::List(bool links) + : m_links(links) {} + + /** Parses the tokens sent by PackageManager::list */ + void List::operator() (AptProtocol* slave, const QString& tag, const QString& value ) + { + static QRegExp rx_manpage("/man/.*\\.\\d[^/]*$"); + + static QStringList files; + + if (tag == "begin") + { + m_result_count = 0; + } + else if (tag == "error") + { + *slave << "<div class=\"error\">" + value + "</div>"; + } + else if (tag == "file" && value != "/.") + { + if (m_links) + { + KURL url; + if (rx_manpage.search(value) >= 0) + url.setProtocol("man"); + else + url.setProtocol("file"); + + url.setPath(value); + + files += "<a href=\"" + url.htmlURL() + "\">" + value + "</a>"; + } + else + { + files += value; + } + + ++m_result_count; + } + else if (tag == "end") + { + files.sort(); + *slave << + "<div class=\"filelist\">\n" + files.join("\n<br>") + "\n</div>\n" + "<div class=\"footer\">" + i18n("%1 files in the package").arg(result_count()) + "</div>\n"; + files.clear(); + } + } +} diff --git a/src/parsers/parsers.cpp b/src/parsers/parsers.cpp new file mode 100644 index 0000000..2f959ce --- /dev/null +++ b/src/parsers/parsers.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#include "parsers.h" + +#include <kuserprofile.h> + +#include <kio/slavebase.h> +#include <qhtmlstream.h> +#include <qregexp.h> + +#include <stdlib.h> + +namespace Parsers +{ + static void print_czstring(KIO::SlaveBase& slave, const char* data, int len) + { + QByteArray nonull; + nonull.setRawData(data, len); + slave.data(nonull); + nonull.resetRawData(data, len); + } + void operator << (KIO::SlaveBase& slave, const QCString& string) + { print_czstring(slave, string.data(), string.size() - 1); } + void operator << (KIO::SlaveBase& slave, const QString& string) + { slave << string.utf8(); } + void operator << (KIO::SlaveBase& slave, const char* string) + { print_czstring(slave, string, strlen(string)); } + + + + Parser::Parser( ) {} + Parser::~Parser( ) {} + + void Parser::attribute_begin(QHtmlStream& stream, const QString& text) + { + stream + << block("tr") << endl + << block("td") << param("class") << "attname" << data() + << text + << close() << endl + << block("td"); + } + void Parser::attribute_end(QHtmlStream& stream) + { stream << close() << endl << close(); } + +// void Parser::operator ( )( KIO::SlaveBase * /*slave*/, +// const QString & /*tag*/, const QString & /*value*/ ) +// {} + + QString mangle_version(QString version) + { return "version_" + version.replace(QRegExp("[-:\\.\\+]"), QString("_")); } + +} + + + diff --git a/src/parsers/parsers.h b/src/parsers/parsers.h new file mode 100644 index 0000000..26e0113 --- /dev/null +++ b/src/parsers/parsers.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#ifndef PARSERS_H +#define PARSERS_H + +#include <qstring.h> + +namespace KIO +{ + class SlaveBase; +} +class QHtmlStream; +class AptProtocol; + +/** Here are defined the functional objects that takes the tokens + * sent by AptCache and PackageManager objects, and produces HTML */ +namespace Parsers +{ + class Parser + { + protected: + int m_result_count; + + static void attribute_begin(QHtmlStream& stream, const QString& text); + static void attribute_end(QHtmlStream& stream); + + public: + Parser(); + virtual ~Parser(); + int result_count() const { return m_result_count; } + virtual void operator () (AptProtocol* slave, const QString& tag, const QString& value) = 0; + }; + + class Search : public Parser + { + public: + void operator () (AptProtocol* slave, const QString& tag, const QString& value); + }; + + class List : public Parser + { + bool m_links; + public: + List(bool show_links); + void operator () (AptProtocol* slave, const QString& tag, const QString& value); + }; + + class FileSearch : public Parser + { + public: + void operator () (AptProtocol* slave, const QString& tag, const QString& value); + }; + + class Show : public Parser + { + QString m_package, m_installed; + bool m_act; + + public: + Show(const QString& package, const QString& installed, bool act); + void operator () (AptProtocol* slave, const QString& tag, const QString& value); + }; + + class Policy : public Parser + { + QString m_package, m_installed; + bool m_has_adept_batch; + bool m_act; + + public: + Policy(const QString& package, bool act); + QString getInstalled() const { return m_installed; } + void operator () (AptProtocol* slave, const QString& tag, const QString& value); + }; + + void operator << (KIO::SlaveBase& slave, const QCString& string); + void operator << (KIO::SlaveBase& slave, const QString& string); + void operator << (KIO::SlaveBase& slave, const char* string); + + QString mangle_version(QString version); +} + +#endif diff --git a/src/parsers/policy.cpp b/src/parsers/policy.cpp new file mode 100644 index 0000000..ad31b7f --- /dev/null +++ b/src/parsers/policy.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#include "parsers.h" +#include "../apt.h" + +#include <klocale.h> +#include <kdebug.h> +#include <qhtmlstream.h> +#include <qregexp.h> + +static void policy_begin(QHtmlStream& stream) +{ + stream + << block("div") << endl + << block("table", "policy") << endl + << block("tr") << block("td") << endl + << block("table", "curver") << endl + << block("tbody"); +} + +static void add_button(QHtmlStream& stream, const QString& mode, const QString& text, const QString& package) +{ + stream + << block("form") + << param("action") << "apt:/" + << param("method") << "get" << endl + << block("p") << endl + << tag("input") + << param("type") << "hidden" + << param("name") << "get" + << param("value") << mode << endl + << tag("input") + << param("type") << "hidden" + << param("name") << "package" + << param("value") << package << endl + << tag("input") + << param("type") << "submit" + << param("value") << text << endl + << close() + << close() << endl; +} + +static void add_version_link(QHtmlStream& stream, AptProtocol* slave, const QString& package, const QString& version) +{ + KURL url(slave->buildURL("show", package)); + url.setHTMLRef(Parsers::mangle_version(version)); + + stream + << block("a", "vtable-version") + << param("href") << url.htmlURL() + << data() << version + << close(); +} + +namespace Parsers +{ + +Policy::Policy(const QString& package, bool act) + : m_package(package), m_act(false) +{ + m_act = act; +} + +void Policy::operator() (AptProtocol* slave, const QString& type, const QString& value) +{ + static bool first_version = false, received_sth = false; + static QString buffer; + static QHtmlStream* stream; + + static QRegExp rx_notinstalled("(none)"); + + kdDebug() << "policy : " << type << " " << value << endl; + + if (type == "begin") + { + stream = new QHtmlStream(&buffer); + policy_begin(*stream); + } + else if (type == "installed") + { + received_sth = true; + + attribute_begin(*stream, i18n("Installed")); + if (rx_notinstalled.match(value) >= 0) + { + m_installed = QString::null; + *stream << i18n("no"); + } + else + { + m_installed = value.stripWhiteSpace(); + add_version_link(*stream, slave, m_package, m_installed); + } + attribute_end(*stream); + } + else if (type == "candidate") + { + received_sth = true; + + bool has_candidate = (rx_notinstalled.match(value) == -1); + + if (m_act && has_candidate) + { + *stream + << block("tr") << endl + << block("td") << param("colspan") << 2 << endl; + + if (m_installed.isEmpty()) + add_button(*stream, "install", i18n("Install"), m_package); + else + add_button(*stream, "remove", i18n("Remove"), m_package); + *stream << close() << close() << endl; + } + + attribute_begin(*stream, i18n("Candidate")); + if (has_candidate) + add_version_link(*stream, slave, m_package, value); + else + *stream << i18n("none"); + attribute_end(*stream); + + if (m_act && has_candidate + && !m_installed.isEmpty() && m_installed != value) + { + *stream + << block("tr") << endl + << block("td") << param("colspan") << 2 << endl; + add_button(*stream, "install", i18n("Upgrade"), m_package); + *stream << close() << close() << endl; + } + } + else if (type == "version_table") + { + received_sth = true; + + *stream + << close() << close() << endl // tbody, table, form + << close() << endl; // td + + first_version = true; + } + else if (type == "version") + { + QString version = value.section(' ', 0, 0); + QString pin = value.section(' ', 1, 1); + + if (first_version) + { + *stream + << block("td") << endl + << block("div", "vtable") << endl + << block("div", "header") << i18n("Version Table") << close() << endl + << block("div", "versions") << endl; + } /*else { + *stream << close() << close(); + }*/ + + QString version_link; + version_link = "<a href=\"apt:/show?" + m_package + "#" + mangle_version(version) + "\">" + + version + "</a>"; + + *stream << tag("br") << endl; + add_version_link(*stream, slave, m_package, version); + *stream << "[Pin " << block("span", "version-pin") << pin << close() << "]"; + + first_version = false; + } + else if (type == "location") + { + QStringList sections = QStringList::split(' ', value); + QString pin = sections.first(); + sections.pop_front(); + // remove the "Packages" field if it is here + if (sections.last() == "Packages") + sections.pop_back(); + + *stream << tag("br") << endl; + *stream << block("span", "location-pin") << pin << close() << sections.join(" ") << endl; + } + else if (type == "end") + { + if (received_sth) + { + *stream << close_all() << endl; + *slave << buffer; + } + + buffer = QString::null; + received_sth = false; + delete stream; + } +} + +} diff --git a/src/parsers/qhtmlstream.h b/src/parsers/qhtmlstream.h new file mode 100644 index 0000000..330f9d5 --- /dev/null +++ b/src/parsers/qhtmlstream.h @@ -0,0 +1,286 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ +#ifndef QHtmlStream_H +#define QHtmlStream_H + +#include <qtextstream.h> +#include <qstringlist.h> + +class QHtmlStream; +class QHtmlStreamManip; + +/** +@author Sylvain Joyeux +*/ + +class QHtmlStreamManip +{ +protected: + virtual void apply(QHtmlStream& stream) const = 0; + +public: + virtual ~QHtmlStreamManip() {}; + void operator () (QHtmlStream& stream) const + { apply(stream); } +}; + +class QHtmlStream +{ + QTextOStream m_stream; + + enum States + { + NORMAL_FLOW, + TAG, + BLOCK, + PARAM + }; + int m_state, m_enclosing_state; + + bool m_newline; + QString m_indent; + QStringList m_blockstack; + + void finalize_open() + { + if (m_state == PARAM) + m_state = m_enclosing_state; + + if (m_state == BLOCK) + m_stream << ">"; + else if (m_state == TAG) + m_stream << " />"; + + m_state = NORMAL_FLOW; + } + + void indent() + { + if (m_newline) + { + m_stream << m_indent; + m_newline = false; + } + } + + template<class T> + QHtmlStream& output(const T& o) + { + indent(); + + if (m_state == PARAM) + { + m_stream << "=\"" << o << "\""; + m_state = m_enclosing_state; + return *this; + } + + if (m_state == BLOCK) + { + m_stream << ">"; + m_state = NORMAL_FLOW; + } + else if (m_state == TAG) + { + m_stream << "/>"; + m_state = NORMAL_FLOW; + } + m_stream << o; + + return *this; + } + +public: + QHtmlStream(QString* buffer) + : m_stream(buffer), m_state(NORMAL_FLOW), m_newline(true) {} + ~QHtmlStream() {} + + void tag(const QString& name, const QString& cl, const QString& id) + { + finalize_open(); + indent(); + + m_stream << '<' << name; + m_state = TAG; + + if (!cl.isEmpty()) + m_stream << " class=\"" << cl << "\""; + if (!id.isEmpty()) + m_stream << " id=\"" << id << "\""; + } + + void block(const QString& name, const QString& cl, const QString& id) + { + finalize_open(); + indent(); + + m_stream << '<' << name; + m_indent += '\t'; + m_blockstack.push_front(name); + m_state = BLOCK; + + if (!cl.isEmpty()) + m_stream << " class=\"" << cl << "\""; + if (!id.isEmpty()) + m_stream << " id=\"" << id << "\""; + } + + void parameter(const QString& param_name) + { + if (m_state == NORMAL_FLOW) return; + + m_stream << " " << param_name; + m_enclosing_state = m_state; + m_state = PARAM; + } + + void close() + { + finalize_open(); + + m_indent.truncate(m_indent.length() - 1); + indent(); + m_stream << "</" << m_blockstack.first() << ">"; + m_blockstack.pop_front(); + } + void close_all(bool indent) + { + while( ! m_blockstack.empty() ) + { + if (indent) + (*this) << endl; + close(); + } + } + + void data() + { + finalize_open(); + } + + QHtmlStream & operator<< ( QChar c ) { return output(c); } + QHtmlStream & operator<< ( char c ) { return output(c); } + QHtmlStream & operator<< ( signed short i ) { return output(i); } + QHtmlStream & operator<< ( unsigned short i ) { return output(i); } + QHtmlStream & operator<< ( signed int i ) { return output(i); } + QHtmlStream & operator<< ( unsigned int i ) { return output(i); } + QHtmlStream & operator<< ( signed long i ) { return output(i); } + QHtmlStream & operator<< ( unsigned long i ) { return output(i); } + QHtmlStream & operator<< ( float f ) { return output(f); } + QHtmlStream & operator<< ( double f ) { return output(f); } + QHtmlStream & operator<< ( const char * s ) { return output(s); } + QHtmlStream & operator<< ( const QString & s ) { return output(s); } + QHtmlStream & operator<< ( const QCString & s ) { return output(s); } + + QHtmlStream & operator<< ( const QHtmlStreamManip& op ) + { + op(*this); + return *this; + } + + QHtmlStream & operator<< (QTSManip m) + { + finalize_open(); + m_stream << m; + return (*this); + } + + QHtmlStream & operator<< (QTSFUNC f) + { + finalize_open(); + int old_flags = m_stream.flags(); + m_stream << f; + if (old_flags == m_stream.flags()) + m_newline = true; + return (*this); + } +}; + +/*************************************************************************************** +* Stream manipulators +*/ + +class QHtmlStreamManip0 : public QHtmlStreamManip +{ +public: + typedef void (QHtmlStream::*Method)(); + +private: + Method m_method; + + void apply (QHtmlStream& stream) const + { (stream.*m_method)(); } + +public: + QHtmlStreamManip0(Method m) + : m_method(m) {} +}; + +class QHtmlStreamManip1 : public QHtmlStreamManip +{ +public: + typedef void (QHtmlStream::*Method)(const QString& param); + +private: + Method m_method; + QString m_param; + + void apply(QHtmlStream& stream) const + { (stream.*m_method)(m_param); } + +public: + QHtmlStreamManip1(Method m, const QString& param) + : m_method(m), m_param(param) {} +}; + +class QHtmlStreamManip3 : public QHtmlStreamManip +{ +public: + typedef void (QHtmlStream::*Method)(const QString& param0, const QString& param1, const QString& param2); + +private: + Method m_method; + QString m_param0, m_param1, m_param2; + + void apply(QHtmlStream& stream) const + { (stream.*m_method)(m_param0, m_param1, m_param2); } + +public: + QHtmlStreamManip3(Method m, const QString& param0, const QString& param1, const QString& param2) + : m_method(m), + m_param0(param0), m_param1(param1), m_param2(param2) {} +}; + +class CloseAll : public QHtmlStreamManip +{ +private: + bool m_indent; + void apply(QHtmlStream& stream) const + { stream.close_all(m_indent); } +public: + CloseAll(bool indent) : m_indent(indent) {} +}; + +inline QHtmlStreamManip3 tag(const QString& name, const QString& cl = QString::null, const QString& id = QString::null) +{ return QHtmlStreamManip3(&QHtmlStream::tag, name, cl, id); } +inline QHtmlStreamManip3 block(const QString& name, const QString& cl = QString::null, const QString& id = QString::null) +{ return QHtmlStreamManip3(&QHtmlStream::block, name, cl, id); } + +inline QHtmlStreamManip1 param(const QString& name) +{ return QHtmlStreamManip1(&QHtmlStream::parameter, name); } + +inline QHtmlStreamManip0 close() +{ return QHtmlStreamManip0(&QHtmlStream::close); } +inline QHtmlStreamManip0 data() +{ return QHtmlStreamManip0(&QHtmlStream::data); } +inline CloseAll close_all(bool indent = true) +{ return CloseAll(indent); } + +#endif diff --git a/src/parsers/search.cpp b/src/parsers/search.cpp new file mode 100644 index 0000000..0d0a952 --- /dev/null +++ b/src/parsers/search.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#include "parsers.h" +#include "../apt.h" + +#include "qhtmlstream.h" + +#include <kio/slavebase.h> + +namespace Parsers +{ +/** Parses the output of apt-cache search */ +void Search::operator() (AptProtocol* slave, const QString& tag, const QString& value) +{ + static QMap<QString, QString> results; + static QString cur_package; + static QString query; + + if (tag == "begin") + { + query = value; + m_result_count = 0; + } + else if (tag == "package") + { + ++m_result_count; + cur_package = value; + } + else if (tag == "short_desc") + { + results[cur_package] = value; + } + else if (tag == "end") + { + // We separate results whose package name matches the query + // and those who matches only with the description + QString normal, special; + QHtmlStream sstream(&special), nstream(&normal); + + // QMap iteration sorts wrt the key < operator + // with QStrings, it means case insensitive sort + QMap<QString, QString>::ConstIterator i; + for (i = results.begin(); i != results.end(); ++i) + { + const QString key = i.key(); + QHtmlStream* stream = &nstream; + if (key == query) + stream = &sstream; + + (*stream) + << block("tr") + << block("td") + << block("a") << param("href") << "apt:/show?" + key + << key + << close() + << close() << block("td") << *i << close() << endl + << close() << endl; + } + + if (!special.isEmpty()) + *slave << QString("<table>") + special + QString("</table>\n<hr>\n"); + *slave << QString("<table>") + normal + QString("</table>"); + + results.clear(); + } +} +} + diff --git a/src/parsers/show.cpp b/src/parsers/show.cpp new file mode 100644 index 0000000..0a1c503 --- /dev/null +++ b/src/parsers/show.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** + * Copyright (C) 2003 by Sylvain Joyeux * + * [email protected] * + * * + * 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. * + ***************************************************************************/ + +#include "parsers.h" +#include "../apt.h" + +#include <klocale.h> +#include <qregexp.h> + +static const QString + html_attribute_begin("<tr><td class=\"attname\">%1</td>\n\t<td>\n\t\t"), + html_attribute_classed("<tr class=\"%1\"><td class=\"attname\">%2</td>\n\t<td>\n\t\t"), + html_attribute_end("\n\t</td>\n</tr>\n"); + +// Converts the special chars in orig into its HTML equivalents +static QString text2html(const QString& orig) +{ QString ret(orig); + ret = ret.replace("<(?!a href)", "<"); + //ret = ret.replace( QRegExp("\n"), "<br />\n"); + return ret; +} + +static void close_indent(int indent, QString& buffer) +{ + if (buffer.isEmpty()) return; + if (indent) + buffer += "\n\t\t</div>"; +} +static void close_item(int indent, QString& buffer) +{ + if (buffer.isEmpty()) return; + close_indent(indent, buffer); + buffer += html_attribute_end; +} + +static void close_table(const QString& version, int indent, QString& buffer) +{ + if (buffer.isEmpty()) return; + close_item(indent, buffer); + buffer = version + "<table class=\"version\">\n" + buffer + "</table>\n"; +} + +static QString version_header_link(const KURL& url, const QString& name) +{ return QString("\t<a class=\"links\" href=\"" + url.htmlURL() + "\">" + name + "</a>\n"); } + +namespace Parsers +{ + +Show::Show(const QString& package, const QString& installed_version, bool act) + : m_package(package), m_installed(installed_version), m_act(false) +{ + m_act = act; +} + +void Show::operator() (AptProtocol* slave, const QString& tag, const QString& value) +{ + // Since we want to show the version first, we should wait for it + // before sending anything + static QString version; + static QString buffer; + static QString attribute; + static int indent; + static bool multiline = false; + static bool first_line = false, new_paragraph = true; + + if (tag == "begin" || tag == "package" || tag == "end") + { + if (multiline && !new_paragraph) + buffer += "</p>"; + + if (tag == "begin") + m_result_count = 0; + else + { + m_result_count += (tag == "package"); + + close_table(version, indent, buffer); + if (!buffer.isEmpty()) *slave << buffer; + } + + // init the state variables for the next package + buffer = ""; + indent = 0; + first_line = false; + new_paragraph = true; + } + else if (tag == "field") + { + if (multiline && !new_paragraph) + buffer += "</p>"; + + attribute = value; + if (value == "Depends" || value == "Description") + { + close_item(indent, buffer); + buffer += + html_attribute_begin.arg(value) + + " "; + + close_item(indent, buffer); + buffer += html_attribute_begin.arg(" "); + } + else if (value != "Version" && value != "Package") + { + close_item(indent, buffer); + buffer += html_attribute_begin.arg(value); + } + + if (value == "Description") + { + multiline = true; + new_paragraph = true; + first_line = true; + } + else + { + multiline = false; + } + } + else if (tag == "indent") + { + close_indent(indent, buffer); + + int new_indent = value.toInt(); + if (new_indent) + buffer += "\n\t<div style=\"margin-left: " + value + "em\">"; + indent = new_indent; + } + else if (tag == "data" && attribute == "Version") + { + KURL action ("apt:/get"); + + QString item_id = mangle_version(value); + if (value == m_installed) + { + action.setQuery("remove"); + version = QString("<div class=\"version-header-installed\" id=\"%1\">").arg(item_id) + + i18n("Installed version %1").arg(value); + } + else + { + action.setQuery("install"); + version = QString("<div class=\"version-header\" id=\"%1\">").arg(item_id) + + i18n("Version %1").arg(value); + } + + action.addQueryItem("package", m_package); + action.addQueryItem("version", value); + + if (m_act) + { + if (value == m_installed) + version += version_header_link(action, i18n("Remove")); + else + version += version_header_link(action, i18n("Install")); + } + version += "</div>\n"; + + } + else if (tag == "data") + { + if (multiline) + { + static const QRegExp rx_empty("^\\s*$"); + if (rx_empty.exactMatch(value)) + { + buffer += "</p>"; + new_paragraph = true; + } + else if (first_line) + { + new_paragraph = true; + first_line = false; + } + else if (new_paragraph) + { + buffer += "<p>"; + new_paragraph = false; + } + } + buffer += text2html(QString(value).replace(QRegExp("(http://\\S+)"),QString("<a href=\"\\1\">\\1</a>"))); + } + else if (tag == "package_link") + buffer += "<a href=\"" + slave->buildURL("show", value).htmlURL() + "\">" + value + "</a>"; +} + +} |