QtWebkit中浏览器插件的设计2

    前一节介绍的插件设计方式中虽然方便,但是其Mime类型只能是application/x-qt-plugin或者application/x-qt-styled-widget,这个有时候可能满足不了实际应用需求,那么另一种就没有这种限制,那可以是任意Mime类型的。这种设计需要重新实现QWebPluginFactory这个纯虚基类。先看看他的声明:

前一节介绍的插件设计方式中虽然方便,但是其Mime类型只能是application/x-qt-plugin或者application/x-qt-styled-widget,这个有时候可能满足不了实际应用需求,那么另一种就没有这种限制,那可以是任意Mime类型的。这种设计需要重新实现QWebPluginFactory这个纯虚基类。先看看他的声明:

class QWEBKIT_EXPORT QWebPluginFactory : public QObject {

……

public:

struct Plugin {

QString name;

QString description;

QList<MimeType> mimeTypes;

};

explicit QWebPluginFactory(QObject* parent = 0);

virtual ~QWebPluginFactory();

 

virtual QList<Plugin> plugins() const = 0;

virtual void refreshPlugins();

 

virtual QObject *create(const QString& mimeType,

const QUrl&,

const QStringList& argumentNames,

const QStringList& argumentValues) const = 0;

 

 

virtual bool extension(Extension extension, const ExtensionOption* option = 0, ExtensionReturn* output = 0);

virtual bool supportsExtension(Extension extension) const;

……

};

重点要实现的接口是plugins,用于获取plugin的列表,用于webkit内部判断该mime类型是否被支持,如果可以支持,那么就会调用create来创建这个插件,而具体打开哪个文件以及参数都会传递进来。

后两个extensionsupportsExtension接口暂时没有发现有什么用处,暂不考虑。

因此重新实现的WebPluginFactory如下:

class WebPluginFactory: public QWebPluginFactory

{

    public:

        WebPluginFactory(QObject *parent = 0);

        ~WebPluginFactory(){};

        QList<QWebPluginFactory::Plugin> plugins()const ;

        void refreshPlugins();

        QObject *create(const QString &mimeType,

                const QUrl &url,

                const QStringList &argumentNames,

                const QStringList &argumentValues) const ;

        bool extension(QWebPluginFactory::Extension extension, const QWebPluginFactory::ExtensionOption *option = 0, QWebPluginFactory::ExtensionReturn *output = 0);

        bool supportsExtension(QWebPluginFactory::Extension extension) const;

    private:

        // 用于将载入的插件记录下来

        mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist;

        mutable QList<WebKitPluginInteface *> interfaces;

};

具体实现主要是create和plugins两个函数:

QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins() const

{

    const char * s=getenv("BROWSER_PLUGIN_DIR");

    static bool isFirst=true;

    if(!isFirst)

    {

        return pluginslist;

    }

    isFirst=false;

    QString spath;

    if(s)

    spath=s;

    else

{

spath=".";

}

    QDir dir(spath);

    QStringList filters;

    QString abspath=dir.absolutePath();

filters<<"libqtweb*.so"; //查找下面的扩张,linux下是so,windows下则应该是dll,

    QStringList files=dir.entryList(filters);

    foreach(QString file,files)

    {

        file=dir.filePath(file);

        QPluginLoader loader(file,0);

        QObject * obj= loader.instance();

//下面是载入自定义的接口,只有这样才能支持动态插件创建,如果固定死了,将不利于扩展,后一节会介绍这部分内容

        WebKitPluginInteface * interface= qobject_cast<WebKitPluginInteface*> (obj);

        if(interface==0)

        {

            //ignore error when loading so ;

            continue;

        }

        interface->plugins();

        plugins.append(interface->plugins());

        pluginslist.append(interface->plugins());

        interfaces.append(interface);

    }

    return plugins;

}

void WebPluginFactory::refreshPlugins()

{

    Reload();

}

QObject * WebPluginFactory::create(const QString &mimeType,

        const QUrl &url,

        const QStringList &argumentNames,

        const QStringList &argumentValues) const

{

    for(int i=0;i<pluginslist.size();i++)

    {

        for( int j=0;j< pluginslist[i].size();j++)

        {

            foreach(WebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes)

            {

                if(mt.name == mimeType) //查找到,创建实例

                    return interfaces[i]->create( mimeType, url, argumentNames, argumentValues);

            }

        }

    }

    return NULL; //如果没有,直接返回NULL,webkit会进行处理的

}

这两个最主要的接口都是围绕着mimetype进行的,通过返回的列表告诉webkit插件支持什么类型的文件,而create则根据mimetype来识别文件类型,然后创建相应的插件。

下一节会简单的创建一个插件来演示如何创建一个插件。

原文地址:https://www.cnblogs.com/baizx/p/1785836.html