18 #include <QApplication> 
   23 #include <QMouseEvent> 
   24 #include <QTreeWidget> 
   25 #include <QTreeWidgetItem> 
   35 #include "qgsconfig.h" 
   46     : mArchiveName( archiveName ), mBaseDir( baseDir )
 
   48   QgsDebugMsg( 
"archiveName = " + archiveName + 
" baseDir = " + baseDir );
 
   52   foreach ( QString path, QDir( 
mBaseDir ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name ) )
 
   54     if ( path == 
"selections" )
 
   66   QDir seldir( 
mBaseDir + QDir::separator() + 
"selections" );
 
   67   QgsDebugMsg( 
"populating selection from " + seldir.path() );
 
   68   foreach ( QString selfile, seldir.entryList( QStringList( 
"*.xml" ), QDir::Files ) )
 
   70     QgsDebugMsg( 
"file= " + seldir.path() + 
"/" + selfile );
 
   72                                            seldir.dirName() +  QDir::separator() + selfile );
 
   74     if ( selItem->isValid() )
 
  113   if ( archiveName.isNull() )
 
  127   baseDir = settings.value( 
"CptCity/baseDir",
 
  140   if ( startDir == 
"" || ! startDir.startsWith( baseDir ) )
 
  143   QDir dir = QDir( startDir );
 
  145   while ( ! dir.exists( target ) && dir.path() != 
baseDir )
 
  150   if ( ! dir.exists( target ) )
 
  153     return dir.path() + QDir::separator() + target;
 
  173   if ( fileName.isNull() )
 
  178     QgsDebugMsg( 
"found copying info in copyingInfoMap, file = " + fileName );
 
  186   if ( !f.open( QFile::ReadOnly ) )
 
  188     QgsDebugMsg( 
"Couldn't open xml file: " + fileName );
 
  193   QDomDocument doc( 
"license" );
 
  194   if ( !doc.setContent( &f ) )
 
  197     QgsDebugMsg( 
"Couldn't parse xml file: " + fileName );
 
  203   QDomElement docElem = doc.documentElement();
 
  204   if ( docElem.tagName() != 
"copying" )
 
  206     QgsDebugMsg( 
"Incorrect root tag: " + docElem.tagName() );
 
  211   QDomElement authorsElement = docElem.firstChildElement( 
"authors" );
 
  212   if ( authorsElement.isNull() )
 
  218     QDomElement e = authorsElement.firstChildElement();
 
  220     while ( ! e.isNull() )
 
  222       if ( e.tagName() == 
"author" )
 
  224         if ( ! e.firstChildElement( 
"name" ).isNull() )
 
  225           authors << e.firstChildElement( 
"name" ).text().simplified();
 
  228       e = e.nextSiblingElement();
 
  230     copyingMap[ 
"authors" ] = authors.join( 
", " );
 
  234   QDomElement licenseElement = docElem.firstChildElement( 
"license" );
 
  235   if ( licenseElement.isNull() )
 
  241     QDomElement e = licenseElement.firstChildElement( 
"informal" );
 
  243       copyingMap[ 
"license/informal" ] = e.text().simplified();
 
  244     e = licenseElement.firstChildElement( 
"year" );
 
  246       copyingMap[ 
"license/year" ] = e.text().simplified();
 
  247     e = licenseElement.firstChildElement( 
"text" );
 
  248     if ( ! e.isNull() && e.attribute( 
"href" ) != QString() )
 
  249       copyingMap[ 
"license/url" ] = e.attribute( 
"href" );
 
  253   QDomElement element = docElem.firstChildElement( 
"src" );
 
  254   if ( element.isNull() )
 
  260     QDomElement e = element.firstChildElement( 
"link" );
 
  261     if ( ! e.isNull() && e.attribute( 
"href" ) != QString() )
 
  262       copyingMap[ 
"src/link" ] = e.attribute( 
"href" );
 
  274   QgsDebugMsg( 
"description fileName = " + fileName );
 
  277   if ( ! f.open( QFile::ReadOnly ) )
 
  279     QgsDebugMsg( 
"description file " + fileName + 
" ] does not exist" );
 
  285   QDomDocument doc( 
"description" );
 
  286   if ( !doc.setContent( &f, &errMsg ) )
 
  289     QgsDebugMsg( 
"Couldn't parse file " + fileName + 
" : " + errMsg );
 
  295   QDomElement docElem = doc.documentElement();
 
  296   if ( docElem.tagName() != 
"description" )
 
  298     QgsDebugMsg( 
"Incorrect root tag: " + docElem.tagName() );
 
  303   QDomElement e = docElem.firstChildElement( 
"name" );
 
  308   descMap[ 
"name" ] = e.text().simplified();
 
  309   e = docElem.firstChildElement( 
"full" );
 
  314   descMap[ 
"full" ] = e.text().simplified();
 
  321   QMap< double, QPair<QColor, QColor> > colorMap;
 
  325   if ( !f.open( QFile::ReadOnly ) )
 
  327     QgsDebugMsg( 
"Couldn't open SVG file: " + fileName );
 
  332   QDomDocument doc( 
"gradient" );
 
  333   if ( !doc.setContent( &f ) )
 
  336     QgsDebugMsg( 
"Couldn't parse SVG file: " + fileName );
 
  341   QDomElement docElem = doc.documentElement();
 
  343   if ( docElem.tagName() != 
"svg" )
 
  345     QgsDebugMsg( 
"Incorrect root tag: " + docElem.tagName() );
 
  350   QDomElement rampsElement = docElem.firstChildElement( 
"linearGradient" );
 
  351   if ( rampsElement.isNull() )
 
  353     QDomNodeList nodeList = docElem.elementsByTagName( 
"linearGradient" );
 
  354     if ( ! nodeList.isEmpty() )
 
  355       rampsElement = nodeList.at( 0 ).toElement();
 
  357   if ( rampsElement.isNull() )
 
  364   QDomElement e = rampsElement.firstChildElement();
 
  366   while ( !e.isNull() )
 
  368     if ( e.tagName() == 
"stop" )
 
  372       QString offsetStr = e.attribute( 
"offset" ); 
 
  373       QString colorStr = e.attribute( 
"stop-color", 
"" ); 
 
  374       QString opacityStr = e.attribute( 
"stop-opacity", 
"1.0" ); 
 
  375       if ( offsetStr.endsWith( 
"%" ) )
 
  376         offset = offsetStr.remove( offsetStr.size() - 1, 1 ).toDouble() / 100.0;
 
  378         offset = offsetStr.toDouble();
 
  382       if ( color != QColor() )
 
  384         int alpha = opacityStr.toDouble() * 255; 
 
  385         color.setAlpha( alpha );
 
  386         if ( colorMap.contains( offset ) )
 
  387           colorMap[offset].second = color;
 
  389           colorMap[offset] = qMakePair( color, color );
 
  393         QgsDebugMsg( QString( 
"at offset=%1 invalid color" ).arg( offset ) );
 
  401     e = e.nextSiblingElement();
 
  425   QgsDebugMsg( 
"archiveName = " + archiveName + 
" archiveBaseDir = " + archiveBaseDir );
 
  436   QString 
baseDir = settings.value( 
"CptCity/baseDir",
 
  442     initArchive( defArchiveName, baseDir + QDir::separator() + defArchiveName );
 
  448   QString 
baseDir, defArchiveName;
 
  452   baseDir = settings.value( 
"CptCity/baseDir",
 
  457   QgsDebugMsg( 
"baseDir= " + baseDir + 
" defArchiveName= " + defArchiveName );
 
  461     foreach ( QString entry, dir.entryList( QStringList( 
"cpt-city*" ), QDir::Dirs ) )
 
  463       if ( QFile::exists( baseDir + QDir::separator() + entry + 
"/VERSION.xml" ) )
 
  464         archivesMap[ entry ] = baseDir + QDir::separator() + entry;
 
  469     archivesMap[ defArchiveName ] = baseDir + QDir::separator() + defArchiveName;
 
  472   for ( QgsStringMap::iterator it = archivesMap.begin();
 
  473         it != archivesMap.end(); ++it )
 
  475     if ( QDir( it.value() ).exists() )
 
  479       QgsDebugMsg( QString( 
"not loading archive [%1] because dir %2 does not exist " ).arg( it.key() ).arg( it.value() ) );
 
  487   for ( QMap< QString, QgsCptCityArchive* >::iterator it = 
mArchiveRegistry.begin();
 
  497                                         QString name, QString path )
 
  499     : QObject(), mType( type ), mParent( parent ), mPopulated( false ),
 
  500     mName( name ), mPath( path ), mValid( true )
 
  528   QVector<QgsCptCityDataItem*> 
children;
 
  539   QApplication::setOverrideCursor( Qt::WaitCursor );
 
  549   QApplication::restoreOverrideCursor();
 
  653   for ( 
int i = 0; i < items.size(); i++ )
 
  656     if ( items[i]->
equal( item ) )
 
  666   QApplication::setOverrideCursor( Qt::WaitCursor );
 
  671   QVector<QgsCptCityDataItem*> 
remove;
 
  674     if ( 
findItem( items, child ) >= 0 )
 
  676     remove.append( child );
 
  695   QApplication::restoreOverrideCursor();
 
  700   if ( metaObject()->className() == other->metaObject()->className() &&
 
  711     QString name, QString path, QString variantName, 
bool initialize )
 
  713     mInitialised( false ), mRamp( path, variantName, false )
 
  722     QString name, QString path, QStringList variantList, 
bool initialize )
 
  724     mInitialised( false ), mRamp( path, variantList, QString(), false )
 
  757     if ( variantList.isEmpty() )
 
  762       mInfo = QString::number( count ) + 
" " + 
tr( 
"colors" ) + 
" - ";
 
  770           mInfo += 
tr( 
"continuous (multi)" );
 
  776       mInfo = QString::number( variantList.count() ) + 
" " + 
tr( 
"variants" );
 
  803   return icon( QSize( 100, 15 ) );
 
  810     if ( icon.availableSizes().contains( size ) )
 
  824     QPixmap blankPixmap( size );
 
  825     blankPixmap.fill( Qt::white );
 
  826     icon = QIcon( blankPixmap );
 
  836     QString name, QString path )
 
  853   QVector< QgsCptCityDataItem* > rampItems;
 
  854   QVector< QgsCptCityDataItem* > deleteItems;
 
  863     QgsDebugMsgLevel( QString( 
"child path= %1 coll= %2 ramp = %3" ).arg( childItem->
path() ).arg( collectionItem != 0 ).arg( rampItem != 0 ), 2 );
 
  864     if ( collectionItem && recursive )
 
  874         rampItems << rampItem;
 
  876         deleteItems << rampItem;
 
  887     QgsDebugMsg( QString( 
"item %1 is invalid, will be deleted" ).arg( deleteItem->
path() ) );
 
  899     QString name, QString path )
 
  907                  + QDir::separator() + 
