(empty message)
[qanava.git] / src / qanRepository.cpp
blobb8462907ec496d13438f663015f0ce28327006f3
1 /*
2 Qanava - Graph drawing library for QT
3 Copyright (C) 2006 Benoit AUTHEMAN
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //-----------------------------------------------------------------------------
21 // This file is a part of the Qanava software.
23 // \file qanRepository.cpp
24 // \author Benoit Autheman (benoit@libqanava.org)
25 // \date 2005 December 23
26 //-----------------------------------------------------------------------------
29 // Qanava headers
30 #include "./qanRepository.h"
33 // Standard headers
34 #include <iostream>
35 #include <fstream>
36 #include <sstream>
39 // QT headers
40 #include <QFile>
43 namespace qan { // ::qan
46 /* Graph Serialization Management *///-----------------------------------------
47 void PajekRepository::load( Graph* graph )
49 std::ifstream netFile( getName( ).c_str( ) );
50 if ( !netFile.is_open( ) )
51 return;
53 Mode mode = UNDEFINED;
54 while ( !netFile.eof( ) )
56 std::string line;
57 std::getline( netFile, line ); // Parse the file line by line
59 std::string header( "" );
61 std::stringstream lineStream;
62 lineStream << line;
63 lineStream >> header;
66 Mode oldMode = mode;
67 if ( header == "*Vertices" )
68 mode = VERTICES;
69 else if ( header == "*Arcs" )
70 mode = ARCS;
71 else if ( header == "*Edges" )
72 mode = EDGES;
73 if ( oldMode != mode )
74 continue; // A header line has just been read, jump to the next line
76 std::stringstream lineStream;
77 lineStream << line;
79 switch ( mode )
81 case VERTICES:
83 int nodeId( -1 );
84 lineStream >> nodeId;
86 std::string nodeName( "" );
87 lineStream >> nodeName;
89 if ( ( nodeId > 0 ) && nodeName.size( ) > 0 )
91 graph->insertNode( QString( nodeName.c_str( ) ) );
94 break;
96 case ARCS:
98 int nodeSrcId( -1 );
99 lineStream >> nodeSrcId;
101 int nodeDstId( -1 );
102 lineStream >> nodeDstId;
104 if ( nodeSrcId > 0 && nodeDstId > 0 )
106 Node* nodeSrc = graph->findNode( nodeSrcId - 1 );
107 Node* nodeDst = graph->findNode( nodeDstId - 1 );
108 if ( nodeSrc != 0 && nodeDst != 0 )
109 graph->addEdge( *nodeSrc, *nodeDst );
112 break;
114 case EDGES:
116 int nodeSrcId( -1 );
117 lineStream >> nodeSrcId;
119 int nodeDstId( -1 );
120 lineStream >> nodeDstId;
122 if ( nodeSrcId > 0 && nodeDstId > 0 )
124 Node* nodeSrc = graph->findNode( nodeSrcId - 1 );
125 Node* nodeDst = graph->findNode( nodeDstId - 1 );
126 if ( nodeSrc != 0 && nodeDst != 0 )
127 graph->addEdge( *nodeSrc, *nodeDst );
130 break;
132 case UNDEFINED:
133 default:
134 break;
137 netFile.close( );
138 graph->generateRootNodes( );
141 void PajekRepository::save( Graph* graph )
145 //-----------------------------------------------------------------------------
148 /* Graph Serialization Management *///-----------------------------------------
149 void GraphvizRepository::load( Graph* graph )
154 void GraphvizRepository::save( Graph* graph )
156 std::ofstream ofs;
157 ofs.open( getName( ).c_str( ) );
158 if ( !ofs.is_open( ) )
159 return;
161 ofs << "graph g {\n";
162 ofs << "\t center=true; \n";
163 ofs << "#\t page=\"18,18\"; \n";
164 ofs << "\t size=\"20,20\"; \n";
165 ofs << "#\t ratio=compress; \n";
166 ofs << "#\t concentrate=true; \n";
167 ofs << "\t overlap=true; \n";
168 ofs << "\t orientation=paysage; \n";
170 ofs << "\t node [ shape=box, style=filled, fontsize=10, height=0.2, width=0.4 ];\n";
171 ofs << "\t edge [ len=1.5 ];\n";
173 // Dump nodes
174 Node::List::iterator nodeIter = graph->getNodes( ).begin( );
175 for ( int n = 0; nodeIter != graph->getNodes( ).end( ); nodeIter++ )
177 Node* node = *nodeIter;
178 //ofs << "\t" << n++/*node->getId( )*/ << " [label=\"" << node->getLabel( ).c_str( ) << "\"];\n";
179 assert( false ); // FIXME
182 // Dump nodes edges
183 for ( nodeIter = graph->getNodes( ).begin( ); nodeIter != graph->getNodes( ).end( ); nodeIter++ )
185 Node* node = *nodeIter;
186 const Edge::List& edges = node->getOutEdges( );
187 Edge::List::const_iterator edgeIter = edges.begin( );
188 for ( ; edgeIter != edges.end( ); edgeIter++ )
190 //Edge* edge = *edgeIter;
191 ofs << "\t" << 0/*edge->getSrc( ).getId( )*/ << " -- " << 0/*edge->getDst( ).getId( )*/ << "\n";
194 ofs << "}\n";
195 ofs.close( );
197 //-----------------------------------------------------------------------------
200 /* GML Graph Serialization Management *///-------------------------------------
201 GMLRepository::GMLRepository( const std::string& name ) :
202 Repository( name )
207 void GMLRepository::load( Graph* graph )
209 if ( getName( ).size( ) <= 0 )
210 return;
212 QFile file( getName( ).c_str( ) );
213 if ( !file.open( QFile::ReadOnly | QFile::Text ) )
214 return;
216 QString errorStr( "" );
217 int errorLine = -1;
218 int errorColumn = -1;
220 QDomDocument domDocument;
221 if ( !domDocument.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) )
222 return;
224 QDomElement root = domDocument.documentElement( );
225 if ( root.tagName( ) != "graphml" )
226 return;
228 QDomElement graphChild = root.firstChildElement( "graph" );
229 if ( !graphChild.isNull( ) )
230 parseGraph( domDocument, graphChild, graph );
233 void GMLRepository::parseGraph( QDomDocument domDocument, QDomElement element, Graph* graph )
235 if ( element.tagName( ) != "graph" )
236 return;
238 // Parse nodes
239 QDomNodeList nodes = element.elementsByTagName( "node" );
240 for( unsigned int n = 0; n < nodes.length( ); n++ )
242 QDomElement node = nodes.item( n ).toElement( );
243 if ( node.isNull( ) )
244 continue;
245 QString nodeId = node.attribute( "id" );
246 Node* laNode = graph->insertNode( nodeId );
249 // Parse data elements
250 QDomNodeList dataNodes = node.elementsByTagName( "data" );
251 for ( unsigned int dn = 0; dn < dataNodes.length( ); dn++ )
253 QDomElement dataNode = dataNodes.item( dn ).toElement( );
254 if ( dataNode.isNull( ) )
255 continue;
257 QString dataKey = dataNode.attribute( "key" );
258 QString dataText = dataNode.text( );
260 if ( dataKey.length( ) <= 0 )
261 continue;
263 if ( graph->hasAttribute( dataKey ) == -1 )
264 graph->addAttribute< QString >( dataKey, QString( "" ) );
265 graph->setAttribute< QString >( laNode, dataKey, dataText );
269 graph->generateRootNodes( );
271 //return;
272 // Parse edges
273 QDomNodeList edges = element.elementsByTagName( "edge" );
274 for( unsigned int e = 0; e < edges.length( ); e++ )
276 QDomElement edge = edges.item( e ).toElement( );
277 if ( edge.isNull( ) )
278 continue;
279 QString edgeSource = edge.attribute( "source" );
280 QString edgeTarget = edge.attribute( "target" );
283 // Parse data elements
284 double weight = 0.;
285 QDomNodeList dataNodes = edge.elementsByTagName( "data" );
286 for ( unsigned int dn = 0; dn < dataNodes.length( ); dn++ )
288 QDomElement dataNode = dataNodes.item( dn ).toElement( );
289 if ( dataNode.isNull( ) )
290 continue;
292 QString dataKey = dataNode.attribute( "key" );
293 QString dataText = dataNode.text( );
295 if ( dataKey.length( ) <= 0 )
296 continue;
298 if ( dataKey == "weight" )
299 weight = dataText.toDouble( );
302 if ( ( edgeSource.length( ) > 0 ) && ( edgeTarget.length( ) > 0 ) )
304 Node* laSrc = graph->findNode( edgeSource );
305 Node* laDst = graph->findNode( edgeTarget );
306 if ( ( laSrc != 0 ) && ( laDst != 0 ) )
307 graph->addEdge( *laSrc, *laDst, weight );
309 //break;
312 graph->generateRootNodes( );
315 void GMLRepository::save( Graph* graph )
319 //-----------------------------------------------------------------------------
322 } // ::qan