You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeaddons/konq-plugins/microformat/konqmficon.cpp

324 lines
9.6 KiB

/*
Copyright (C) 2004 Teemu Rytilahti <tpr@d5k.net>
Copyright (C) 2005 George Staikos <staikos@kde.org>
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 "konqmficon.h"
#include <dcopref.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <kiconloader.h>
#include <kparts/statusbarextension.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <kurllabel.h>
#include <tqcursor.h>
#include <tqstylesheet.h>
#include <tqtimer.h>
#include <tqtooltip.h>
typedef KGenericFactory<KonqMFIcon> KonqMFIconFactory;
K_EXPORT_COMPONENT_FACTORY(libmfkonqmficon,
KonqMFIconFactory("mfkonqmficon"))
KonqMFIcon::KonqMFIcon(TQObject *parent, const char *name, const TQStringList &)
: KParts::Plugin(parent, name), PluginBase(), m_part(0), m_mfIcon(0), m_statusBarEx(0), m_menu(0) {
KGlobal::locale()->insertCatalogue("mf_konqplugin");
m_part = dynamic_cast<KHTMLPart*>(parent);
if (!m_part) {
kdDebug() << "couldn't get part" << endl;
return;
}
TQTimer::singleShot(0, this, TQT_SLOT(waitPartToLoad()));
}
void KonqMFIcon::waitPartToLoad() {
connect(m_part, TQT_SIGNAL(completed()), this, TQT_SLOT(addMFIcon()));
connect(m_part, TQT_SIGNAL(completed(bool)), this, TQT_SLOT(addMFIcon())); // to make pages with metarefresh to work
connect(m_part, TQT_SIGNAL(started(KIO::Job *)), this, TQT_SLOT(removeMFIcon()));
}
KonqMFIcon::~KonqMFIcon() {
KGlobal::locale()->removeCatalogue("mf_konqplugin");
delete m_menu;
m_menu = 0L;
}
static TQString textForNode(DOM::Node node) {
TQString rc;
DOM::NodeList nl = node.childNodes();
for (unsigned int i = 0; i < nl.length(); ++i) {
DOM::Node n = nl.item(i);
if (n.nodeType() == DOM::Node::TEXT_NODE) {
rc += n.nodeValue().string();
}
}
// FIXME: entries need to be escaped for vcard/vevent
return rc.stripWhiteSpace();
}
static TQString extractAddress(DOM::Node node) {
TQString rc = ";;";
TQMap<TQString,TQString> entry;
DOM::NodeList nodes = node.childNodes();
unsigned int n = nodes.length();
for (unsigned int i = 0; i < n; ++i) {
DOM::Node node = nodes.item(i);
DOM::NamedNodeMap map = node.attributes();
for (unsigned int j = 0; j < map.length(); ++j) {
if (map.item(j).nodeName().string() != "class") {
continue;
}
TQString a = map.item(j).nodeValue().string();
if (a == "street-address") {
entry["street-address"] = textForNode(node);
} else if (a == "locality") {
entry["locality"] = textForNode(node);
} else if (a == "region") {
entry["region"] = textForNode(node);
} else if (a == "postal-code") {
entry["postal-code"] = textForNode(node);
}
}
}
rc += entry["street-address"] + ";" + entry["locality"] + ";" + entry["region"] + ";" + entry["postal-code"] + ";" + entry["country"];
return rc.stripWhiteSpace();
}
void KonqMFIcon::extractCard(DOM::Node node) {
TQString name, value;
DOM::NodeList nodes = node.childNodes();
unsigned int n = nodes.length();
value += "BEGIN:VCARD\nVERSION:3.0\n";
for (unsigned int i = 0; i < n; ++i) {
DOM::Node node = nodes.item(i);
DOM::NamedNodeMap map = node.attributes();
for (unsigned int j = 0; j < map.length(); ++j) {
if (map.item(j).nodeName().string() != "class") {
continue;
}
TQStringList l = TQStringList::split(' ', map.item(j).nodeValue().string());
for (TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
if (*it == "photo") {
} else if (*it == "adr") {
value += "ADR:" + extractAddress(node) + "\n";
} else if (*it == "tel") {
value += "TEL;TYPE=VOICE:" + textForNode(node) + "\n";
} else if (*it == "fn") {
name = textForNode(node);
value += "FN:" + name + "\n";
} else if (*it == "url") {
DOM::Node at = node.attributes().getNamedItem("href");
if (!at.isNull()) {
value += "URL:" + at.nodeValue().string().stripWhiteSpace() + "\n";
}
} else if (*it == "email") {
DOM::Node at = node.attributes().getNamedItem("href");
if (!at.isNull()) {
TQString v = at.nodeValue().string();
if (v.startsWith("mailto:")) {
v = v.mid(7);
}
value += "EMAIL:" + v.stripWhiteSpace() + "\n";
}
} else if (*it == "org") {
value += "ORG:" + textForNode(node) + "\n";
}
}
}
}
if (!name.isEmpty()) {
value += "END:VCARD\n";
_cards.append(tqMakePair(name, value));
}
}
void KonqMFIcon::extractEvent(DOM::Node node) {
TQString name, value = "BEGIN:VCALENDAR\nPRODID:-//Konqueror//EN\nVERSION:2.0\nBEGIN:VEVENT\n";
DOM::NodeList nodes = node.childNodes();
unsigned int n = nodes.length();
for (unsigned int i = 0; i < n; ++i) {
DOM::Node node = nodes.item(i);
DOM::NamedNodeMap map = node.attributes();
for (unsigned int j = 0; j < map.length(); ++j) {
if (map.item(j).nodeName().string() != "class") {
continue;
}
TQStringList l = TQStringList::split(' ', map.item(j).nodeValue().string());
for (TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
if (*it == "url") {
DOM::Node at = node.attributes().getNamedItem("href");
if (!at.isNull()) {
value += "URL:" + at.nodeValue().string().stripWhiteSpace() + "\n";
}
} else if (*it == "dtstart") {
DOM::Node at = node.attributes().getNamedItem("title");
if (!at.isNull()) {
value += "DTSTART:" + at.nodeValue().string().stripWhiteSpace() + "\n";
}
} else if (*it == "dtend") {
DOM::Node at = node.attributes().getNamedItem("title");
if (!at.isNull()) {
value += "DTEND:" + at.nodeValue().string().stripWhiteSpace() + "\n";
}
} else if (*it == "summary") {
name = textForNode(node);
value += "SUMMARY:" + name + "\n";
} else if (*it == "location") {
value += "LOCATION:" + textForNode(node) + "\n";
}
}
}
}
if (!name.isEmpty()) {
value += "END:VEVENT\nEND:VCALENDAR\n";
_events.append(tqMakePair(name, value));
}
}
bool KonqMFIcon::hasMicroFormat(DOM::NodeList nodes) {
bool ok = false;
unsigned int n = nodes.length();
for (unsigned int i = 0; i < n; ++i) {
DOM::Node node = nodes.item(i);
DOM::NamedNodeMap map = node.attributes();
for (unsigned int j = 0; j < map.length(); ++j) {
if (map.item(j).nodeName().string() != "class") {
continue;
}
if (map.item(j).nodeValue().string() == "vevent") {
ok = true;
extractEvent(node);
break;
}
if (map.item(j).nodeValue().string() == "vcard") {
ok = true;
extractCard(node);
break;
}
}
if (hasMicroFormat(node.childNodes())) {
ok = true;
}
}
return ok;
}
bool KonqMFIcon::mfFound() {
_events.clear();
_cards.clear();
return hasMicroFormat(m_part->document().childNodes());
}
void KonqMFIcon::contextMenu() {
delete m_menu;
m_menu = new KPopupMenu(m_part->widget());
m_menu->insertTitle(i18n("Microformats"));
connect(m_menu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(addMF(int)));
int id = 0;
for (TQValueList<TQPair<TQString, TQString> >::ConstIterator it = _events.begin(); it != _events.end(); ++it) {
m_menu->insertItem(SmallIcon("bookmark_add"), (*it).first, id);
id++;
}
for (TQValueList<TQPair<TQString, TQString> >::ConstIterator it = _cards.begin(); it != _cards.end(); ++it) {
m_menu->insertItem(SmallIcon("bookmark_add"), (*it).first, id);
id++;
}
m_menu->insertSeparator();
m_menu->insertItem(SmallIcon("bookmark_add"), i18n("Import All Microformats"), this, TQT_SLOT(addMFs()), 0, 50000 );
m_menu->popup(TQCursor::pos());
}
void KonqMFIcon::addMFIcon() {
if (!mfFound() || m_mfIcon) {
return;
}
m_statusBarEx = KParts::StatusBarExtension::childObject(m_part);
if (!m_statusBarEx) {
return;
}
m_mfIcon = new KURLLabel(m_statusBarEx->statusBar());
m_mfIcon->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
m_mfIcon->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
m_mfIcon->setUseCursor(false);
//FIXME hackish
m_mfIcon->setPixmap(TQPixmap(locate("data", "microformat/pics/microformat.png")));
TQToolTip::remove(m_mfIcon);
TQToolTip::add(m_mfIcon, i18n("This site has a microformat entry", "This site has %n microformat entries", _events.count() + _cards.count()));
m_statusBarEx->addStatusBarItem(m_mfIcon, 0, true);
connect(m_mfIcon, TQT_SIGNAL(leftClickedURL()), this, TQT_SLOT(contextMenu()));
}
void KonqMFIcon::removeMFIcon() {
_events.clear();
_cards.clear();
if (m_mfIcon) {
m_statusBarEx->removeStatusBarItem(m_mfIcon);
delete m_mfIcon;
m_mfIcon = 0;
}
// Close the popup if it's open, otherwise we crash
delete m_menu;
m_menu = 0L;
}
void KonqMFIcon::addMF(int id) {
if (id < int(_events.count())) {
} else if (id < int(_cards.count())) {
id -= _cards.count() - 1;
addVCardViaDCOP(_cards[id].second);
}
}
void KonqMFIcon::addMFs() {
int n = _events.count() + _cards.count();
for (int i = 0; i < n; ++i) {
addMF(i);
}
}
#include "konqmficon.moc"