1
0
mirror of https://github.com/qgis/QGIS.git synced 2025-04-17 00:04:02 -04:00

Browser: Abstract creation of custom data items into QgsDataItemProvider

This commit is contained in:
Martin Dobias 2015-03-04 19:26:42 +07:00
parent 427adf79bb
commit cdb44a3cc6
12 changed files with 267 additions and 78 deletions

@ -26,6 +26,8 @@
%Include qgscrscache.sip
%Include qgsdatadefined.sip
%Include qgsdataitem.sip
%Include qgsdataitemprovider.sip
%Include qgsdataitemproviderregistry.sip
%Include qgsdataprovider.sip
%Include qgsdatasourceuri.sip
%Include qgsdatumtransformstore.sip

@ -0,0 +1,20 @@
class QgsDataItemProvider
{
%TypeHeaderCode
#include <qgsdataitemprovider.h>
%End
public:
virtual ~QgsDataItemProvider();
//! Human-readable name of the provider name
virtual QString name() = 0;
//! Return combination of flags from QgsDataProvider::DataCapabilities
virtual int capabilities() = 0;
//! Create a new instance of QgsDataItem (or null) for given path and parent item.
//! Caller takes responsibility of deleting created items.
virtual QgsDataItem* createDataItem( const QString& path, QgsDataItem* parentItem ) = 0 /Factory/;
};

@ -0,0 +1,19 @@
class QgsDataItemProviderRegistry
{
%TypeHeaderCode
#include <qgsdataitemproviderregistry.h>
%End
public:
//! Returns the instance pointer, creating the object on the first call
static QgsDataItemProviderRegistry * instance();
~QgsDataItemProviderRegistry();
//! Get list of available providers
QList<QgsDataItemProvider*> providers() const;
private:
QgsDataItemProviderRegistry();
};

