QGIS API Documentation  2.99.0-Master (e077efd)
qgsmimedatautils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmimedatautils.cpp
3  ---------------------
4  begin : November 2011
5  copyright : (C) 2011 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include <QStringList>
16 
17 #include "qgsmimedatautils.h"
18 
19 #include "qgsdataitem.h"
20 #include "qgslayertree.h"
21 #include "qgslogger.h"
22 #include "qgspluginlayer.h"
23 #include "qgsrasterdataprovider.h"
24 #include "qgsrasterlayer.h"
25 #include "qgsvectordataprovider.h"
26 #include "qgsvectorlayer.h"
27 
28 static const char* QGIS_URILIST_MIMETYPE = "application/x-vnd.qgis.qgis.uri";
29 
30 
32 {
33 }
34 
35 QgsMimeDataUtils::Uri::Uri( QString& encData )
36 {
37  QgsDebugMsg( "encData: " + encData );
38  QStringList decoded = decode( encData );
39  if ( decoded.size() < 4 )
40  return;
41 
42  layerType = decoded[0];
43  providerKey = decoded[1];
44  name = decoded[2];
45  uri = decoded[3];
46 
47  if ( layerType == QLatin1String( "raster" ) && decoded.size() == 6 )
48  {
49  supportedCrs = decode( decoded[4] );
50  supportedFormats = decode( decoded[5] );
51  }
52  else
53  {
54  supportedCrs.clear();
55  supportedFormats.clear();
56  }
57 
58  QgsDebugMsg( QString( "type:%1 key:%2 name:%3 uri:%4 supportedCRS:%5 supportedFormats:%6" )
59  .arg( layerType, providerKey, name, uri,
60  supportedCrs.join( ", " ),
61  supportedFormats.join( ", " ) ) );
62 }
63 
65 {
66  return encode( QStringList() << layerType << providerKey << name << uri << encode( supportedCrs ) << encode( supportedFormats ) );
67 }
68 
69 // -----
70 
71 bool QgsMimeDataUtils::isUriList( const QMimeData* data )
72 {
73  return data->hasFormat( QGIS_URILIST_MIMETYPE );
74 }
75 
77 {
78  QMimeData *mimeData = new QMimeData();
79 
80  mimeData->setData( QGIS_URILIST_MIMETYPE, uriListToByteArray( layers ) );
81  return mimeData;
82 }
83 
84 
86 {
87  QByteArray encodedData = data->data( QGIS_URILIST_MIMETYPE );
88  QDataStream stream( &encodedData, QIODevice::ReadOnly );
89  QString xUri; // extended uri: layer_type:provider_key:uri
90  UriList list;
91  while ( !stream.atEnd() )
92  {
93  stream >> xUri;
94  QgsDebugMsg( xUri );
95  list.append( Uri( xUri ) );
96  }
97  return list;
98 }
99 
100 
102 {
103  if ( QgsLayerTree::isGroup( node ) )
104  {
105  Q_FOREACH ( QgsLayerTreeNode* child, QgsLayerTree::toGroup( node )->children() )
106  _addLayerTreeNodeToUriList( child, uris );
107  }
108  else if ( QgsLayerTree::isLayer( node ) )
109  {
110  QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node );
111  if ( !nodeLayer->layer() )
112  return;
113 
115  if ( QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( nodeLayer->layer() ) )
116  {
117  uri.layerType = QStringLiteral( "vector" );
118  uri.name = vlayer->name();
119  uri.providerKey = vlayer->dataProvider()->name();
120  uri.uri = vlayer->dataProvider()->dataSourceUri();
121  }
122  else if ( QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer*>( nodeLayer->layer() ) )
123  {
124  uri.layerType = QStringLiteral( "raster" );
125  uri.name = rlayer->name();
126  uri.providerKey = rlayer->dataProvider()->name();
127  uri.uri = rlayer->dataProvider()->dataSourceUri();
128  }
129  else
130  {
131  // plugin layers do not have a standard way of storing their URI...
132  return;
133  }
134  uris << uri;
135  }
136 }
137 
138 QByteArray QgsMimeDataUtils::layerTreeNodesToUriList( const QList<QgsLayerTreeNode *>& nodes )
139 {
140  UriList uris;
141  Q_FOREACH ( QgsLayerTreeNode* node, nodes )
142  _addLayerTreeNodeToUriList( node, uris );
143  return uriListToByteArray( uris );
144 }
145 
146 QString QgsMimeDataUtils::encode( const QStringList& items )
147 {
148  QString encoded;
149  Q_FOREACH ( const QString& item, items )
150  {
151  QString str = item;
152  str.replace( '\\', QLatin1String( "\\\\" ) );
153  str.replace( ':', QLatin1String( "\\:" ) );
154  encoded += str + ':';
155  }
156  return encoded.left( encoded.length() - 1 );
157 }
158 
159 QStringList QgsMimeDataUtils::decode( const QString& encoded )
160 {
161  QStringList items;
162  QString item;
163  bool inEscape = false;
164  Q_FOREACH ( QChar c, encoded )
165  {
166  if ( c == '\\' && inEscape )
167  {
168  item += c;
169  }
170  else if ( c == '\\' )
171  {
172  inEscape = true;
173  }
174  else if ( c == ':' && !inEscape )
175  {
176  items.append( item );
177  item = QLatin1String( "" );
178  }
179  else
180  {
181  item += c;
182  inEscape = false;
183  }
184  }
185  items.append( item );
186  return items;
187 }
188 
189 
190 QByteArray QgsMimeDataUtils::uriListToByteArray( const QgsMimeDataUtils::UriList& layers )
191 {
192  QByteArray encodedData;
193 
194  QDataStream stream( &encodedData, QIODevice::WriteOnly );
195  Q_FOREACH ( const Uri& u, layers )
196  {
197  stream << u.data();
198  }
199  return encodedData;
200 }
QString layerType
Type of URI. Recognized types: "vector" / "raster" / "plugin" / "custom".
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
static UriList decodeUriList(const QMimeData *data)
QString name
Human readable name to be used e.g. in layer tree.
static QMimeData * encodeUriList(const UriList &layers)
QStringList supportedFormats
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
Definition: qgslayertree.h:46
static bool isUriList(const QMimeData *data)
QString data() const
Returns encoded representation of the object.
static void _addLayerTreeNodeToUriList(QgsLayerTreeNode *node, QgsMimeDataUtils::UriList &uris)
This class is a base class for nodes in a layer tree.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:40
QgsMapLayer * layer() const
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
Definition: qgslayertree.h:52
QString providerKey
For "vector" / "raster" type: provider id.
QString uri
Identifier of the data source recognized by its providerKey.
static QByteArray layerTreeNodesToUriList(const QList< QgsLayerTreeNode *> &nodes)
Returns encoded URI list from a list of layer tree nodes.
Uri()
Constructs invalid URI.
static const char * QGIS_URILIST_MIMETYPE
Represents a vector layer which manages a vector based data sets.
QList< Uri > UriList
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:34
Layer tree node points to a map layer.