moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kmplot / kmplot / kmplotio.cpp
blob954d4c211a6ae014d2f49aa308655a856d70d094
1 /*
2 * KmPlot - a math. function plotter for the KDE-Desktop
4 * Copyright (C) 1998, 1999 Klaus-Dieter Möller
5 * 2000, 2002 kd.moeller@t-online.de
7 * This file is part of the KDE Project.
8 * KmPlot is part of the KDE-EDU Project.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 // Qt includes
27 #include <qdom.h>
28 #include <qfile.h>
30 // KDE includes
31 #include <kio/netaccess.h>
32 #include <klocale.h>
33 #include <kmessagebox.h>
34 #include <ktempfile.h>
36 // ANSI-C includes
37 #include <stdlib.h>
39 // local includes
40 #include "kmplotio.h"
41 #include "MainDlg.h"
42 #include "settings.h"
44 class XParser;
46 KmPlotIO::KmPlotIO( XParser *parser)
47 : m_parser(parser)
51 KmPlotIO::~KmPlotIO()
54 bool KmPlotIO::save( const KURL &url )
56 // saving as xml by a QDomDocument
57 QDomDocument doc( "kmpdoc" );
58 // the root tag
59 QDomElement root = doc.createElement( "kmpdoc" );
60 root.setAttribute( "version", "2" );
61 doc.appendChild( root );
63 // the axes tag
64 QDomElement tag = doc.createElement( "axes" );
66 tag.setAttribute( "color", Settings::axesColor().name() );
67 tag.setAttribute( "width", Settings::axesLineWidth() );
68 tag.setAttribute( "tic-width", Settings::ticWidth() );
69 tag.setAttribute( "tic-legth", Settings::ticLength() );
71 addTag( doc, tag, "show-axes", Settings::showAxes() ? "1" : "-1" );
72 addTag( doc, tag, "show-arrows", Settings::showArrows() ? "1" : "-1" );
73 addTag( doc, tag, "show-label", Settings::showLabel() ? "1" : "-1" );
74 addTag( doc, tag, "show-frame", Settings::showExtraFrame() ? "1" : "-1" );
75 addTag( doc, tag, "show-extra-frame", Settings::showExtraFrame() ? "1" : "-1" );
77 addTag( doc, tag, "xcoord", QString::number( Settings::xRange() ) );
78 if( Settings::xRange() == 4 ) // custom plot range
80 addTag( doc, tag, "xmin", Settings::xMin() );
81 addTag( doc, tag, "xmax", Settings::xMax() );
84 addTag( doc, tag, "ycoord", QString::number( Settings::yRange() ) );
85 if( Settings::yRange() == 4 ) // custom plot range
87 addTag( doc, tag, "ymin", Settings::yMin() );
88 addTag( doc, tag, "ymax", Settings::yMax() );
91 root.appendChild( tag );
93 tag = doc.createElement( "grid" );
95 tag.setAttribute( "color", Settings::gridColor().name() );
96 tag.setAttribute( "width", Settings::gridLineWidth() );
98 addTag( doc, tag, "mode", QString::number( Settings::gridStyle() ) );
100 root.appendChild( tag );
102 tag = doc.createElement( "scale" );
104 QString temp;
105 temp.setNum(Settings::xScaling());
106 addTag( doc, tag, "tic-x", temp );
107 temp.setNum(Settings::yScaling());
108 addTag( doc, tag, "tic-y", temp );
109 temp.setNum(Settings::xPrinting());
110 addTag( doc, tag, "print-tic-x", temp );
111 temp.setNum(Settings::yPrinting());
112 addTag( doc, tag, "print-tic-y", temp);
114 root.appendChild( tag );
117 for( QValueVector<Ufkt>::iterator it = m_parser->ufkt.begin(); it != m_parser->ufkt.end(); ++it)
119 if ( !it->fstr.isEmpty() )
121 tag = doc.createElement( "function" );
123 //tag.setAttribute( "number", ix );
124 tag.setAttribute( "visible", it->f_mode );
125 tag.setAttribute( "color", QColor( it->color ).name() );
126 tag.setAttribute( "width", it->linewidth );
127 tag.setAttribute( "use-slider", it->use_slider );
129 if ( it->f1_mode)
131 tag.setAttribute( "visible-deriv", it->f1_mode );
132 tag.setAttribute( "deriv-color", QColor( it->f1_color ).name() );
133 tag.setAttribute( "deriv-width", it->f1_linewidth );
136 if ( it->f2_mode)
138 tag.setAttribute( "visible-2nd-deriv", it->f2_mode );
139 tag.setAttribute( "deriv2nd-color", QColor( it->f2_color ).name() );
140 tag.setAttribute( "deriv2nd-width", it->f2_linewidth );
143 if ( it->integral_mode)
145 tag.setAttribute( "visible-integral", "1" );
146 tag.setAttribute( "integral-color", QColor( it->integral_color ).name() );
147 tag.setAttribute( "integral-width", it->integral_linewidth );
148 tag.setAttribute( "integral-use-precision", it->integral_use_precision );
149 tag.setAttribute( "integral-precision", it->integral_precision );
150 tag.setAttribute( "integral-startx", it->str_startx );
151 tag.setAttribute( "integral-starty", it->str_starty );
154 addTag( doc, tag, "equation", it->fstr );
156 QStringList str_parameters;
157 for ( QValueList<ParameterValueItem>::Iterator k = it->parameters.begin(); k != it->parameters.end(); ++k )
158 str_parameters.append( (*k).expression);
160 if( !str_parameters.isEmpty() )
161 addTag( doc, tag, "parameterlist", str_parameters.join( ";" ) );
163 if (it->usecustomxmin)
164 addTag( doc, tag, "arg-min", it->str_dmin );
165 if (it->usecustomxmax)
166 addTag( doc, tag, "arg-max", it->str_dmax );
168 root.appendChild( tag );
173 tag = doc.createElement( "fonts" );
174 addTag( doc, tag, "axes-font", Settings::axesFont() );
175 addTag( doc, tag, "header-table-font", Settings::headerTableFont() );
176 root.appendChild( tag );
178 QFile xmlfile;
179 if (!url.isLocalFile() )
181 KTempFile tmpfile;
182 xmlfile.setName(tmpfile.name() );
183 if (!xmlfile.open( IO_WriteOnly ) )
185 tmpfile.unlink();
186 return false;
188 QTextStream ts( &xmlfile );
189 doc.save( ts, 4 );
190 xmlfile.close();
192 if ( !KIO::NetAccess::upload(tmpfile.name(), url,0))
194 tmpfile.unlink();
195 return false;
197 tmpfile.unlink();
199 else
201 xmlfile.setName(url.prettyURL(0,KURL::StripFileProtocol) );
202 if (!xmlfile.open( IO_WriteOnly ) )
203 return false;
204 QTextStream ts( &xmlfile );
205 doc.save( ts, 4 );
206 xmlfile.close();
207 return true;
209 return true;
213 void KmPlotIO::addTag( QDomDocument &doc, QDomElement &parentTag, const QString tagName, const QString tagValue )
215 QDomElement tag = doc.createElement( tagName );
216 QDomText value = doc.createTextNode( tagValue );
217 tag.appendChild( value );
218 parentTag.appendChild( tag );
221 bool KmPlotIO::load( const KURL &url )
223 QDomDocument doc( "kmpdoc" );
224 QFile f;
225 if ( !url.isLocalFile() )
227 if( !KIO::NetAccess::exists( url, true, 0 ) )
229 KMessageBox::error(0,i18n("The file does not exist."));
230 return false;
232 QString tmpfile;
233 if( !KIO::NetAccess::download( url, tmpfile, 0 ) )
235 KMessageBox::error(0,i18n("An error appeared when opening this file"));
236 return false;
238 f.setName(tmpfile);
240 else
241 f.setName( url.prettyURL(0,KURL::StripFileProtocol) );
243 if ( !f.open( IO_ReadOnly ) )
245 KMessageBox::error(0,i18n("An error appeared when opening this file"));
246 return false;
248 if ( !doc.setContent( &f ) )
250 KMessageBox::error(0,i18n("The file could not be loaded"));
251 f.close();
252 return false;
254 f.close();
256 QDomElement element = doc.documentElement();
257 QString version = element.attribute( "version" );
258 if ( version.isNull()) //an old kmplot-file
260 MainDlg::oldfileversion = true;
261 for ( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
263 if ( n.nodeName() == "axes" )
264 oldParseAxes( n.toElement() );
265 if ( n.nodeName() == "grid" )
266 parseGrid( n.toElement() );
267 if ( n.nodeName() == "scale" )
268 oldParseScale( n.toElement() );
269 if ( n.nodeName() == "function" )
270 oldParseFunction( m_parser, n.toElement() );
273 else if (version == "1" || version == "2")
275 MainDlg::oldfileversion = false;
276 for ( QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
278 if ( n.nodeName() == "axes" )
279 parseAxes( n.toElement() );
280 if ( n.nodeName() == "grid" )
281 parseGrid( n.toElement() );
282 if ( n.nodeName() == "scale" )
283 parseScale( n.toElement() );
284 if ( n.nodeName() == "function")
285 parseFunction( m_parser, n.toElement() );
288 else
289 KMessageBox::error(0,i18n("The file had an unknown version number"));
291 if ( !url.isLocalFile() )
292 KIO::NetAccess::removeTempFile( f.name() );
293 return true;
296 void KmPlotIO::parseAxes( const QDomElement &n )
298 Settings::setAxesLineWidth( n.attribute( "width", "1" ).toInt() );
299 Settings::setAxesColor( QColor( n.attribute( "color", "#000000" ) ) );
300 Settings::setTicWidth( n.attribute( "tic-width", "3" ).toInt() );
301 Settings::setTicLength( n.attribute( "tic-length", "10" ).toInt() );
303 Settings::setShowAxes( n.namedItem( "show-axes" ).toElement().text().toInt() == 1 );
304 Settings::setShowArrows( n.namedItem( "show-arrows" ).toElement().text().toInt() == 1 );
305 Settings::setShowLabel( n.namedItem( "show-label" ).toElement().text().toInt() == 1 );
306 Settings::setShowFrame( n.namedItem( "show-frame" ).toElement().text().toInt() == 1 );
307 Settings::setShowExtraFrame( n.namedItem( "show-extra-frame" ).toElement().text().toInt() == 1 );
308 Settings::setXRange( n.namedItem( "xcoord" ).toElement().text().toInt() );
309 Settings::setXMin( n.namedItem( "xmin" ).toElement().text() );
310 Settings::setXMax( n.namedItem( "xmax" ).toElement().text() );
311 Settings::setYRange( n.namedItem( "ycoord" ).toElement().text().toInt() );
312 Settings::setYMin( n.namedItem( "ymin" ).toElement().text() );
313 Settings::setYMax( n.namedItem( "ymax" ).toElement().text() );
316 void KmPlotIO::parseGrid( const QDomElement & n )
318 Settings::setGridColor( QColor( n.attribute( "color", "#c0c0c0" ) ) );
319 Settings::setGridLineWidth( n.attribute( "width", "1" ).toInt() );
321 Settings::setGridStyle( n.namedItem( "mode" ).toElement().text().toInt() );
324 int unit2index( const QString unit )
326 QString units[ 9 ] = { "10", "5", "2", "1", "0.5", "pi/2", "pi/3", "pi/4",i18n("automatic") };
327 int index = 0;
328 while( ( index < 9 ) && ( unit!= units[ index ] ) ) index ++;
329 if( index == 9 ) index = -1;
330 return index;
334 void KmPlotIO::parseScale(const QDomElement & n )
336 Settings::setXScaling( n.namedItem( "tic-x" ).toElement().text().toInt() );
337 Settings::setYScaling( n.namedItem( "tic-y" ).toElement().text().toInt() );
338 Settings::setXPrinting( n.namedItem( "print-tic-x" ).toElement().text().toInt() );
339 Settings::setYPrinting( n.namedItem( "print-tic-y" ).toElement().text().toInt() );
342 void KmPlotIO::parseFunction( XParser *m_parser, const QDomElement & n )
344 QString temp;
345 Ufkt ufkt;
346 m_parser->prepareAddingFunction(&ufkt);
347 int const next_index=m_parser->getNextIndex()+1;
349 ufkt.f_mode = n.attribute( "visible" ).toInt();
350 ufkt.color = QColor( n.attribute( "color" ) ).rgb();
351 ufkt.linewidth = n.attribute( "width" ).toInt();
352 ufkt.use_slider = n.attribute( "use-slider" ).toInt();
354 temp = n.attribute( "visible-deriv" );
355 if (!temp.isNull())
357 ufkt.f1_mode = temp.toInt();
358 ufkt.f1_color = QColor(n.attribute( "deriv-color" )).rgb();
359 ufkt.f1_linewidth = n.attribute( "deriv-width" ).toInt();
361 else
363 ufkt.f1_mode = 0;
364 ufkt.f1_color = m_parser->defaultColor(next_index);
365 ufkt.f1_linewidth = m_parser->linewidth0;
368 temp = n.attribute( "visible-2nd-deriv" );
369 if (!temp.isNull())
371 ufkt.f2_mode = temp.toInt();
372 ufkt.f2_color = QColor(n.attribute( "deriv2nd-color" )).rgb();
373 ufkt.f2_linewidth = n.attribute( "deriv2nd-width" ).toInt();
375 else
377 ufkt.f2_mode = 0;
378 ufkt.f2_color = m_parser->defaultColor(next_index);
379 ufkt.f2_linewidth = m_parser->linewidth0;
382 temp = n.attribute( "visible-integral" );
383 if (!temp.isNull())
385 ufkt.integral_mode = temp.toInt();
386 ufkt.integral_color = QColor(n.attribute( "integral-color" )).rgb();
387 ufkt.integral_linewidth = n.attribute( "integral-width" ).toInt();
388 ufkt.integral_use_precision = n.attribute( "integral-use-precision" ).toInt();
389 ufkt.integral_precision = n.attribute( "integral-precision" ).toInt();
390 ufkt.str_startx = n.attribute( "integral-startx" );
391 ufkt.startx = m_parser->eval( ufkt.str_startx );
392 ufkt.str_starty = n.attribute( "integral-starty" );
393 ufkt.starty = m_parser->eval( ufkt.str_starty );
396 else
398 ufkt.integral_mode = 0;
399 ufkt.integral_color = m_parser->defaultColor(next_index);
400 ufkt.integral_linewidth = m_parser->linewidth0;
401 ufkt.integral_use_precision = 0;
402 ufkt.integral_precision = ufkt.linewidth;
405 ufkt.str_dmin = n.namedItem( "arg-min" ).toElement().text();
406 if( ufkt.str_dmin.isEmpty() )
407 ufkt.usecustomxmin = false;
408 else
410 ufkt.usecustomxmin = true;
411 ufkt.dmin = m_parser->eval( ufkt.str_dmin );
414 ufkt.str_dmax = n.namedItem( "arg-max" ).toElement().text();
415 if( ufkt.str_dmax.isEmpty() )
416 ufkt.usecustomxmax = false;
417 else
419 ufkt.usecustomxmax = true;
420 ufkt.dmax = m_parser->eval( ufkt.str_dmax );
423 if (ufkt.usecustomxmin && ufkt.usecustomxmax && ufkt.str_dmin==ufkt.str_dmax)
425 ufkt.usecustomxmin = false;
426 ufkt.usecustomxmax = false;
429 ufkt.fstr = n.namedItem( "equation" ).toElement().text();
430 if (MainDlg::oldfileversion)
431 parseThreeDotThreeParameters( m_parser, n, ufkt );
432 else
433 parseParameters( m_parser, n, ufkt );
435 QString fstr = ufkt.fstr;
436 if ( !fstr.isEmpty() )
438 int const i = fstr.find( ';' );
439 QString str;
440 if ( i == -1 )
441 str = fstr;
442 else
443 str = fstr.left( i );
444 m_parser->addfkt( str );
445 Ufkt *added_function = &m_parser->ufkt.last();
446 added_function->f_mode = ufkt.f_mode;
447 added_function->f1_mode = ufkt.f1_mode;
448 added_function->f2_mode = ufkt.f2_mode;
449 added_function->integral_mode = ufkt.integral_mode;
450 added_function->integral_use_precision = ufkt.integral_use_precision;
451 added_function->linewidth = ufkt.linewidth;
452 added_function->f1_linewidth = ufkt.f1_linewidth;
453 added_function->f2_linewidth = ufkt.f2_linewidth;
454 added_function->integral_linewidth = ufkt.integral_linewidth;
455 added_function->str_dmin = ufkt.str_dmin;
456 added_function->str_dmax = ufkt.str_dmax;
457 added_function->dmin = ufkt.dmin;
458 added_function->dmax = ufkt.dmax;
459 added_function->str_startx = ufkt.str_startx;
460 added_function->str_starty = ufkt.str_starty;
461 added_function->oldx = ufkt.oldx;
462 added_function->starty = ufkt.starty;
463 added_function->startx = ufkt.startx;
464 added_function->integral_precision = ufkt.integral_precision;
465 added_function->color = ufkt.color;
466 added_function->f1_color = ufkt.f1_color;
467 added_function->f2_color = ufkt.f2_color;
468 added_function->integral_color = ufkt.integral_color;
469 added_function->parameters = ufkt.parameters;
470 added_function->use_slider = ufkt.use_slider;
471 added_function->usecustomxmin = ufkt.usecustomxmin;
472 added_function->usecustomxmax = ufkt.usecustomxmax;
476 void KmPlotIO::parseParameters( XParser *m_parser, const QDomElement &n, Ufkt &ufkt )
478 QStringList str_parameters;
479 for ( QValueList<ParameterValueItem>::Iterator it = ufkt.parameters.begin(); it != ufkt.parameters.end(); ++it )
480 str_parameters.append( (*it).expression);
481 str_parameters = QStringList::split( ";", n.namedItem( "parameterlist" ).toElement().text() );
482 for( QStringList::Iterator it = str_parameters.begin(); it != str_parameters.end(); ++it )
483 ufkt.parameters.append( ParameterValueItem( *it, m_parser->eval( *it ) ));
486 void KmPlotIO::parseThreeDotThreeParameters( XParser *m_parser, const QDomElement &n, Ufkt &ufkt )
488 QStringList str_parameters;
489 for ( QValueList<ParameterValueItem>::Iterator it = ufkt.parameters.begin(); it != ufkt.parameters.end(); ++it )
490 str_parameters.append( (*it).expression);
491 str_parameters = QStringList::split( ",", n.namedItem( "parameterlist" ).toElement().text() );
492 for( QStringList::Iterator it = str_parameters.begin(); it != str_parameters.end(); ++it )
493 ufkt.parameters.append( ParameterValueItem( *it, m_parser->eval( *it ) ));
496 void KmPlotIO::oldParseFunction( XParser *m_parser, const QDomElement & n )
498 kdDebug() << "parsing old function" << endl;
499 Ufkt ufkt;
500 m_parser->prepareAddingFunction(&ufkt);
502 ufkt.f_mode = n.attribute( "visible" ).toInt();
503 ufkt.f1_mode = n.attribute( "visible-deriv" ).toInt();
504 ufkt.f2_mode = n.attribute( "visible-2nd-deriv" ).toInt();
505 ufkt.f2_mode = 0;
506 ufkt.linewidth = n.attribute( "width" ).toInt();
507 ufkt.use_slider = -1;
508 ufkt.color = ufkt.f1_color = ufkt.f2_color = ufkt.integral_color = QColor( n.attribute( "color" ) ).rgb();
510 ufkt.str_dmin = n.namedItem( "arg-min" ).toElement().text();
511 if( ufkt.str_dmin.isEmpty() )
512 ufkt.usecustomxmin = false;
513 else
515 ufkt.dmin = m_parser->eval( ufkt.str_dmin );
516 ufkt.usecustomxmin = true;
518 ufkt.str_dmax = n.namedItem( "arg-max" ).toElement().text();
519 if( ufkt.str_dmax.isEmpty() )
520 ufkt.usecustomxmax = false;
521 else
523 ufkt.dmax = m_parser->eval( ufkt.str_dmax );
524 ufkt.usecustomxmax = true;
526 if (ufkt.usecustomxmin && ufkt.usecustomxmax && ufkt.str_dmin==ufkt.str_dmax)
528 ufkt.usecustomxmin = false;
529 ufkt.usecustomxmax = false;
532 const QString tmp_fstr = n.namedItem( "equation" ).toElement().text();
533 const int pos = tmp_fstr.find(';');
534 if ( pos == -1 )
535 ufkt.fstr = tmp_fstr;
536 else
538 ufkt.fstr = tmp_fstr.left(pos);
539 if ( !m_parser->getext( &ufkt, tmp_fstr) )
541 KMessageBox::error(0,i18n("The function %1 could not be loaded").arg(ufkt.fstr));
542 return;
546 QString fstr = ufkt.fstr;
547 if ( !fstr.isEmpty() )
549 int const i = fstr.find( ';' );
550 QString str;
551 if ( i == -1 )
552 str = fstr;
553 else
554 str = fstr.left( i );
555 m_parser->addfkt( str );
556 Ufkt *added_function = &m_parser->ufkt.last();
557 added_function->f_mode = ufkt.f_mode;
558 added_function->f1_mode = ufkt.f1_mode;
559 added_function->f2_mode = ufkt.f2_mode;
560 added_function->integral_mode = ufkt.integral_mode;
561 added_function->integral_use_precision = ufkt.integral_use_precision;
562 added_function->linewidth = ufkt.linewidth;
563 added_function->f1_linewidth = ufkt.f1_linewidth;
564 added_function->f2_linewidth = ufkt.f2_linewidth;
565 added_function->integral_linewidth = ufkt.integral_linewidth;
566 added_function->str_dmin = ufkt.str_dmin;
567 added_function->str_dmax = ufkt.str_dmax;
568 added_function->dmin = ufkt.dmin;
569 added_function->dmax = ufkt.dmax;
570 added_function->str_startx = ufkt.str_startx;
571 added_function->str_starty = ufkt.str_starty;
572 added_function->oldx = ufkt.oldx;
573 added_function->starty = ufkt.starty;
574 added_function->startx = ufkt.startx;
575 added_function->integral_precision = ufkt.integral_precision;
576 added_function->color = ufkt.color;
577 added_function->f1_color = ufkt.f1_color;
578 added_function->f2_color = ufkt.f2_color;
579 added_function->integral_color = ufkt.integral_color;
580 added_function->parameters = ufkt.parameters;
581 added_function->use_slider = ufkt.use_slider;
582 added_function->usecustomxmin = ufkt.usecustomxmin;
583 added_function->usecustomxmax = ufkt.usecustomxmax;
587 void KmPlotIO::oldParseAxes( const QDomElement &n )
589 Settings::setAxesLineWidth( n.attribute( "width", "1" ).toInt() );
590 Settings::setAxesColor( QColor( n.attribute( "color", "#000000" ) ) );
591 Settings::setTicWidth( n.attribute( "tic-width", "3" ).toInt() );
592 Settings::setTicLength( n.attribute( "tic-length", "10" ).toInt() );
594 Settings::setShowAxes( true );
595 Settings::setShowArrows( true );
596 Settings::setShowLabel( true );
597 Settings::setShowFrame( true );
598 Settings::setShowExtraFrame( true );
599 Settings::setXRange( n.namedItem( "xcoord" ).toElement().text().toInt() );
600 Settings::setXMin( n.namedItem( "xmin" ).toElement().text() );
601 Settings::setXMax( n.namedItem( "xmax" ).toElement().text() );
602 Settings::setYRange( n.namedItem( "ycoord" ).toElement().text().toInt() );
603 Settings::setYMin( n.namedItem( "ymin" ).toElement().text() );
604 Settings::setYMax( n.namedItem( "ymax" ).toElement().text() );
607 void KmPlotIO::oldParseScale( const QDomElement & n )
609 Settings::setXScaling( unit2index( n.namedItem( "tic-x" ).toElement().text() ) );
610 Settings::setYScaling( unit2index( n.namedItem( "tic-y" ).toElement().text() ) );
611 Settings::setXPrinting( unit2index( n.namedItem( "print-tic-x" ).toElement().text() ) );
612 Settings::setYPrinting( unit2index( n.namedItem( "print-tic-y" ).toElement().text() ) );