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