lib

wdgscriptsmanager.cpp

00001 /*
00002  * This file is part of the KDE project
00003  *
00004  * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net>
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU Library General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  */
00019 #include "wdgscriptsmanager.h"
00020 
00021 #include <qfile.h>
00022 #include <qfileinfo.h>
00023 #include <qheader.h>
00024 #include <qobjectlist.h>
00025 #include <qtooltip.h>
00026 
00027 #include <kapplication.h>
00028 #include <kdeversion.h>
00029 #include <kfiledialog.h>
00030 #include <kiconloader.h>
00031 #include <klistview.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kpushbutton.h>
00035 #include <kstandarddirs.h>
00036 #include <ktoolbar.h>
00037 
00038 #if KDE_IS_VERSION(3, 4, 0)
00039   // The KNewStuffSecure we use internaly for the GetHotNewStuff-functionality
00040   // was introduced with KDE 3.4.
00041   #define KROSS_SUPPORT_NEWSTUFF
00042 #endif
00043 
00044 #ifdef KROSS_SUPPORT_NEWSTUFF
00045   #include <knewstuff/provider.h>
00046   #include <knewstuff/engine.h>
00047   #include <knewstuff/downloaddialog.h>
00048   #include <knewstuff/knewstuffsecure.h>
00049 #endif
00050 
00051 #include "scriptguiclient.h"
00052 #include "scriptaction.h"
00053 
00054 namespace Kross { namespace Api {
00055 
00056 #ifdef KROSS_SUPPORT_NEWSTUFF
00057 class ScriptNewStuff : public KNewStuffSecure
00058 {
00059     public:
00060         ScriptNewStuff(ScriptGUIClient* scripguiclient, const QString& type, QWidget *parentWidget = 0)
00061             : KNewStuffSecure(type, parentWidget)
00062             , m_scripguiclient(scripguiclient) {}
00063         virtual ~ScriptNewStuff() {}
00064     private:
00065         ScriptGUIClient* m_scripguiclient;
00066         virtual void installResource() { m_scripguiclient->installScriptPackage( m_tarName ); }
00067 };
00068 #endif
00069 
00070 class ListItem : public QListViewItem
00071 {
00072     private:
00073         ScriptActionCollection* m_collection;
00074         ScriptAction::Ptr m_action;
00075     public:
00076         ListItem(QListView* parentview, ScriptActionCollection* collection)
00077             : QListViewItem(parentview), m_collection(collection), m_action(0) {}
00078 
00079         ListItem(ListItem* parentitem, QListViewItem* afteritem, ScriptAction::Ptr action)
00080             : QListViewItem(parentitem, afteritem), m_collection( parentitem->collection() ), m_action(action) {}
00081 
00082         ScriptAction::Ptr action() const { return m_action; }
00083         ScriptActionCollection* collection() const { return m_collection; }
00084         //ScriptActionMenu* actionMenu() const { return m_menu; }
00085 };
00086 
00087 class ToolTip : public QToolTip
00088 {
00089     public:
00090         ToolTip(KListView* parent) : QToolTip(parent->viewport()), m_parent(parent) {}
00091         virtual ~ToolTip () { remove(m_parent->viewport()); }
00092     protected:
00093         virtual void maybeTip(const QPoint& p) {
00094             ListItem* item = dynamic_cast<ListItem*>( m_parent->itemAt(p) );
00095             if(item) {
00096                 QRect r( m_parent->itemRect(item) );
00097                 if(r.isValid() && item->action()) {
00098                     tip(r, QString("<qt>%1</qt>").arg(item->action()->toolTip()));
00099                 }
00100             }
00101         }
00102     private:
00103         KListView* m_parent;
00104 };
00105 
00106 class WdgScriptsManagerPrivate
00107 {
00108     friend class WdgScriptsManager;
00109     ScriptGUIClient* m_scripguiclient;
00110     ToolTip* m_tooltip;
00111 #ifdef KROSS_SUPPORT_NEWSTUFF
00112     ScriptNewStuff* newstuff;
00113 #endif
00114     //enum { LoadBtn = 0, UnloadBtn, InstallBtn, UninstallBtn, ExecBtn, NewStuffBtn };
00115 };
00116 
00117 WdgScriptsManager::WdgScriptsManager(ScriptGUIClient* scr, QWidget* parent, const char* name, WFlags fl )
00118     : WdgScriptsManagerBase(parent, name, fl)
00119     , d(new WdgScriptsManagerPrivate)
00120 {
00121     d->m_scripguiclient = scr;
00122     d->m_tooltip = new ToolTip(scriptsList);
00123 #ifdef KROSS_SUPPORT_NEWSTUFF
00124     d->newstuff = 0;
00125 #endif
00126 
00127     scriptsList->header()->hide();
00128     //scriptsList->header()->setClickEnabled(false);
00129     scriptsList->setAllColumnsShowFocus(true);
00130     //scriptsList->setRootIsDecorated(true);
00131     scriptsList->setSorting(-1);
00132     scriptsList->addColumn("text");
00133     //scriptsList->setColumnWidthMode(1, QListView::Manual);
00134 
00135     slotFillScriptsList();
00136 
00137     slotSelectionChanged(0);
00138     connect(scriptsList, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(slotSelectionChanged(QListViewItem*)));
00139 
00140     btnExec->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "exec", KIcon::MainToolbar, 16 ));
00141     connect(btnExec, SIGNAL(clicked()), this, SLOT(slotExecuteScript()));
00142     btnLoad->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "fileopen", KIcon::MainToolbar, 16 ));
00143     connect(btnLoad, SIGNAL(clicked()), this, SLOT(slotLoadScript()));
00144     btnUnload->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "fileclose", KIcon::MainToolbar, 16 ));
00145     connect(btnUnload, SIGNAL(clicked()), this, SLOT(slotUnloadScript()));
00146     btnInstall->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "fileimport", KIcon::MainToolbar, 16 ));
00147     connect(btnInstall, SIGNAL(clicked()), this, SLOT(slotInstallScript()));
00148     btnUninstall->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "fileclose", KIcon::MainToolbar, 16 ));
00149     connect(btnUninstall, SIGNAL(clicked()), this, SLOT(slotUninstallScript()));
00150 #ifdef KROSS_SUPPORT_NEWSTUFF
00151     btnNewStuff->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "knewstuff", KIcon::MainToolbar, 16 ));
00152     connect(btnNewStuff, SIGNAL(clicked()), this, SLOT(slotGetNewScript()));
00153 #endif
00154 /*
00155     toolBar->setIconText( KToolBar::IconTextRight );
00156 
00157     toolBar->insertButton("exec", WdgScriptsManagerPrivate::ExecBtn, false, i18n("Execute"));
00158     toolBar->addConnection(WdgScriptsManagerPrivate::ExecBtn, SIGNAL(clicked()), this, SLOT(slotExecuteScript()));
00159     toolBar->insertLineSeparator();
00160     toolBar->insertButton("fileopen", WdgScriptsManagerPrivate::LoadBtn, true, i18n("Load"));
00161     toolBar->addConnection(WdgScriptsManagerPrivate::LoadBtn, SIGNAL(clicked()), this, SLOT(slotLoadScript()));
00162     toolBar->insertButton("fileclose", WdgScriptsManagerPrivate::UnloadBtn, false, i18n("Unload"));
00163     toolBar->addConnection(WdgScriptsManagerPrivate::UnloadBtn, SIGNAL(clicked()), this, SLOT(slotUnloadScript()));
00164     toolBar->insertLineSeparator();
00165     toolBar->insertButton("fileimport", WdgScriptsManagerPrivate::InstallBtn, true, i18n("Install"));
00166     toolBar->addConnection(WdgScriptsManagerPrivate::InstallBtn, SIGNAL(clicked()), this, SLOT(slotInstallScript()));
00167     toolBar->insertButton("fileclose", WdgScriptsManagerPrivate::UninstallBtn, false, i18n("Uninstall"));
00168     toolBar->addConnection(WdgScriptsManagerPrivate::UninstallBtn, SIGNAL(clicked()), this, SLOT(slotUninstallScript()));
00169 #ifdef KROSS_SUPPORT_NEWSTUFF
00170     toolBar->insertLineSeparator();
00171     toolBar->insertButton("knewstuff", WdgScriptsManagerPrivate::NewStuffBtn, true, i18n("Get More Scripts"));
00172     toolBar->addConnection(WdgScriptsManagerPrivate::NewStuffBtn, SIGNAL(clicked()), this, SLOT(slotGetNewScript()));
00173 #endif
00174 */
00175     connect(scr, SIGNAL( collectionChanged(ScriptActionCollection*) ),
00176             this, SLOT( slotFillScriptsList() ));
00177 }
00178 
00179 WdgScriptsManager::~WdgScriptsManager()
00180 {
00181     delete d->m_tooltip;
00182     delete d;
00183 }
00184 
00185 void WdgScriptsManager::slotFillScriptsList()
00186 {
00187     scriptsList->clear();
00188 
00189     addItem( d->m_scripguiclient->getActionCollection("executedscripts") );
00190     addItem( d->m_scripguiclient->getActionCollection("loadedscripts") );
00191     addItem( d->m_scripguiclient->getActionCollection("installedscripts") );
00192 }
00193 
00194 void WdgScriptsManager::addItem(ScriptActionCollection* collection)
00195 {
00196     if(! collection)
00197         return;
00198 
00199     ListItem* i = new ListItem(scriptsList, collection);
00200     i->setText(0, collection->actionMenu()->text());
00201     i->setOpen(true);
00202 
00203     QValueList<ScriptAction::Ptr> list = collection->actions();
00204     QListViewItem* lastitem = 0;
00205     for(QValueList<ScriptAction::Ptr>::Iterator it = list.begin(); it != list.end(); ++it)
00206         lastitem = addItem(*it, i, lastitem);
00207 }
00208 
00209 QListViewItem* WdgScriptsManager::addItem(ScriptAction::Ptr action, QListViewItem* parentitem, QListViewItem* afteritem)
00210 {
00211     if(! action)
00212         return 0;
00213 
00214     ListItem* i = new ListItem(dynamic_cast<ListItem*>(parentitem), afteritem, action);
00215     i->setText(0, action->text()); // FIXME: i18nise it for ko2.0
00216     //i->setText(1, action->getDescription()); // FIXME: i18nise it for ko2.0
00217     //i->setText(2, action->name());
00218 
00219     QPixmap pm;
00220     if(action->hasIcon()) {
00221         KIconLoader* icons = KGlobal::iconLoader();
00222         pm = icons->loadIconSet(action->icon(), KIcon::Small).pixmap(QIconSet::Small, QIconSet::Active);
00223     }
00224     else {
00225         pm = action->iconSet(KIcon::Small, 16).pixmap(QIconSet::Small, QIconSet::Active);
00226     }
00227     if(! pm.isNull())
00228         i->setPixmap(0, pm); // display the icon
00229 
00230     return i;
00231 }
00232 
00233 void WdgScriptsManager::slotSelectionChanged(QListViewItem* item)
00234 {
00235     ListItem* i = dynamic_cast<ListItem*>(item);
00236     Kross::Api::ScriptActionCollection* installedcollection = d->m_scripguiclient->getActionCollection("installedscripts");
00237 
00238     //toolBar->setItemEnabled(WdgScriptsManagerPrivate::ExecBtn, i && i->action());
00239     //toolBar->setItemEnabled(WdgScriptsManagerPrivate::UninstallBtn, i && i->action() && i->collection() == installedcollection);
00240     //toolBar->setItemEnabled(WdgScriptsManagerPrivate::UnloadBtn, i && i->action() && i->collection() != installedcollection);
00241     btnExec->setEnabled(i && i->action());
00242     btnUnload->setEnabled(i && i->action() && i->collection() != installedcollection);
00243     btnUninstall->setEnabled(i && i->action() && i->collection() == installedcollection);
00244 }
00245 
00246 void WdgScriptsManager::slotLoadScript()
00247 {
00248     if(d->m_scripguiclient->loadScriptFile())
00249         slotFillScriptsList();
00250 }
00251 
00252 void WdgScriptsManager::slotInstallScript()
00253 {
00254     KFileDialog* filedialog = new KFileDialog(
00255         QString::null, // startdir
00256         "*.tar.gz *.tgz *.bz2", // filter
00257         this, // parent widget
00258         "WdgScriptsManagerInstallFileDialog", // name
00259         true // modal
00260     );
00261     filedialog->setCaption( i18n("Install Script Package") );
00262 
00263     if(! filedialog->exec())
00264         return;
00265 
00266     if(! d->m_scripguiclient->installScriptPackage( filedialog->selectedURL().path() )) {
00267         kdWarning() << "Failed to install scriptpackage" << endl;
00268         return;
00269     }
00270 
00271     slotFillScriptsList();
00272 }
00273 
00274 void WdgScriptsManager::slotUninstallScript()
00275 {
00276     ListItem* item = dynamic_cast<ListItem*>( scriptsList->currentItem() );
00277     if( !item || !item->action() )
00278         return;
00279 
00280     Kross::Api::ScriptActionCollection* installedcollection = d->m_scripguiclient->getActionCollection("installedscripts");
00281     if( !item->collection() || item->collection() != installedcollection)
00282         return;
00283 
00284     const QString packagepath = item->action()->getPackagePath();
00285     if( !packagepath)
00286         return;
00287 
00288     if( KMessageBox::warningContinueCancel(0,
00289         i18n("Uninstall the script package \"%1\" and delete the package's folder \"%2\"?")
00290             .arg(item->action()->text()).arg(packagepath),
00291         i18n("Uninstall")) != KMessageBox::Continue )
00292     {
00293         return;
00294     }
00295 
00296     if(! d->m_scripguiclient->uninstallScriptPackage(packagepath)) {
00297         kdWarning() << "Failed to uninstall scriptpackage" << endl;
00298         return;
00299     }
00300 
00301     slotFillScriptsList();
00302 }
00303 
00304 void WdgScriptsManager::slotExecuteScript()
00305 {
00306     ListItem* item = dynamic_cast<ListItem*>( scriptsList->currentItem() );
00307     if(item && item->action())
00308         item->action()->activate();
00309 }
00310 
00311 void WdgScriptsManager::slotUnloadScript()
00312 {
00313     ListItem* item = dynamic_cast<ListItem*>( scriptsList->currentItem() );
00314     if(item && item->action()) {
00315         item->collection()->detach( item->action() );
00316         slotFillScriptsList();
00317     }
00318 }
00319 
00320 void WdgScriptsManager::slotGetNewScript()
00321 {
00322 #ifdef KROSS_SUPPORT_NEWSTUFF
00323     const QString appname = KApplication::kApplication()->name();
00324     const QString type = QString("%1/script").arg(appname);
00325 
00326     if(! d->newstuff) {
00327         d->newstuff = new ScriptNewStuff(d->m_scripguiclient, type);
00328         connect(d->newstuff, SIGNAL(installFinished()), this, SLOT(slotResourceInstalled()));
00329     }
00330 
00331     KNS::Engine *engine = new KNS::Engine(d->newstuff, type, this);
00332     KNS::DownloadDialog *d = new KNS::DownloadDialog( engine, this );
00333     d->setType(type);
00334 
00335     KNS::ProviderLoader *p = new KNS::ProviderLoader(this);
00336     QObject::connect(p, SIGNAL(providersLoaded(Provider::List*)),
00337                      d, SLOT(slotProviders(Provider::List*)));
00338 
00339     p->load(type, QString("http://download.kde.org/khotnewstuff/%1scripts-providers.xml").arg(appname));
00340     d->exec();
00341 #endif
00342 }
00343 
00344 void WdgScriptsManager::slotResourceInstalled()
00345 {
00346     // Delete KNewStuff's configuration entries. These entries reflect what has
00347     // already been installed. As we cannot yet keep them in sync after uninstalling
00348     // scripts, we deactivate the check marks entirely.
00349     KGlobal::config()->deleteGroup("KNewStuffStatus");
00350 }
00351 
00352 }}
00353 
00354 #include "wdgscriptsmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys