[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Auto download of flash plugin / bug 66179
From:       Benoît_Canet <bcanet () dental-on-line ! fr>
Date:       2005-09-14 12:44:54
Message-ID: 200509141444.54173.bcanet () dental-on-line ! fr
[Download RAW message or body]

Hello,

I've written a small flash installer for kde 3.5 khtml.
I know 3.5 is feature freeze but maybe this patch can be usefull for some 
people who make their own kde based distro.
The installer use an xml configuration file to retrieve some infos about 
available netscape plugins.
The URL of this configuration file must be given in kcmnspluginrc with a key 
like PluginsListFile=file://$HOME/config.xml.
When this key is present the installer get the xml file with Netaccess and 
parse it.
If a plugin is available for this platform and this mimetype a KWizard is 
shown.
If no plugin is available the normal download plugin dialog is displayed.
The install wizard looks like Firefox plugin install wizard.
The wizard download the licence and the plugin tar.gz from macromedia web site 
so there no licence problem.

shortcomings :
	the wizard doesn't reload the current web page at the end of the install.
	I'm not sure if this installer works with the AMD64 platform.

Best Regards

Benoît Canet
Dental On Line

ps : the patch apply to kdelibs/khtml

["plugins.xml" (text/xml)]

<?xml version="1.0"?>
<arch architecture="ia32">
    <os name="Linux">
        <plugin mimetype="application/x-shockwave-flash">
            <pluginname>Macromedia Flash Player 7.0</pluginname>
            <pluginurl>http://fpdownload.macromedia.com/get/shockwave/flash/english/linux/7.0r25/install_flash_player_7_linux.tar.gz</pluginurl>
                
            <licenceurl>http://www.macromedia.com//shockwave/download/license/desktop/ssi/eula_ssi.html</licenceurl>
                
            <licence>this field appear if licenceurl doesn't exist</licence>
            <pluginfile>install_flash_player_7_linux/flashplayer.xpt</pluginfile>
            <pluginfile>install_flash_player_7_linux/libflashplayer.so</pluginfile>
        </plugin>
    </os>
</arch>    


["patch.diff" (text/x-diff)]

Index: misc/knsplugininstaller.cpp
===================================================================
--- misc/knsplugininstaller.cpp	(revision 0)
+++ misc/knsplugininstaller.cpp	(revision 0)
@@ -0,0 +1,658 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2005 Benoit Canet <bcanet@dental-on-line.fr>
+ *           with some advices from 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 Steet, 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 <qbuttongroup.h>
+#include <qdir.h>
+#include <qiodevice.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h> 
+#include <qmap.h>
+#include <qstringlist.h>
+#include <qtextstream.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 QListViewItem
+{
+
+public:
+    PluginListItem(KNSPluginInfo pluginInfo, QListView *parent)
+    : QListViewItem(parent, pluginInfo.pluginName())
+    , m_pluginInfo(pluginInfo) {}
+    KNSPluginInfo pluginInfo() const { return m_pluginInfo; }
+
+private:
+    KNSPluginInfo m_pluginInfo;
+
+};
+
+
+// public methods 
+
+KNSPluginInstallEngine::KNSPluginInstallEngine(KMimeType::Ptr mime) : QObject()
+{
+    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
+    QString pluginsListFile;
+    KConfig cfg("kcmnspluginrc", true);
+    cfg.setGroup("Misc");
+    pluginsListFile = cfg.readPathEntry("PluginsListFile");
+    return !pluginsListFile.isEmpty();
+}
+
+const QValueList<KNSPluginInfo>& KNSPluginInstallEngine::pluginList() const
+{
+    return m_pluginList;
+}
+
+// private methods 
+bool KNSPluginInstallEngine::loadConfig()
+{
+    QString pluginsListFile;
+    KConfig 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())
+    {
+        QString tmpFile;
+        if(KIO::NetAccess::download(m_pluginsListFileURL, tmpFile, NULL)) {
+            QFile f(tmpFile);
+            if(!f.open(IO_ReadOnly))
+                return false;
+            QTextStream stream(&f);
+            stream.setEncoding(QTextStream::UnicodeUTF8);
+            m_pluginsXmlConfig = stream.read();
+            f.close();
+            KIO::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;
+    QString sysname(sysinfo.sysname);
+    QString machine(sysinfo.machine);
+    QString arch = m_archMap[machine]; 
+    
+    // Parse the document
+    QDomDocument doc("xmlConfig");
+    doc.setContent(m_pluginsXmlConfig);
+    QDomNodeList archList = doc.elementsByTagName(QString("arch"));
+    QDomNode archNode, osNode , pluginNode, node;
+    QDomElement 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") , QString(".tar.gz"));
+    m_tmpPluginFileName = tempFile.name();
+    tempFile.unlink();
+    tempFile.close();
+    // start the download job
+    m_downloadJob  = KIO::copy(info.pluginURL(), "file://"+m_tmpPluginFileName, \
false ); +    // connect signals 
+    connect(m_downloadJob, SIGNAL(percent (KIO::Job *, unsigned long)), this , \
SLOT(slotDownLoadProgress(KIO::Job *, unsigned long))); +    connect(m_downloadJob, \
SIGNAL(result(KIO::Job *)), this, SLOT(slotDownloadResult(KIO::Job *)) ); +    \
kdDebug(DEBUG_NUMBER) << "download plugin " << m_tmpPluginFileName << endl; +} 
+
+void KNSPluginInstallEngine::slotDownLoadProgress(KIO::Job *, unsigned long percent)
+{ 
+    // propagate the download progression
+    emit installProgress( ((int)percent)/3 );
+}
+
+void KNSPluginInstallEngine::slotDownloadResult(KIO::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
+       QDir dir(QDir::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://"+QDir::homeDirPath()+"/.mozilla/plugins");
+
+       // construct the source kurlList
+       KURL::List urlList;
+       QStringList pluginFileList = m_toInstallPluginInfo.pluginFileList();
+
+       QStringList::iterator it;
+       for( it = pluginFileList.begin(); it != pluginFileList.end(); ++it ) {
+           urlList.append( KURL("tar://"+m_tmpPluginFileName+"/"+(*it)) );
+        }
+       m_installFileJob  = KIO::copy(urlList , destURL, false );
+       connect(m_installFileJob, SIGNAL(percent (KIO::Job *, unsigned long)), this , \
SLOT(slotCopyProgress(KIO::Job *, unsigned long))); +       connect(m_installFileJob, \
SIGNAL(result(KIO::Job *)), this, SLOT(slotCopyResult(KIO::Job *)) ); +    }
+    kdDebug(DEBUG_NUMBER) << "COPY FILE " << m_tmpPluginFileName << endl;
+
+    // zero the download job pointer
+    m_downloadJob = NULL;
+}
+
+void KNSPluginInstallEngine::slotCopyProgress(KIO::Job *, unsigned long percent)
+{
+    // propagate the download progression
+    emit installProgress( ((int)percent)/3 + 33 );
+} 
+ 
+void KNSPluginInstallEngine::slotCopyResult(KIO::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 QProcess( this );
+       m_scanProc->addArgument( "nspluginscan" );
+       m_scanProc->addArgument( "--verbose" );
+
+       connect( m_scanProc, SIGNAL(readyReadStdout()),
+               this, SLOT(readScanProcFromStdout()) );
+       connect( m_scanProc, SIGNAL(processExited()),
+               this, SLOT(endScanProc()) );
+       if ( !m_scanProc->start() ) {
+            emit installFailed();
+       }
+    }
+}
+
+void KNSPluginInstallEngine::readScanProcFromStdout()
+{
+    // Monitor the scan progress
+    QString 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(QWidget *parent, const char *name, KMimeType::Ptr \
mime) +: KWizard(parent, name, true)
+, m_installEngine(mime)
+{
+    setCaption(i18n("KDE plugin wizard"));
+    setModal(true);
+
+    // read the plugin installer configuration
+    m_installEngine.pluginAvailable();
+
+    // init the wizzard Pages
+    initConfirmationPage();
+    initLicencePage();
+    initInstallationProgressPage();
+    initFinishPage();
+
+    // connect signals and slots
+    connectSignals();
+
+    //set correct default installation status
+    m_installationComplete = false;
+
+};
+
+
+KNSPluginWizard::~KNSPluginWizard()
+{
+};
+
+void KNSPluginWizard::initConfirmationPage() 
+{
+
+        m_confirmationVBox = new QVBox(this);
+        new QLabel(i18n("The following plugins are available."), \
m_confirmationVBox); +        m_pluginListView = new KListView(m_confirmationVBox);   \
 +        m_pluginListView->addColumn(i18n("Name"));
+        m_pluginListView->setSelectionMode(QListView::Single);
+        new QLabel(i18n("Click on next to install the selected plugin."), \
m_confirmationVBox); +        addPage (m_confirmationVBox, i18n("Plugin installation \
confirmation")); +        
+        
+        // set the corrects buttons for the wizard
+        setNextEnabled(m_confirmationVBox, false);
+        setFinishEnabled(m_confirmationVBox, false);
+        setHelpEnabled(m_confirmationVBox, false);
+
+        bool selected = false;
+  
+        // Fill the plugin list
+        QValueList<KNSPluginInfo>::iterator it;
+        QValueList<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 QVBox(this);
+    m_licencePageLabel = new QLabel(m_licenceVBox);
+    m_licencePageText = new KTextEdit(m_licenceVBox);
+    m_licencePageText->setReadOnly(true);
+    
+    // invisible buttonGroup
+    QButtonGroup *buttonGroup = new QButtonGroup(this);
+    m_agreementButtonGroup = buttonGroup;
+    buttonGroup->hide();
+    buttonGroup->setExclusive(true);
+    
+    m_licencePageAgree = new QRadioButton ( i18n("I agree."), m_licenceVBox);
+    
+    m_licencePageDisagree = new QRadioButton ( i18n("I do not agree (plugin will not \
be installed)."), m_licenceVBox); +
+    buttonGroup->insert(m_licencePageAgree);
+    buttonGroup->insert(m_licencePageDisagree);
+    m_licencePageAgree->setChecked(true);
+    
+    addPage (m_licenceVBox, i18n("Plugin licence"));
+
+    setNextEnabled(m_licenceVBox    , true);
+    setBackEnabled(m_licenceVBox  , false);
+    setFinishEnabled(m_licenceVBox  , false);
+    setHelpEnabled(m_licenceVBox    , false);
+
+    connect(buttonGroup, SIGNAL(clicked(int)), this, \
SLOT(slotAgreementClicked(int))); +}
+
+void KNSPluginWizard::initInstallationProgressPage() {
+
+    m_installationProgressWidget = new QWidget(this);
+    QVBoxLayout *layout = new QVBoxLayout(m_installationProgressWidget);
+    layout->addWidget(new QLabel(i18n("Installation in progress."), \
m_installationProgressWidget)); +    layout->addItem(new \
QSpacerItem(40,20,QSizePolicy::Expanding,QSizePolicy::Expanding )); +    \
m_installationProgressBar = new KProgress(m_installationProgressWidget); +    \
m_installationProgressBar->setTotalSteps(100); +    \
layout->addWidget(m_installationProgressBar); +    
+    addPage( m_installationProgressWidget, i18n("Plugin installation"));
+    
+    setNextEnabled(m_installationProgressWidget     , false);
+    setBackEnabled(m_installationProgressWidget     , false);
+    setFinishEnabled(m_installationProgressWidget   , false);
+    setHelpEnabled(m_installationProgressWidget     , false);
+}
+
+void KNSPluginWizard::initFinishPage()
+{
+    m_finishWidget = new QWidget(this);
+    QVBoxLayout *layout = new QVBoxLayout(m_finishWidget);
+    layout->addItem(new \
QSpacerItem(40,20,QSizePolicy::Expanding,QSizePolicy::Expanding )); +    \
m_finishLabel = new QLabel(m_finishWidget); +    layout->addWidget(m_finishLabel);
+    layout->addItem(new \
QSpacerItem(40,20,QSizePolicy::Expanding,QSizePolicy::Expanding )); +    
+    addPage(m_finishWidget, i18n("Installation status"));
+    
+    setNextEnabled(m_finishWidget     , false);
+    setBackEnabled(m_finishWidget     , false);
+    setFinishEnabled(m_finishWidget   , true);
+    setHelpEnabled(m_finishWidget     , false);
+}
+
+
+void KNSPluginWizard::connectSignals() {
+    connect(&m_installEngine, SIGNAL(installProgress(int)), \
m_installationProgressBar, SLOT(setProgress(int)) ); +    connect(&m_installEngine, \
SIGNAL(installCompleted()), this, SLOT(slotInstallationCompleted()) ); +     \
connect(&m_installEngine, SIGNAL(installFailed()), this, \
SLOT(slotInstallationFailed()) ); +     
+
+}
+
+void KNSPluginWizard::showPage(QWidget *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")); +        QString licence;
+        licence = info.licence();
+        QString tmpFile;
+        if(info.licenceURL().isValid()) 
+            // retrieve the licence if we have an url
+            if(KIO::NetAccess::download(info.licenceURL(), tmpFile, NULL)) {
+                    QFile f(tmpFile);
+                    if(f.open(IO_ReadOnly)) {
+                        QTextStream stream(&f);
+                        stream.setEncoding(QTextStream::UnicodeUTF8);
+                        licence  = stream.read();
+                        f.close();
+                        KIO::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 QDialog::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;
+    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(QDomNode pluginNode)
+{
+    QDomElement e;
+    QDomNode 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
+QString KNSPluginInfo::pluginName() const
+{
+    return m_pluginName;
+}
+
+QString KNSPluginInfo::licence() const
+{
+    return m_licence;
+}
+
+KURL KNSPluginInfo::licenceURL() const
+{
+    return m_licenceURL;
+}
+
+KURL KNSPluginInfo::pluginURL() const
+{
+    return m_pluginURL;
+}
+
+const QStringList& KNSPluginInfo::pluginFileList() const
+{
+    return m_pluginFileList;
+}
Index: misc/Makefile.am
===================================================================
--- misc/Makefile.am	(revision 460523)
+++ misc/Makefile.am	(working copy)
@@ -22,14 +22,14 @@
 noinst_LTLIBRARIES = libkhtmlmisc.la
 libkhtmlmisc_la_SOURCES = \
 	decoder.cpp    loader.cpp loader_jpeg.cpp guess_ja.cpp\
-	htmlhashes.cpp helper.cpp arena.cpp stringit.cpp
+	htmlhashes.cpp helper.cpp arena.cpp stringit.cpp knsplugininstaller.cpp
 libkhtmlmisc_la_LIBADD = $(LIBJPEG)
 libkhtmlmisc_la_LDFLAGS = $(USER_LDFLAGS)
 libkhtmlmisc_la_METASOURCES = AUTO
 
 noinst_HEADERS = \
 	decoder.h khtmllayout.h loader_jpeg.h loader.h guess_ja.h\
-	stringit.h htmlhashes.h helper.h shared.h arena.h 
+	stringit.h htmlhashes.h helper.h shared.h arena.h knsplugininstaller.h
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/dcop -I$(top_srcdir)/kio \
                -I$(top_srcdir)/libltdl \
            -I$(top_srcdir)/khtml -I$(top_srcdir)/kutils $(all_includes)
Index: misc/knsplugininstaller.h
===================================================================
--- misc/knsplugininstaller.h	(revision 0)
+++ misc/knsplugininstaller.h	(revision 0)
@@ -0,0 +1,266 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2005 Benoit Canet <bcanet@dental-on-line.fr>
+ *           with some advices from 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 Steet, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KNSPLUGININSTALLER_H
+#define KNSPLUGININSTALLER_H
+
+#include <job.h>
+#include <ktextedit.h>
+#include <kmimetype.h>
+#include <kprogress.h> 
+#include <kurl.h>
+#include <kwizard.h>
+
+#include <qbuttongroup.h>
+#include <qdom.h>
+#include <qlabel.h>
+#include <qobject.h>
+#include <qprocess.h>
+#include <qradiobutton.h>
+#include <qvaluelist.h>
+#include <qvbox.h>
+#include <qwidget.h>
+
+class QStringList;
+
+/*
+ * This class contains all the infos needed to install a given plugin
+ * Takes and parse a QDomNode in its constructor
+ */
+class KNSPluginInfo 
+{
+
+public:
+
+    /*
+     * Construct the plugin info object
+     */
+    KNSPluginInfo();
+    KNSPluginInfo(QDomNode pluginNode);
+    ~KNSPluginInfo();
+
+    /*
+     * Check the validity of the plugin info object
+     */
+    bool isValid() const;
+
+    //Accessor methods
+    QString pluginName() const;
+    QString licence() const;
+    KURL licenceURL() const;
+    KURL pluginURL() const;
+    const QStringList& pluginFileList() const;
+   
+private:
+ 
+    // plugin info
+    QString m_pluginName;
+    QString m_licence;
+    KURL m_licenceURL;
+    KURL m_pluginURL;
+    QStringList m_pluginFileList;
+    
+    
+};
+
+
+/*
+ * This class contain all the the methods used to perform a plugin installation
+ *
+ */
+class KNSPluginInstallEngine : public QObject
+{
+    Q_OBJECT
+public:
+
+    /*
+     * Construct the class
+     */
+    KNSPluginInstallEngine(KMimeType::Ptr mime);
+    ~KNSPluginInstallEngine();
+    
+    /*
+     * Check if the installer engine and wizzard is activated
+     */
+    static bool isActive();
+    /**
+     * Check the availability of a plugin 
+     */
+    bool pluginAvailable();
+    /*
+     * Return the list of plugins Available
+     */
+    const QValueList<KNSPluginInfo>& pluginList() const;
+    void startInstall(KNSPluginInfo info);
+
+    
+
+private:
+
+    // methods used to check the kde config and detect if an adequate plugin is \
available + 
+    /*
+     * load kde KNSPluginInstaller config
+     */
+    bool loadConfig();
+    /*
+     * retrieve the xml configuration file
+     */
+    bool loadXmlConfig();
+    /*
+     * parse the xml configuration file
+     */
+    bool findPlugin();
+    
+
+    QMap<QString, QString> m_archMap;
+    QString m_pluginsXmlConfig;
+    QValueList<KNSPluginInfo> m_pluginList;
+    KMimeType::Ptr m_mime;
+    KURL m_pluginsListFileURL;
+    QString m_tmpPluginFileName;
+    KIO::CopyJob *m_downloadJob;
+    KIO::CopyJob *m_installFileJob;
+    KNSPluginInfo m_toInstallPluginInfo;
+    QProcess *m_scanProc;
+    
+signals:
+    // Signals used to communicate with the wizzard 
+    void installProgress(int percent);
+    void installCompleted();
+    void installFailed();
+   
+private slots:
+    // Used to monitor the plugin downloading
+    void slotDownLoadProgress(KIO::Job *job, unsigned long percent);
+    void slotDownloadResult(KIO::Job *job);
+    
+    // Used to monitor the plugin installation
+    void slotCopyProgress(KIO::Job *job, unsigned long percent);
+    void slotCopyResult(KIO::Job *job);
+
+    // Used to monitor the plugins scan
+    void readScanProcFromStdout();
+    void endScanProc();
+
+
+
+};
+
+/*
+ * This class is a wizzard used to install a plugin 
+ */
+class KNSPluginWizard : public KWizard
+{
+    Q_OBJECT
+public:
+        
+    /**
+    * Construct a KNSpluginInstaller
+    */
+    KNSPluginWizard(QWidget *parent, const char *name,  KMimeType::Ptr mime);
+    ~KNSPluginWizard();
+
+
+    /**
+     * Lauch the wizzard
+     */
+    int exec();
+    /*
+     * Check the availability of a plugin
+     */
+    bool pluginAvailable();
+
+
+private:
+    // methods used in the constructor to init the wizzard pages
+    void initConfirmationPage();
+    void initLicencePage();
+    void initInstallationProgressPage();
+    void initFinishPage();
+    
+    /*
+     * Connect signals
+     */
+    void connectSignals();
+    
+    /*
+     * Overiden method called when a page is shown
+     */
+    void showPage(QWidget *page);
+
+
+    // Plugin installation engine
+    KNSPluginInstallEngine m_installEngine;
+
+    // pages widgets
+    QVBox *m_confirmationVBox;
+    QVBox *m_licenceVBox;
+    QWidget *m_installationProgressWidget;
+    QWidget *m_finishWidget;
+    
+    // plugin list
+    KListView *m_pluginListView;
+    
+    // licence stuff
+    QLabel *m_licencePageLabel;
+    KTextEdit *m_licencePageText;
+    QRadioButton *m_licencePageAgree;
+    QRadioButton *m_licencePageDisagree;
+    QButtonGroup *m_agreementButtonGroup;
+
+    // installation progress bar
+    KProgress *m_installationProgressBar;
+
+    // Finish Label 
+    QLabel *m_finishLabel;
+
+    // installation status
+    bool m_installationComplete;
+ 
+private slots:
+    /*
+     * Check if the user Agree or disagree with the licence
+     */
+    void slotAgreementClicked(int id);
+    /*
+     * Called when the installation is completed
+     */
+    void slotInstallationCompleted();
+    /*
+     * Called when the installation has failed
+     */
+    void slotInstallationFailed();
+
+signals:
+    /*
+     * Emited when the installation has complete - TODO connect this signal to \
reload the page +     */
+    void pluginInstallCompleted();
+};
+
+
+
+   
+
+#endif
Index: rendering/render_frames.cpp
===================================================================
--- rendering/render_frames.cpp	(revision 460523)
+++ rendering/render_frames.cpp	(working copy)
@@ -35,6 +35,7 @@
 #include "misc/htmltags.h"
 #include "khtmlview.h"
 #include "khtml_part.h"
+#include "misc/knsplugininstaller.h"
 
 #include <kapplication.h>
 #include <kmessagebox.h>
@@ -816,17 +817,30 @@
         if (!mimeName.isEmpty() && part->docImpl() && \
!part->pluginPageQuestionAsked( serviceType ) )  {
             part->setPluginPageQuestionAsked( serviceType );
-            // Prepare the URL to show in the question (host only if http, to make \
                it short)
-            KURL pluginPageURL( embed->pluginPage );
-            QString shortURL = pluginPageURL.protocol() == "http" ? \
                pluginPageURL.host() : pluginPageURL.prettyURL();
-            int res = KMessageBox::questionYesNo( m_view,
-                                                  i18n("No plugin found for \
                '%1'.\nDo you want to download one from \
                %2?").arg(mimeName).arg(shortURL),
-                                                  i18n("Missing Plugin"), \
                i18n("Download"), i18n("Do Not Download"), \
                QString("plugin-")+serviceType);
-            if ( res == KMessageBox::Yes )
+            bool pluginAvailable;
+            pluginAvailable = false;
+            // check if a pluginList file is in the config
+            if(KNSPluginInstallEngine::isActive())
             {
-                // Display vendor download page
-                ext->createNewWindow( pluginPageURL );
-                return;
+                KNSPluginWizard pluginWizard(m_view, "pluginInstaller", mime);
+                if(pluginWizard.pluginAvailable()) {
+                    pluginAvailable = true;
+                    pluginWizard.exec();
+                }
+            } 
+            if(!pluginAvailable) {
+                // Prepare the URL to show in the question (host only if http, to \
make it short) +                KURL pluginPageURL( embed->pluginPage );
+                QString shortURL = pluginPageURL.protocol() == "http" ? \
pluginPageURL.host() : pluginPageURL.prettyURL(); +                int res = \
KMessageBox::questionYesNo( m_view, +                                                 \
i18n("No plugin found for '%1'.\nDo you want to download one from \
%2?").arg(mimeName).arg(shortURL), +                                                  \
i18n("Missing Plugin"), i18n("Download"), i18n("Do Not Download"), \
QString("plugin-")+serviceType); +                if ( res == KMessageBox::Yes )
+                {
+                    // Display vendor download page
+                    ext->createNewWindow( pluginPageURL );
+                    return;
+                }
             }
         }
     }
@@ -886,4 +900,5 @@
   }
 }
 
+
 #include "render_frames.moc"



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic