/*************************************************************************** * Copyright (C) 2005 by Florian Roth * * florian@synatic.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. * ***************************************************************************/ #include "metabarwidget.h" #include "configdialog.h" #include "defaultplugin.h" #include "settingsplugin.h" #include "remoteplugin.h" #include "httpplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define EVENT_TYPE DOM::DOMString("click") #define ACTIVATION 1 MetabarWidget::MetabarWidget(TQWidget *parent, const char *name) : TQWidget(parent, name) { skip = false; loadComplete = false; currentItems = new KFileItemList; currentItems->setAutoDelete(true); config = new TDEConfig("metabarrc"); dir_watch = new KDirWatch(); connect(dir_watch, TQT_SIGNAL(dirty(const TQString&)), this, TQT_SLOT(slotUpdateCurrentInfo(const TQString&))); connect(dir_watch, TQT_SIGNAL(created(const TQString&)), this, TQT_SLOT(slotUpdateCurrentInfo(const TQString&))); connect(dir_watch, TQT_SIGNAL(deleted(const TQString&)), this, TQT_SLOT(slotDeleteCurrentInfo(const TQString&))); html = new KHTMLPart(this, "metabarhtmlpart"); html->setJScriptEnabled(true); html->setPluginsEnabled(true); html->setCaretVisible(false); html->setDNDEnabled(false); html->setJavaEnabled(false); html->view()->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding); html->view()->hide(); connect(html->browserExtension(), TQT_SIGNAL(openURLRequest( const KURL &, const KParts::URLArgs & )), this, TQT_SLOT(handleURLRequest(const KURL &, const KParts::URLArgs &))); connect(html, TQT_SIGNAL(completed()), this, TQT_SLOT(loadCompleted())); connect(html, TQT_SIGNAL(popupMenu(const TQString &, const TQPoint &)), this, TQT_SLOT(slotShowPopup(const TQString&, const TQPoint &))); functions = new MetabarFunctions(html, TQT_TQOBJECT(this)); currentPlugin = 0; defaultPlugin = new DefaultPlugin(html, functions); HTTPPlugin *httpPlugin = new HTTPPlugin(html, functions); //plugins.setAutoDelete(true); plugins.insert("settings", new SettingsPlugin(html, functions)); plugins.insert("remote", new RemotePlugin(html, functions)); //plugins.insert("trash", new TrashPlugin(html, functions)); plugins.insert("http", httpPlugin); plugins.insert("https", httpPlugin); TQVBoxLayout *layout = new TQVBoxLayout(this); layout->addWidget(html->view()); popup = new KPopupMenu(0); KAction *configAction = new KAction(i18n("Configure %1...").arg("Metabar"), "configure", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotShowConfig()), html->actionCollection(), "configure"); configAction->plug(popup); KAction *reloadAction = new KAction(i18n("Reload Theme"), "reload", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(setTheme()), html->actionCollection(), "reload"); reloadAction->plug(popup); setTheme(); } MetabarWidget::~MetabarWidget() { config->sync(); delete config; delete dir_watch; delete currentItems; } void MetabarWidget::setFileItems(const KFileItemList &items, bool check) { if(!loadComplete){ return; } if(skip){ skip = false; return; } if(check){ int count = items.count(); KURL url(getCurrentURL()); KFileItem *newItem = items.getFirst(); KFileItem *oldItem = currentItems->getFirst(); if(count == 0){ if(oldItem){ if(oldItem->url() == url){ return; } } currentItems->clear(); currentItems->append(new KFileItem(S_IFDIR, KFileItem::Unknown, url, true)); } else if(count == 1){ if(newItem){ if(newItem->url().isEmpty()){ return; } if(currentItems->count() == items.count() && oldItem){ if(newItem->url() == oldItem->url()){ return; } } } currentItems = new KFileItemList(items); } else{ if(currentItems && *currentItems == items){ return; } currentItems = new KFileItemList(items); } } else{ currentItems = new KFileItemList(items); } if(currentPlugin){ currentPlugin->deactivate(); } TQString protocol = currentItems->getFirst()->url().protocol(); currentPlugin = plugins[protocol]; if(!currentPlugin){ currentPlugin = defaultPlugin; } ProtocolPlugin::activePlugin = currentPlugin; currentPlugin->setFileItems(*currentItems); } TQString MetabarWidget::getCurrentURL() { DCOPRef ref(kapp->dcopClient()->appId(), this->topLevelWidget()->name()); DCOPReply reply = ref.call("currentURL()"); if (reply.isValid()) { TQString url; reply.get(url, TQSTRING_OBJECT_NAME_STRING); if(!url.isNull() && !url.isEmpty()){ return url; } } return 0; } void MetabarWidget::openURL(const TQString &url) { DCOPRef ref(kapp->dcopClient()->appId(), this->topLevelWidget()->name()); DCOPReply reply = ref.call("openURL", url); } void MetabarWidget::openTab(const TQString &url) { DCOPRef ref(kapp->dcopClient()->appId(), this->topLevelWidget()->name()); DCOPReply reply = ref.call("newTab", url); } void MetabarWidget::callAction(const TQString &action) { DCOPRef ref(kapp->dcopClient()->appId(), TQString(TQString(this->topLevelWidget()->name()).append("/action/").append(action)).utf8()); if(ref.call("enabled()")){ ref.call("activate()"); } } void MetabarWidget::loadLinks() { config->setGroup("General"); TQStringList links = config->readListEntry("Links"); if(links.count() == 0){ functions->hide("links"); } else{ functions->show("links"); DOM::HTMLDocument doc = html->htmlDocument(); DOM::HTMLElement node = doc.getElementById("links"); if(!node.isNull()){ DOM::DOMString innerHTML; for(TQStringList::Iterator it = links.begin(); it != links.end(); ++it){ config->setGroup("Link_" + (*it)); addEntry(innerHTML, config->readEntry("Name"), config->readEntry("URL"), config->readEntry("Icon", "folder")); } node.setInnerHTML(innerHTML); } functions->adjustSize("links"); } } void MetabarWidget::loadCompleted() { DOM::HTMLDocument doc = html->htmlDocument(); DOM::NodeList i18n_a_list = doc.getElementsByTagName("a"); for(uint i = 0; i < i18n_a_list.length(); i++){ DOM::HTMLElement node = static_cast(i18n_a_list.item(i)); if(!node.isNull()){ if(node.hasAttribute("i18n")){ TQString text = node.innerText().string(); node.setInnerText(DOM::DOMString(i18n(text.utf8().data()))); } if(node.hasAttribute("image")){ TQString icon = node.getAttribute("image").string(); TQString url = getIconPath(icon); TQString style = TQString("background-image: url(%1);").arg(url); node.setAttribute("style", style); } } } DOM::NodeList i18n_ul_list = doc.getElementsByTagName("ul"); for(uint i = 0; i < i18n_ul_list.length(); i++){ DOM::HTMLElement node = static_cast(i18n_ul_list.item(i)); if(!node.isNull()){ if(node.hasAttribute("i18n")){ TQString text = node.innerText().string(); node.setInnerText(DOM::DOMString(i18n(text.utf8().data()))); } } } config->setGroup("General"); TQString file = locate("data", TQString("metabar/themes/%1/default.css").arg(config->readEntry("Theme", "default"))); if(file.isNull()){ file = locate("data", TQString("metabar/themes/default/default.css")); } TQFile cssfile(file); if(cssfile.open(IO_ReadOnly)){ TQTextStream stream( &cssfile ); TQString tmp = stream.read(); cssfile.close(); tmp.replace("./", KURL::fromPathOrURL(file).directory(false)); html->setUserStyleSheet(tmp); } loadComplete = true; html->view()->setFrameShape(config->readBoolEntry("ShowFrame", true) ? TQFrame::StyledPanel : TQFrame::NoFrame); html->view()->show(); if(currentItems && !currentItems->isEmpty()){ setFileItems(*currentItems, false); } else{ TQString url = getCurrentURL(); KFileItem *item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL(url), true); KFileItemList list; list.append(item); setFileItems(list, false); } loadLinks(); } void MetabarWidget::handleURLRequest(const KURL &url, const KParts::URLArgs &args) { if(!currentPlugin){ return; } TQString protocol = url.protocol(); if(currentPlugin->handleRequest(url)){ return; } if(protocol == "desktop"){ TQString path = url.path(); if(KDesktopFile::isDesktopFile(path)){ KRun::run(new KDesktopFile(path, true), KURL::List()); } } else if(protocol == "tdecmshell"){ TQString module = url.path().remove('/'); KRun::runCommand("tdecmshell " + module); } else if(protocol == "action"){ TQString action = url.url().right(url.url().length() - 9); if(action.startsWith("metabar/")){ TQString newact = action.right(action.length() - 8); if(newact == "share"){ slotShowSharingDialog(); } } else{ callAction(action); } } else if(protocol == "preview"){ if(currentItems && !currentItems->isEmpty()){ KFileItem *item = currentItems->getFirst(); DOM::HTMLDocument doc = html->htmlDocument(); DOM::HTMLElement node = static_cast(doc.getElementById("preview")); DOM::HTMLImageElement image = static_cast(doc.getElementById("previewimage")); if(!node.isNull()){ skip = true; //needed to prevent some weired reload DOM::DOMString innerHTML; innerHTML += TQString("
    ").arg(image.width(), image.height()); innerHTML += "mimetype(); innerHTML += "\" data=\""; innerHTML += item->url().url(); innerHTML += "\" width=\""; innerHTML += TQString(TQString().setNum(image.width())); innerHTML += "\" height=\""; innerHTML += TQString(TQString().setNum(image.height())); innerHTML += "\" />"; node.setInnerHTML(innerHTML); } } } else if(protocol == "more"){ TQString name = url.host(); DOM::HTMLDocument doc = html->htmlDocument(); DOM::NodeList list = doc.getElementsByName(name); DOM::HTMLElement element = static_cast(doc.getElementById(name)); bool showMore = true; for(uint i = 0; i < list.length(); i++){ DOM::HTMLElement node = static_cast(list.item(i)); if(!node.isNull()){ DOM::HTMLElement parent = static_cast(node.parentNode()); DOM::CSSStyleDeclaration style = parent.style(); DOM::DOMString display = style.getPropertyValue("display"); DOM::DOMString newDisplay = display == "none" ? "block" : "none"; style.setProperty("display", newDisplay, "important"); showMore = display == "block"; } } if(element.id().string().startsWith("hidden")){ TQString style = TQString("background-image: url(%1);").arg(getIconPath(showMore ? "1downarrow" : "1uparrow")); element.setInnerText( showMore ? i18n("More") : i18n("Less") ); element.setAttribute("style", style); } DOM::HTMLElement parent = static_cast(element.parentNode().parentNode()); functions->adjustSize(parent.id()); } else if(protocol == "function"){ functions->handleRequest(url); } else if(protocol == "configure"){ slotShowConfig(); } else if(protocol == "openwith"){ if(currentItems && !currentItems->isEmpty()){ KFileItem *item = currentItems->getFirst(); KRun::displayOpenWithDialog(KURL::List(item->url()), false); } } else{ if(args.newTab()){ openTab(url.url()); } else{ openURL(url.url()); } } } TQString MetabarWidget::getIconPath(const TQString &name) { TQPixmap icon = SmallIcon(name); TQByteArray data; TQBuffer buffer(data); buffer.open(IO_WriteOnly); icon.save(&buffer, "PNG"); return TQString::fromLatin1("data:image/png;base64,%1").arg(KCodecs::base64Encode(data).data()); } void MetabarWidget::slotShowSharingDialog() { if(currentItems && currentItems->count() == 1){ KPropertiesDialog *dialog = new KPropertiesDialog(currentItems->first(), 0, 0, true); dialog->showFileSharingPage(); } } void MetabarWidget::slotShowConfig() { ConfigDialog *config_dialog = new ConfigDialog(this); if(config_dialog->exec() == TQDialog::Accepted){ config->reparseConfiguration(); setFileItems(*currentItems, false); loadLinks(); setTheme(); html->view()->setFrameShape(config->readBoolEntry("ShowFrame", true) ? TQFrame::StyledPanel : TQFrame::NoFrame); } delete config_dialog; } void MetabarWidget::slotShowPopup(const TQString &url, const TQPoint &point) { popup->exec(point); } void MetabarWidget::slotUpdateCurrentInfo(const TQString &path) { if(currentItems){ KFileItem *item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL(path), true); if(currentItems->count() == 1){ currentItems->clear(); currentItems->append(item); } setFileItems(*currentItems, false); } } void MetabarWidget::slotDeleteCurrentInfo(const TQString&) { if(currentItems && currentItems->count() == 1){ TQString url = getCurrentURL(); KURL currentURL; if(currentItems){ currentURL = currentItems->getFirst()->url(); } if(!currentURL.isEmpty() && KURL(url) != currentURL){ if(dir_watch->contains(currentURL.path())){ dir_watch->removeDir(currentURL.path()); } dir_watch->addDir(url); KFileItem *item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true); currentItems->clear(); currentItems->append(item); setFileItems(*currentItems, false); } } } void MetabarWidget::addEntry(DOM::DOMString &html, const TQString name, const TQString url, const TQString icon, const TQString id, const TQString nameatt, bool hidden) { html += ""; html += name; html += ""; } void MetabarWidget::setTheme() { loadComplete = false; config->setGroup("General"); TQString file = locate("data", TQString("metabar/themes/%1/layout.html").arg(config->readEntry("Theme", "default"))); html->openURL(KURL(file)); } #include "metabarwidget.moc"