@ -77,6 +77,8 @@ SET(QGIS_CORE_SRCS
qgsdatadefined.cpp
qgsdatasourceuri.cpp
qgsdataitem.cpp
qgsdataitemprovider.cpp
qgsdataitemproviderregistry.cpp
qgsdatumtransformstore.cpp
qgsdbfilterproxymodel.cpp
qgsdiagramrendererv2.cpp
@ -475,6 +477,9 @@ SET(QGIS_CORE_HDRS
qgscsexception.h
qgsdartmeasurement.h
qgsdatadefined.h
qgsdataitem.h
qgsdataitemprovider.h
qgsdataitemproviderregistry.h
qgsdatasourceuri.h
qgsdatumtransformstore.h
qgsdbfilterproxymodel.h

@ -15,6 +15,7 @@
#include "qgsapplication.h"
#include "qgscrscache.h"
#include "qgsdataitemproviderregistry.h"
#include "qgsexception.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
@ -626,6 +627,7 @@ void QgsApplication::exitQgis()
QgsMapLayerRegistry::cleanup();
QgsNetworkAccessManager::cleanup();
QgsCoordinateTransformCache::cleanup();
QgsDataItemProviderRegistry::cleanup();
// Cleanup providers
delete QgsProviderRegistry::instance();

@ -19,6 +19,8 @@
#include "qgis.h"
#include "qgsapplication.h"
#include "qgsdataitemprovider.h"
#include "qgsdataitemproviderregistry.h"
#include "qgsdataprovider.h"
#include "qgsmimedatautils.h"
#include "qgslogger.h"
@ -123,40 +125,19 @@ void QgsBrowserModel::addRootItems()
mRootItems << vols;
#endif
// Add non file top level items
QStringList providersList = QgsProviderRegistry::instance()->providerList();
// container for displaying providers as sorted groups (by QgsDataProvider::DataCapability enum)
QMap<int, QgsDataItem *> providerMap;
foreach ( QString key, providersList )
foreach ( QgsDataItemProvider* pr, QgsDataItemProviderRegistry::instance()->providers() )
{
QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( key );
if ( !library )
continue;
dataCapabilities_t * dataCapabilities = ( dataCapabilities_t * ) cast_to_fptr( library->resolve( "dataCapabilities" ) );
if ( !dataCapabilities )
{
QgsDebugMsg( library->fileName() + " does not have dataCapabilities" );
continue;
}
int capabilities = dataCapabilities();
int capabilities = pr->capabilities();
if ( capabilities == QgsDataProvider::NoDataCapabilities )
{
QgsDebugMsg( library->fileName() + " does not have any dataCapabilities" );
QgsDebugMsg( pr->name() + " does not have any dataCapabilities" );
continue;
}
dataItem_t *dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
if ( !dataItem )
{
QgsDebugMsg( library->fileName() + " does not have dataItem" );
continue;
}
QgsDataItem *item = dataItem( "", NULL ); // empty path -> top level
QgsDataItem *item = pr->createDataItem( "", NULL ); // empty path -> top level
if ( item )
{
QgsDebugMsg( "Add new top level item : " + item->name() );

@ -32,6 +32,8 @@
#include "qgis.h"
#include "qgsdataitem.h"
#include "qgsdataitemprovider.h"
#include "qgsdataitemproviderregistry.h"
#include "qgsdataprovider.h"
#include "qgslogger.h"
#include "qgsproviderregistry.h"
@ -715,39 +717,6 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem* parent, QString name, QString d
void QgsDirectoryItem::init()
{
if ( mLibraries.size() > 0 )
return;
QStringList keys = QgsProviderRegistry::instance()->providerList();
QStringList::const_iterator i;
for ( i = keys.begin(); i != keys.end(); ++i )
{
QString k( *i );
// some providers hangs with empty uri (Postgis) etc...
// -> using libraries directly
QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( k );
if ( library )
{
dataCapabilities_t * dataCapabilities = ( dataCapabilities_t * ) cast_to_fptr( library->resolve( "dataCapabilities" ) );
if ( !dataCapabilities )
{
QgsDebugMsg( library->fileName() + " does not have dataCapabilities" );
continue;
}
if ( dataCapabilities() == QgsDataProvider::NoDataCapabilities )
{
QgsDebugMsg( library->fileName() + " has NoDataCapabilities" );
continue;
}
QgsDebugMsg( QString( "%1 dataCapabilities : %2" ).arg( library->fileName() ).arg( dataCapabilities() ) );
mLibraries.append( library );
}
else
{
//QgsDebugMsg ( "Cannot get provider " + k );
}
}
}
QgsDirectoryItem::~QgsDirectoryItem()
@ -761,6 +730,7 @@ QIcon QgsDirectoryItem::icon()
return iconDir();
}
QVector<QgsDataItem*> QgsDirectoryItem::createChildren()
{
QVector<QgsDataItem*> children;
@ -808,18 +778,9 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren()
}
}
foreach ( QLibrary *library, mLibraries )
foreach ( QgsDataItemProvider* provider, QgsDataItemProviderRegistry::instance()->providers() )
{
// we could/should create separate list of providers for each purpose
// TODO: use existing fileVectorFilters(),directoryDrivers() ?
dataCapabilities_t * dataCapabilities = ( dataCapabilities_t * ) cast_to_fptr( library->resolve( "dataCapabilities" ) );
if ( !dataCapabilities )
{
continue;
}
int capabilities = dataCapabilities();
int capabilities = provider->capabilities();
if ( !(( fileInfo.isFile() && ( capabilities & QgsDataProvider::File ) ) ||
( fileInfo.isDir() && ( capabilities & QgsDataProvider::Dir ) ) ) )
@ -827,19 +788,13 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren()
continue;
}
dataItem_t * dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
if ( ! dataItem )
{
QgsDebugMsg( library->fileName() + " does not have dataItem" );
continue;
}
QgsDataItem * item = dataItem( path, this );
QgsDataItem * item = provider->createDataItem( path, this );
if ( item )
{
children.append( item );
}
}
}
return children;

@ -362,7 +362,8 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
/* static QVector<QgsDataProvider*> mProviders; */
//! @note not available via python bindings
static QVector<QLibrary*> mLibraries;
//! @note deprecated since 2.10 - use QgsDataItemProviderRegistry
Q_DECL_DEPRECATED static QVector<QLibrary*> mLibraries;
public slots:
virtual void childrenCreated() override;

@ -0,0 +1,18 @@
/***************************************************************************
qgsdataitemprovider.cpp
--------------------------------------
Date : March 2015
Copyright : (C) 2015 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "qgsdataitemprovider.h"
// no implementation currently

@ -0,0 +1,52 @@
/***************************************************************************
qgsdataitemprovider.h
--------------------------------------
Date : March 2015
Copyright : (C) 2015 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef QGSDATAITEMPROVIDER_H
#define QGSDATAITEMPROVIDER_H
class QgsDataItem;
class QString;
/**
* This is the interface for those who want to add custom data items to the browser tree.
*
* The method createDataItem() is ever called only if capabilities() return non-zero value.
* There are two occasions when createDataItem() is called:
* 1. to create root items (passed path is empty, parent item is null).
* 2. to create items in directory structure. For this capabilities have to return at least
* of the following: QgsDataProider::Dir or QgsDataProvider::File. Passed path is the file
* or directory being inspected, parent item is a valid QgsDirectoryItem
*
* @note added in 2.10
*/
class CORE_EXPORT QgsDataItemProvider
{
public:
virtual ~QgsDataItemProvider() {}
//! Human-readable name of the provider name
virtual QString name() = 0;
//! Return combination of flags from QgsDataProvider::DataCapabilities
virtual int capabilities() = 0;
//! Create a new instance of QgsDataItem (or null) for given path and parent item.
//! Caller takes responsibility of deleting created items.
virtual QgsDataItem* createDataItem( const QString& path, QgsDataItem* parentItem ) = 0;
};
#endif // QGSDATAITEMPROVIDER_H

@ -0,0 +1,86 @@
/***************************************************************************
qgsdataitemproviderregistry.cpp
--------------------------------------
Date : March 2015
Copyright : (C) 2015 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "qgsdataitemproviderregistry.h"
#include "qgsdataitem.h"
#include "qgsdataitemprovider.h"
#include "qgsdataprovider.h"
#include "qgslogger.h"
#include "qgsproviderregistry.h"
/** Simple data item provider implementation that handles the support for provider plugins (which may contain
* dataCapabilities() and dataItem() functions).
*
* Ideally the provider plugins should directly provide implementation of QgsDataItemProvider, for the time being
* this is a wrapper for the legacy interface.
*/
class QgsDataItemProviderFromPlugin : public QgsDataItemProvider
{
public:
QgsDataItemProviderFromPlugin( const QString& name, dataCapabilities_t* capabilitiesFunc, dataItem_t* dataItemFunc )
: mName( name )
, mCapabilitiesFunc( capabilitiesFunc )
, mDataItemFunc( dataItemFunc )
{
}
virtual QString name() { return mName; }
virtual int capabilities() { return mCapabilitiesFunc(); }
virtual QgsDataItem* createDataItem( const QString& path, QgsDataItem* parentItem ) { return mDataItemFunc( path, parentItem ); }
protected:
QString mName;
dataCapabilities_t* mCapabilitiesFunc;
dataItem_t* mDataItemFunc;
};
QgsDataItemProviderRegistry::QgsDataItemProviderRegistry()
{
QStringList providersList = QgsProviderRegistry::instance()->providerList();
foreach ( QString key, providersList )
{
QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( key );
if ( !library )
continue;
dataCapabilities_t * dataCapabilities = ( dataCapabilities_t * ) cast_to_fptr( library->resolve( "dataCapabilities" ) );
if ( !dataCapabilities )
{
QgsDebugMsg( library->fileName() + " does not have dataCapabilities" );
continue;
}
dataItem_t *dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
if ( !dataItem )
{
QgsDebugMsg( library->fileName() + " does not have dataItem" );
continue;
}
mProviders.append( new QgsDataItemProviderFromPlugin( library->fileName(), dataCapabilities, dataItem ) );
}
}
QgsDataItemProviderRegistry::~QgsDataItemProviderRegistry()
{
qDeleteAll( mProviders );
}

@ -0,0 +1,48 @@
/***************************************************************************
qgsdataitemproviderregistry.h
--------------------------------------
Date : March 2015
Copyright : (C) 2015 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef QGSDATAITEMPROVIDERREGISTRY_H
#define QGSDATAITEMPROVIDERREGISTRY_H
#include "qgssingleton.h"
#include <QList>
class QgsDataItemProvider;
/**
* This singleton class keeps a list of data item providers that may add items to the browser tree.
* When created, it automatically adds providers from provider plugins (e.g. PostGIS, WMS, ...)
*
* @note added in 2.10
*/
class CORE_EXPORT QgsDataItemProviderRegistry : public QgsSingleton<QgsDataItemProviderRegistry>
{
public:
~QgsDataItemProviderRegistry();
//! Get list of available providers
QList<QgsDataItemProvider*> providers() const { return mProviders; }
private:
QgsDataItemProviderRegistry();
friend class QgsSingleton<QgsDataItemProviderRegistry>; // Let QgsSingleton access private constructor
//! available providers. this class owns the pointers
QList<QgsDataItemProvider*> mProviders;
};
#endif // QGSDATAITEMPROVIDERREGISTRY_H