summaryrefslogtreecommitdiffstats
path: root/tdehtml/misc/knsplugininstaller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdehtml/misc/knsplugininstaller.cpp')
-rw-r--r--tdehtml/misc/knsplugininstaller.cpp671
1 files changed, 671 insertions, 0 deletions
diff --git a/tdehtml/misc/knsplugininstaller.cpp b/tdehtml/misc/knsplugininstaller.cpp
new file mode 100644
index 000000000..b953f34fb
--- /dev/null
+++ b/tdehtml/misc/knsplugininstaller.cpp
@@ -0,0 +1,671 @@
+/*
+ This file is part of the KDE libraries
+
+ Copyright (C) 2005 Benoit Canet <bcanet@dental-on-line.fr>
+ Copyright (C) 2005 Aurelien Gateau <agateau@dental-on-line.fr>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include "knsplugininstaller.moc"
+
+#include <kdebug.h>
+#include <kdiroperator.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kstddirs.h>
+#include <ktempfile.h>
+#include <netaccess.h>
+
+#include <tqbuttongroup.h>
+#include <tqdir.h>
+#include <tqiodevice.h>
+#include <tqfile.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqmap.h>
+#include <tqstringlist.h>
+#include <tqtextstream.h>
+
+#include <sys/utsname.h>
+
+// Use 6031 for debugging (render_frame)
+#define DEBUG_NUMBER 6031
+
+/*
+ * Utility class to associate a list item with a pluginInfo object
+ */
+class PluginListItem : public TQListViewItem
+{
+
+public:
+ PluginListItem(KNSPluginInfo pluginInfo, TQListView *parent)
+ : TQListViewItem(parent, pluginInfo.pluginName())
+ , m_pluginInfo(pluginInfo) {}
+ KNSPluginInfo pluginInfo() const { return m_pluginInfo; }
+
+private:
+ KNSPluginInfo m_pluginInfo;
+
+};
+
+
+// public methods
+
+KNSPluginInstallEngine::KNSPluginInstallEngine(KMimeType::Ptr mime) : TQObject()
+{
+ m_mime = mime;
+
+ // Fill the architecture map
+ m_archMap["i386"] = "ia32";
+ m_archMap["i486"] = "ia32";
+ m_archMap["i586"] = "ia32";
+ m_archMap["i686"] = "ia32";
+}
+
+KNSPluginInstallEngine::~KNSPluginInstallEngine()
+{
+}
+
+bool KNSPluginInstallEngine::pluginAvailable()
+{
+
+ if(m_pluginList.count())
+ return true;
+
+ // check if pluginsListFile is present in kde config
+ if(!loadConfig())
+ return false;
+
+ // load the xml configuration file
+ if(!loadXmlConfig())
+ return false;
+
+ return findPlugin();
+}
+
+bool KNSPluginInstallEngine::isActive()
+{
+ // check if we have a configuration key in the kde registry
+ TQString pluginsListFile;
+ TDEConfig cfg("kcmnspluginrc", true);
+ cfg.setGroup("Misc");
+ pluginsListFile = cfg.readPathEntry("PluginsListFile");
+ return !pluginsListFile.isEmpty();
+}
+
+const TQValueList<KNSPluginInfo>& KNSPluginInstallEngine::pluginList() const
+{
+ return m_pluginList;
+}
+
+// private methods
+bool KNSPluginInstallEngine::loadConfig()
+{
+ TQString pluginsListFile;
+ TDEConfig cfg("kcmnspluginrc", true);
+ cfg.setGroup("Misc");
+ pluginsListFile = cfg.readPathEntry("PluginsListFile");
+ if(!pluginsListFile.isEmpty())
+ {
+ m_pluginsListFileURL = KURL(pluginsListFile);
+ kdDebug(DEBUG_NUMBER) << "config loaded "<<endl;
+ return true;
+ }
+ return false;
+}
+
+bool KNSPluginInstallEngine::loadXmlConfig()
+{
+
+ // load the Xml configuration file
+ if(m_pluginsXmlConfig.isEmpty())
+ {
+ TQString tmpFile;
+ if(TDEIO::NetAccess::download(m_pluginsListFileURL, tmpFile, NULL)) {
+ TQFile f(tmpFile);
+ if(!f.open(IO_ReadOnly))
+ return false;
+ TQTextStream stream(&f);
+ stream.setEncoding(TQTextStream::UnicodeUTF8);
+ m_pluginsXmlConfig = stream.read();
+ f.close();
+ TDEIO::NetAccess::removeTempFile(tmpFile);
+ } else
+ return false;
+ }
+ kdDebug(DEBUG_NUMBER) << "xml config loaded :" << endl;
+ return true;
+}
+
+bool KNSPluginInstallEngine::findPlugin()
+{
+
+ // get system infos
+ // TODO/FIX : correct this to work with x86-64 machines
+ utsname sysinfo;
+ if(uname(&sysinfo))
+ return false;
+ TQString sysname(sysinfo.sysname);
+ TQString machine(sysinfo.machine);
+ TQString arch = m_archMap[machine];
+
+ // Parse the document
+ TQDomDocument doc("xmlConfig");
+ doc.setContent(m_pluginsXmlConfig);
+ TQDomNodeList archList = doc.elementsByTagName(TQString("arch"));
+ TQDomNode archNode, osNode , pluginNode, node;
+ TQDomElement e;
+
+ // look for the correct architecture
+ bool found = false;
+ unsigned int i;
+ for(i=0; i < archList.count() ; i++) {
+ archNode = archList.item(i);
+ e = archNode.toElement();
+ if( e.attribute("architecture") == arch) {
+ kdDebug(DEBUG_NUMBER) << "found correct architecture :" << arch << endl;
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ return false;
+
+ // look for the correct os
+ found = false;
+ osNode = archNode.firstChild();
+ while(!osNode.isNull()) {
+ e = osNode.toElement();
+ if( e.tagName() == "os" && e.attribute("name") == sysname) {
+ kdDebug(DEBUG_NUMBER) << "found correct os :" << sysname << endl;
+ found = true;
+ break;
+ }
+ osNode=osNode.nextSibling();
+ }
+
+ if(!found)
+ return false;
+
+ // Look for a plugin with the given mimetype
+ pluginNode = osNode.firstChild();
+ while(!pluginNode.isNull()) {
+ e = pluginNode.toElement();
+ if( e.tagName() == "plugin" && m_mime->is(e.attribute("mimetype")) ) {
+ kdDebug(DEBUG_NUMBER) << "found correct plugin :" << e.attribute("mimetype") << endl;
+ KNSPluginInfo pluginInfo(pluginNode);
+ if(pluginInfo.isValid())
+ m_pluginList.append(pluginInfo);
+ }
+ pluginNode=pluginNode.nextSibling();
+ }
+
+ if(m_pluginList.count())
+ return true;
+ else
+ return false;
+}
+
+
+void KNSPluginInstallEngine::startInstall(KNSPluginInfo info)
+{
+ m_toInstallPluginInfo = info;
+ // create a temporary dowload file
+ KTempFile tempFile(locateLocal("tmp", "plugin") , TQString(".tar.gz"));
+ m_tmpPluginFileName = tempFile.name();
+ tempFile.unlink();
+ tempFile.close();
+ // start the download job
+ m_downloadJob = TDEIO::copy(info.pluginURL(), "file://"+m_tmpPluginFileName, false );
+ // connect signals
+ connect(m_downloadJob, TQT_SIGNAL(percent (TDEIO::Job *, unsigned long)), this , TQT_SLOT(slotDownLoadProgress(TDEIO::Job *, unsigned long)));
+ connect(m_downloadJob, TQT_SIGNAL(result(TDEIO::Job *)), this, TQT_SLOT(slotDownloadResult(TDEIO::Job *)) );
+ kdDebug(DEBUG_NUMBER) << "download plugin " << m_tmpPluginFileName << endl;
+}
+
+void KNSPluginInstallEngine::slotDownLoadProgress(TDEIO::Job *, unsigned long percent)
+{
+ // propagate the download progression
+ emit installProgress( ((int)percent)/3 );
+}
+
+void KNSPluginInstallEngine::slotDownloadResult(TDEIO::Job *job)
+{
+ // test if the download job suceed
+ if(job->error()) {
+ kdDebug(DEBUG_NUMBER) << "download error" << m_tmpPluginFileName << endl;
+ emit installFailed();
+ }
+ else {
+ kdDebug(DEBUG_NUMBER) << "download completed" << m_tmpPluginFileName << endl;
+ // the download succeed copy the plugins files
+
+ // test the existance of the homedir
+ TQDir dir(TQDir::homeDirPath());
+ if(!dir.exists()) {
+ emit installFailed();
+ return;
+ }
+
+ // test and create firefox plugins directory
+ if(!dir.exists(".mozilla"))
+ dir.mkdir(".mozilla");
+ if(!dir.exists(".mozilla/plugins"))
+ dir.mkdir(".mozilla/plugins");
+ // destination kurl
+ KURL destURL("file://"+TQDir::homeDirPath()+"/.mozilla/plugins");
+
+ // construct the source kurlList
+ KURL::List urlList;
+ TQStringList pluginFileList = m_toInstallPluginInfo.pluginFileList();
+
+ TQStringList::iterator it;
+ for( it = pluginFileList.begin(); it != pluginFileList.end(); ++it ) {
+ urlList.append( KURL("tar://"+m_tmpPluginFileName+"/"+(*it)) );
+ }
+ m_installFileJob = TDEIO::copy(urlList , destURL, false );
+ connect(m_installFileJob, TQT_SIGNAL(percent (TDEIO::Job *, unsigned long)), this , TQT_SLOT(slotCopyProgress(TDEIO::Job *, unsigned long)));
+ connect(m_installFileJob, TQT_SIGNAL(result(TDEIO::Job *)), this, TQT_SLOT(slotCopyResult(TDEIO::Job *)) );
+ }
+ kdDebug(DEBUG_NUMBER) << "COPY FILE " << m_tmpPluginFileName << endl;
+
+ // zero the download job pointer
+ m_downloadJob = NULL;
+}
+
+void KNSPluginInstallEngine::slotCopyProgress(TDEIO::Job *, unsigned long percent)
+{
+ // propagate the download progression
+ emit installProgress( ((int)percent)/3 + 33 );
+}
+
+void KNSPluginInstallEngine::slotCopyResult(TDEIO::Job *job)
+{
+ // test if the download job suceed
+ if(job->error()) {
+ kdDebug(DEBUG_NUMBER) << "download error" << m_tmpPluginFileName << endl;
+ emit installFailed();
+ }
+ else {
+ // start the plugins scan
+ m_scanProc = new TQProcess( this );
+ m_scanProc->addArgument( "nspluginscan" );
+ m_scanProc->addArgument( "--verbose" );
+
+ connect( m_scanProc, TQT_SIGNAL(readyReadStdout()),
+ this, TQT_SLOT(readScanProcFromStdout()) );
+ connect( m_scanProc, TQT_SIGNAL(processExited()),
+ this, TQT_SLOT(endScanProc()) );
+ if ( !m_scanProc->start() ) {
+ emit installFailed();
+ }
+ }
+}
+
+void KNSPluginInstallEngine::readScanProcFromStdout()
+{
+ // Monitor the scan progress
+ TQString progress = m_scanProc->readLineStdout();
+ int percent;
+ bool ok;
+ percent = progress.toInt(&ok);
+ if(!ok)
+ emit installFailed();
+ emit installProgress( (percent)/3 + 66 );
+}
+
+
+void KNSPluginInstallEngine::endScanProc()
+{
+ // end of scan
+ if(m_scanProc->normalExit()) {
+ emit installProgress( 100 );
+ emit installCompleted();
+ } else
+ emit installFailed();
+}
+
+KNSPluginWizard::KNSPluginWizard(TQWidget *parent, const char *name, KMimeType::Ptr mime)
+: KWizard(parent, name, true)
+, m_installEngine(mime)
+{
+ setCaption(i18n("TDE plugin wizard"));
+ setModal(true);
+
+ // read the plugin installer configuration
+ m_installEngine.pluginAvailable();
+
+ // init the wizzard Pages
+ initConfirmationPage();
+ initLicencePage();
+ initInstallationProgressPage();
+ initFinishPage();
+ initPagesButtonStates();
+
+ // connect signals and slots
+ connectSignals();
+
+ //set correct default installation status
+ m_installationComplete = false;
+
+};
+
+
+KNSPluginWizard::~KNSPluginWizard()
+{
+};
+
+void KNSPluginWizard::initConfirmationPage()
+{
+
+ m_confirmationVBox = new TQVBox(this);
+ new TQLabel(i18n("The following plugins are available."), m_confirmationVBox);
+ m_pluginListView = new KListView(m_confirmationVBox);
+ m_pluginListView->addColumn(i18n("Name"));
+ m_pluginListView->setSelectionMode(TQListView::Single);
+ new TQLabel(i18n("Click on next to install the selected plugin."), m_confirmationVBox);
+ addPage (m_confirmationVBox, i18n("Plugin installation confirmation"));
+
+ bool selected = false;
+
+ // Fill the plugin list
+ TQValueList<KNSPluginInfo>::iterator it;
+ TQValueList<KNSPluginInfo> pluginList = m_installEngine.pluginList();
+ for( it = pluginList.begin(); it != pluginList.end(); ++it ) {
+ PluginListItem *item = new PluginListItem((*it) , m_pluginListView);
+ if(!selected) {
+ selected = true;
+ m_pluginListView->setSelected(item, true);
+ }
+ kdDebug(DEBUG_NUMBER) << "New Plugin List item"<< endl;
+ setNextEnabled(m_confirmationVBox, true);
+ }
+}
+
+void KNSPluginWizard::initLicencePage()
+{
+ m_licenceVBox = new TQVBox(this);
+ m_licencePageLabel = new TQLabel(m_licenceVBox);
+ m_licencePageText = new KTextEdit(m_licenceVBox);
+ m_licencePageText->setReadOnly(true);
+
+ // invisible buttonGroup
+ TQButtonGroup *buttonGroup = new TQButtonGroup(this);
+ m_agreementButtonGroup = buttonGroup;
+ buttonGroup->hide();
+ buttonGroup->setExclusive(true);
+
+ m_licencePageAgree = new TQRadioButton ( i18n("I agree."), m_licenceVBox);
+
+ m_licencePageDisagree = new TQRadioButton ( i18n("I do not agree (plugin will not be installed)."), m_licenceVBox);
+
+ buttonGroup->insert(m_licencePageAgree);
+ buttonGroup->insert(m_licencePageDisagree);
+ m_licencePageDisagree->setChecked(true);
+
+ addPage (m_licenceVBox, i18n("Plugin licence"));
+
+
+ connect(buttonGroup, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(slotAgreementClicked(int)));
+}
+
+void KNSPluginWizard::initInstallationProgressPage() {
+
+ m_installationProgressWidget = new TQWidget(this);
+ TQVBoxLayout *layout = new TQVBoxLayout(m_installationProgressWidget);
+ layout->addWidget(new TQLabel(i18n("Installation in progress."), m_installationProgressWidget));
+ layout->addItem(new TQSpacerItem(40,20,TQSizePolicy::Expanding,TQSizePolicy::Expanding ));
+ m_installationProgressBar = new KProgress(m_installationProgressWidget);
+ m_installationProgressBar->setTotalSteps(100);
+ layout->addWidget(m_installationProgressBar);
+
+ addPage( m_installationProgressWidget, i18n("Plugin installation"));
+
+}
+
+void KNSPluginWizard::initFinishPage()
+{
+ m_finishWidget = new TQWidget(this);
+ TQVBoxLayout *layout = new TQVBoxLayout(m_finishWidget);
+ layout->addItem(new TQSpacerItem(40,20,TQSizePolicy::Expanding,TQSizePolicy::Expanding ));
+ m_finishLabel = new TQLabel(m_finishWidget);
+ layout->addWidget(m_finishLabel);
+ layout->addItem(new TQSpacerItem(40,20,TQSizePolicy::Expanding,TQSizePolicy::Expanding ));
+
+ addPage(m_finishWidget, i18n("Installation status"));
+
+}
+
+
+void KNSPluginWizard::initPagesButtonStates()
+{
+ // set buttons states for the confirmation page
+ setNextEnabled(m_confirmationVBox, true);
+ setFinishEnabled(m_confirmationVBox, false);
+ setHelpEnabled(m_confirmationVBox, false);
+
+ // set buttons states for the licence page
+ setNextEnabled(m_licenceVBox , false);
+ setBackEnabled(m_licenceVBox , false);
+ setFinishEnabled(m_licenceVBox , false);
+ setHelpEnabled(m_licenceVBox , false);
+
+ // for the installation page
+ setNextEnabled(m_installationProgressWidget , false);
+ setBackEnabled(m_installationProgressWidget , false);
+ setFinishEnabled(m_installationProgressWidget , false);
+ setHelpEnabled(m_installationProgressWidget , false);
+
+ // for the finish page
+ setNextEnabled(m_finishWidget , false);
+ setBackEnabled(m_finishWidget , false);
+ setFinishEnabled(m_finishWidget , true);
+ setHelpEnabled(m_finishWidget , false);
+}
+
+
+
+void KNSPluginWizard::connectSignals() {
+ connect(&m_installEngine, TQT_SIGNAL(installProgress(int)), m_installationProgressBar, TQT_SLOT(setProgress(int)) );
+ connect(&m_installEngine, TQT_SIGNAL(installCompleted()), this, TQT_SLOT(slotInstallationCompleted()) );
+ connect(&m_installEngine, TQT_SIGNAL(installFailed()), this, TQT_SLOT(slotInstallationFailed()) );
+
+
+}
+
+void KNSPluginWizard::showPage(TQWidget *page)
+{
+
+ // if the licence page is shown set the label and the licence content
+ if(page == m_licenceVBox && m_licencePageLabel->text().isEmpty()) {
+ KNSPluginInfo info = static_cast<PluginListItem *>(m_pluginListView->selectedItem())->pluginInfo();
+ m_licencePageLabel->setText(i18n("To install ")+info.pluginName()+i18n(" you need to agree to the following"));
+ TQString licence;
+ licence = info.licence();
+ TQString tmpFile;
+ if(info.licenceURL().isValid())
+ // retrieve the licence if we have an url
+ if(TDEIO::NetAccess::download(info.licenceURL(), tmpFile, NULL)) {
+ TQFile f(tmpFile);
+ if(f.open(IO_ReadOnly)) {
+ TQTextStream stream(&f);
+ stream.setEncoding(TQTextStream::UnicodeUTF8);
+ licence = stream.read();
+ f.close();
+ TDEIO::NetAccess::removeTempFile(tmpFile);
+ }
+ }
+ // else display the licence found in the xml config
+ m_licencePageText->setText(licence);
+
+ }
+
+ // if the installation page is shown start the download
+ if(page == m_installationProgressWidget) {
+ KNSPluginInfo info = static_cast<PluginListItem *>(m_pluginListView->selectedItem())->pluginInfo();
+ m_installEngine.startInstall(info);
+
+ }
+
+ // If we must display the finish page
+ if(page == m_finishWidget) {
+ if(m_installationComplete) {
+ m_finishLabel->setText(i18n("Installation completed. Reload the page."));
+
+ } else
+ m_finishLabel->setText(i18n("Installation failed"));
+
+ }
+
+
+ KWizard::showPage(page);
+}
+
+int KNSPluginWizard::exec()
+{
+ if(!m_installEngine.pluginList().count())
+ return TQDialog::Rejected;
+
+ return KWizard::exec();
+}
+
+
+bool KNSPluginWizard::pluginAvailable()
+{
+ return m_installEngine.pluginAvailable();
+}
+
+void KNSPluginWizard::slotAgreementClicked(int id)
+{
+ if( id == m_agreementButtonGroup->id(m_licencePageAgree) ) {
+ setNextEnabled(m_licenceVBox, true);
+
+ } else {
+ setNextEnabled(m_licenceVBox, false);
+ }
+
+}
+
+void KNSPluginWizard::slotInstallationCompleted()
+{
+ m_installationComplete = true;
+ // enable next button
+ setNextEnabled(m_installationProgressWidget, true);
+ next();
+}
+void KNSPluginWizard::slotInstallationFailed()
+{
+ m_installationComplete = false;
+ showPage(m_finishWidget);
+}
+
+
+// KNSPlugin info copy constructor
+
+KNSPluginInfo::KNSPluginInfo()
+{
+
+}
+
+// KNSPlugin info constructor par an xml dom fragment
+KNSPluginInfo::KNSPluginInfo(TQDomNode pluginNode)
+{
+ TQDomElement e;
+ TQDomNode node;
+
+ // Read plugin informations
+ node = pluginNode.firstChild();
+ while(!node.isNull()) {
+ e = node.toElement();
+ if( e.tagName() == "pluginname") {
+ kdDebug(DEBUG_NUMBER) << "found name " << e.text() << endl;
+ m_pluginName = e.text();
+ }
+
+ if( e.tagName() == "pluginurl") {
+ kdDebug(DEBUG_NUMBER) << "found plugin url " << e.text() << endl;
+ m_pluginURL = KURL(e.text());
+ }
+
+ if( e.tagName() == "licence") {
+ kdDebug(DEBUG_NUMBER) << "found licence " << e.text() << endl;
+ m_licence = e.text();
+ }
+
+ if( e.tagName() == "licenceurl") {
+ kdDebug(DEBUG_NUMBER) << "found licenceurl " << e.text() << endl;
+ m_licenceURL = KURL(e.text());
+ }
+
+ if( e.tagName() == "pluginfile") {
+ kdDebug(DEBUG_NUMBER) << "found pluginfile " << e.text() << endl;
+ m_pluginFileList.append(e.text());
+ }
+ node = node.nextSibling();
+ }
+}
+
+
+KNSPluginInfo::~KNSPluginInfo()
+{
+
+}
+
+
+bool KNSPluginInfo::isValid() const
+{
+ // tell if the pluginInfo is a valid One
+ if( m_pluginName.isEmpty() || ( m_licence.isEmpty() && !m_licenceURL.isValid() ) || !m_pluginURL.isValid() || m_pluginFileList.empty() ) {
+ kdDebug(DEBUG_NUMBER) << "invalid plugin info" << endl;
+ return false;
+
+ }
+
+ else {
+
+ kdDebug(DEBUG_NUMBER) << "valid plugin info" << endl;
+ return true;
+ }
+}
+
+// Accesors
+TQString KNSPluginInfo::pluginName() const
+{
+ return m_pluginName;
+}
+
+TQString KNSPluginInfo::licence() const
+{
+ return m_licence;
+}
+
+KURL KNSPluginInfo::licenceURL() const
+{
+ return m_licenceURL;
+}
+
+KURL KNSPluginInfo::pluginURL() const
+{
+ return m_pluginURL;
+}
+
+const TQStringList& KNSPluginInfo::pluginFileList() const
+{
+ return m_pluginFileList;
+}