Skip to content

Commit

Permalink
Browser: Abstract creation of custom data items into QgsDataItemProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Mar 4, 2015
1 parent 427adf7 commit cdb44a3
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 78 deletions.
2 changes: 2 additions & 0 deletions python/core/core.sip
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions python/core/qgsdataitemprovider.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/;

};
19 changes: 19 additions & 0 deletions python/core/qgsdataitemproviderregistry.sip
@@ -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();

};
5 changes: 5 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -77,6 +77,8 @@ SET(QGIS_CORE_SRCS
qgsdatadefined.cpp
qgsdatasourceuri.cpp
qgsdataitem.cpp
qgsdataitemprovider.cpp
qgsdataitemproviderregistry.cpp
qgsdatumtransformstore.cpp
qgsdbfilterproxymodel.cpp
qgsdiagramrendererv2.cpp
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsapplication.cpp
Expand Up @@ -15,6 +15,7 @@

#include "qgsapplication.h"
#include "qgscrscache.h"
#include "qgsdataitemproviderregistry.h"
#include "qgsexception.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -626,6 +627,7 @@ void QgsApplication::exitQgis()
QgsMapLayerRegistry::cleanup();
QgsNetworkAccessManager::cleanup();
QgsCoordinateTransformCache::cleanup();
QgsDataItemProviderRegistry::cleanup();

// Cleanup providers
delete QgsProviderRegistry::instance();
Expand Down
31 changes: 6 additions & 25 deletions src/core/qgsbrowsermodel.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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" );
continue;
}

dataItem_t *dataItem = ( dataItem_t * ) cast_to_fptr( library->resolve( "dataItem" ) );
if ( !dataItem )
{
QgsDebugMsg( library->fileName() + " does not have dataItem" );
QgsDebugMsg( pr->name() + " does not have any dataCapabilities" );
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() );
Expand Down
59 changes: 7 additions & 52 deletions src/core/qgsdataitem.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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()
Expand All @@ -761,6 +730,7 @@ QIcon QgsDirectoryItem::icon()
return iconDir();
}


QVector<QgsDataItem*> QgsDirectoryItem::createChildren()
{
QVector<QgsDataItem*> children;
Expand Down Expand Up @@ -808,38 +778,23 @@ 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 ) ) ) )
{
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;
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsdataitem.h
Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions src/core/qgsdataitemprovider.cpp
@@ -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
52 changes: 52 additions & 0 deletions src/core/qgsdataitemprovider.h
@@ -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 comments on commit cdb44a3

Please sign in to comment.