xml-freemind.cpp
author insilmaril
Mon Jul 30 09:47:11 2007 +0000 (2007-07-30)
changeset 572 a97aabc21136
child 574 56fa27b2be3e
permissions -rw-r--r--
1.9.4 New base class for XML based file parsing (vym & Freemind)
     1 #include "xml-freemind.h"
     2 
     3 #include <QMessageBox>
     4 #include <QColor>
     5 #include <QTextStream>
     6 #include <iostream>
     7 
     8 #include "misc.h"
     9 #include "settings.h"
    10 #include "linkablemapobj.h"
    11 #include "version.h"
    12 
    13 static BranchObj *lastBranch;
    14 static FloatObj *lastFloat;
    15 static OrnamentedObj *lastOO;
    16 
    17 extern Settings settings;
    18 extern QString vymVersion;
    19 
    20 extern QString flagsPath;
    21 
    22 parseFMHandler::parseFMHandler() {}
    23 
    24 parseFMHandler::~parseFMHandler() {}
    25 
    26 QString parseFMHandler::errorProtocol() { return errorProt; }
    27 
    28 
    29 bool parseFMHandler::startDocument()
    30 {
    31     errorProt = "";
    32     state = StateInit;
    33     laststate = StateInit;
    34 	stateStack.clear();
    35 	stateStack.append(StateInit);
    36     branchDepth=0;
    37 	htmldata="";
    38 	isVymPart=false;
    39     return true;
    40 }
    41 
    42 
    43 QString parseFMHandler::parseHREF(QString href)
    44 {
    45 	QString type=href.section(":",0,0);
    46 	QString path=href.section(":",1,1);
    47 	if (!tmpDir.endsWith("/"))
    48 		return tmpDir + "/" + path;
    49 	else	
    50 		return tmpDir + path;
    51 }
    52 
    53 bool parseFMHandler::startElement  ( const QString&, const QString&,
    54                     const QString& eName, const QXmlAttributes& atts ) 
    55 {
    56     QColor col;
    57 	/* Testing
    58 	cout << "startElement <"<< eName.ascii()
    59 		<<">  state="<<state 
    60 		<<"  laststate="<<stateStack.last()
    61 		<<"   loadMode="<<loadMode
    62 	//	<<"       line="<<QXmlDefaultHandler::lineNumber().ascii()
    63 		<<endl;
    64 	*/	
    65 	stateStack.append (state);	
    66     if ( state == StateInit && (eName == "map")  ) 
    67 	{
    68         state = StateMap;
    69 		if (!atts.value( "version").isEmpty() ) 
    70 		{
    71 			QString v="0.8.0";
    72 			if (!checkVersion(atts.value("version"),v))
    73 				QMessageBox::warning( 0, "Warning: Version Problem" ,
    74 				   "<h3>Freemind map is newer than version " +v +" </h3>"
    75 				   "<p>The map you are just trying to load was "
    76 				   "saved using freemind " +atts.value("version")+". "
    77 				   "The version of this vym can parse freemind " + v +"."); 
    78 		}
    79 		mc->addBranch();
    80 		lastBranch=mc->getLastBranch();
    81 		lastBranch->move2RelPos (200,0);
    82 		lastBranch->setHeading ("  ");
    83 		mc->addBranch();
    84 		lastBranch=mc->getLastBranch();
    85 		lastBranch->move2RelPos (-200,0);
    86 		lastBranch->setHeading ("  ");
    87 		lastBranch=mc;
    88 
    89 	} else if ( eName == "node" &&  (state == StateMap || state == StateNode )) 
    90 	{
    91 		if (!atts.value( "POSITION").isEmpty() )
    92 		{
    93 			if (atts.value ("POSITION")=="left")
    94 			{
    95 				me->select ("bo:1");
    96 				lastBranch=me->getSelectedBranch();
    97 				if (lastBranch)
    98 				{
    99 					lastBranch->addBranch();
   100 					lastBranch=lastBranch->getLastBranch();
   101 					readNodeAttr (atts);
   102 				}	
   103 			} else if (atts.value ("POSITION")=="right")
   104 			{
   105 				me->select ("bo:0");
   106 				lastBranch=me->getSelectedBranch();
   107 				if (lastBranch)
   108 				{
   109 					lastBranch->addBranch();
   110 					lastBranch=lastBranch->getLastBranch();
   111 					readNodeAttr (atts);
   112 				}	
   113 			}
   114 		} else
   115 		{
   116 			if (state!=StateMap)
   117 			{
   118 				lastBranch->addBranch();
   119 				lastBranch=lastBranch->getLastBranch();
   120 			}
   121 			readNodeAttr (atts);
   122 		}
   123 		state=StateNode;
   124 	} else if ( eName == "font" && state == StateNode) 
   125 	{
   126 		state=StateFont;
   127 	} else if ( eName == "edge" && state == StateNode) 
   128 	{
   129 		state=StateEdge;
   130 	} else if ( eName == "hook" && state == StateNode) 
   131 	{
   132 		state=StateHook;
   133 	} else if ( eName == "icon" && state == StateNode) 
   134 	{
   135 		state=StateIcon;
   136 		if (!atts.value("BUILTIN").isEmpty() )
   137 		{
   138 			QString f=atts.value("BUILTIN");
   139 			QString v;
   140 			if (f=="help")
   141 				v="questionmark";
   142 			else if (f=="messagebox_warning")
   143 				v="freemind-warning"; 
   144 			else if (f=="idea")
   145 				v="lamp"; 
   146 			else if (f=="button_ok")
   147 				v="hook-green"; 
   148 			else if (f=="button_cancel")
   149 				v="cross-red"; 
   150 			else if (f.contains("full-"))
   151 				v=f.replace("full-","freemind-priority-"); //FIXME
   152 			else if (f=="back")
   153 				v="freemind-back"; 
   154 			else if (f=="forward")
   155 				v="freemind-forward"; 
   156 			else if (f=="attach")
   157 				v="freemind-attach"; 
   158 			else if (f=="ksmiletris")
   159 				v="smiley-good"; // 
   160 			else if (f=="clanbomber")
   161 				v="freemind-clanbomber"; 
   162 			else if (f=="desktop_new")
   163 				v="freemind-desktopnew"; 
   164 			else if (f=="flag")
   165 				v="freemind-flag"; 
   166 			else if (f=="gohome")
   167 				v="freemind-gohome"; 
   168 			else if (f=="kaddressbook")
   169 				v="freemind-kaddressbook"; 
   170 			else if (f=="knotify")
   171 				v="freemind-knotify"; 
   172 			else if (f=="korn")
   173 				v="freemind-korn";
   174 			else if (f=="Mail")
   175 				v="freemind-mail"; 
   176 			else if (f=="password")
   177 				v="freemind-password"; 
   178 			else if (f=="pencil")
   179 				v="freemind-pencil";
   180 			else if (f=="stop")
   181 				v="freemind-stop"; 
   182 			else if (f=="wizard")
   183 				v="freemind-wizard";
   184 			else if (f=="xmag")
   185 				v="freemind-xmag";
   186 			else if (f=="bell")
   187 				v="freemind-bell";
   188 			else if (f=="bookmark")
   189 				v="freemind-bookmark"; 
   190 			else if (f=="penguin")
   191 				v="freemind-penguin"; 
   192 			else if (f=="licq")
   193 				v="freemind-licq"; 
   194 
   195 			lastBranch->activateStandardFlag( v);
   196 		}
   197 	} else if ( eName == "arrowlink" && state == StateNode) 
   198 	{
   199 		state=StateArrowLink;
   200 	} else if ( eName == "cloud" && state == StateNode) 
   201 	{
   202 		state=StateCloud;
   203 	} else if ( eName == "text" && state == StateHook) 
   204 	{
   205 		state=StateText;
   206 	} else 
   207         return false;   // Error
   208     return true;
   209 }
   210 
   211 bool parseFMHandler::endElement  ( const QString&, const QString&, const QString &eName)
   212 {
   213 	/* Testing
   214 	cout << "endElement </" <<eName.ascii()
   215 		<<">  state=" <<state 
   216 		<<"  laststate=" <<laststate
   217 		<<"  stateStack="<<stateStack.last() 
   218 		<<endl;
   219 	*/
   220     switch ( state ) 
   221 	{
   222         case StateNode: 
   223 			lastBranch=(BranchObj*)(lastBranch->getParObj());
   224             break;
   225 		default: 
   226 			break;
   227     }  
   228 	state=stateStack.takeLast();	
   229 	return true;
   230 }
   231 
   232 bool parseFMHandler::characters   ( const QString& ch)
   233 {
   234 	//cout << "characters \""<<ch.ascii()<<"\"  state="<<state <<"  laststate="<<laststate<<endl;
   235 
   236 	QString ch_org=quotemeta (ch);
   237     QString ch_simplified=ch.simplifyWhiteSpace();
   238     if ( ch_simplified.isEmpty() ) return true;
   239 
   240     switch ( state ) 
   241     {
   242         case StateInit: break;
   243         case StateMap: break; 
   244         case StateNode: break; 
   245         case StateCloud: break; 
   246         case StateEdge: break; 
   247         case StateIcon: break; 
   248         case StateArrowLink: break; 
   249         case StateFont: break; 
   250         case StateHook: break; 
   251         case StateText: 
   252 			lastBranch->setNote (ch_simplified);
   253 			break; 
   254         default: 
   255 			return false;
   256     }
   257     return true;
   258 }
   259 
   260 QString parseFMHandler::errorString() 
   261 {
   262     return "the document is not in the VYM file format";
   263 }
   264 
   265 bool parseFMHandler::fatalError( const QXmlParseException& exception ) 
   266 {
   267     errorProt += QString( "Fatal parsing error: %1 in line %2, column %3\n")
   268     .arg( exception.message() )
   269     .arg( exception.lineNumber() )
   270     .arg( exception.columnNumber() );
   271 	// Try to read the bogus line
   272 	errorProt+=QString("File is: %1\n").arg(inputFile);
   273 	QString s;
   274 	if (loadStringFromDisk (inputFile,s))
   275 	{
   276 		QStringList sl=QStringList::split ("\n",s);
   277 		int i=1;
   278 		QStringList::Iterator it = sl.begin();
   279 		while (i<exception.lineNumber())
   280 		{
   281 			it++;
   282 			i++;
   283 		}
   284 		s=*it;
   285 		s.insert (exception.columnNumber()-1,"<ERROR>");
   286 		errorProt+=s;
   287     }
   288     return QXmlDefaultHandler::fatalError( exception );
   289 }
   290 
   291 void parseFMHandler::setMapEditor (MapEditor* e)
   292 {
   293     me=e;
   294 	mc=me->getMapCenter();
   295 }
   296 
   297 void parseFMHandler::setTmpDir (QString tp)
   298 {
   299 	tmpDir=tp;
   300 }
   301 
   302 void parseFMHandler::setInputFile (QString f)
   303 {
   304 	inputFile=f;
   305 }
   306 
   307 void parseFMHandler::setLoadMode (const LoadMode &lm)
   308 {
   309 	loadMode=lm;
   310 }
   311 
   312 bool parseFMHandler::readNodeAttr (const QXmlAttributes& a)
   313 {
   314 	lastOO=lastBranch;
   315 
   316 	if (a.value( "FOLDED")=="true" )
   317 		lastBranch->toggleScroll();
   318 	if (!a.value( "TEXT").isEmpty() )
   319 		lastBranch->setHeading (a.value ("TEXT"));
   320 
   321 	if (!a.value( "COLOR").isEmpty() )
   322 		lastBranch->setColor (QColor (a.value ("COLOR")));
   323 
   324 	if (!a.value( "LINK").isEmpty() )
   325 		lastBranch->setURL (a.value ("LINK"));
   326 
   327 	return true;	
   328 }
   329 
   330