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.
593 lines
17 KiB
593 lines
17 KiB
/***************************************************************************
|
|
* 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 <tqwidget.h>
|
|
#include <tqlayout.h>
|
|
#include <tqdir.h>
|
|
#include <tqfile.h>
|
|
#include <tqtextstream.h>
|
|
#include <tqvaluelist.h>
|
|
#include <tqurl.h>
|
|
#include <tqbuffer.h>
|
|
|
|
#include <khtmlview.h>
|
|
#include <kapplication.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kurl.h>
|
|
#include <kdebug.h>
|
|
#include <kglobal.h>
|
|
#include <kiconloader.h>
|
|
#include <kicontheme.h>
|
|
#include <ktrader.h>
|
|
#include <klocale.h>
|
|
#include <krun.h>
|
|
#include <kdesktopfile.h>
|
|
#include <kpropertiesdialog.h>
|
|
#include <kaction.h>
|
|
#include <kactioncollection.h>
|
|
#include <kshortcut.h>
|
|
#include <kmimetype.h>
|
|
#include <kcmoduleinfo.h>
|
|
#include <kmdcodec.h>
|
|
|
|
#include <kparts/browserextension.h>
|
|
|
|
#include <dom2_events.h>
|
|
#include <dom2_views.h>
|
|
#include <dom_doc.h>
|
|
#include <dom_element.h>
|
|
#include <dom_string.h>
|
|
#include <html_element.h>
|
|
#include <html_misc.h>
|
|
#include <html_image.h>
|
|
#include <css_value.h>
|
|
|
|
#include <dcopref.h>
|
|
#include <dcopclient.h>
|
|
|
|
#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 KConfig("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 *tqlayout = new TQVBoxLayout(this);
|
|
tqlayout->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<DOM::HTMLElement>(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<DOM::HTMLElement>(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 == "kcmshell"){
|
|
TQString module = url.path().remove('/');
|
|
|
|
KRun::runCommand("kcmshell " + 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<DOM::HTMLElement>(doc.getElementById("preview"));
|
|
DOM::HTMLImageElement image = static_cast<DOM::HTMLImageElement>(doc.getElementById("previewimage"));
|
|
|
|
if(!node.isNull()){
|
|
skip = true; //needed to prevent some weired reload
|
|
|
|
DOM::DOMString innerHTML;
|
|
innerHTML += TQString("<ul style=\"width: %1px; height: %1px\">").arg(image.width(), image.height());
|
|
innerHTML += "<object class=\"preview\" type=\"";
|
|
innerHTML += item->mimetype();
|
|
innerHTML += "\" data=\"";
|
|
innerHTML += item->url().url();
|
|
innerHTML += "\" width=\"";
|
|
innerHTML += TQString(TQString().setNum(image.width()));
|
|
innerHTML += "\" height=\"";
|
|
innerHTML += TQString(TQString().setNum(image.height()));
|
|
innerHTML += "\" /></ul>";
|
|
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<DOM::HTMLElement>(doc.getElementById(name));
|
|
bool showMore = true;
|
|
|
|
for(uint i = 0; i < list.length(); i++){
|
|
DOM::HTMLElement node = static_cast<DOM::HTMLElement>(list.item(i));
|
|
if(!node.isNull()){
|
|
DOM::HTMLElement parent = static_cast<DOM::HTMLElement>(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<DOM::HTMLElement>(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 += "<ul";
|
|
|
|
if(hidden){
|
|
html += " style=\"display: none;\"";
|
|
}
|
|
|
|
html += "><a";
|
|
|
|
if(!id.isNull() && !id.isEmpty()){
|
|
html += " id=\"";
|
|
html += id;
|
|
html += "\"";
|
|
}
|
|
|
|
if(!nameatt.isNull() && !nameatt.isEmpty()){
|
|
html += " name=\"";
|
|
html += nameatt;
|
|
html += "\"";
|
|
}
|
|
|
|
html += " href=\"";
|
|
html += url;
|
|
html += "\" onClick=\"this.blur();\" style=\"background-image: url(";
|
|
html += getIconPath(icon);
|
|
html += ");\">";
|
|
html += name;
|
|
html += "</a></ul>";
|
|
}
|
|
|
|
void MetabarWidget::setTheme()
|
|
{
|
|
loadComplete = false;
|
|
|
|
config->setGroup("General");
|
|
TQString file = locate("data", TQString("metabar/themes/%1/tqlayout.html").arg(config->readEntry("Theme", "default")));
|
|
|
|
html->openURL(KURL(file));
|
|
}
|
|
|
|
#include "metabarwidget.moc"
|