mPath );
 
  913                      mPath + QDir::separator() + 
"DESC.xml";
 
  915   if ( descMap.contains( 
"name" ) )
 
  916     mInfo = descMap.value( 
"name" );
 
  928     return QVector<QgsCptCityDataItem*>();
 
  930   QVector<QgsCptCityDataItem*> 
children;
 
  933   QMapIterator< QString, QStringList> it( 
rampsMap() );
 
  934   while ( it.hasNext() )
 
  952       children << childItem;
 
  955   QgsDebugMsg( QString( 
"name= %1 path= %2 found %3 children" ).arg( 
mName ).arg( 
mPath ).arg( children.count() ) );
 
  965   QString curName, prevName, prevPath, curVariant, curSep, schemeName;
 
  966   QStringList listVariant;
 
  967   QStringList schemeNamesAll, schemeNames;
 
  969   bool ok, prevAdd, curAdd;
 
  972   schemeNamesAll = dir.entryList( QStringList( 
"*.svg" ), QDir::Files, QDir::Name );
 
  975   for ( 
int i = 0; i < schemeNamesAll.count(); i++ )
 
  978     schemeName = schemeNamesAll[i];
 
  979     schemeName.chop( 4 );
 
  982     curName = schemeName;
 
  987     if ( schemeName.length() > 1 && schemeName.endsWith( 
"a" ) && ! listVariant.isEmpty() &&
 
  988          (( prevName + listVariant.last()  + 
"a" ) == curName ) )
 
  991       curVariant = listVariant.last() + 
"a";
 
  995       num = schemeName.right( 3 ).toInt( &ok );
 
  999         curName = schemeName.left( schemeName.size() - 3 );
 
 1000         curVariant = schemeName.right( 3 );
 
 1004         num = schemeName.right( 2 ).toInt( &ok );
 
 1007           curName = schemeName.left( schemeName.size() - 2 );
 
 1008           curVariant = schemeName.right( 2 );
 
 1012           num = schemeName.right( 1 ).toInt( &ok );
 
 1015             curName = schemeName.left( schemeName.size() - 1 );
 
 1016             curVariant = schemeName.right( 1 );
 
 1021     curSep = curName.right( 1 );
 
 1022     if ( curSep == 
"-" || curSep == 
"_" )
 
 1025       curVariant = curSep + curVariant;
 
 1028     if ( prevName == 
"" )
 
 1034     if ( curName == 
"" )
 
 1035       curName = 
"__empty__";
 
 1037     if ( curName == prevName )
 
 1040       if ( i == schemeNamesAll.count() - 1 )
 
 1042       listVariant << curVariant;
 
 1046       if ( prevName != 
"" )
 
 1051       if ( i == schemeNamesAll.count() - 1 )
 
 1060       if ( listVariant.count() == 0 )
 
 1064         schemeNames << prevName;
 
 1065         mRampsMap[ 
mPath + QDir::separator() + prevName ] = QStringList();
 
 1067       else if ( listVariant.count() <= 3 )
 
 1070         for ( 
int j = 0; j < listVariant.count(); j++ )
 
 1073           schemeNames << prevName + listVariant[j];
 
 1074           mRampsMap[ 
mPath + QDir::separator() + prevName + listVariant[j] ] = QStringList();
 
 1081         schemeNames << prevName;
 
 1083       listVariant.clear();
 
 1087       if ( curVariant != 
"" )
 
 1088         curName += curVariant;
 
 1089       schemeNames << curName;
 
 1090       mRampsMap[ 
mPath + QDir::separator() + curName ] = QStringList();
 
 1093     if ( prevAdd || curAdd )
 
 1096       if ( curVariant != 
"" )
 
 1097         listVariant << curVariant;
 
 1114                QDir::separator() + 
mPath ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name );
 
 1124   return ( 
path() == other->
path() );
 
 1128     QString name, QString path )
 
 1130   QgsDebugMsg( 
"name= " + name + 
" path= " + path );
 
 1134   if ( dirItem && ! dirItem->
isValid() )
 
 1143   QStringList theDirEntries = dirItem->
dirEntries();
 
 1144   QMap< QString, QStringList > theRampsMap = dirItem->
rampsMap();
 
 1146   QgsDebugMsg( QString( 
"item has %1 dirs and %2 ramps" ).arg( theDirEntries.count() ).arg( theRampsMap.count() ) );
 
 1149   if ( theDirEntries.count() > 0 )
 
 1153   if ( theRampsMap.count() == 0 )
 
 1160   else if ( theRampsMap.count() == 1 )
 
 1165                                    theRampsMap.begin().key(), theRampsMap.begin().value() );
 
 1179     QString name, QString path )
 
 1183   mValid = ! path.isNull();
 
 1195     return QVector<QgsCptCityDataItem*>();
 
 1198   QVector<QgsCptCityDataItem*> 
children;
 
 1205     QgsDebugMsg( 
"childPath = " + childPath + 
" name= " + QFileInfo( childPath ).baseName() );
 
 1206     if ( childPath.endsWith( 
"/" ) )
 
 1208       childPath.chop( 1 );
 
 1214           children << childItem;
 
 1223       if ( item->isValid() )
 
 1230   QgsDebugMsg( QString( 
"path= %1 inserted %2 children" ).arg( 
mPath ).arg( children.count() ) );
 
 1241   QFile f( filename );
 
 1242   if ( ! f.open( QFile::ReadOnly ) )
 
 1250   QDomDocument doc( 
"selection" );
 
 1251   if ( !doc.setContent( &f, &errMsg ) )
 
 1254     QgsDebugMsg( 
"Couldn't parse file " + filename + 
" : " + errMsg );
 
 1260   QDomElement docElem = doc.documentElement();
 
 1261   if ( docElem.tagName() != 
"selection" )
 
 1263     QgsDebugMsg( 
"Incorrect root tag: " + docElem.tagName() );
 
 1266   QDomElement e = docElem.firstChildElement( 
"name" );
 
 1267   if ( ! e.isNull() && ! e.text().isNull() )
 
 1269   mInfo = docElem.firstChildElement( 
"synopsis" ).text().simplified();
 
 1272   QDomElement collectsElem = docElem.firstChildElement( 
"seealsocollects" );
 
 1273   e = collectsElem.firstChildElement( 
"collect" );
 
 1274   while ( ! e.isNull() )
 
 1276     if ( ! e.attribute( 
"dir" ).isNull() )
 
 1281     e = e.nextSiblingElement();
 
 1284   QDomElement gradientsElem = docElem.firstChildElement( 
"gradients" );
 
 1285   e = gradientsElem.firstChildElement( 
"gradient" );
 
 1286   while ( ! e.isNull() )
 
 1288     if ( ! e.attribute( 
"dir" ).isNull() )
 
 1292       mSelectionsList << e.attribute( 
"dir" ) + 
"/" + e.attribute( 
"file" );
 
 1294     e = e.nextSiblingElement();
 
 1305   return ( 
path() == other->
path() );
 
 1310     QString name,  QVector<QgsCptCityDataItem*> items )
 
 1325     return QVector<QgsCptCityDataItem*>();
 
 1327   QVector<QgsCptCityDataItem*> 
children;
 
 1344     : QAbstractItemModel( parent ), mArchive( archive ), mViewType( viewType )
 
 1384   if ( !index.isValid() )
 
 1387   Qt::ItemFlags 
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
 
 1394   if ( !index.isValid() )
 
 1403   else if ( role == Qt::DisplayRole )
 
 1405     if ( index.column() == 0 )
 
 1406       return item->
name();
 
 1407     if ( index.column() == 1 )
 
 1409       return item->
info();
 
 1412   else if ( role == Qt::ToolTipRole )
 
 1416       return item->
path() + 
"\n" + item->
info();
 
 1419   else if ( role == Qt::DecorationRole && index.column() == 1 &&
 
 1425   else if ( role == Qt::FontRole &&
 
 1426             ( dynamic_cast< QgsCptCityCollectionItem* >( item ) != 0 ) )
 
 1430     font.setPointSize( 11 ); 
 
 1431     font.setBold( 
true );
 
 1444   Q_UNUSED( section );
 
 1445   if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
 
 1448       return QVariant( 
tr( 
"Name" ) );
 
 1449     else if ( section == 1 )
 
 1450       return QVariant( 
tr( 
"Info" ) );
 
 1459   if ( !parent.isValid() )
 
 1468     return item ? item->
rowCount() : 0;
 
 1474   if ( !parent.isValid() )
 
 1490   QModelIndex theIndex; 
 
 1491   bool foundParent = 
false, foundChild = 
true;
 
 1497   if ( path.isEmpty() )
 
 1499     for ( 
int i = 0; i < 
rowCount( theIndex ); i++ )
 
 1501       QModelIndex idx = 
index( i, 0, theIndex );
 
 1504         return QModelIndex(); 
 
 1506       itemPath = item->
path();
 
 1508       if ( itemPath == path )
 
 1516   while ( foundChild )
 
 1522     if ( itemPath.isEmpty() )
 
 1524     for ( ; i < 
rowCount( theIndex ); i++ )
 
 1526       QModelIndex idx = 
index( i, 0, theIndex );
 
 1529         return QModelIndex(); 
 
 1531       itemPath = item->
path();
 
 1533       if ( itemPath == path )
 
 1539       if ( ! itemPath.endsWith( 
"/" ) )
 
 1542       foundParent = 
false;
 
 1552           if ( childPath.endsWith( 
"/" ) )
 
 1553             childPath.chop( 1 );
 
 1555           if ( path.startsWith( childPath ) )
 
 1563       else if ( path.startsWith( itemPath ) )
 
 1581   return QModelIndex(); 
 
 1594   QModelIndex idx = 
findPath( path );
 
 1595   if ( idx.isValid() )
 
 1608   return item ? createIndex( row, column, item ) : QModelIndex();
 
 1615     return QModelIndex();
 
 1622   const QVector<QgsCptCityDataItem*> &items = parent ? parent->
children() : 
mRootItems;
 
 1624   for ( 
int i = 0; i < items.size(); i++ )
 
 1626     if ( items[i] == item )
 
 1627       return createIndex( i, 0, item );
 
 1629     QModelIndex childIndex = 
findItem( item, items[i] );
 
 1630     if ( childIndex.isValid() )
 
 1634   return QModelIndex();
 
 1651   QModelIndex idx = 
findItem( parent );
 
 1652   if ( !idx.isValid() )
 
 1655   beginInsertRows( idx, first, last );
 
 1666   QModelIndex idx = 
findItem( parent );
 
 1667   if ( !idx.isValid() )
 
 1669   beginRemoveRows( idx, first, last );
 
 1716 QStringList QgsCptCityBrowserModel::mimeTypes()
 const 
 1721   types << 
"application/x-vnd.qgis.qgis.uri";
 
 1725 QMimeData * QgsCptCityBrowserModel::mimeData( 
const QModelIndexList &indexes )
 const 
 1728   foreach ( 
const QModelIndex &
index, indexes )
 
 1730     if ( index.isValid() )
 
 1733       if ( ptr->
type() != QgsCptCityDataItem::Layer ) 
continue;
 
 1741 bool QgsCptCityBrowserModel::dropMimeData( 
const QMimeData * data, Qt::DropAction action, 
int row, 
int column, 
const QModelIndex & parent )
 
 1759   void *v = idx.internalPointer();
 
 1761   Q_ASSERT( !v || d );