diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /filters/kpresenter/ooimpress | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'filters/kpresenter/ooimpress')
-rw-r--r-- | filters/kpresenter/ooimpress/Makefile.am | 21 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop | 63 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop | 64 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/ooimpressexport.cc | 1160 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/ooimpressexport.h | 92 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/ooimpressimport.cc | 2433 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/ooimpressimport.h | 120 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/status.html | 227 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/stylefactory.cc | 1629 | ||||
-rw-r--r-- | filters/kpresenter/ooimpress/stylefactory.h | 282 |
10 files changed, 6091 insertions, 0 deletions
diff --git a/filters/kpresenter/ooimpress/Makefile.am b/filters/kpresenter/ooimpress/Makefile.am new file mode 100644 index 00000000..b69dc04c --- /dev/null +++ b/filters/kpresenter/ooimpress/Makefile.am @@ -0,0 +1,21 @@ +####### General stuff + +INCLUDES= -I$(srcdir)/../../liboofilter $(KOFFICE_INCLUDES) $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libooimpressimport.la libooimpressexport.la + + +libooimpressimport_la_SOURCES = ooimpressimport.cc +libooimpressimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libooimpressimport_la_LIBADD = ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +libooimpressexport_la_SOURCES = ooimpressexport.cc stylefactory.cc +libooimpressexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libooimpressexport_la_LIBADD = ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = kpresenter_ooimpress_import.desktop kpresenter_ooimpress_export.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop b/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop new file mode 100644 index 00000000..d645efbf --- /dev/null +++ b/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Impress Export Filter for KPresenter +Name[ar]=مِرْشَح استيراد OpenOffice.org Impress لدى KPresenter +Name[bg]=Филтър за експортиране от OpenOffice.org Impress в KPresenter +Name[br]=Sil ezporzh OpenOffice.org Impress evit KPresenter +Name[ca]=Filtre d'exportació OpenOffice.org Impress per a KPresenter +Name[cs]=OpenOffice.org Impress exportní filtr pro KPresenter +Name[cy]=Hidlen Allforio Impress OpenOffice.org ar gyfer KPresenter +Name[da]=OpenOffice.org Impress eksport-filter for KPresenter +Name[de]=KPresenter OpenOffice.org-Impress-Exportfilter +Name[el]=Φίλτρο εξαγωγής OpenOffice.org Impress για το KPresenter +Name[es]=Filtro de importación de OpenOffice.org Impress para KPresenter +Name[et]=KPresenteri OpenOffice.org Impress'i ekspordifilter +Name[eu]=KPresenter-en OpenOffice.org Impress esportaziorako iragazkia +Name[fa]=پالایۀ صادرات OpenOffice.org Impress برای KPresenter +Name[fi]=OpenOffice.org Impress -vientisuodin KPresenterille +Name[fr]=Filtre d'exportation OpenOffice.org Impress pour KPresenter +Name[fy]=OpenOffice.org Impress-Eksportfilter foar KPresenter +Name[gl]=Filtro de Exportación de OpenOffice.org Impress para KPresenter +Name[he]=מסנן ייצוא מ־KPresenter ל־OpenOffice.org Impress +Name[hi]=के-प्रेज़ेन्टर के लिए ओपन-ऑफ़िस.ऑर्ग इम्प्रेस निर्यात छननी +Name[hr]=OpenOffice.org Impress filtar izvoza za KPresenter +Name[hu]=OpenOffice.org Impress exportszűrő a KPresenterhez +Name[is]=OpenOffice.org Impress útflutningssía fyrir KPresenter +Name[it]=Filtro di esportazione OpenOffice.org Impress per KPresenter +Name[ja]=KPresenter OpenOffice.org Impress エクスポートフィルタ +Name[km]=តម្រងនាំចេញ OpenOffice.org Impress សម្រាប់ KPresenter +Name[lt]=OpenOffice.org Impress eksportavimo filtras skirtas KPresenter +Name[lv]=OpenOffice.org Impress eksporta filtrs priekš KPresenter +Name[ms]=Penapis Eksport OpenOffice.org Impress bagi KPresenter +Name[nb]=OpenOffice.org Impress-eksportfilter for KPresenter +Name[nds]="OpenOffice.org Impress"-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि OpenOffice.org इम्प्रेस निर्यात फिल्टर +Name[nl]=OpenOffice.org Impress-exportfilter voor KPresenter +Name[nn]=OpenOffice.org Impress-eksportfilter for KPresenter +Name[pl]=Filtr eksportu do OpenOffice.org Impress dla KPresenter +Name[pt]=Filtro de Exportação de OpenOffice.org Impress para o KPresenter +Name[pt_BR]=Filtro de Exportação OpenOffice.org Impress para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в OpenOffice.org Impress +Name[se]=KPresenter:a OpenOffice.org Impress-olggosfievrridansilli +Name[sk]=Filter pre import OpenOffice.org Impress pre KPresenter +Name[sl]=Izvozni filter OpenOffice.org Impress za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у OpenOffice Impress +Name[sr@Latn]=KPresenter-ov filter za izvoz u OpenOffice Impress +Name[sv]=OpenOffice.org Impress-exportfilter för Kpresenter +Name[ta]=openoffice.org Impress ஏற்றுமதி வடிகட்டி kpresenter +Name[tg]=Филтри Содироти OpenOffice.org Impress барои KPresenter +Name[tr]=KPresenter için OpenOffice.org Impress Alma Filtresi +Name[uk]=Фільтр експорту презентацій OpenOffice.org для KPresenter +Name[uz]=KPresenter uchun OpenOffice.org Impress eksport filteri +Name[uz@cyrillic]=KPresenter учун OpenOffice.org Impress экспорт филтери +Name[wa]=Passete OpenOffice.org Impress di rexhowe po KPresenter +Name[zh_CN]=KPresenter 的 OpenOffice.org Impress 导出过滤器 +Name[zh_TW]=KPresenter 的 OpenOffice.org Impress 匯出過濾程式 +X-KDE-Export=application/vnd.sun.xml.impress +X-KDE-Import=application/x-kpresenter +X-KDE-Weight=1 +X-KDE-Library=libooimpressexport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop b/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop new file mode 100644 index 00000000..b5b5a79f --- /dev/null +++ b/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Impress Import Filter for KPresenter +Name[ar]=مِرْشَح استيراد OpenOffice.org Impress لدى KPresenter +Name[bg]=Филтър за импортиране от OpenOffice.org Impress в KPresenter +Name[br]=Sil enporzh OpenOffice.org Impress evit KPresenter +Name[ca]=Filtre d'importació OpenOffice.org Impress per a KPresenter +Name[cs]=OpenOffice.org Impress importní filtr pro KPresenter +Name[cy]=Hidlen Fewnforio OpenOffice.org Impress i KPresenter +Name[da]=OpenOffice.org Impress import-filter for KPresenter +Name[de]=KPresenter OpenOffice.org-Impress-Importfilter +Name[el]=Φίλτρο εισαγωγής OpenOffice.org Impress για το KPresenter +Name[es]=Filtro de importación de Impress para KPresenter +Name[et]=KPresenteri OpenOffice.org Impress'i impordifilter +Name[eu]=KPresenter-en OpenOffice.org Impress inportaziorako iragazkia +Name[fa]=پالایۀ صادرات OpenOffice.org Impress برای KPresenter +Name[fi]=OpenOffice.org Impress -tuontisuodin KPresenterille +Name[fr]=Filtre d'importation OpenOffice.org Impress pour KPresenter +Name[fy]=OpenOffice.org Impress-Ymportfilter foar KPresenter +Name[gl]=Filtro de Importación de OpenOffice.org Impress para KPresenter +Name[he]=מסנן ייבוא מ־OpenOffice.org Impress ל־KPresenter +Name[hi]=के-प्रेज़ेन्टर के लिए ओपन-ऑफ़िस.ऑर्ग इम्प्रेस आयात छननी +Name[hr]=OpenOffice.org Impress filtar uvoza za KPresenter +Name[hu]=OpenOffice Impress importszűrő a KPresenterhez +Name[is]=OpenOffice.org Impress innflutningssía fyrir KPresenter +Name[it]=Filtro di importazione OpenOffice.org Impress per KPresenter +Name[ja]=KPresenter OpenOffice.org Impress インポートフィルタ +Name[km]=តម្រងនាំចូល OpenOffice.org Impress សម្រាប់ KPresenter +Name[lo]= ຕົວຕອງການນຳເຂົ້າ CSV ຂອງກະດາດຄຳນວນ K +Name[lt]=OpenOffice.org Impress importavimo filtras skirtas KPresenter +Name[lv]=OpenOffice.org Impress importa filtrs priekš KPresenter +Name[ms]=Penapis Import OpenOffice.org Impress bagi KPresenter +Name[nb]=OpenOffice.org Impress-importfilter for KPresenter +Name[nds]="OpenOffice.org Impress"-Importfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि OpenOffice.org इम्प्रेस निर्यात फिल्टर +Name[nl]=OpenOffice.org Impress-importfilter voor KPresenter +Name[nn]=OpenOffice.org Impress-importfilter for KPresenter +Name[pl]=Filtr importu z OpenOffice.org Impress dla KSpread +Name[pt]=Filtro de Importação de OpenOffice.org Impress para o KPresenter +Name[pt_BR]=Filtro de Importação OpenOffice.org Impress para o KPresenter +Name[ru]=Фильтр импорта презентаций OpenOffice.org Impress в KPresenter +Name[se]=KPresenter:a OpenOffice.org Impress-sisafievrridansilli +Name[sk]=Filter pre import OpenOffice.org Impress pre KPresenter +Name[sl]=Uvozni filter OpenOffice.org Impress za KPresenter +Name[sr]=KPresenter-ов филтер за увоз из OpenOffice Impress-а +Name[sr@Latn]=KPresenter-ov filter za uvoz iz OpenOffice Impress-a +Name[sv]=OpenOffice Impress-importfilter för Kpresenter +Name[ta]=openoffice.org impress இறக்குமதி வடிகட்டி for kpresenter +Name[tg]=Филтри Воридоти OpenOffice.org Impress барои KPresenter +Name[tr]=KPresenter için OpenOffice.org Impress Alma Filtresi +Name[uk]=Фільтр імпорту презентацій OpenOffice.org для KPresenter +Name[uz]=KPresenter uchun OpenOffice.org Impress import filteri +Name[uz@cyrillic]=KPresenter учун OpenOffice.org Impress импорт филтери +Name[xh]=OpenOffice.org Iphawula Isihluzi Sorhwebo se KPresenter +Name[zh_CN]=KPresenter 的 OpenOffice.org Impress 导入过滤器 +Name[zh_TW]=KPresenter 的 OpenOffice.org Impress 匯入過濾程式 +X-KDE-Export=application/x-kpresenter +X-KDE-Import=application/vnd.sun.xml.impress,application/vnd.sun.xml.impress.template +X-KDE-Weight=1 +X-KDE-Library=libooimpressimport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/ooimpress/ooimpressexport.cc b/filters/kpresenter/ooimpress/ooimpressexport.cc new file mode 100644 index 00000000..27d0781d --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressexport.cc @@ -0,0 +1,1160 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "ooimpressexport.h" + +#include <qdom.h> +#include <qfile.h> +#include <qdatetime.h> + +#include <kdebug.h> +#include <kgenericfactory.h> +#include <KoFilterChain.h> +#include <KoGlobal.h> +#include <KoUnit.h> + +typedef KGenericFactory<OoImpressExport, KoFilter> OoImpressExportFactory; +K_EXPORT_COMPONENT_FACTORY( libooimpressexport, OoImpressExportFactory( "kofficefilters" ) ) + + +OoImpressExport::OoImpressExport( KoFilter *, const char *, const QStringList & ) + : KoFilter() + , m_currentPage( 0 ) + , m_objectIndex( 0 ) + , m_pageHeight( 0 ) + , m_activePage( 0 ) + , m_gridX( -1.0 ) + , m_gridY( -1.0 ) + , m_snapToGrid( false ) + , m_pictureIndex( 0 ) + , m_storeinp( 0L ) + , m_storeout( 0L ) +{ +} + +OoImpressExport::~OoImpressExport() +{ + delete m_storeout; + delete m_storeinp; +} + +KoFilter::ConversionStatus OoImpressExport::convert( const QCString & from, + const QCString & to ) +{ + kdDebug(30518) << "Entering Ooimpress Export filter: " << from << " - " << to << endl; + + if ( ( to != "application/vnd.sun.xml.impress") || (from != "application/x-kpresenter" ) ) + { + kdWarning(30518) << "Invalid mimetypes " << to << " " << from << endl; + return KoFilter::NotImplemented; + } + + // read in the KPresenter file + KoFilter::ConversionStatus preStatus = openFile(); + + if ( preStatus != KoFilter::OK ) + return preStatus; + + QDomImplementation impl; + QDomDocument meta( impl.createDocumentType( "office:document-meta", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentMeta( meta ); + + // store document meta + m_storeout = KoStore::createStore( m_chain->outputFile(), KoStore::Write, "", KoStore::Zip ); + + if ( !m_storeout ) + { + kdWarning(30518) << "Couldn't open the requested file." << endl; + return KoFilter::FileNotFound; + } + + if ( !m_storeout->open( "meta.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'meta.xml'." << endl; + return KoFilter::CreationError; + } + + QCString metaString = meta.toCString(); + //kdDebug(30518) << "meta :" << metaString << endl; + m_storeout->write( metaString , metaString.length() ); + m_storeout->close(); + + QDomDocument content( impl.createDocumentType( "office:document-content", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentContent( content ); + + // add the automatic styles + m_styleFactory.addAutomaticStyles( content, m_styles ); + + // store document content + if ( !m_storeout->open( "content.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'content.xml'." << endl; + return KoFilter::CreationError; + } + + QCString contentString = content.toCString(); + //kdDebug(30518) << "content :" << contentString << endl; + m_storeout->write( contentString , contentString.length() ); + m_storeout->close(); + + QDomDocument settings( impl.createDocumentType( "office:document-content", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentSettings( settings ); + + // store document content + if ( !m_storeout->open( "settings.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'settings.xml'." << endl; + return KoFilter::CreationError; + } + + QCString settingsString = settings.toCString(); + //kdDebug(30518) << "content :" << settingsString << endl; + m_storeout->write( settingsString , settingsString.length() ); + m_storeout->close(); + + + QDomDocument styles( impl.createDocumentType( "office:document-styles", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentStyles( styles ); + + // store document styles + if ( !m_storeout->open( "styles.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'styles.xml'." << endl; + return KoFilter::CreationError; + } + + QCString stylesString = styles.toCString(); + //kdDebug(30518) << "styles :" << stylesString << endl; + m_storeout->write( stylesString , stylesString.length() ); + m_storeout->close(); + + QDomDocument manifest( impl.createDocumentType( "manifest:manifest", + "-//OpenOffice.org//DTD Manifest 1.0//EN", + "Manifest.dtd" ) ); + + createDocumentManifest( manifest ); + + // store document manifest + m_storeout->enterDirectory( "META-INF" ); + if ( !m_storeout->open( "manifest.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'META-INF/manifest.xml'." << endl; + return KoFilter::CreationError; + } + + QCString manifestString = manifest.toCString(); + //kdDebug(30518) << "manifest :" << manifestString << endl; + m_storeout->write( manifestString , manifestString.length() ); + m_storeout->close(); + + return KoFilter::OK; +} + +KoFilter::ConversionStatus OoImpressExport::openFile() +{ + m_storeinp = KoStore::createStore( m_chain->inputFile(), KoStore::Read ); + + if ( !m_storeinp ) + { + kdWarning(30518) << "Couldn't open the requested file." << endl; + return KoFilter::FileNotFound; + } + + if ( !m_storeinp->open( "maindoc.xml" ) ) + { + kdWarning(30518) << "This file doesn't seem to be a valid KPresenter file" << endl; + return KoFilter::WrongFormat; + } + + m_maindoc.setContent( m_storeinp->device() ); + m_storeinp->close(); + + if ( m_storeinp->open( "documentinfo.xml" ) ) + { + m_documentinfo.setContent( m_storeinp->device() ); + m_storeinp->close(); + } + else + kdWarning(30518) << "Documentinfo do not exist!" << endl; + + emit sigProgress( 10 ); + + return KoFilter::OK; +} + +void OoImpressExport::createDocumentMeta( QDomDocument & docmeta ) +{ + docmeta.appendChild( docmeta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = docmeta.createElement( "office:document-meta" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/" ); + content.setAttribute( "xmlns:meta", "http://openoffice.org/2000/meta" ); + content.setAttribute( "office:version", "1.0" ); + + QDomNode meta = docmeta.createElement( "office:meta" ); + + QDomElement generator = docmeta.createElement( "meta:generator" ); + generator.appendChild( docmeta.createTextNode( "KPresenter 1.5" ) ); + meta.appendChild( generator ); + + QDomNode i = m_documentinfo.namedItem( "document-info" ); + if ( !i.isNull() ) + { + QDomNode n = i.namedItem( "author" ).namedItem( "full-name" ); + if ( !n.isNull() ) + { + QDomElement fullName = n.toElement(); + QDomElement creator = docmeta.createElement( "meta:initial-creator" ); + creator.appendChild( docmeta.createTextNode( fullName.text() ) ); + meta.appendChild( creator ); + + creator = docmeta.createElement( "meta:creator" ); + creator.appendChild( docmeta.createTextNode( fullName.text() ) ); + meta.appendChild( creator ); + } + n = i.namedItem( "about" ).namedItem( "abstract" ); + if ( !n.isNull() ) + { + QDomElement user = docmeta.createElement( "dc:description" ); + user.appendChild( n.firstChild() ); + meta.appendChild( user ); + } + n = i.namedItem( "about" ).namedItem( "keyword" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement key = docmeta.createElement( "meta:keywords" ); + QDomElement keyword = docmeta.createElement( "meta:keyword" ); + key.appendChild( keyword ); + keyword.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( key ); + } + n = i.namedItem( "about" ).namedItem( "subject" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement subjet = docmeta.createElement( "dc:subject" ); + subjet.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( subjet ); + } + n = i.namedItem( "about" ).namedItem( "title" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement title = docmeta.createElement( "dc:title" ); + title.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( title ); + } + } + +// QDomElement statistic = docmeta.createElement( "meta:document-statistic" ); +// statistic.setAttribute( "meta:object-count", 0 ); +// meta.appendChild( data ); + + content.appendChild( meta ); + docmeta.appendChild( content ); +} + +void OoImpressExport::createDocumentStyles( QDomDocument & docstyles ) +{ + docstyles.appendChild( docstyles.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = docstyles.createElement( "office:document-content" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" ); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "office:version", "1.0" ); + + // order important here! + QDomElement styles = docstyles.createElement( "office:styles" ); + m_styleFactory.addOfficeStyles( docstyles, styles ); + content.appendChild( styles ); + + QDomElement automatic = docstyles.createElement( "office:automatic-styles" ); + m_styleFactory.addOfficeAutomatic( docstyles, automatic ); + content.appendChild( automatic ); + + QDomElement master = docstyles.createElement( "office:master-styles" ); + m_styleFactory.addOfficeMaster( docstyles, master ); + content.appendChild( master ); + + docstyles.appendChild( content ); +} + +void OoImpressExport::createDocumentSettings( QDomDocument & docsetting ) +{ + docsetting.appendChild( docsetting.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement setting = docsetting.createElement( "office:document-settings" ); + setting.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + setting.setAttribute( "xmlns:config", "http://openoffice.org/2001/config" ); + setting.setAttribute( "office:class", "presentation" ); + setting.setAttribute( "office:version", "1.0" ); + + QDomElement begin = docsetting.createElement( "office:settings" ); + + QDomElement configItem = docsetting.createElement("config:config-item-set" ); + configItem.setAttribute( "config:name", "view-settings" ); + + QDomElement mapIndexed = docsetting.createElement( "config:config-item-map-indexed" ); + mapIndexed.setAttribute("config:name", "Views" ); + configItem.appendChild( mapIndexed ); + + //<config:config-item-map-indexed config:name="Views"> + + QDomElement mapItem = docsetting.createElement("config:config-item-map-entry" ); + + QDomElement attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "SnapLinesDrawing" ); + attribute.setAttribute( "config:type", "string" ); + attribute.appendChild( docsetting.createTextNode( m_helpLine ) ); + mapItem.appendChild( attribute ); + //<config:config-item config:name="SnapLinesDrawing" config:type="string">H5983V700V10777H4518V27601P50000,9000P8021,2890</config:config-item> + + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "IsSnapToGrid" ); + attribute.setAttribute( "config:type", "boolean" ); + attribute.appendChild( docsetting.createTextNode( m_snapToGrid ? "true" : "false" ) ); + mapItem.appendChild( attribute ); + + if ( m_gridX >=0 ) + { + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "GridFineWidth" ); + attribute.setAttribute( "config:type", "int" ); + attribute.appendChild( docsetting.createTextNode( QString::number( ( int ) ( KoUnit::toMM( ( m_gridX ) )*100 ) ) ) ); + mapItem.appendChild( attribute ); + } + + if ( m_gridY >=0 ) + { + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "GridFineHeight" ); + attribute.setAttribute( "config:type", "int" ); + attribute.appendChild( docsetting.createTextNode( QString::number( ( int ) ( KoUnit::toMM( ( m_gridY ) )*100 ) ) ) ); + mapItem.appendChild( attribute ); + } + + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "SelectedPage" ); + attribute.setAttribute( "config:type", "short" ); + attribute.appendChild( docsetting.createTextNode( QString::number( m_activePage ) ) ); + mapItem.appendChild( attribute ); + + + mapIndexed.appendChild( mapItem ); + + begin.appendChild( configItem ); + + setting.appendChild( begin ); + + + docsetting.appendChild( setting ); + +} + +void OoImpressExport::createDocumentContent( QDomDocument & doccontent ) +{ + doccontent.appendChild( doccontent.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doccontent.createElement( "office:document-content" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "xmlns:presentation", "http://openoffice.org/2000/presentation" ); + content.setAttribute( "office:class", "presentation" ); + content.setAttribute( "office:version", "1.0" ); + + QDomElement script = doccontent.createElement( "office:script" ); + content.appendChild( script ); + + m_styles = doccontent.createElement( "office:automatic-styles" ); + content.appendChild( m_styles ); + + QDomElement body = doccontent.createElement( "office:body" ); + exportBody( doccontent, body ); + content.appendChild( body ); + + doccontent.appendChild( content ); +} + +void OoImpressExport::createDocumentManifest( QDomDocument & docmanifest ) +{ + docmanifest.appendChild( docmanifest.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement manifest = docmanifest.createElement( "manifest:manifest" ); + manifest.setAttribute( "xmlns:manifest", "http://openoffice.org/2001/manifest" ); + + QDomElement entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "application/vnd.sun.xml.impress" ); + entry.setAttribute( "manifest:full-path", "/" ); + manifest.appendChild( entry ); + + QMap<QString, QString>::Iterator it; + for ( it = m_pictureLst.begin(); it != m_pictureLst.end(); ++it ) + { + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", it.data() ); + entry.setAttribute( "manifest:full-path", it.key() ); + manifest.appendChild( entry ); + } + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "content.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "styles.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "meta.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "settings.xml" ); + manifest.appendChild( entry ); + + docmanifest.appendChild( manifest ); +} + +QString OoImpressExport::pictureKey( QDomElement &elem ) +{ + // Default date/time is the *nix epoch: 1970-01-01 00:00:00,000 + int year=1970, month=1, day=1; + int hour=0, minute=0, second=0, msec=0; // We must initialize to zero, as not all compilers are C99-compliant + if ( elem.tagName() == "KEY" ) + { + if( elem.hasAttribute( "year" ) ) + year=elem.attribute( "year" ).toInt(); + if( elem.hasAttribute( "month" ) ) + month=elem.attribute( "month" ).toInt(); + if( elem.hasAttribute( "day" ) ) + day=elem.attribute( "day" ).toInt(); + if( elem.hasAttribute( "hour" ) ) + hour=elem.attribute( "hour" ).toInt(); + if( elem.hasAttribute( "minute" ) ) + minute=elem.attribute( "minute" ).toInt(); + if( elem.hasAttribute( "second" ) ) + second=elem.attribute( "second" ).toInt(); + if( elem.hasAttribute( "msec" ) ) + msec=elem.attribute( "msec" ).toInt(); + } + QDateTime key; + key.setDate( QDate( year, month, day ) ); + key.setTime( QTime( hour, minute, second, msec ) ); + return key.toString(); +} + +void OoImpressExport::createPictureList( QDomNode &pictures ) +{ + pictures = pictures.firstChild(); + for( ; !pictures.isNull(); pictures = pictures.nextSibling() ) + { + if ( pictures.isElement() ) + { + QDomElement element = pictures.toElement(); + if ( element.tagName() == "KEY" ) + { + //kdDebug(30518)<<"element.attribute( name ) :"<<element.attribute( "name" )<<endl; + m_kpresenterPictureLst.insert( pictureKey( element ), element.attribute( "name" ) ); + } + else + kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl; + } + } +} + +void OoImpressExport::createAttribute( QDomNode &attributeValue ) +{ + QDomElement elem = attributeValue.toElement(); + if(elem.hasAttribute("activePage")) + m_activePage=elem.attribute("activePage").toInt(); + if(elem.hasAttribute("gridx")) + m_gridX = elem.attribute("gridx").toDouble(); + if(elem.hasAttribute("gridy")) + m_gridY = elem.attribute("gridy").toDouble(); + if(elem.hasAttribute("snaptogrid")) + m_snapToGrid = (bool)elem.attribute("snaptogrid").toInt(); +} + +void OoImpressExport::createHelpLine( QDomNode &helpline ) +{ + helpline = helpline.firstChild(); + QDomElement helplines; + for( ; !helpline.isNull(); helpline = helpline.nextSibling() ) + { + if ( helpline.isElement() ) + { + helplines = helpline.toElement(); + if ( helplines.tagName()=="Vertical" ) + { + int tmpX = ( int ) ( KoUnit::toMM( helplines.attribute("value").toDouble() )*100 ); + m_helpLine+="V"+QString::number( tmpX ); + } + else if ( helplines.tagName()=="Horizontal" ) + { + int tmpY = ( int ) ( KoUnit::toMM( helplines.attribute("value").toDouble() )*100 ); + m_helpLine+="H"+QString::number( tmpY ); + } + else if ( helplines.tagName()=="HelpPoint" ) + { + QString str( "P%1,%2" ); + int tmpX = ( int ) ( KoUnit::toMM( helplines.attribute("posX").toDouble() )*100 ); + int tmpY = ( int ) ( KoUnit::toMM( helplines.attribute("posY").toDouble() )*100 ); + m_helpLine+=str.arg( QString::number( tmpX ) ).arg( QString::number( tmpY ) ); + } + } + } + //kdDebug(30518)<<"m_helpLine :"<<m_helpLine<<endl; +} + + +void OoImpressExport::exportBody( QDomDocument & doccontent, QDomElement & body ) +{ + QDomNode doc = m_maindoc.namedItem( "DOC" ); + QDomNode paper = doc.namedItem( "PAPER" ); + QDomNode background = doc.namedItem( "BACKGROUND" ); + QDomNode header = doc.namedItem( "HEADER" ); + QDomNode footer = doc.namedItem( "FOOTER" ); + QDomNode titles = doc.namedItem( "PAGETITLES" ); + QDomNode notes = doc.namedItem( "PAGENOTES" ); + QDomNode objects = doc.namedItem( "OBJECTS" ); + QDomNode pictures = doc.namedItem( "PICTURES" ); + QDomNode sounds = doc.namedItem( "SOUNDS" ); + QDomNode helpline = doc.namedItem( "HELPLINES" ); + QDomNode attributeValue = doc.namedItem( "ATTRIBUTES" ); + QDomNode infiniLoop = doc.namedItem( "INFINITLOOP" ); + QDomNode manualSwitch = doc.namedItem( "MANUALSWITCH" ); + QDomNode customSlideShow = doc.namedItem( "CUSTOMSLIDESHOWCONFIG" ); + QDomNode customSlideShowDefault = doc.namedItem( "DEFAULTCUSTOMSLIDESHOWNAME" ); + + QDomNode bgpage = background.firstChild(); + + createPictureList( pictures ); + + createHelpLine( helpline ); + + createAttribute( attributeValue ); + + // store the paper settings + QDomElement p = paper.toElement(); + m_masterPageStyle = m_styleFactory.createPageMasterStyle( p ); + m_pageHeight = p.attribute( "ptHeight" ).toFloat(); + + m_currentPage = 1; + + // parse all pages + QDomNode note = notes.firstChild(); + for ( QDomNode title = titles.firstChild(); !title.isNull() && !note.isNull(); + title = title.nextSibling(), note = note.nextSibling() ) + { + // create the page style and ignore the fact that there may + // be less backgrounds than pages + QDomElement bg = bgpage.toElement(); + QString ps = m_styleFactory.createPageStyle( bg ); + bgpage = bgpage.nextSibling(); + + QDomElement t = title.toElement(); + QDomElement drawPage = doccontent.createElement( "draw:page" ); + drawPage.setAttribute( "draw:name", t.attribute( "title" ) ); + drawPage.setAttribute( "draw:style-name", ps ); + drawPage.setAttribute( "draw:id", m_currentPage ); + drawPage.setAttribute( "draw:master-page-name", m_masterPageStyle ); + + appendObjects( doccontent, objects, drawPage ); + + QDomElement noteElement = note.toElement(); + appendNote( doccontent, noteElement, drawPage ); + body.appendChild( drawPage ); + m_currentPage++; + } + int infiniLoopValue = -1; + int manualSwitchValue = -1; + if ( !infiniLoop.isNull() && infiniLoop.toElement().hasAttribute( "value" )) + { + bool ok; + int val = infiniLoop.toElement().attribute( "value" ).toInt( &ok ); + if ( ok ) + infiniLoopValue = val; + } + if ( !manualSwitch.isNull() && manualSwitch.toElement().hasAttribute( "value" )) + { + bool ok; + int val = manualSwitch.toElement().attribute( "value" ).toInt( &ok ); + if ( ok ) + manualSwitchValue = val; + } + if ( infiniLoopValue != -1 || manualSwitchValue != -1 || !customSlideShowDefault.isNull()) + { + QDomElement settings = doccontent.createElement( "presentation:settings" ); + if ( infiniLoopValue !=-1 ) + settings.setAttribute( "presentation:force-manual", ( manualSwitchValue==1 ) ? "true" : "false" ); + if ( manualSwitchValue != -1 ) + settings.setAttribute( "presentation:endless", ( infiniLoopValue==1 ) ? "true": "false" ); + if ( !customSlideShowDefault.isNull() ) + settings.setAttribute( "presentation:show", customSlideShowDefault.toElement().attribute( "name" ) ); + + if ( !customSlideShow.isNull() ) + { + for ( QDomNode customPage = customSlideShow.firstChild(); !customPage.isNull(); + customPage = customPage.nextSibling() ) + { + QDomElement show = customPage.toElement(); + if ( !show.isNull() && show.tagName()=="CUSTOMSLIDESHOW" ) + { + QDomElement showElement = doccontent.createElement( "presentation:show" ); + showElement.setAttribute( "presentation:name",show.attribute( "name" ) ); + showElement.setAttribute( "presentation:pages",show.attribute( "pages" ) ); + settings.appendChild( showElement ); + } + } + } + body.appendChild( settings ); + } +} + + +void OoImpressExport::appendObjects(QDomDocument & doccontent, QDomNode &objects, QDomElement &drawPage) +{ + // I am not sure if objects are always stored sorted so I parse all + // of them to find the ones belonging to a certain page. + for ( QDomNode object = objects.firstChild(); !object.isNull(); + object = object.nextSibling() ) + { + QDomElement o = object.toElement(); + + QDomElement orig = o.namedItem( "ORIG" ).toElement(); + float y = orig.attribute( "y" ).toFloat(); + + if ( y < m_pageHeight * ( m_currentPage - 1 ) || + y >= m_pageHeight * m_currentPage ) + continue; // object not on current page + + switch( o.attribute( "type" ).toInt() ) + { + case 0: // image + appendPicture( doccontent, o, drawPage ); + break; + case 1: // line + appendLine( doccontent, o, drawPage ); + break; + case 2: // rectangle + appendRectangle( doccontent, o, drawPage ); + break; + case 3: // circle, ellipse + appendEllipse( doccontent, o, drawPage ); + break; + case 4: // textbox + appendTextbox( doccontent, o, drawPage ); + break; + case 5: + kdDebug(30518)<<" autoform not implemented\n"; + break; + case 6: + kdDebug(30518)<<" clipart not implemented\n"; + break; + case 8: // pie, chord, arc + appendEllipse( doccontent, o, drawPage, true ); + break; + case 9: //part + kdDebug(30518)<<" part object not implemented \n"; + break; + case 10: + appendGroupObject( doccontent, o, drawPage ); + break; + case 11: + kdDebug(30518)<<" free hand not implemented\n"; + break; + case 12: // polyline + appendPolyline( doccontent, o, drawPage ); + break; + case 13: //OT_QUADRICBEZIERCURVE = 13 + case 14: //OT_CUBICBEZIERCURVE = 14 + //todo + // "draw:path" + break; + case 15: // polygon + case 16: // close polygone + appendPolyline( doccontent, o, drawPage, true /*polygon*/ ); + break; + } + ++m_objectIndex; + } + +} + +void OoImpressExport::appendGroupObject( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement groupElement = doc.createElement( "draw:g" ); + QDomNode objects = source.namedItem( "OBJECTS" ); + appendObjects( doc, objects, groupElement); + target.appendChild( groupElement ); +} + +void OoImpressExport::appendNote( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QString noteText = source.attribute("note"); + //kdDebug(30518)<<"noteText :"<<noteText<<endl; + if ( noteText.isEmpty() ) + return; + QDomElement noteElement = doc.createElement( "presentation:notes" ); + QDomElement noteTextBox = doc.createElement( "draw:text-box" ); + + //TODO : add draw:text-box size : + //<draw:text-box draw:style-name="gr2" draw:text-style-name="P2" draw:layer="layout" svg:width="13.336cm" svg:height="56.288cm" svg:x="-0.54cm" svg:y="-14.846cm"> + + QStringList text = QStringList::split( "\n", noteText ); + for ( QStringList::Iterator it = text.begin(); it != text.end(); ++it ) { + QDomElement tmp = doc.createElement( "text:p" ); + tmp.appendChild( doc.createTextNode( *it ) ); + noteTextBox.appendChild( tmp ); + } + noteElement.appendChild( noteTextBox ); + target.appendChild( noteElement ); +} + +void OoImpressExport::appendTextbox( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement textbox = doc.createElement( "draw:text-box" ); + + QDomNode textobject = source.namedItem( "TEXTOBJ" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + textbox.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, textbox ); + + // parse every paragraph + for ( QDomNode paragraph = textobject.firstChild(); !paragraph.isNull(); + paragraph = paragraph.nextSibling() ) + { + QDomElement p = paragraph.toElement(); + appendParagraph( doc, p, textbox ); + } + + target.appendChild( textbox ); +} + +void OoImpressExport::appendParagraph( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement paragraph = doc.createElement( "text:p" ); + + // create the paragraph style + QString ps = m_styleFactory.createParagraphStyle( source ); + paragraph.setAttribute( "text:style-name", ps ); + + // parse every text element + for ( QDomNode text = source.firstChild(); !text.isNull(); + text = text.nextSibling() ) + { + if ( text.nodeName() == "TEXT" ) + { + QDomElement t = text.toElement(); + appendText( doc, t, paragraph ); + } + } + + // take care of lists + QDomNode counter = source.namedItem( "COUNTER" ); + if ( !counter.isNull() ) + { + QDomElement c = counter.toElement(); + int type = c.attribute( "type" ).toInt(); + + int level = 1; + if ( c.hasAttribute( "depth" ) ) + level = c.attribute( "depth" ).toInt() + 1; + + QDomElement endOfList = target; + for ( int l = 0; l < level; l++ ) + { + QDomElement list; + if ( type == 1 ) + { + list = doc.createElement( "text:ordered-list" ); + list.setAttribute( "text:continue-numbering", "true" ); + } + else + list = doc.createElement( "text:unordered-list" ); + + if ( l == 0 ) + { + // create the list style + QString ls = m_styleFactory.createListStyle( c ); + list.setAttribute( "text:style-name", ls ); + } + + QDomElement item = doc.createElement( "text:list-item" ); + list.appendChild( item ); + endOfList.appendChild( list ); + endOfList = item; + } + + endOfList.appendChild( paragraph ); + } + else + target.appendChild( paragraph ); +} + +void OoImpressExport::appendText( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement textspan = doc.createElement( "text:span" ); + + // create the text style + QString ts = m_styleFactory.createTextStyle( source ); + textspan.setAttribute( "text:style-name", ts ); + + textspan.appendChild( doc.createTextNode( source.text() ) ); + target.appendChild( textspan ); +} + +void OoImpressExport::appendPicture( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement image = doc.createElement( "draw:image" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + image.setAttribute( "draw:style-name", gs ); + QDomElement key = source.namedItem( "KEY" ).toElement(); + + QString pictureName = QString( "Picture/Picture%1" ).arg( m_pictureIndex ); + + image.setAttribute( "xlink:type", "simple" ); + image.setAttribute( "xlink:show", "embed" ); + image.setAttribute( "xlink:actuate", "onLoad"); + + if ( !key.isNull() ) + { + QString str = pictureKey( key ); + QString returnstr = m_kpresenterPictureLst[str]; + const int pos=returnstr.findRev('.'); + if (pos!=-1) + { + const QString extension( returnstr.mid(pos+1) ); + pictureName +="."+extension; + } + + if ( m_storeinp->open( returnstr ) ) + { + if ( m_storeout->open( pictureName ) ) + { + QByteArray data(8*1024); + uint total = 0; + for ( int block = 0; ( block = m_storeinp->read(data.data(), data.size()) ) > 0; + total += block ) + m_storeout->write(data.data(), data.size()); + m_storeout->close(); + m_storeinp->close(); + } + } + } + image.setAttribute( "xlink:href", "#" + pictureName ); + +// set the geometry + set2DGeometry( source, image ); + target.appendChild( image ); + + m_pictureLst.insert( pictureName , "image/png" ); + + ++m_pictureIndex; +} + + +void OoImpressExport::appendLine( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement line = doc.createElement( "draw:line" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + line.setAttribute( "draw:style-name", gs ); + + // set the geometry + setLineGeometry( source, line ); + + target.appendChild( line ); +} + +void OoImpressExport::appendRectangle( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement rectangle = doc.createElement( "draw:rect" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + rectangle.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, rectangle ); + + target.appendChild( rectangle ); +} + +void OoImpressExport::appendPolyline( QDomDocument & doc, QDomElement & source, QDomElement & target, bool _poly) +{ + QDomElement polyline = doc.createElement( _poly ? "draw:polygon" : "draw:polyline" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + polyline.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, polyline, false, true /*multipoint*/ ); + + target.appendChild( polyline ); +} + +void OoImpressExport::appendEllipse( QDomDocument & doc, QDomElement & source, QDomElement & target, bool pieObject ) +{ + QDomElement size = source.namedItem( "SIZE" ).toElement(); + + double width = size.attribute( "width" ).toDouble(); + double height = size.attribute( "height" ).toDouble(); + + QDomElement ellipse = doc.createElement( (width == height) ? "draw:circle" : "draw:ellipse" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + ellipse.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, ellipse, pieObject ); + + target.appendChild( ellipse ); +} + +void OoImpressExport::set2DGeometry( QDomElement & source, QDomElement & target, bool pieObject, bool multiPoint ) +{ + QDomElement orig = source.namedItem( "ORIG" ).toElement(); + QDomElement size = source.namedItem( "SIZE" ).toElement(); + QDomElement name = source.namedItem( "OBJECTNAME").toElement(); + float y = orig.attribute( "y" ).toFloat(); + y -= m_pageHeight * ( m_currentPage - 1 ); + + QDomElement angle = source.namedItem( "ANGLE").toElement(); + if ( !angle.isNull() ) + { + QString returnAngle = rotateValue( angle.attribute( "value" ).toDouble() ); + if ( !returnAngle.isEmpty() ) + target.setAttribute("draw:transform",returnAngle ); + } + + target.setAttribute( "draw:id", QString::number( m_objectIndex ) ); + target.setAttribute( "svg:x", StyleFactory::toCM( orig.attribute( "x" ) ) ); + target.setAttribute( "svg:y", QString( "%1cm" ).arg( KoUnit::toCM( y ) ) ); + target.setAttribute( "svg:width", StyleFactory::toCM( size.attribute( "width" ) ) ); + target.setAttribute( "svg:height", StyleFactory::toCM( size.attribute( "height" ) ) ); + QString nameStr = name.attribute("objectName"); + if( !nameStr.isEmpty() ) + target.setAttribute( "draw:name", nameStr ); + if ( pieObject ) + { + QDomElement pie = source.namedItem( "PIETYPE").toElement(); + if( !pie.isNull() ) + { + int typePie = pie.attribute("value").toInt(); + switch( typePie ) + { + case 0: + target.setAttribute( "draw:kind", "section"); + break; + case 1: + target.setAttribute( "draw:kind", "arc"); + break; + case 2: + target.setAttribute( "draw:kind", "cut"); + break; + default: + kdDebug(30518)<<" type unknown : "<<typePie<<endl; + break; + } + } + else + target.setAttribute( "draw:kind", "section");//by default + QDomElement pieAngle = source.namedItem( "PIEANGLE").toElement(); + int startangle = 45; + if( !pieAngle.isNull() ) + { + startangle = (pieAngle.attribute("value").toInt())/16; + target.setAttribute( "draw:start-angle", startangle); + } + else + { + //default value take it into kppieobject + target.setAttribute( "draw:start-angle", 45 ); + } + QDomElement pieLength = source.namedItem( "PIELENGTH").toElement(); + if( !pieLength.isNull() ) + { + int value = pieLength.attribute("value").toInt(); + value = value /16; + value = value + startangle; + target.setAttribute( "draw:end-angle", value ); + } + else + { + //default value take it into kppieobject + //default is 90 into kpresenter + target.setAttribute( "draw:end-angle", (90+startangle) ); + } + } + if ( multiPoint ) + { + //loadPoint + QDomElement point = source.namedItem( "POINTS" ).toElement(); + if ( !point.isNull() ) { + QDomElement elemPoint = point.firstChild().toElement(); + QString listOfPoint; + int maxX=0; + int maxY=0; + while ( !elemPoint.isNull() ) { + if ( elemPoint.tagName() == "Point" ) { + int tmpX = 0; + int tmpY = 0; + if( elemPoint.hasAttribute( "point_x" ) ) + tmpX = ( int ) ( KoUnit::toMM( elemPoint.attribute( "point_x" ).toDouble() )*100 ); + if( elemPoint.hasAttribute( "point_y" ) ) + tmpY = ( int ) ( KoUnit::toMM(elemPoint.attribute( "point_y" ).toDouble() )*100 ); + if ( !listOfPoint.isEmpty() ) + listOfPoint += QString( " %1,%2" ).arg( tmpX ).arg( tmpY ); + else + listOfPoint = QString( "%1,%2" ).arg( tmpX ).arg( tmpY ); + maxX = QMAX( maxX, tmpX ); + maxY = QMAX( maxY, tmpY ); + } + elemPoint = elemPoint.nextSibling().toElement(); + } + target.setAttribute( "draw:points", listOfPoint ); + target.setAttribute( "svg:viewBox", QString( "0 0 %1 %2" ).arg( maxX ).arg( maxY ) ); + } + } +} + +QString OoImpressExport::rotateValue( double val ) +{ + QString str; + if ( val!=0.0 ) + { + double value = -1 * ( ( double )val* M_PI )/180.0; + str=QString( "rotate (%1)" ).arg( value ); + } + return str; +} + + +void OoImpressExport::setLineGeometry( QDomElement & source, QDomElement & target ) +{ + QDomElement orig = source.namedItem( "ORIG" ).toElement(); + QDomElement size = source.namedItem( "SIZE" ).toElement(); + QDomElement linetype = source.namedItem( "LINETYPE" ).toElement(); + QDomElement name = source.namedItem( "OBJECTNAME").toElement(); + QDomElement angle = source.namedItem( "ANGLE").toElement(); + if ( !angle.isNull() ) + { + QString returnAngle = rotateValue( angle.attribute( "value" ).toDouble() ); + if ( !returnAngle.isEmpty() ) + target.setAttribute("draw:transform",returnAngle ); + } + float x1 = orig.attribute( "x" ).toFloat(); + float y1 = orig.attribute( "y" ).toFloat(); + float x2 = size.attribute( "width" ).toFloat(); + float y2 = size.attribute( "height" ).toFloat(); + int type = 0; + if ( !linetype.isNull() ) + type = linetype.attribute( "value" ).toInt(); + y1 -= m_pageHeight * ( m_currentPage - 1 ); + x2 += x1; + y2 += y1; + + target.setAttribute( "draw:id", QString::number( m_objectIndex ) ); + QString xpos1 = StyleFactory::toCM( orig.attribute( "x" ) ); + QString xpos2 = QString( "%1cm" ).arg( KoUnit::toCM( x2 ) ); + + if ( type == 0 ) + { + target.setAttribute( "svg:y1", QString( "%1cm" ).arg( KoUnit::toCM( y2/2.0 ) ) ); + target.setAttribute( "svg:y2", QString( "%1cm" ).arg( KoUnit::toCM( y2/2.0 ) ) ); + } + else if ( type == 1 ) + { + target.setAttribute( "svg:y1", QString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) ); + target.setAttribute( "svg:y2", QString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) ); + xpos1 = QString( "%1cm" ).arg( KoUnit::toCM( x1/2.0 ) ); + xpos2 = xpos1; + } + else if ( type == 3 ) // from left bottom to right top + { + target.setAttribute( "svg:y1", QString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) ); + target.setAttribute( "svg:y2", QString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) ); + } + else // from left top to right bottom + { + target.setAttribute( "svg:y1", QString( "%1cm" ).arg( KoUnit::toCM( y1 ) ) ); + target.setAttribute( "svg:y2", QString( "%1cm" ).arg( KoUnit::toCM( y2 ) ) ); + } + target.setAttribute( "svg:x1", xpos1 ); + target.setAttribute( "svg:x2", xpos2 ); + + QString nameStr = name.attribute("objectName"); + if( !nameStr.isEmpty() ) + target.setAttribute( "draw:name", nameStr ); +} + +#include "ooimpressexport.moc" diff --git a/filters/kpresenter/ooimpress/ooimpressexport.h b/filters/kpresenter/ooimpress/ooimpressexport.h new file mode 100644 index 00000000..9ab3d153 --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressexport.h @@ -0,0 +1,92 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef OOIMPRESSEXPORT_H +#define OOIMPRESSEXPORT_H + +#include "stylefactory.h" + +#include <qdom.h> + +#include <KoFilter.h> + +class QDomElement; +class KoStore; + +class OoImpressExport : public KoFilter +{ + Q_OBJECT +public: + OoImpressExport( KoFilter * parent, const char * name, const QStringList & ); + virtual ~OoImpressExport(); + + virtual KoFilter::ConversionStatus convert( const QCString & from, + const QCString & to ); + +private: + KoFilter::ConversionStatus openFile(); + + void exportBody( QDomDocument & doccontent, QDomElement & body ); + void createDocumentMeta( QDomDocument & docmeta ); + void createDocumentStyles( QDomDocument & docstyles ); + void createDocumentContent( QDomDocument & doccontent ); + void createDocumentManifest( QDomDocument & docmanifest ); + void createDocumentSettings( QDomDocument & docsetting ); + void appendTextbox( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendParagraph( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendText( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendLine( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendRectangle( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendEllipse( QDomDocument & doc, QDomElement & source, QDomElement & target, bool pieObject = false ); + void set2DGeometry( QDomElement & source, QDomElement & target, bool pieObject = false, bool multiPoint = false ); + void setLineGeometry( QDomElement & source, QDomElement & target ); + void appendPolyline( QDomDocument & doc, QDomElement & source, QDomElement & target, bool polygone = false); + void appendPicture( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void createPictureList( QDomNode &pictures ); + void appendNote( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendGroupObject( QDomDocument & doc, QDomElement & source, QDomElement & target ); + QString rotateValue( double val ); + QString pictureKey( QDomElement &element ); + void createHelpLine( QDomNode &helpline ); + void createAttribute( QDomNode &attributeValue ); + void appendObjects(QDomDocument & doccontent, QDomNode &objects, QDomElement &drawPage); + + int m_currentPage; + int m_objectIndex; + float m_pageHeight; + StyleFactory m_styleFactory; + QString m_masterPageStyle; + QDomElement m_styles; + QDomDocument m_maindoc; + QDomDocument m_documentinfo; + QMap<QString, QString> m_pictureLst; + + QString m_helpLine; + int m_activePage; + double m_gridX, m_gridY; + bool m_snapToGrid; + + //load from kpresenter file format + QMap<QString, QString> m_kpresenterPictureLst; + int m_pictureIndex; + KoStore *m_storeinp; + KoStore *m_storeout; +}; + +#endif diff --git a/filters/kpresenter/ooimpress/ooimpressimport.cc b/filters/kpresenter/ooimpress/ooimpressimport.cc new file mode 100644 index 00000000..be6c094d --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressimport.cc @@ -0,0 +1,2433 @@ +// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* This file is part of the KDE project + Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + Copyright (c) 2003 Lukas Tinkl <lukas@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "ooimpressimport.h" + +#include <math.h> + +#include <qregexp.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#include <qdir.h> + +#include <kzip.h> +#include <karchive.h> +#include <kdebug.h> +#include <KoUnit.h> +#include <KoDocumentInfo.h> +#include <KoDocument.h> + +#include <kgenericfactory.h> +#include <KoFilterChain.h> +#include <KoGlobal.h> +#include <ooutils.h> +#include <KoDom.h> +#include <KoOasisSettings.h> + +typedef KGenericFactory<OoImpressImport, KoFilter> OoImpressImportFactory; +K_EXPORT_COMPONENT_FACTORY( libooimpressimport, OoImpressImportFactory( "kofficefilters" ) ) + + +OoImpressImport::OoImpressImport( KoFilter *, const char *, const QStringList & ) + : KoFilter(), + m_numPicture( 1 ), + m_numSound(1), + m_styles( 23, true ), + m_styleStack( ooNS::style, ooNS::fo ) +{ + m_styles.setAutoDelete( true ); + m_listStyles.setAutoDelete( true ); +} + +OoImpressImport::~OoImpressImport() +{ + QDictIterator<animationList> it( m_animations ); // See QDictIterator + for( ; it.current(); ++it ) + { + delete it.current()->element; + } + m_animations.clear(); +} + +KoFilter::ConversionStatus OoImpressImport::convert( QCString const & from, QCString const & to ) +{ + kdDebug(30518) << "Entering Ooimpress Import filter: " << from << " - " << to << endl; + + if ( (from != "application/vnd.sun.xml.impress" && from != "application/vnd.sun.xml.impress.template" ) + || to != "application/x-kpresenter" ) + { + kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl; + return KoFilter::NotImplemented; + } + + m_zip = new KZip( m_chain->inputFile() ); + + if ( !m_zip->open( IO_ReadOnly ) ) + { + kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl; + delete m_zip; + return KoFilter::FileNotFound; + } + + KoFilter::ConversionStatus preStatus = openFile(); + + if ( preStatus != KoFilter::OK ) + { + m_zip->close(); + delete m_zip; + return preStatus; + } + + QDomDocument docinfo; + createDocumentInfo( docinfo ); + + // store document info + KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); + if( out ) + { + QCString info = docinfo.toCString(); + //kdDebug(30518) << " info :" << info << endl; + // WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. + out->writeBlock( info , info.length() ); + } + + QDomDocument doccontent; + createDocumentContent( doccontent ); + + // store document content + out = m_chain->storageFile( "maindoc.xml", KoStore::Write ); + if( out ) + { + QCString content = doccontent.toCString(); + kdDebug(30518) << " content :" << content << endl; + out->writeBlock( content , content.length() ); + } + + m_zip->close(); + delete m_zip; + + kdDebug(30518) << "######################## OoImpressImport::convert done ####################" << endl; + return KoFilter::OK; +} + +// Very related to OoWriterImport::openFile() +KoFilter::ConversionStatus OoImpressImport::openFile() +{ + KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content ); + if ( status != KoFilter::OK ) + { + kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl; + return status; + } + + // We do not stop if the following calls fail. + QDomDocument styles; + loadAndParse( "styles.xml", styles ); + loadAndParse( "meta.xml", m_meta ); + loadAndParse( "settings.xml", m_settings ); + + emit sigProgress( 10 ); + createStyleMap( styles ); + + return KoFilter::OK; +} + +KoFilter::ConversionStatus OoImpressImport::loadAndParse(const QString& filename, QDomDocument& doc) +{ + return OoUtils::loadAndParse( filename, doc, m_zip); +} + +// Very related to OoWriterImport::createDocumentInfo +void OoImpressImport::createDocumentInfo( QDomDocument &docinfo ) +{ + docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" ); + + OoUtils::createDocumentInfo(m_meta, docinfo); + //kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl; +} + +void OoImpressImport::createDocumentContent( QDomDocument &doccontent ) +{ + QDomDocument doc = KoDocument::createDomDocument( "kpresenter", "DOC", "1.2" ); + QDomElement docElement = doc.documentElement(); + docElement.setAttribute( "editor", "KPresenter" ); + docElement.setAttribute( "mime", "application/x-kpresenter" ); + docElement.setAttribute( "syntaxVersion", "2" ); + + QDomElement content = m_content.documentElement(); + + // content.xml contains some automatic-styles that we need to store + QDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); + if ( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); + if ( body.isNull() ) + return; + + QDomElement customSlideShow = doc.createElement( "CUSTOMSLIDESHOWCONFIG" ); + + // presentation settings + QDomElement settings = KoDom::namedItemNS( body, ooNS::presentation, "settings"); + if (!settings.isNull()) + { + if (settings.attributeNS( ooNS::presentation, "endless", QString::null)=="true") + { + QDomElement infElem = doc.createElement("INFINITLOOP"); + infElem.setAttribute("value", 1); + docElement.appendChild(infElem); + } + + if (settings.attributeNS( ooNS::presentation, "show-end-of-presentation-slide", QString::null)=="true") + { + QDomElement infElem = doc.createElement("SHOWENDOFPRESENTATIONSLIDE"); + infElem.setAttribute("value", 1); + docElement.appendChild(infElem); + } + + if (settings.attributeNS( ooNS::presentation, "force-manual", QString::null)=="true") + { + QDomElement manualElem = doc.createElement("MANUALSWITCH"); + manualElem.setAttribute("value", 1); + docElement.appendChild(manualElem); + } + if ( settings.hasAttributeNS( ooNS::presentation, "show") ) + { + QDomElement defaultPage = doc.createElement("DEFAULTCUSTOMSLIDESHOWNAME"); + defaultPage.setAttribute("name", settings.attributeNS( ooNS::presentation, "show", QString::null) ); + docElement.appendChild(defaultPage); + } + } + + QDomElement presentationShow; + forEachElement( presentationShow, settings ) + { + if ( presentationShow.localName()=="show" && presentationShow.namespaceURI() == ooNS::presentation ) + { + if ( presentationShow.hasAttributeNS( ooNS::presentation, "pages") && + presentationShow.hasAttributeNS( ooNS::presentation, "name")) + { + QDomElement slide=doc.createElement("CUSTOMSLIDESHOW"); + slide.setAttribute( "pages", presentationShow.attributeNS( ooNS::presentation, "pages", QString::null )); + slide.setAttribute( "name", presentationShow.attributeNS( ooNS::presentation, "name", QString::null )); + customSlideShow.appendChild( slide ); + } + } + } + // it seems that ooimpress has different paper-settings for every slide. + // we take the settings of the first slide for the whole document. + QDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); + if ( drawPage.isNull() ) // no slides? give up. + return; + + QDomElement objectElement = doc.createElement( "OBJECTS" ); + QDomElement pictureElement = doc.createElement( "PICTURES" ); + QDomElement pageTitleElement = doc.createElement( "PAGETITLES" ); + QDomElement pageNoteElement = doc.createElement( "PAGENOTES" ); + QDomElement backgroundElement = doc.createElement( "BACKGROUND" ); + QDomElement soundElement = doc.createElement( "SOUNDS" ); + QDomElement selSlideElement = doc.createElement( "SELSLIDES" ); + QDomElement helpLineElement = doc.createElement( "HELPLINES" ); + QDomElement attributeElement = doc.createElement( "ATTRIBUTES" ); + QDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", QString::null )]; + + appendObject(*master, doc, soundElement,pictureElement,pageNoteElement,objectElement, 0, true); + + QDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", QString::null )]; + QDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" ); + //kdDebug(30518)<<" master->attribute( draw:style-name ) :"<<master->attributeNS( ooNS::draw, "style-name", QString::null )<<endl; + QDomElement *backgroundStyle = m_stylesPresentation[ master->attributeNS( ooNS::draw, "style-name", QString::null ).isEmpty() ? "Standard-background" : master->attributeNS( ooNS::draw, "style-name", QString::null ) ]; + + //kdDebug(30518)<<" backgroundStyle :"<<backgroundStyle<<endl; + double pageHeight; + QDomElement paperElement = doc.createElement( "PAPER" ); + if ( properties.isNull() ) + { + paperElement.setAttribute( "ptWidth", CM_TO_POINT(28) ); + paperElement.setAttribute( "ptHeight", CM_TO_POINT(21) ); + paperElement.setAttribute( "unit", 0 ); + paperElement.setAttribute( "format", 5 ); + paperElement.setAttribute( "tabStopValue", 42.5198 ); + paperElement.setAttribute( "orientation", 0 ); + pageHeight = 21; + + QDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" ); + paperBorderElement.setAttribute( "ptRight", 0 ); + paperBorderElement.setAttribute( "ptBottom", 0 ); + paperBorderElement.setAttribute( "ptLeft", 0 ); + paperBorderElement.setAttribute( "ptTop", 0 ); + paperElement.appendChild( paperBorderElement ); + } + else + { + paperElement.setAttribute( "ptWidth", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", QString::null ) ) ); + paperElement.setAttribute( "ptHeight", KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", QString::null ) ) ); +// paperElement.setAttribute( "unit", 0 ); +// paperElement.setAttribute( "format", 5 ); +// paperElement.setAttribute( "tabStopValue", 42.5198 ); +// paperElement.setAttribute( "orientation", 0 ); + // Keep pageHeight in cm to avoid rounding-errors that would + // get multiplied with every new slide. + + if (properties.attributeNS( ooNS::style, "print-orientation", QString::null)=="portrait") + paperElement.setAttribute("orientation", 0); + else if (properties.attributeNS( ooNS::style, "print-orientation", QString::null)=="landscape") + paperElement.setAttribute("orientation", 1); + + + + pageHeight = properties.attributeNS( ooNS::fo, "page-height", QString::null ).remove( "cm" ).toDouble(); + + QDomElement paperBorderElement = doc.createElement( "PAPERBORDERS" ); + paperBorderElement.setAttribute( "ptRight", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-right", QString::null ) ) ); + paperBorderElement.setAttribute( "ptBottom", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-bottom", QString::null ) ) ); + paperBorderElement.setAttribute( "ptLeft", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-left", QString::null ) ) ); + paperBorderElement.setAttribute( "ptTop", KoUnit::parseValue( properties.attributeNS( ooNS::fo, "margin-top", QString::null ) ) ); + paperElement.appendChild( paperBorderElement ); + } + + + // parse all pages + forEachElement( drawPage, body ) + { + if ( drawPage.localName()=="page" && drawPage.namespaceURI() == ooNS::draw && drawPage.hasAttributeNS( ooNS::draw, "id" )) + { + m_styleStack.clear(); // remove all styles + fillStyleStack( drawPage ); + m_styleStack.save(); + int pagePos = drawPage.attributeNS( ooNS::draw, "id", QString::null ).toInt() - 1; + // take care of a possible page background or slide transition or sound + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) + || m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style" )) + { + appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement ); + } + else if ( !m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) && backgroundStyle) + { + m_styleStack.save(); + m_styleStack.push( *backgroundStyle ); + appendBackgroundPage( doc, backgroundElement,pictureElement, soundElement ); + m_styleStack.restore(); + kdDebug(30518)<<" load standard bacground \n"; + } + if ( m_styleStack.hasAttributeNS( ooNS::presentation, "visibility" ) ) + { + QString str = m_styleStack.attributeNS( ooNS::presentation, "visibility" ); + QDomElement slide = doc.createElement("SLIDE"); + slide.setAttribute( "nr", pagePos ); + slide.setAttribute( "show", ( ( str=="hidden" ) ? "0" : "1" )); + selSlideElement.appendChild( slide ); + + //todo add support + kdDebug(30518)<<"m_styleStack.hasAttribute( presentation:visibility ) :"<<str<<" position page "<<pagePos<<endl; + } + // set the pagetitle + QDomElement titleElement = doc.createElement( "Title" ); + titleElement.setAttribute( "title", drawPage.attributeNS( ooNS::draw, "name", QString::null ) ); + pageTitleElement.appendChild( titleElement ); + + // The '+1' is necessary to avoid that objects that start on the first line + // of a slide will show up on the last line of the previous slide. + double offset = CM_TO_POINT( ( drawPage.attributeNS( ooNS::draw, "id", QString::null ).toInt() - 1 ) * pageHeight ) + 1; + + // animations (object effects) + createPresentationAnimation(KoDom::namedItemNS( drawPage, ooNS::presentation, "animations") ); + + // parse all objects + appendObject(drawPage, doc, soundElement,pictureElement,pageNoteElement,objectElement, offset); + + //m_animations.clear(); + m_styleStack.restore(); + } + } + + docElement.appendChild( paperElement ); + docElement.appendChild( backgroundElement ); + if ( parseSettings( doc, helpLineElement, attributeElement ) ) + docElement.appendChild( helpLineElement ); + docElement.appendChild( attributeElement ); + docElement.appendChild( pageTitleElement ); + docElement.appendChild( pageNoteElement ); + docElement.appendChild( objectElement ); + docElement.appendChild( selSlideElement ); + docElement.appendChild( customSlideShow ); + docElement.appendChild( soundElement ); + docElement.appendChild( pictureElement ); + + doccontent.appendChild( doc ); +} + +bool OoImpressImport::parseSettings( QDomDocument &doc, QDomElement &helpLineElement, QDomElement &attributeElement ) +{ + bool foundElement = false; + KoOasisSettings settings( m_settings, ooNS::office, ooNS::config ); + KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" ); + //setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit"))); + KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" ); + KoOasisSettings::Items firstView = viewMap.entry( 0 ); + //<config:config-item config:name="SnapLinesDrawing" config:type="string">V7939H1139</config:config-item> + //by default show line + + if ( !firstView.isNull() ) + { + QString str = firstView.parseConfigItemString( "SnapLinesDrawing" ); + if ( !str.isEmpty() ) + { + parseHelpLine( doc, helpLineElement, str ); + //display it by default + helpLineElement.setAttribute( "show", true ); + foundElement = true; + } + + int gridX = firstView.parseConfigItemInt( "GridFineWidth" ); + int gridY = firstView.parseConfigItemInt( "GridFineHeight" ); + bool snapToGrid = firstView.parseConfigItemBool( "IsSnapToGrid" ); + int selectedPage = firstView.parseConfigItemInt( "SelectedPage" ); + + attributeElement.setAttribute( "activePage", selectedPage ); + attributeElement.setAttribute( "gridx", MM_TO_POINT( gridX / 100.0 ) ); + attributeElement.setAttribute( "gridy", MM_TO_POINT( gridY / 100.0 ) ); + attributeElement.setAttribute( "snaptogrid", (int)snapToGrid ); + + } + + //kdDebug(30518)<<" gridX :"<<gridX<<" gridY :"<<gridY<<" snapToGrid :"<<snapToGrid<<" selectedPage :"<<selectedPage<<endl; + return foundElement; +} + +void OoImpressImport::parseHelpLine( QDomDocument &doc,QDomElement &helpLineElement, const QString &text ) +{ + QString str; + int newPos = text.length()-1; //start to element = 1 + for ( int pos = text.length()-1; pos >=0;--pos ) + { + if ( text[pos]=='P' ) + { + + //point + str = text.mid( pos+1, ( newPos-pos ) ); + QDomElement point=doc.createElement("HelpPoint"); + + //kdDebug(30518)<<" point element :"<< str <<endl; + QStringList listVal = QStringList::split( ",", str ); + int posX = ( listVal[0].toInt()/100 ); + int posY = ( listVal[1].toInt()/100 ); + point.setAttribute("posX", MM_TO_POINT( posX )); + point.setAttribute("posY", MM_TO_POINT( posY )); + + helpLineElement.appendChild( point ); + newPos = pos-1; + } + else if ( text[pos]=='V' ) + { + QDomElement lines=doc.createElement("Vertical"); + //vertical element + str = text.mid( pos+1, ( newPos-pos ) ); + //kdDebug(30518)<<" vertical :"<< str <<endl; + int posX = ( str.toInt()/100 ); + lines.setAttribute( "value", MM_TO_POINT( posX ) ); + helpLineElement.appendChild( lines ); + + newPos = ( pos-1 ); + + } + else if ( text[pos]=='H' ) + { + //horizontal element + QDomElement lines=doc.createElement("Horizontal"); + str = text.mid( pos+1, ( newPos-pos ) ); + //kdDebug(30518)<<" horizontal :"<< str <<endl; + int posY = ( str.toInt()/100 ); + lines.setAttribute( "value", MM_TO_POINT( posY ) ); + helpLineElement.appendChild( lines ); + newPos = pos-1; + } + } +} + +void OoImpressImport::appendObject(QDomNode & drawPage, QDomDocument & doc, QDomElement & soundElement, QDomElement & pictureElement, QDomElement & pageNoteElement, QDomElement &objectElement, double offset, bool sticky) +{ + QDomElement o; + forEachElement( o, drawPage ) + { + const QString localName = o.localName(); + const QString ns = o.namespaceURI(); + const QString drawID = o.attributeNS( ooNS::draw, "id", QString::null); + m_styleStack.save(); + + QDomElement e; + if ( localName == "text-box" && ns == ooNS::draw ) // textbox + { + fillStyleStack( o, sticky ); + e = doc.createElement( "OBJECT" ); + e.setAttribute( "type", 4 ); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry( doc, e, o, (int)offset ); + appendName(doc, e, o); + appendPen( doc, e ); + appendBrush( doc, e ); + appendRounding( doc, e, o ); + appendShadow( doc, e ); + appendObjectEffect(doc, e, o, soundElement); + e.appendChild( parseTextBox( doc, o ) ); + } + else if ( localName == "rect" && ns == ooNS::draw ) // rectangle + { + fillStyleStack( o, sticky ); + e = doc.createElement( "OBJECT" ); + e.setAttribute( "type", 2 ); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry( doc, e, o, (int)offset ); + appendName(doc, e, o); + appendPen( doc, e ); + appendBrush( doc, e ); + appendRounding( doc, e, o ); + appendShadow( doc, e ); + + appendObjectEffect(doc, e, o, soundElement); + } + else if ( ( localName == "circle" || localName == "ellipse" ) && ns == ooNS::draw ) + { + fillStyleStack( o, sticky ); + e = doc.createElement( "OBJECT" ); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry( doc, e, o, (int)offset ); + appendName(doc, e, o); + appendPen( doc, e ); + appendShadow( doc, e ); + appendLineEnds( doc, e ); + appendObjectEffect(doc, e, o, soundElement); + + if ( o.hasAttributeNS( ooNS::draw, "kind" ) ) // pie, chord or arc + { + e.setAttribute( "type", 8 ); + appendPie( doc, e, o ); + QDomElement type = doc.createElement( "PIETYPE" ); + + QString kind = o.attributeNS( ooNS::draw, "kind", QString::null ); + if ( kind == "section" ) + { + appendBrush( doc, e ); + type.setAttribute( "value", 0 ); + } + else if ( kind == "cut" ) + { + appendBrush( doc, e ); + type.setAttribute( "value", 2 ); + } + else if ( kind == "arc" ) + { + // arc has no brush + type.setAttribute( "value", 1 ); + } + e.appendChild( type ); + } + else // circle or ellipse + { + e.setAttribute( "type", 3 ); + appendBrush( doc, e ); + } + } + else if ( localName == "line" && ns == ooNS::draw ) // line + { + fillStyleStack( o, sticky ); + e = doc.createElement( "OBJECT" ); + e.setAttribute( "type", 1 ); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + bool orderEndStartLine = appendLineGeometry( doc, e, o, (int)offset ); + appendName(doc, e, o); + appendPen( doc, e ); + appendBrush( doc, e ); + appendShadow( doc, e ); + appendLineEnds( doc, e, orderEndStartLine ); + appendObjectEffect(doc, e, o, soundElement); + } + else if ( localName=="polyline" && ns == ooNS::draw ) { // polyline + fillStyleStack(o, sticky); + e = doc.createElement("OBJECT"); + e.setAttribute("type", 12); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry(doc, e, o, (int)offset); + appendName(doc, e, o); + appendPoints(doc, e, o); + appendPen(doc, e); + appendBrush(doc, e); + appendLineEnds(doc, e); + //appendShadow(doc, e); + appendObjectEffect(doc, e, o, soundElement); + } + else if ( localName=="polygon" && ns == ooNS::draw ) { // polygon + fillStyleStack(o, sticky); + e = doc.createElement("OBJECT"); + e.setAttribute("type", 16); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry(doc, e, o, (int)offset); + appendName(doc, e, o); + appendPoints(doc, e, o); + appendPen(doc, e); + appendBrush(doc, e); + //appendLineEnds(doc, e); + //appendShadow(doc, e); + appendObjectEffect(doc, e, o, soundElement); + } + else if ( localName == "image" && ns == ooNS::draw ) // image + { + fillStyleStack( o, sticky ); + e = doc.createElement( "OBJECT" ); + e.setAttribute( "type", 0 ); + if ( sticky ) + e.setAttribute( "sticky", "1" ); + append2DGeometry( doc, e, o, (int)offset ); + appendName(doc, e, o); + appendImage( doc, e, pictureElement, o ); + appendObjectEffect(doc, e, o, soundElement); + } + else if ( localName == "object" && ns == ooNS::draw ) + { + //todo add part object + } + else if ( localName == "g" && ns == ooNS::draw ) + { + //todo add group object + } + else if ( localName == "path" && ns == ooNS::draw ) + { + //todo add path object (freehand/cubic/quadricbeziercurve + } + else if ( localName == "notes" && ns == ooNS::presentation ) // notes + { + QDomNode textBox = KoDom::namedItemNS( o, ooNS::draw, "text-box" ); + if ( !textBox.isNull() ) + { + QString note; + QDomElement t; + forEachElement( t, textBox ) + { + // We don't care about styles as they are not supported in kpresenter. + // Only add a linebreak for every child. + note += t.text() + "\n"; + } + QDomElement notesElement = doc.createElement( "Note" ); + notesElement.setAttribute( "note", note ); + pageNoteElement.appendChild( notesElement ); + } + } + else + { + kdDebug(30518) << "Unsupported object '" << localName << "'" << endl; + m_styleStack.restore(); + continue; + } + + objectElement.appendChild( e ); + m_styleStack.restore(); + } +} + +void OoImpressImport::appendBackgroundPage( QDomDocument &doc, QDomElement &backgroundElement, QDomElement & pictureElement, QDomElement &soundElement) +{ + QDomElement bgPage = doc.createElement( "PAGE" ); + + // background + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) ) + { + const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" ); + if ( fill == "solid" ) + { + QDomElement backColor1 = doc.createElement( "BACKCOLOR1" ); + backColor1.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) ); + bgPage.appendChild( backColor1 ); + + QDomElement bcType = doc.createElement( "BCTYPE" ); + bcType.setAttribute( "value", 0 ); // plain + bgPage.appendChild( bcType ); + + QDomElement backType = doc.createElement( "BACKTYPE" ); + backType.setAttribute( "value", 0 ); // color/gradient + bgPage.appendChild( backType ); + } + else if ( fill == "gradient" ) + { + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); + QDomElement* draw = m_draws[style]; + appendBackgroundGradient( doc, bgPage, *draw ); + } + else if ( fill == "bitmap" ) + { + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-image-name" ); + QDomElement* draw = m_draws[style]; + appendBackgroundImage( doc, bgPage, pictureElement, *draw ); + + QDomElement backView = doc.createElement( "BACKVIEW" ); + if ( m_styleStack.hasAttributeNS( ooNS::style, "repeat" ) ) + { + QString repeat = m_styleStack.attributeNS( ooNS::style, "repeat" ); + if ( repeat == "stretch" ) + backView.setAttribute( "value", 0 ); // zoomed + else if ( repeat == "no-repeat" ) + backView.setAttribute( "value", 1 ); // centered + else + backView.setAttribute( "value", 2 ); // use tiled as default + } + else + backView.setAttribute( "value", 2 ); // use tiled as default + bgPage.appendChild( backView ); + + QDomElement backType = doc.createElement( "BACKTYPE" ); + backType.setAttribute( "value", 1 ); // image + bgPage.appendChild( backType ); + } + } + + if ( m_styleStack.hasAttributeNS( ooNS::presentation, "duration" ) ) + { + QString str = m_styleStack.attributeNS( ooNS::presentation, "duration"); + kdDebug(30518)<<"styleStack.hasAttribute(presentation:duration ) :"<<str<<endl; + //convert date duration + int hour( str.mid( 2, 2 ).toInt() ); + int minute( str.mid( 5, 2 ).toInt() ); + int second( str.mid( 8, 2 ).toInt() ); + int pageTimer = second + minute*60 + hour*60*60; + QDomElement pgEffect = doc.createElement("PGTIMER"); + pgEffect.setAttribute( "timer", pageTimer ); + bgPage.appendChild(pgEffect); + } + // slide transition + if (m_styleStack.hasAttributeNS( ooNS::presentation, "transition-style")) + { + QDomElement pgEffect = doc.createElement("PGEFFECT"); + + const QString effect = m_styleStack.attributeNS( ooNS::presentation, "transition-style"); + //kdDebug(30518) << "Transition name: " << effect << endl; + int pef; + + if (effect=="vertical-stripes" || effect=="vertical-lines") // PEF_BLINDS_VER + pef=14; + else if (effect=="horizontal-stripes" || effect=="horizontal-lines") // PEF_BLINDS_HOR + pef=13; + else if (effect=="spiralin-left" || effect=="spiralin-right" + || effect== "spiralout-left" || effect=="spiralout-right") // PEF_SURROUND1 + pef=11; + else if (effect=="fade-from-upperleft") // PEF_STRIPS_RIGHT_DOWN + pef=39; + else if (effect=="fade-from-upperright") // PEF_STRIPS_LEFT_DOWN + pef=37; + else if (effect=="fade-from-lowerleft") // PEF_STRIPS_RIGHT_UP + pef=38; + else if (effect=="fade-from-lowerright") // PEF_STRIPS_LEFT_UP + pef=36; + else if (effect=="fade-from-top") // PEF_COVER_DOWN + pef=19; + else if (effect=="fade-from-bottom") // PEF_COVER_UP + pef=21; + else if (effect=="fade-from-left") // PEF_COVER_RIGHT + pef=25; + else if (effect=="fade-from-right") // PEF_COVER_LEFT + pef=23; + else if (effect=="fade-to-center") // PEF_CLOSE_ALL + pef=3; + else if (effect=="fade-from-center") // PEF_OPEN_ALL + pef=6; + else if (effect=="open-vertical") // PEF_OPEN_HORZ; really, no kidding ;) + pef=4; + else if (effect=="open-horizontal") // PEF_OPEN_VERT + pef=5; + else if (effect=="close-vertical") // PEF_CLOSE_HORZ + pef=1; + else if (effect=="close-horizontal") // PEF_CLOSE_VERT + pef=2; + else if (effect=="dissolve") // PEF_DISSOLVE; perfect hit ;) + pef=35; + else if (effect=="horizontal-checkerboard") // PEF_CHECKBOARD_ACROSS + pef=17; + else if (effect=="vertical-checkerboard") // PEF_CHECKBOARD_DOWN + pef=18; + else if (effect=="roll-from-left") // PEF_UNCOVER_RIGHT + pef=26; + else if (effect=="roll-from-right") // PEF_UNCOVER_LEFT + pef=24; + else if (effect=="roll-from-bottom") // PEF_UNCOVER_UP + pef=22; + else if (effect=="roll-from-top") // PEF_UNCOVER_DOWN + pef=20; + else if (effect=="random") // PEF_RANDOM + pef=-1; + else // we choose a random transition instead of the unsupported ones ;) + pef=-1; + + pgEffect.setAttribute("value", pef); + bgPage.appendChild(pgEffect); + } + + // slide transition sound + if (m_styleStack.hasChildNodeNS( ooNS::presentation, "sound")) + { + QString soundUrl = storeSound(m_styleStack.childNodeNS( ooNS::presentation, "sound"), + soundElement, doc); + + if (!soundUrl.isNull()) + { + QDomElement pseElem = doc.createElement("PGSOUNDEFFECT"); + pseElem.setAttribute("soundEffect", 1); + pseElem.setAttribute("soundFileName", soundUrl); + + bgPage.appendChild(pseElem); + } + } + + backgroundElement.appendChild(bgPage); +} + +void OoImpressImport::appendName(QDomDocument& doc, QDomElement& e, const QDomElement& object) +{ + if( object.hasAttributeNS( ooNS::draw, "name" )) + { + QDomElement name = doc.createElement( "OBJECTNAME" ); + name.setAttribute( "objectName", object.attributeNS( ooNS::draw, "name", QString::null )); + e.appendChild( name ); + } +} + +void OoImpressImport::append2DGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ) +{ + QDomElement orig = doc.createElement( "ORIG" ); + orig.setAttribute( "x", KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", QString::null ) ) ); + orig.setAttribute( "y", KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", QString::null ) ) + offset ); + e.appendChild( orig ); + + QDomElement size = doc.createElement( "SIZE" ); + size.setAttribute( "width", KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", QString::null ) ) ); + size.setAttribute( "height", KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", QString::null ) ) ); + e.appendChild( size ); + if( object.hasAttributeNS( ooNS::draw, "transform" )) + { + kdDebug(30518)<<" object transform \n"; + //todo parse it + QString transform = object.attributeNS( ooNS::draw, "transform", QString::null ); + if( transform.contains("rotate (")) + { + //kdDebug(30518)<<" rotate object \n"; + transform = transform.remove("rotate (" ); + transform = transform.left(transform.find(")")); + //kdDebug(30518)<<" transform :"<<transform<<endl; + bool ok; + double radian = transform.toDouble(&ok); + if( ok ) + { + QDomElement angle = doc.createElement( "ANGLE" ); + //angle is defined as a radian in oo but degree into kpresenter. + angle.setAttribute("value", (-1 * ((radian*180)/M_PI))); + + e.appendChild( angle ); + } + } + } +} + +//return true if (x1 < x2) necessary to load correctly start-line and end-line +bool OoImpressImport::appendLineGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ) +{ + double x1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x1", QString::null ) ); + double y1 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y1", QString::null ) ); + double x2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x2", QString::null ) ); + double y2 = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y2", QString::null ) ); + + double x = QMIN( x1, x2 ); + double y = QMIN( y1, y2 ); + + QDomElement orig = doc.createElement( "ORIG" ); + orig.setAttribute( "x", x ); + orig.setAttribute( "y", y + offset ); + e.appendChild( orig ); + + QDomElement size = doc.createElement( "SIZE" ); + size.setAttribute( "width", fabs( x1 - x2 ) ); + size.setAttribute( "height", fabs( y1 - y2 ) ); + e.appendChild( size ); + + QDomElement linetype = doc.createElement( "LINETYPE" ); + if ( ( x1 < x2 && y1 < y2 ) || ( x1 > x2 && y1 > y2 ) ) + linetype.setAttribute( "value", 2 ); + else + linetype.setAttribute( "value", 3 ); + + e.appendChild( linetype ); + return (x1 < x2); +} + +void OoImpressImport::appendPen( QDomDocument& doc, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" )) + { + QDomElement pen = doc.createElement( "PEN" ); + if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" ) + pen.setAttribute( "style", 0 ); + else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" ) + pen.setAttribute( "style", 1 ); + else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" ) + { + QString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" ); + if ( style == "Ultrafine Dashed" || style == "Fine Dashed" || + style == "Fine Dashed (var)" || style == "Dashed (var)" ) + pen.setAttribute( "style", 2 ); + else if ( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" || + style == "Line with Fine Dots" ) + pen.setAttribute( "style", 3 ); + else if ( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" ) + pen.setAttribute( "style", 4 ); + else if ( style == "2 Dots 1 Dash" ) + pen.setAttribute( "style", 5 ); + } + + if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) ) + pen.setAttribute( "width", (int) KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ) ); + if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) ) + pen.setAttribute( "color", m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) ); + e.appendChild( pen ); + } +} + +void OoImpressImport::appendBrush( QDomDocument& doc, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) ) + { + const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" ); + //kdDebug(30518)<<"void OoImpressImport::appendBrush( QDomDocument& doc, QDomElement& e ) :"<<fill<<endl; + if ( fill == "solid" ) + { + QDomElement brush = doc.createElement( "BRUSH" ); + if ( m_styleStack.hasAttributeNS( ooNS::draw, "transparency" ) ) + { + QString transparency = m_styleStack.attributeNS( ooNS::draw, "transparency" ); + transparency = transparency.remove( '%' ); + int value = transparency.toInt(); + if ( value >= 94 && value <= 99 ) + { + brush.setAttribute( "style", 2 ); + } + else if ( value>=64 && value <= 93 ) + { + brush.setAttribute( "style", 3 ); + } + else if ( value>=51 && value <= 63 ) + { + brush.setAttribute( "style", 4 ); + } + else if ( value>=38 && value <= 50 ) + { + brush.setAttribute( "style", 5 ); + } + else if ( value>=13 && value <= 37 ) + { + brush.setAttribute( "style", 6 ); + } + else if ( value>=7 && value <= 12 ) + { + brush.setAttribute( "style", 7 ); + } + else if ( value>=1 && value <= 6 ) + { + brush.setAttribute( "style", 8 ); + } + } + else + brush.setAttribute( "style", 1 ); + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) ) + brush.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) ); + e.appendChild( brush ); + } + else if ( fill == "hatch" ) + { + QDomElement brush = doc.createElement( "BRUSH" ); + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-hatch-name" ); + QDomElement* draw = m_draws[style]; + if ( draw ) + { + if( draw->hasAttributeNS( ooNS::draw, "color" ) ) + brush.setAttribute( "color", draw->attributeNS( ooNS::draw, "color", QString::null ) ); + int angle = 0; + if( draw->hasAttributeNS( ooNS::draw, "rotation" )) + { + angle = (draw->attributeNS( ooNS::draw, "rotation", QString::null ).toInt())/10; + kdDebug(30518)<<"angle :"<<angle<<endl; + } + if( draw->hasAttributeNS( ooNS::draw, "style" )) + { + QString styleHash = draw->attributeNS( ooNS::draw, "style", QString::null ); + if( styleHash == "single") + { + switch( angle ) + { + case 0: + case 180: + brush.setAttribute( "style", 9 ); + break; + case 45: + case 225: + brush.setAttribute( "style", 12 ); + break; + case 90: + case 270: + brush.setAttribute( "style", 10 ); + break; + case 135: + case 315: + brush.setAttribute( "style", 13 ); + break; + default: + //todo fixme when we will have a kopaint + kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl; + break; + } + } + else if( styleHash == "double") + { + switch( angle ) + { + case 0: + case 180: + case 90: + case 270: + brush.setAttribute("style", 11 ); + break; + case 45: + case 135: + case 225: + case 315: + brush.setAttribute("style",14 ); + break; + default: + //todo fixme when we will have a kopaint + kdDebug(30518)<<" draw:rotation 'angle' : "<<angle<<endl; + break; + } + + } + else if( styleHash == "triple") + { + kdDebug(30518)<<" it is not implemented :( \n"; + } + + } + } + e.appendChild( brush ); + } + else if ( fill == "gradient" ) + { + // We have to set a brush with brushstyle != no background fill + // otherwise the properties dialog for the object won't + // display the preview for the gradient. + QDomElement brush = doc.createElement( "BRUSH" ); + brush.setAttribute( "style", 1 ); + e.appendChild( brush ); + + QDomElement gradient = doc.createElement( "GRADIENT" ); + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); + + QDomElement* draw = m_draws[style]; + if ( draw ) + { + gradient.setAttribute( "color1", draw->attributeNS( ooNS::draw, "start-color", QString::null ) ); + gradient.setAttribute( "color2", draw->attributeNS( ooNS::draw, "end-color", QString::null ) ); + + QString type = draw->attributeNS( ooNS::draw, "style", QString::null ); + //kdDebug(30518)<<" type !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<type<<endl; + if ( type == "linear" ) + { + int angle = draw->attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if ( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + kdDebug(30518)<<"nearAngle :"<<nearAngle<<endl; + // nearAngle should now be one of: 0, 45, 90, 135, 180... + if ( nearAngle == 0 || nearAngle == 180 ) + gradient.setAttribute( "type", 1 ); // horizontal + else if ( nearAngle == 90 || nearAngle == 270 ) + gradient.setAttribute( "type", 2 ); // vertical + else if ( nearAngle == 45 || nearAngle == 225 ) + gradient.setAttribute( "type", 3 ); // diagonal 1 + else if ( nearAngle == 135 || nearAngle == 315 ) + gradient.setAttribute( "type", 4 ); // diagonal 2 + } + else if ( type == "radial" || type == "ellipsoid" ) + gradient.setAttribute( "type", 5 ); // circle + else if ( type == "square" || type == "rectangular" ) + gradient.setAttribute( "type", 6 ); // rectangle + else if ( type == "axial" ) + gradient.setAttribute( "type", 7 ); // pipecross + + // Hard to map between x- and y-center settings of ooimpress + // and (un-)balanced settings of kpresenter. Let's try it. + int x, y; + if ( draw->hasAttributeNS( ooNS::draw, "cx" ) ) + x = draw->attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt(); + else + x = 50; + + if ( draw->hasAttributeNS( ooNS::draw, "cy" ) ) + y = draw->attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt(); + else + y = 50; + + if ( x == 50 && y == 50 ) + { + gradient.setAttribute( "unbalanced", 0 ); + gradient.setAttribute( "xfactor", 100 ); + gradient.setAttribute( "yfactor", 100 ); + } + else + { + gradient.setAttribute( "unbalanced", 1 ); + // map 0 - 100% to -200 - 200 + gradient.setAttribute( "xfactor", 4 * x - 200 ); + gradient.setAttribute( "yfactor", 4 * y - 200 ); + } + } + e.appendChild( gradient ); + + QDomElement fillType = doc.createElement( "FILLTYPE" ); + fillType.setAttribute( "value", 1 ); + e.appendChild( fillType ); + } + } +} + +void OoImpressImport::appendPie( QDomDocument& doc, QDomElement& e, const QDomElement& object ) +{ + QDomElement angle = doc.createElement( "PIEANGLE" ); + int start = (int) ( object.attributeNS( ooNS::draw, "start-angle", QString::null ).toDouble() ); + angle.setAttribute( "value", start * 16 ); + e.appendChild( angle ); + + QDomElement length = doc.createElement( "PIELENGTH" ); + int end = (int) ( object.attributeNS( ooNS::draw, "end-angle", QString::null ).toDouble() ); + if ( end < start ) + length.setAttribute( "value", ( 360 - start + end ) * 16 ); + else + length.setAttribute( "value", ( end - start ) * 16 ); + e.appendChild( length ); +} + +void OoImpressImport::appendImage( QDomDocument& doc, QDomElement& e, QDomElement& p, + const QDomElement& object ) +{ + QString fileName = storeImage( object ); + + // create a key for the picture + QTime time = QTime::currentTime(); + QDate date = QDate::currentDate(); + + QDomElement image = doc.createElement( "KEY" ); + image.setAttribute( "msec", time.msec() ); + image.setAttribute( "second", time.second() ); + image.setAttribute( "minute", time.minute() ); + image.setAttribute( "hour", time.hour() ); + image.setAttribute( "day", date.day() ); + image.setAttribute( "month", date.month() ); + image.setAttribute( "year", date.year() ); + image.setAttribute( "filename", fileName ); + e.appendChild( image ); + + QDomElement settings = doc.createElement( "PICTURESETTINGS" ); + if ( m_styleStack.hasAttributeNS( ooNS::draw, "color-mode" ) && ( m_styleStack.attributeNS( ooNS::draw, "color-mode" )=="greyscale" ) ) + settings.setAttribute( "grayscal", 1 ); + else + settings.setAttribute( "grayscal", 0 ); + + if ( m_styleStack.hasAttributeNS( ooNS::draw, "luminance" ) ) + { + QString str( m_styleStack.attributeNS( ooNS::draw, "luminance" ) ); + str = str.remove( '%' ); + settings.setAttribute( "bright", str ); + } + else + settings.setAttribute( "bright", 0 ); + + settings.setAttribute( "mirrorType", 0 ); + settings.setAttribute( "swapRGB", 0 ); + settings.setAttribute( "depth", 0 ); + e.appendChild( settings ); + + QDomElement effects = doc.createElement( "EFFECTS" ); + bool hasEffect = false; + if ( m_styleStack.hasAttributeNS( ooNS::draw, "contrast" ) ) + { + QString str( m_styleStack.attributeNS( ooNS::draw, "contrast" ) ); + str = str.remove( '%' ); + int val = str.toInt(); + val = ( int )( 255.0 *val/100.0 ); + effects.setAttribute( "type", "5" ); + effects.setAttribute( "param1", QString::number( val ) ); + hasEffect = true; + } + if ( hasEffect ) + e.appendChild( effects ); + + QDomElement key = image.cloneNode().toElement(); + key.setAttribute( "name", "pictures/" + fileName ); + p.appendChild( key ); +} + +void OoImpressImport::appendBackgroundImage( QDomDocument& doc, QDomElement& e, + QDomElement& p, const QDomElement& object ) +{ + QString fileName = storeImage( object ); + + // create a key for the picture + QTime time = QTime::currentTime(); + QDate date = QDate::currentDate(); + + QDomElement image = doc.createElement( "BACKPICTUREKEY" ); + image.setAttribute( "msec", time.msec() ); + image.setAttribute( "second", time.second() ); + image.setAttribute( "minute", time.minute() ); + image.setAttribute( "hour", time.hour() ); + image.setAttribute( "day", date.day() ); + image.setAttribute( "month", date.month() ); + image.setAttribute( "year", date.year() ); + image.setAttribute( "filename", fileName ); + e.appendChild( image ); + + QDomElement key = image.cloneNode().toElement(); + key.setTagName( "KEY" ); + key.setAttribute( "name", "pictures/" + fileName ); + p.appendChild( key ); +} + +void OoImpressImport::appendBackgroundGradient( QDomDocument& doc, QDomElement& e, + const QDomElement& object ) +{ + QDomElement backColor1 = doc.createElement( "BACKCOLOR1" ); + backColor1.setAttribute( "color", object.attributeNS( ooNS::draw, "start-color", QString::null ) ); + e.appendChild( backColor1 ); + + QDomElement backColor2 = doc.createElement( "BACKCOLOR2" ); + backColor2.setAttribute( "color", object.attributeNS( ooNS::draw, "end-color", QString::null ) ); + e.appendChild( backColor2 ); + + QDomElement backType = doc.createElement( "BACKTYPE" ); + backType.setAttribute( "value", 0 ); // color/gradient + e.appendChild( backType ); + + QDomElement bcType = doc.createElement( "BCTYPE" ); + QString type = object.attributeNS( ooNS::draw, "style", QString::null ); + if ( type == "linear" ) + { + int angle = object.attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if ( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + + // nearAngle should now be one of: 0, 45, 90, 135, 180... + if ( nearAngle == 0 || nearAngle == 180 ) + bcType.setAttribute( "value", 1 ); // horizontal + else if ( nearAngle == 90 || nearAngle == 270 ) + bcType.setAttribute( "value", 2 ); // vertical + else if ( nearAngle == 45 || nearAngle == 225 ) + bcType.setAttribute( "value", 3 ); // diagonal 1 + else if ( nearAngle == 135 || nearAngle == 315 ) + bcType.setAttribute( "value", 4 ); // diagonal 2 + } + else if ( type == "radial" || type == "ellipsoid" ) + bcType.setAttribute( "value", 5 ); // circle + else if ( type == "square" || type == "rectangular" ) + bcType.setAttribute( "value", 6 ); // rectangle + else if ( type == "axial" ) + bcType.setAttribute( "value", 7 ); // pipecross + + e.appendChild( bcType ); + + QDomElement bGradient = doc.createElement( "BGRADIENT" ); + + // Hard to map between x- and y-center settings of ooimpress + // and (un-)balanced settings of kpresenter. Let's try it. + int x, y; + if ( object.hasAttributeNS( ooNS::draw, "cx" ) ) + x = object.attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt(); + else + x = 50; + + if ( object.hasAttributeNS( ooNS::draw, "cy" ) ) + y = object.attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt(); + else + y = 50; + + if ( x == 50 && y == 50 ) + { + bGradient.setAttribute( "unbalanced", 0 ); + bGradient.setAttribute( "xfactor", 100 ); + bGradient.setAttribute( "yfactor", 100 ); + } + else + { + bGradient.setAttribute( "unbalanced", 1 ); + // map 0 - 100% to -200 - 200 + bGradient.setAttribute( "xfactor", 4 * x - 200 ); + bGradient.setAttribute( "yfactor", 4 * y - 200 ); + } + + e.appendChild( bGradient ); +} + +void OoImpressImport::appendRounding( QDomDocument& doc, QDomElement& e, const QDomElement& object ) +{ + if ( object.hasAttributeNS( ooNS::draw, "corner-radius" ) ) + { + // kpresenter uses percent, ooimpress uses cm ... hmm? + QDomElement rounding = doc.createElement( "RNDS" ); + int corner = static_cast<int>(KoUnit::parseValue(object.attributeNS( ooNS::draw, "corner-radius", QString::null))); + rounding.setAttribute( "x", corner ); + rounding.setAttribute( "y", corner ); + e.appendChild( rounding ); + } +} + +void OoImpressImport::appendShadow( QDomDocument& doc, QDomElement& e ) +{ + // Note that ooimpress makes a difference between shadowed text and + // a shadowed object while kpresenter only knows the attribute 'shadow'. + // This means that a shadowed textobject in kpresenter will always show + // a shadowed text but no shadow for the object itself. + + // make sure this is a textobject or textspan + if ( !e.hasAttribute( "type" ) || + ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "4" ) ) + { + if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-shadow" ) && + m_styleStack.attributeNS( ooNS::fo, "text-shadow" ) != "none" ) + { + // use the shadow attribute to indicate a text-shadow + QDomElement shadow = doc.createElement( "SHADOW" ); + QString distance = m_styleStack.attributeNS( ooNS::fo, "text-shadow" ); + distance.truncate( distance.find( ' ' ) ); + shadow.setAttribute( "distance", KoUnit::parseValue( distance ) ); + shadow.setAttribute( "direction", 5 ); + shadow.setAttribute( "color", "#a0a0a0" ); + e.appendChild( shadow ); + } + } + else if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow" ) && + m_styleStack.attributeNS( ooNS::draw, "shadow" ) == "visible" ) + { + // use the shadow attribute to indicate an object-shadow + QDomElement shadow = doc.createElement( "SHADOW" ); + double x = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-x" ) ); + double y = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-y" ) ); + + if ( x < 0 && y < 0 ) + { + shadow.setAttribute( "direction", 1 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x == 0 && y < 0 ) + { + shadow.setAttribute( "direction", 2 ); + shadow.setAttribute( "distance", (int) fabs ( y ) ); + } + else if ( x > 0 && y < 0 ) + { + shadow.setAttribute( "direction", 3 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x > 0 && y == 0 ) + { + shadow.setAttribute( "direction", 4 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x > 0 && y > 0 ) + { + shadow.setAttribute( "direction", 5 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x == 0 && y > 0 ) + { + shadow.setAttribute( "direction", 6 ); + shadow.setAttribute( "distance", (int) fabs ( y ) ); + } + else if ( x < 0 && y > 0 ) + { + shadow.setAttribute( "direction", 7 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x < 0 && y == 0 ) + { + shadow.setAttribute( "direction", 8 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + + if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow-color" ) ) + shadow.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "shadow-color" ) ); + + e.appendChild( shadow ); + } + if ( m_styleStack.hasAttributeNS( ooNS::draw, "size-protect" ) || m_styleStack.hasAttributeNS( ooNS::draw, "move-protect" ) ) + { + bool b = ( m_styleStack.attributeNS( ooNS::draw, "size-protect" ) == "true" ) || ( m_styleStack.attributeNS( ooNS::draw, "move-protect" ) == "true" ); + if ( b ) + { + QDomElement protect = doc.createElement( "PROTECT" ); + protect.setAttribute("state" , b); + e.appendChild(protect); + } + } +} + +void OoImpressImport::appendLineEnds( QDomDocument& doc, QDomElement& e, bool orderEndStartLine) +{ + const char* attr = orderEndStartLine ? "marker-start" : "marker-end"; + if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) ) + { + QDomElement lineBegin = doc.createElement( "LINEBEGIN" ); + QString type = m_styleStack.attributeNS( ooNS::draw, attr ); + if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" || + type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" ) + lineBegin.setAttribute( "value", 1 ); + else if ( type == "Square" ) + lineBegin.setAttribute( "value", 2 ); + else if ( type == "Circle" || type == "Square 45" ) + lineBegin.setAttribute( "value", 3 ); + else if ( type == "Line Arrow" ) + lineBegin.setAttribute( "value", 4 ); + else if ( type == "Dimension Lines" ) + lineBegin.setAttribute( "value", 5 ); + else if ( type == "Double Arrow" ) + lineBegin.setAttribute( "value", 6 ); + e.appendChild( lineBegin ); + } + attr = orderEndStartLine ? "marker-end" : "marker-start"; + if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) ) + { + QDomElement lineEnd = doc.createElement( "LINEEND" ); + QString type = m_styleStack.attributeNS( ooNS::draw, attr ); + if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" || + type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" ) + lineEnd.setAttribute( "value", 1 ); + else if ( type == "Square" ) + lineEnd.setAttribute( "value", 2 ); + else if ( type == "Circle" || type == "Square 45" ) + lineEnd.setAttribute( "value", 3 ); + else if ( type == "Line Arrow" ) + lineEnd.setAttribute( "value", 4 ); + else if ( type == "Dimension Lines" ) + lineEnd.setAttribute( "value", 5 ); + else if ( type == "Double Arrow" ) + lineEnd.setAttribute( "value", 6 ); + e.appendChild( lineEnd ); + } +} + +void OoImpressImport::appendTextObjectMargin( QDomDocument& /*doc*/, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::fo, "padding" ) ) + { + double tmpValue = KoUnit::parseValue(m_styleStack.attributeNS( ooNS::fo, "padding" ) ); + e.setAttribute( "btoppt", tmpValue ); + e.setAttribute( "bbottompt", tmpValue ); + e.setAttribute( "bleftpt", tmpValue ); + e.setAttribute( "brightpt", tmpValue ); + } + else + { + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-top" ) ) + e.setAttribute( "btoppt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-top" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-bottom" ) ) + e.setAttribute( "bbottompt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-bottom" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-left" ) ) + e.setAttribute( "bleftpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-left" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-right" ) ) + e.setAttribute( "brightpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-right" ) ) ); + } +} + +QDomElement OoImpressImport::parseTextBox( QDomDocument& doc, const QDomElement& textBox ) +{ + QDomElement textObjectElement = doc.createElement( "TEXTOBJ" ); + appendTextObjectMargin( doc, textObjectElement ); + + // vertical alignment + if ( m_styleStack.hasAttributeNS( ooNS::draw, "textarea-vertical-align" ) ) + { + QString alignment = m_styleStack.attributeNS( ooNS::draw, "textarea-vertical-align" ); + if ( alignment == "top" ) + textObjectElement.setAttribute( "verticalAlign", "top" ); + else if ( alignment == "middle" ) + textObjectElement.setAttribute( "verticalAlign", "center" ); + else if ( alignment == "bottom" ) + textObjectElement.setAttribute( "verticalAlign", "bottom" ); + + textObjectElement.setAttribute("verticalValue", 0.0); + } + + parseParagraphs( doc, textObjectElement, textBox ); + + return textObjectElement; +} + +void OoImpressImport::parseParagraphs( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& parent ) +{ + QDomElement t; + forEachElement( t, parent ) + { + m_styleStack.save(); + const QString localName = t.localName(); + const QString ns = t.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + + QDomElement e; + if ( isTextNS && localName == "p" ) // text paragraph + e = parseParagraph( doc, t ); + else if ( isTextNS && localName == "h" ) // heading - can this happen in ooimpress? + { + e = parseParagraph( doc, t ); + } + else if ( isTextNS && ( localName == "unordered-list" || localName == "ordered-list" ) ) + { + parseList( doc, textObjectElement, t ); + m_styleStack.restore(); + continue; + } + // TODO text:sequence-decls + else + { + kdDebug(30518) << "Unsupported texttype '" << localName << "'" << endl; + } + + if ( !e.isNull() ) + textObjectElement.appendChild( e ); + m_styleStack.restore(); // remove the styles added by the paragraph or list + } +} + +void OoImpressImport::applyListStyle( QDomElement& paragraph ) +{ + // Spec: see 3.3.5 p137 + if ( m_listStyleStack.hasListStyle() && m_nextItemIsListItem ) { + //const QDomElement listStyle = m_listStyleStack.currentListStyle(); + //bool heading = paragraph.localName() == "h"; + m_nextItemIsListItem = false; + /*int level = heading ? paragraph.attributeNS( ooNS::text, "level", QString::null ).toInt() + : m_listStyleStack.level();*/ + + QDomElement counter = paragraph.ownerDocument().createElement( "COUNTER" ); + counter.setAttribute( "numberingtype", 0 ); + counter.setAttribute( "depth", 0 ); + + if ( m_insideOrderedList ) + counter.setAttribute( "type", 1 ); + else + counter.setAttribute( "type", 10 ); // a disc bullet + paragraph.appendChild( counter ); + } +} + +static QDomElement findListLevelStyle( QDomElement& fullListStyle, int level ) +{ + QDomElement listLevelItem; + forEachElement( listLevelItem, fullListStyle ) + { + if ( listLevelItem.attributeNS( ooNS::text, "level", QString::null ).toInt() == level ) + return listLevelItem; + } + return QDomElement(); +} + +bool OoImpressImport::pushListLevelStyle( const QString& listStyleName, int level ) +{ + QDomElement* fullListStyle = m_listStyles[listStyleName]; + if ( !fullListStyle ) { + kdWarning(30518) << "List style " << listStyleName << " not found!" << endl; + return false; + } + else + return pushListLevelStyle( listStyleName, *fullListStyle, level ); +} + +bool OoImpressImport::pushListLevelStyle( const QString& listStyleName, // for debug only + QDomElement& fullListStyle, int level ) +{ + // Find applicable list-level-style for level + int i = level; + QDomElement listLevelStyle; + while ( i > 0 && listLevelStyle.isNull() ) { + listLevelStyle = findListLevelStyle( fullListStyle, i ); + --i; + } + if ( listLevelStyle.isNull() ) { + kdWarning(30518) << "List level style for level " << level << " in list style " << listStyleName << " not found!" << endl; + return false; + } + kdDebug(30518) << "Pushing list-level-style from list-style " << listStyleName << " level " << level << endl; + m_listStyleStack.push( listLevelStyle ); + return true; +} + +void OoImpressImport::parseList( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& list ) +{ + //kdDebug(30518) << k_funcinfo << "parseList"<< endl; + + m_insideOrderedList = ( list.localName() == "ordered-list" ); + QString oldListStyleName = m_currentListStyleName; + if ( list.hasAttributeNS( ooNS::text, "style-name" ) ) + m_currentListStyleName = list.attributeNS( ooNS::text, "style-name", QString::null ); + bool listOK = !m_currentListStyleName.isEmpty(); + const int level = m_listStyleStack.level() + 1; + //kdDebug(30518) << k_funcinfo << " listOK=" << listOK << " level=" << level << endl; + if ( listOK ) + listOK = pushListLevelStyle( m_currentListStyleName, level ); + + // Iterate over list items + QDomElement listItem; + forEachElement( listItem, list ) + { + // It's either list-header (normal text on top of list) or list-item + m_nextItemIsListItem = ( listItem.localName() != "list-header" ); + m_restartNumbering = -1; + if ( listItem.hasAttributeNS( ooNS::text, "start-value" ) ) + m_restartNumbering = listItem.attributeNS( ooNS::text, "start-value", QString::null ).toInt(); + // ### Oasis: can be p h or list only. + parseParagraphs( doc, textObjectElement, listItem ); + m_restartNumbering = -1; + } + if ( listOK ) + m_listStyleStack.pop(); + m_currentListStyleName = oldListStyleName; +} + +QDomElement OoImpressImport::parseParagraph( QDomDocument& doc, const QDomElement& paragraph ) +{ + QDomElement p = doc.createElement( "P" ); + + // parse the paragraph-properties + fillStyleStack( paragraph ); + + // Style name + QString styleName = m_styleStack.userStyleName("paragraph"); + if ( !styleName.isEmpty() ) + { + QDomElement nameElem = doc.createElement("NAME"); + nameElem.setAttribute("value", styleName); + p.appendChild(nameElem); + } + + // Paragraph alignment + if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-align" ) ) + { + QString align = m_styleStack.attributeNS( ooNS::fo, "text-align" ); + if ( align == "center" ) + p.setAttribute( "align", 4 ); + else if ( align == "justify" ) + p.setAttribute( "align", 8 ); + else if ( align == "start" ) + p.setAttribute( "align", 0 ); + else if ( align == "end" ) + p.setAttribute( "align", 2 ); + } + else + p.setAttribute( "align", 0 ); // use left aligned as default + + + // Offset before and after paragraph + OoUtils::importTopBottomMargin( p, m_styleStack ); + + // Indentation (margins) + OoUtils::importIndents( p, m_styleStack ); + + // Line spacing + OoUtils::importLineSpacing( p, m_styleStack ); + + // Tabulators + OoUtils::importTabulators( p, m_styleStack ); + + // Borders + OoUtils::importBorders( p, m_styleStack ); + + applyListStyle( p ); + + uint pos = 0; + + m_styleStack.save(); + // parse every childnode of the paragraph + parseSpanOrSimilar( doc, paragraph, p, pos); + m_styleStack.restore(); // remove possible garbage (should not be needed) + + return p; +} + +void OoImpressImport::parseSpanOrSimilar( QDomDocument& doc, const QDomElement& parent, + QDomElement& outputParagraph, uint& pos) +{ + // Parse every child node of the parent + // Can't use forEachElement here since we also care about text nodes + for( QDomNode node = parent.firstChild(); !node.isNull(); node = node.nextSibling() ) + { + QDomElement ts = node.toElement(); + QString textData; + const QString localName( ts.localName() ); + const QString ns = ts.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + QDomText t = node.toText(); + + // Try to keep the order of the tag names by probability of happening + if ( isTextNS && localName == "span" ) // text:span + { + m_styleStack.save(); + fillStyleStack( ts ); + parseSpanOrSimilar( doc, ts, outputParagraph, pos); + m_styleStack.restore(); + } + else if ( isTextNS && localName == "s" ) // text:s + { + textData = OoUtils::expandWhitespace(ts); + } + else if ( isTextNS && localName == "tab-stop" ) // text:tab-stop + { + // KPresenter currently uses \t. + // Known bug: a line with only \t\t\t\t isn't loaded - XML (QDom) strips out whitespace. + // One more good reason to switch to <text:tab-stop> instead... + textData = '\t'; + } + else if ( isTextNS && localName == "line-break" ) + { + textData = '\n'; + } + else if ( localName == "image" && ns == ooNS::draw ) + { + textData = '#'; // anchor placeholder + // TODO + } + else if ( isTextNS && localName == "a" ) + { + m_styleStack.save(); + QString href( ts.attributeNS( ooNS::xlink, "href", QString::null) ); + if ( href.startsWith("#") ) + { + // We have a reference to a bookmark (### TODO) + // As we do not support it now, treat it as a <text:span> without formatting + parseSpanOrSimilar( doc, ts, outputParagraph, pos); + } + else + { +#if 0 // TODO + // The problem is that KPresenter's hyperlink text is not inside the normal text, but for OOWriter it is nearly a <text:span> + // So we have to fake. + QDomElement fakeParagraph, fakeFormats; + uint fakePos=0; + QString text; + parseSpanOrSimilar( doc, ts, fakeParagraph, fakeFormats, text, fakePos); + textData = '#'; // hyperlink placeholder + QDomElement linkElement (doc.createElement("LINK")); + linkElement.setAttribute("hrefName",ts.attributeNS( ooNS::xlink, "href", QString::null)); + linkElement.setAttribute("linkName",text); + appendVariable(doc, ts, pos, "STRING", 9, text, linkElement); +#endif + } + m_styleStack.restore(); + } + else if ( isTextNS && + (localName == "date" // fields + || localName == "time" + || localName == "page-number" + || localName == "file-name" + || localName == "author-name" + || localName == "author-initials" ) ) + { + textData = "#"; // field placeholder + appendField(doc, outputParagraph, ts, pos); + } + else if ( t.isNull() ) // no textnode, we must ignore + { + kdWarning(30518) << "Ignoring tag " << ts.tagName() << endl; + continue; + } + else + textData = t.data(); + + pos += textData.length(); + + QDomElement text = saveHelper(textData, doc); + + kdDebug(30518) << k_funcinfo << "Para text is: " << textData << endl; + + if (m_styleStack.hasAttributeNS( ooNS::fo, "language" )) { + QString lang = m_styleStack.attributeNS( ooNS::fo, "language" ); + if (lang=="en") + text.setAttribute("language", "en_US"); + else + text.setAttribute("language", lang); + } + + // parse the text-properties + if ( m_styleStack.hasAttributeNS( ooNS::fo, "color" ) ) { + kdDebug(30518) << "color=" << m_styleStack.attributeNS( ooNS::fo, "color" ) << endl; + text.setAttribute( "color", m_styleStack.attributeNS( ooNS::fo, "color" ) ); + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-family" ) // 3.10.9 + || m_styleStack.hasAttributeNS( ooNS::style, "font-name") )//3.10.8 + { + // 'Thorndale/Albany' are not known outside OpenOffice so we substitute them + // with 'Times New Roman/Arial' that look nearly the same. + if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Thorndale" ) + text.setAttribute( "family", "Times New Roman" ); + else if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Albany" ) + text.setAttribute( "family", "Arial" ); + else + text.setAttribute( "family", m_styleStack.attributeNS( ooNS::fo, "font-family" ).remove( "'" ) ); + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-size" ) ) + { + double pointSize = m_styleStack.fontSize(); + text.setAttribute( "pointSize", qRound(pointSize) ); // KPresenter uses toInt()! + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-weight" ) ) // 3.10.24 + if ( m_styleStack.attributeNS( ooNS::fo, "font-weight" ) == "bold" ) + text.setAttribute( "bold", 1 ); + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-style" ) ) + if ( m_styleStack.attributeNS( ooNS::fo, "font-style" ) == "italic" ) + text.setAttribute( "italic", 1 ); + + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-position" ) ) // 3.10.17 + { + QString text_position = m_styleStack.attributeNS( ooNS::style, "text-position"); + QString value; + QString relativetextsize; + OoUtils::importTextPosition( text_position, value, relativetextsize ); + text.setAttribute( "VERTALIGN", value ); + if ( !relativetextsize.isEmpty() ) + text.setAttribute( "relativetextsize", relativetextsize ); + } + + bool wordByWord = (m_styleStack.hasAttributeNS( ooNS::fo, "score-spaces"))// 3.10.25 + && (m_styleStack.attributeNS( ooNS::fo, "score-spaces") == "false"); + + // strikeout + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-crossing-out")// 3.10.6 + && m_styleStack.attributeNS( ooNS::style, "text-crossing-out") != "none") + { + QString strikeOutType = m_styleStack.attributeNS( ooNS::style, "text-crossing-out" ); + if ( strikeOutType =="double-line" ) + { + text.setAttribute( "strikeOut", "double" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + else if ( strikeOutType =="thick-line" ) + { + text.setAttribute( "strikeOut", "single-bold" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + else //if ( strikeOutType == "single-line" ) //fall back to the default strikeout + { + text.setAttribute( "strikeOut", "single" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + + if (wordByWord) + text.setAttribute("wordbyword", 1); + } + + // underlining + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-underline" ) ) // 3.10.22 + { + QString underline; + QString styleline; + OoUtils::importUnderline( m_styleStack.attributeNS( ooNS::style, "text-underline" ), + underline, styleline ); + QString underLineColor = m_styleStack.attributeNS( ooNS::style, "text-underline-color" );// 3.10.23 + + text.setAttribute( "value", underline ); + text.setAttribute( "styleline", styleline ); + + if ( !underLineColor.isEmpty() && underLineColor != "font-color" ) + text.setAttribute("underlinecolor", underLineColor); + if ( wordByWord ) + text.setAttribute("wordbyword", 1); + } +#if 0 // strange ooimpress doesn't implement it + // Small caps, lowercase, uppercase + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-variant" ) // 3.10.1 + || m_styleStack.hasAttributeNS( ooNS::fo, "text-transform" ) ) // 3.10.2 + { + QDomElement fontAttrib( doc.createElement( "FONTATTRIBUTE" ) ); + bool smallCaps = m_styleStack.attributeNS( ooNS::fo, "font-variant" ) == "small-caps"; + if ( smallCaps ) + { + text.setAttribute( "fontattribute", "smallcaps" ); + } else + { + // Both KWord/KPresenter and OO use "uppercase" and "lowercase". + // TODO in KWord: "capitalize". + text.setAttribute( "fontattribute", m_styleStack.attributeNS( ooNS::fo, "text-transform" ) ); + } + } +#endif + // background color (property of the paragraph in OOo, of the text in kword/kpresenter) + if (m_styleStack.hasAttributeNS( ooNS::fo, "background-color" )) + { + QString bgColor = m_styleStack.attributeNS( ooNS::fo, "background-color"); + if (bgColor != "transparent") + text.setAttribute("textbackcolor", bgColor); + } + + appendShadow( doc, outputParagraph ); // this is necessary to take care of shadowed paragraphs + outputParagraph.appendChild( text ); + } // for each text span +} + +void OoImpressImport::createStyleMap( QDomDocument &docstyles ) +{ + QDomElement styles = docstyles.documentElement(); + if ( styles.isNull() ) + return; + + QDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); + if ( !fixedStyles.isNull() ) + { + insertDraws( fixedStyles.toElement() ); + insertStyles( fixedStyles.toElement() ); + insertStylesPresentation( fixedStyles.toElement() ); + } + + QDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); + if ( !automaticStyles.isNull() ) + { + insertStyles( automaticStyles.toElement() ); + insertStylesPresentation( automaticStyles.toElement() ); + } + QDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); + if ( !masterStyles.isNull() ) + insertStyles( masterStyles.toElement() ); +} + +void OoImpressImport::insertDraws( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + if ( !e.hasAttributeNS( ooNS::draw, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::draw, "name", QString::null ); + m_draws.insert( name, new QDomElement( e ) ); + } +} + +void OoImpressImport::insertStyles( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + const QString localName = e.localName(); + const QString ns = e.namespaceURI(); + if ( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + const QString name = e.attributeNS( ooNS::style, "name", QString::null ); + if ( localName == "list-style" && ns == ooNS::text ) { + QDomElement* ep = new QDomElement( e ); + m_listStyles.insert( name, ep ); + kdDebug(30518) << "List style: '" << name << "' loaded " << endl; + } + else + { + m_styles.insert( name, new QDomElement( e ) ); + kdDebug(30518) << "Style: '" << name << "' loaded " << endl; + } + } +} + +void OoImpressImport::insertStylesPresentation( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + if ( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::style, "name", QString::null ); + m_stylesPresentation.insert( name, new QDomElement( e ) ); + //kdDebug(30518) << "Style: '" << name << "' loaded " << endl; + } +} + +void OoImpressImport::fillStyleStack( const QDomElement& object, bool sticky ) +{ + // find all styles associated with an object and push them on the stack + if ( object.hasAttributeNS( ooNS::presentation, "style-name" ) ) + { + kdDebug(30518)<<" presentation:style-name **************************** :"<<object.attributeNS( ooNS::presentation, "style-name", QString::null )<<endl; + if ( sticky ) + addStyles( m_stylesPresentation[object.attributeNS( ooNS::presentation, "style-name", QString::null )] ); + else + addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", QString::null )] ); + } + if ( object.hasAttributeNS( ooNS::draw, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", QString::null )] ); + + if ( object.hasAttributeNS( ooNS::draw, "text-style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", QString::null )] ); + + if ( object.hasAttributeNS( ooNS::text, "style-name" ) ) { + QString styleName = object.attributeNS( ooNS::text, "style-name", QString::null ); + //kdDebug(30518) << "adding style " << styleName << endl; + addStyles( m_styles[styleName] ); + } +} + +void OoImpressImport::addStyles( const QDomElement* style ) +{ + kdDebug(30518)<<" addStyle :" << style->attributeNS( ooNS::style, "name", QString::null ) <<endl; + // this function is necessary as parent styles can have parents themself + if ( style->hasAttributeNS( ooNS::style, "parent-style-name" ) ) + { + //kdDebug(30518)<<"m_styles[style->attribute( style:parent-style-name )] :"<<m_styles[style->attributeNS( ooNS::style, "parent-style-name", QString::null )]<<endl; + addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", QString::null )] ); + } + //kdDebug(30518)<<" void OoImpressImport::addStyles( const QDomElement* style ) :"<<style<<endl; + m_styleStack.push( *style ); +} + +QString OoImpressImport::storeImage( const QDomElement& object ) +{ + // store the picture + QString url = object.attributeNS( ooNS::xlink, "href", QString::null ).remove( '#' ); + KArchiveFile* file = (KArchiveFile*) m_zip->directory()->entry( url ); + + QString extension = url.mid( url.find( '.' ) ); + QString fileName = QString( "picture%1" ).arg( m_numPicture++ ) + extension; + KoStoreDevice* out = m_chain->storageFile( "pictures/" + fileName, KoStore::Write ); + + if ( file && out ) + { + QByteArray buffer = file->data(); + out->writeBlock( buffer.data(), buffer.size() ); + } + + return fileName; +} + +QString OoImpressImport::storeSound(const QDomElement & object, QDomElement & p, QDomDocument & doc) +{ + QFileInfo fi(m_chain->inputFile()); // handle relative URLs + QDir::setCurrent(fi.dirPath(true)); + fi.setFile(object.attributeNS( ooNS::xlink, "href", QString::null)); + QString url = fi.absFilePath(); + + //kdDebug(30518) << "Sound URL: " << url << endl; + + QFile file(url); + if (!file.exists()) + return QString::null; + + QString extension = url.mid( url.find( '.' ) ); + QString fileName = QString( "sound%1" ).arg( m_numSound++ ) + extension; + fileName = "sounds/" + fileName; + KoStoreDevice* out = m_chain->storageFile( fileName, KoStore::Write ); + + if (out) + { + if (!file.open(IO_ReadOnly)) + return QString::null; + + QByteArray data(8*1024); + + uint total = 0; + for ( int block = 0; ( block = file.readBlock(data.data(), data.size()) ) > 0; + total += block ) + out->writeBlock(data.data(), data.size()); + + Q_ASSERT(total == fi.size()); + + file.close(); + } + else + return QString::null; + + QDomElement key = doc.createElement("FILE"); + key.setAttribute("name", fileName); + key.setAttribute("filename", url); + p.appendChild(key); + + return url; +} + +QDomElement OoImpressImport::saveHelper(const QString &tmpText, QDomDocument &doc) +{ + QDomElement element=doc.createElement("TEXT"); + + if(tmpText.stripWhiteSpace().isEmpty()) // ### careful, this also strips \t and \n .... + // working around a bug in QDom + element.setAttribute("whitespace", tmpText.length()); + + element.appendChild(doc.createTextNode(tmpText)); + return element; +} + +void OoImpressImport::appendPoints(QDomDocument& doc, QDomElement& e, const QDomElement& object) +{ + QDomElement ptsElem = doc.createElement("POINTS"); + + QStringList ptList = QStringList::split(' ', object.attributeNS( ooNS::draw, "points", QString::null)); + + QString pt_x, pt_y; + double tmp_x, tmp_y; + for (QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it) + { + QDomElement point = doc.createElement("Point"); + + tmp_x = (*it).section(',',0,0).toInt() / 100; + tmp_y = (*it).section(',',1,1).toInt() / 100; + + pt_x.setNum(tmp_x); + pt_x+="mm"; + + pt_y.setNum(tmp_y); + pt_y+="mm"; + + point.setAttribute("point_x", KoUnit::parseValue(pt_x)); + point.setAttribute("point_y", KoUnit::parseValue(pt_y)); + ptsElem.appendChild(point); + } + + e.appendChild(ptsElem); +} + +void OoImpressImport::appendField(QDomDocument& doc, QDomElement& e, const QDomElement& object, uint pos) +{ + const QString tag = object.localName(); + const QString ns = object.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + + QDomElement custom = doc.createElement("CUSTOM"); + custom.setAttribute("pos", pos); + QDomElement variable = doc.createElement("VARIABLE"); + + if (isTextNS && tag == "date") + { + QDateTime dt(QDate::fromString(object.attributeNS( ooNS::text, "date-value", QString::null), Qt::ISODate)); + + bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true"); + + if (!dt.isValid()) { + dt = QDateTime::currentDateTime(); // OOo docs say so :) + fixed = false; + } + + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "DATE0locale"); // ### find out the correlation between KOffice and OOo date/time types + typeElem.setAttribute("type", 0); // VT_DATE + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + const QDate date(dt.date()); + const QTime time(dt.time()); + QDomElement dateElement = doc.createElement("DATE"); + dateElement.setAttribute("subtype", fixed ? 0 : 1); // VST_DATE_FIX, VST_DATE_CURRENT + dateElement.setAttribute("fix", fixed ? 1 : 0); + dateElement.setAttribute("day", date.day()); + dateElement.setAttribute("month", date.month()); + dateElement.setAttribute("year", date.year()); + dateElement.setAttribute("hour", time.hour()); + dateElement.setAttribute("minute", time.minute()); + dateElement.setAttribute("second", time.second()); + if (object.hasAttributeNS( ooNS::text, "date-adjust")) + dateElement.setAttribute("correct", object.attributeNS( ooNS::text, "date-adjust", QString::null)); + + variable.appendChild(dateElement); + } + else if (isTextNS && tag == "time") + { + // Use QDateTime to work around a possible problem of QTime::FromString in Qt 3.2.2 + QDateTime dt(QDateTime::fromString(object.attributeNS( ooNS::text, "time-value", QString::null), Qt::ISODate)); + + bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true"); + + if (!dt.isValid()) { + dt = QDateTime::currentDateTime(); // OOo docs say so :) + fixed = false; + } + + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "TIMElocale"); // ### find out the correlation between KOffice and OOo date/time types + typeElem.setAttribute("type", 2); // VT_TIME + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + const QTime time(dt.time()); + QDomElement timeElement = doc.createElement("TIME"); + timeElement.setAttribute("subtype", fixed ? 0 : 1); // VST_TIME_FIX, VST_TIME_CURRENT + timeElement.setAttribute("fix", fixed ? 1 : 0); + timeElement.setAttribute("hour", time.hour()); + timeElement.setAttribute("minute", time.minute()); + timeElement.setAttribute("second", time.second()); + /*if (object.hasAttributeNS( ooNS::text, "time-adjust")) + timeElem.setAttribute("correct", object.attributeNS( ooNS::text, "time-adjust", QString::null));*/ // ### TODO + + variable.appendChild(timeElement); + } + else if (isTextNS && tag == "page-number") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "NUMBER"); + typeElem.setAttribute("type", 4); // VT_PGNUM + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + QDomElement pgNumElem = doc.createElement("PGNUM"); + + int subtype = 0; // VST_PGNUM_CURRENT + + if (object.hasAttributeNS( ooNS::text, "select-page")) + { + const QString select = object.attributeNS( ooNS::text, "select-page", QString::null); + + if (select == "previous") + subtype = 3; // VST_PGNUM_PREVIOUS + else if (select == "next") + subtype = 4; // VST_PGNUM_NEXT + else + subtype = 0; // VST_PGNUM_CURRENT + } + + pgNumElem.setAttribute("subtype", subtype); + pgNumElem.setAttribute("value", object.text()); + + variable.appendChild(pgNumElem); + } + else if (isTextNS && tag == "file-name") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "STRING"); + typeElem.setAttribute("type", 8); // VT_FIELD + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + int subtype = 5; + + if (object.hasAttributeNS( ooNS::text, "display")) + { + const QString display = object.attributeNS( ooNS::text, "display", QString::null); + + if (display == "path") + subtype = 1; // VST_DIRECTORYNAME + else if (display == "name") + subtype = 6; // VST_FILENAMEWITHOUTEXTENSION + else if (display == "name-and-extension") + subtype = 0; // VST_FILENAME + else + subtype = 5; // VST_PATHFILENAME + } + + QDomElement fileNameElem = doc.createElement("FIELD"); + fileNameElem.setAttribute("subtype", subtype); + fileNameElem.setAttribute("value", object.text()); + + variable.appendChild(fileNameElem); + } + else if (isTextNS && tag == "author-name" + || isTextNS && tag == "author-initials") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "STRING"); + typeElem.setAttribute("type", 8); // VT_FIELD + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + int subtype = 2; // VST_AUTHORNAME + + if (isTextNS && tag == "author-initials") + subtype = 16; // VST_INITIAL + + QDomElement authorElem = doc.createElement("FIELD"); + authorElem.setAttribute("subtype", subtype); + authorElem.setAttribute("value", object.text()); + + variable.appendChild(authorElem); + } + + custom.appendChild(variable); + e.appendChild(custom); +} + +void OoImpressImport::createPresentationAnimation(const QDomElement& element) +{ + int order = 0; + QDomElement e; + forEachElement( e, element ) + { + const QString localName = e.localName(); + const QString ns = e.namespaceURI(); + if ( ns == ooNS::presentation && localName == "show-shape" && e.hasAttributeNS( ooNS::draw, "shape-id" ) ) + { + QString name = e.attributeNS( ooNS::draw, "shape-id", QString::null ); + //kdDebug(30518)<<" insert animation style : name :"<<name<<endl; + animationList *lst = new animationList; + QDomElement* ep = new QDomElement( e ); + lst->element = ep; + lst->order = order; + m_animations.insert( name, lst ); + ++order; + } + } +} + +QDomElement OoImpressImport::findAnimationByObjectID(const QString & id, int & order) +{ + kdDebug(30518)<<"QDomElement OoImpressImport::findAnimationByObjectID(const QString & id) :"<<id<<endl; + if (m_animations.isEmpty() ) + return QDomElement(); + + animationList *animation = m_animations[id]; + //kdDebug(30518)<<"QDomElement *animation = m_animations[id]; :"<<animation<<endl; + if ( !animation ) + return QDomElement(); + for (QDomNode node = *( animation->element ); !node.isNull(); node = node.nextSibling()) + { + QDomElement e = node.toElement(); + order = animation->order; + kdDebug(30518)<<"e.tagName() :"<<e.tagName()<<" e.attribute(draw:shape-id) :"<<e.attributeNS( ooNS::draw, "shape-id", QString::null)<<endl; + if (e.tagName()=="presentation:show-shape" && e.attributeNS( ooNS::draw, "shape-id", QString::null)==id) + return e; + } + + return QDomElement(); +} + + +void OoImpressImport::appendObjectEffect(QDomDocument& doc, QDomElement& e, const QDomElement& object, + QDomElement& sound) +{ + int order = 0; + QDomElement origEffect = findAnimationByObjectID(object.attributeNS( ooNS::draw, "id", QString::null), order).toElement(); + + if (origEffect.isNull()) + return; + + QString effect = origEffect.attributeNS( ooNS::presentation, "effect", QString::null); + QString dir = origEffect.attributeNS( ooNS::presentation, "direction", QString::null); + QString speed = origEffect.attributeNS( ooNS::presentation, "speed", QString::null); + kdDebug(30518)<<"speed :"<<speed<<endl; + //todo implement speed value. + + int effVal=0; + //kdDebug(30518)<<" effect :"<<effect<<" dir :"<<dir<<endl; + if (effect=="fade") + { + if (dir=="from-right") + effVal=10; // EF_WIPE_RIGHT + else if (dir=="from-left") + effVal=9; // EF_WIPE_LEFT + else if (dir=="from-top") + effVal=11; // EF_WIPE_TOP + else if (dir=="from-bottom") + effVal=12; // EF_WIPE_BOTTOM + else + return; + } + else if (effect=="move") + { + if (dir=="from-right") + effVal=1; // EF_COME_RIGHT + else if (dir=="from-left") + effVal=2; // EF_COME_LEFT + else if (dir=="from-top") + effVal=3; // EF_COME_TOP + else if (dir=="from-bottom") + effVal=4; // EF_COME_BOTTOM + else if (dir=="from-upper-right") + effVal=5; // EF_COME_RIGHT_TOP + else if (dir=="from-lower-right") + effVal=6; // EF_COME_RIGHT_BOTTOM + else if (dir=="from-upper-left") + effVal=7; // EF_COME_LEFT_TOP + else if (dir=="from-lower-left") + effVal=8; // EF_COME_LEFT_BOTTOM + else + return; + } + else + return; // sorry, no more supported effects :( + + QDomElement effElem = doc.createElement("EFFECTS"); + effElem.setAttribute("effect", effVal); + e.appendChild(effElem); + + QDomElement presNum = doc.createElement( "PRESNUM" ); + presNum.setAttribute("value", order); + e.appendChild( presNum ); + + // sound effect + QDomElement origSoundEff = KoDom::namedItemNS( origEffect, ooNS::presentation, "sound"); + if (!origSoundEff.isNull()) + { + QString soundUrl = storeSound(origSoundEff, sound, doc); + + if (!soundUrl.isNull()) + { + QDomElement pseElem = doc.createElement("APPEARSOUNDEFFECT"); + pseElem.setAttribute("appearSoundEffect", 1); + pseElem.setAttribute("appearSoundFileName", soundUrl); + + e.appendChild(pseElem); + } + } +} + +#include "ooimpressimport.moc" diff --git a/filters/kpresenter/ooimpress/ooimpressimport.h b/filters/kpresenter/ooimpress/ooimpressimport.h new file mode 100644 index 00000000..403daf98 --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressimport.h @@ -0,0 +1,120 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + Copyright (c) 2003 Lukas Tinkl <lukas@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef OoImpress_IMPORT_H__ +#define OoImpress_IMPORT_H__ + +#include <KoFilter.h> +#include <KoStore.h> + +#include <qdom.h> +#include <qdict.h> +#include <qcolor.h> +#include <KoStyleStack.h> +#include <liststylestack.h> + +class KZip; + +struct animationList +{ + QDomElement *element; + int order; +}; + +class OoImpressImport : public KoFilter +{ + Q_OBJECT +public: + OoImpressImport( KoFilter * parent, const char * name, const QStringList & ); + virtual ~OoImpressImport(); + + virtual KoFilter::ConversionStatus convert( QCString const & from, QCString const & to ); + +private: + void createDocumentInfo( QDomDocument &docinfo ); + void createDocumentContent( QDomDocument &doccontent ); + void createStyleMap( QDomDocument &docstyles ); + void insertDraws( const QDomElement& styles ); + void insertStyles( const QDomElement& styles ); + void insertStylesPresentation( const QDomElement& styles ); + + void fillStyleStack( const QDomElement& object,bool sticky = false ); + void addStyles( const QDomElement* style ); + void appendName(QDomDocument& doc, QDomElement& e, const QDomElement& object); + void append2DGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ); + bool appendLineGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ); + void appendPoints(QDomDocument& doc, QDomElement& e, const QDomElement& object); + void appendPie( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendImage( QDomDocument& doc, QDomElement& e, QDomElement& p, const QDomElement& object ); + void appendBackgroundImage( QDomDocument& doc, QDomElement& e, QDomElement& p, const QDomElement& object ); + void appendBackgroundGradient( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendRounding( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendPen( QDomDocument& doc, QDomElement& e ); + void appendBrush( QDomDocument& doc, QDomElement& e ); + void appendShadow( QDomDocument& doc, QDomElement& e ); + void appendLineEnds( QDomDocument& doc, QDomElement& e, bool _orderEndStartLine = true ); + void appendTextObjectMargin( QDomDocument& doc, QDomElement& e ); + void appendField(QDomDocument& doc, QDomElement& e, const QDomElement& object, uint pos); + void createPresentationAnimation(const QDomElement& element); + QDomElement findAnimationByObjectID(const QString & id, int & order); + + void appendObjectEffect(QDomDocument& doc, QDomElement& e, const QDomElement& object, QDomElement& sound); + void appendBackgroundPage( QDomDocument &doc, QDomElement &e,QDomElement & pictureElement, QDomElement &soundElement ); + + QDomElement saveHelper(const QString &tmpText, QDomDocument &doc); + void appendObject(QDomNode & drawPage, QDomDocument & doc, QDomElement & soundElement, QDomElement & pictureElement, QDomElement & pageNoteElement, QDomElement &objectElement,double offset, bool sticky = false); + + QString storeImage( const QDomElement& object ); + QString storeSound(const QDomElement & object, QDomElement & p, QDomDocument & doc); + QDomElement parseTextBox( QDomDocument& doc, const QDomElement& textBox ); + bool pushListLevelStyle( const QString& listStyleName, int level ); + bool pushListLevelStyle( const QString& listStyleName, QDomElement& fullListStyle, int level ); + void applyListStyle( QDomElement& paragraph ); + void parseList( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& list ); + void parseParagraphs( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& textBox ); + QDomElement parseParagraph( QDomDocument& doc, const QDomElement& paragraph ); + void parseSpanOrSimilar( QDomDocument& doc, const QDomElement& parent, + QDomElement& outputParagraph, uint& pos); + bool parseSettings( QDomDocument &doc, QDomElement &helpLineElement, QDomElement &attributeElement ); + void parseHelpLine( QDomDocument &doc,QDomElement &helpLineElement, const QString &text ); + + KoFilter::ConversionStatus openFile(); + KoFilter::ConversionStatus loadAndParse(const QString& filename, QDomDocument& doc); + + int m_numPicture; + int m_numSound; + QDomDocument m_content; + QDomDocument m_meta; + QDomDocument m_settings; + QDict<QDomElement> m_styles, m_draws, m_stylesPresentation; + QDict<QDomElement> m_listStyles; + QDict<animationList> m_animations; + + bool m_insideOrderedList; + bool m_nextItemIsListItem; // only the first elem inside list-item is numbered + int m_restartNumbering; + QString m_currentListStyleName; + + KZip * m_zip; + KoStyleStack m_styleStack; + ListStyleStack m_listStyleStack; +}; + +#endif diff --git a/filters/kpresenter/ooimpress/status.html b/filters/kpresenter/ooimpress/status.html new file mode 100644 index 00000000..b0062c04 --- /dev/null +++ b/filters/kpresenter/ooimpress/status.html @@ -0,0 +1,227 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + <title>KOffice filters status: OpenOffice.org Impress Filter</title> +</head> +<body text="#000000" bgcolor="#FFFFFF" link="#000099" vlink="#666666" alink="#666666"> +<A NAME="START"> </A> + +<BR> +<center> + <h1> + KOffice filters status: <i>OpenOffice.org Impress Filter</i> + </h1> +</center> + +<hr NOSHADE SIZE=2 WIDTH="70%"> + +<font size="-1"><b> + <A HREF="#import">Import</A> | + <A HREF="#export">Export</A> +</b></font> + +<BR><BR><BR> +<center><a NAME="import"></a></center> + +<A HREF="#START"><font size="-1"><b>Up</b></font></A> +<center> +<table BORDER=0 CELLSPACING=0 BGCOLOR="#000000" WIDTH="100%"> + <tr> + <td> + <table BORDER=0 CELLPADDING=2 BGCOLOR="#FFFFFF" WIDTH="100%"> + + <tr BGCOLOR="#DDFFDD"> + <td COLSPAN="2"> + <center><b><i><font size="+1"> + <BR> + Import OpenOffice.org Impress for KPresenter<BR> + <BR> + </font></i></b></center> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP WIDTH="1%" NOWRAP><b><font size="+1">Last update</font></b></td> + <td>March 06, 2005</td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">Features</font></b></td> + <td> + - Objects: text (including list), circle, ellipse (including pie, arc and chord), + rectangle, line, image, polyline, polygon<br> + - Slide titles<br> + - Paper settings<br> + - Notes<br> + - Slide background (solid, gradient and image)<br> + - Line settings (width, style and color)<br> + - Fill settings (solid, gradient)<br> + - Line ends (arrows)<br> + - Rounding (for rectangles)<br> + - Shadow<br> + - Text margins<br> + - Vertical alignment for text<br> + - Text style (underline, sub/super script, bold, italic, strikeout, background color)<br> + - Paragraph style (line spacing, offset before/after paragraph, indent first/right/left, borders)<br> + - Presentation settings<br> + - Slide transitions<br> + - Sound<br> + - Fields (number of pages, author, date & time)<br> + - Effects (for objects) and order effect<br> + - Slide duration transition<br> + - Picture effect<br> + - Animation object order<br> + - HelpLine <br> + - Custom Slide Show <br> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Todo</font></b></td> + <td> + - Video (not supported by KPresenter)<br> + - Embedded documents<br> + - Objects: path, 3D objects (not supported by KPresenter)<br> + - Load Layer (kpresenter doesn't support it but we can d�ine it as sticky object <br> + </td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">History</font></b></td> + <td>January 11, 2003: Initial Revision</td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Authors</font></b></td> + <td><a href="mailto:percy@eris23.de">Percy Leonhardt</a><br> + <a href="mailto:montel@kde.org">Laurent Montel</a><br> + <a href="mailto:lukas@kde.org">Lukáš Tinkl</a> + </td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">Links</font></b></td> + <td> + <a href="http://www.koffice.org/kpresenter/">KPresenter homepage</a><br> + <a href="http://xml.openoffice.org">xml.openoffice.org</a> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Progress report </font></b></td> + <td>-</td> + </tr> + </table> + </td> + </tr> +</table> +</center> +<A HREF="#START"><font size="-1"><b>Up</b></font></A> + +<br><br><br> + +<hr NOSHADE SIZE=1> +<br><br><br> + + +<center> + <a NAME="export"></a> +</center> + +<A HREF="#START"><font size="-1"><b>Up</b></font></A> +<center> +<table BORDER=0 CELLSPACING=0 BGCOLOR="#000000" WIDTH="100%"> + <tr> + <td> + <table BORDER=0 CELLPADDING=2 BGCOLOR="#FFFFFF" WIDTH="100%"> + <tr BGCOLOR="#FFDDDD"> + <td COLSPAN="2"> + <center><b><i><font size="+1"> + <BR>Export KPresenter to OpenOffice.org Impress<BR><BR> + </font></i></b></center> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP WIDTH="1%" NOWRAP><b><font size="+1">Last update</font></b></td> + <td>March 06, 2005</td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">Features</font></b></td> + <td> + - Objects: text (including list), circle, ellipse, rectangle, line, image, pie, arc, chord, polyline, polygon<br> + - Slide titles<br> + - Paper settings<br> + - Slide background (solid)<br> + - Line settings (width, style and color)<br> + - Fill settings (solid, gradient)<br> + - Rounding (for rectangles)<br> + - Shadow<br> + - Text style (underline, sub/super script, bold, italic, strikeout, background color)<br> + - Paragraph style (line spacing, offset before/after paragraph, indent first/right/left, borders)<br> + - Slide transitions<br> + - Object rotate<br> + - Slide duration transition<br> + - Objects: image<br> + - Settings element (snap line drawing)<br> + - Export Transparency<br> + - Export Group Object<br> + - Vertical alignment for text<br> + - Text margins<br> + - Export title/keyword/subject<br> + - Custom Slide Show<br> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Todo</font></b></td> + <td> + - Presentation settings<br> + - Slide background (gradient and image)<br> + - Line ends (arrows)<br> + - Notes<br> + - Sound<br> + - Fields (number of pages, author, date & time)<br> + - Effects (for objects)<br> + - Video (not supported by KPresenter)<br> + - Embedded documents<br> + - Objects: path, 3D objects (not supported by KPresenter)<br> + </td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">History</font></b></td> + <td>July 01, 2003: Initial Revision</td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Authors</font></b></td> + <td> + <a href="mailto:percy@eris23.de">Percy Leonhardt</a><br> + <a href="mailto:montel@kde.org">Montel Laurent</a><br> + </td> + </tr> + + <tr BGCOLOR="#CCCCFF"> + <td VALIGN=TOP><b><font size="+1">Links</font></b></td> + <td> + <a href="http://www.koffice.org/kpresenter/">KPresenter homepage</a><br> + <a href="http://xml.openoffice.org">xml.openoffice.org</a> + </td> + </tr> + + <tr BGCOLOR="#EEEEFF"> + <td VALIGN=TOP><b><font size="+1">Progress report </font></b></td> + <td>---</td> + </tr> + </table> + </td> + </tr> +</table> +</center> +<A HREF="#START"><font size="-1"><b>Up</b></font></A> + +</body> +</html> diff --git a/filters/kpresenter/ooimpress/stylefactory.cc b/filters/kpresenter/ooimpress/stylefactory.cc new file mode 100644 index 00000000..0c7d9a2c --- /dev/null +++ b/filters/kpresenter/ooimpress/stylefactory.cc @@ -0,0 +1,1629 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "stylefactory.h" + +#include <qcolor.h> +#include <qdatetime.h> +#include <KoUnit.h> +#include <kdebug.h> + +StyleFactory::StyleFactory() +{ + m_strokeDashStyles.setAutoDelete( true ); + m_gradientStyles.setAutoDelete( true ); + m_hatchStyles.setAutoDelete( true ); + m_markerStyles.setAutoDelete( true ); + m_fillImageStyles.setAutoDelete( true ); + m_listStyles.setAutoDelete( true ); + m_pageStyles.setAutoDelete( true ); + m_textStyles.setAutoDelete( true ); + m_graphicStyles.setAutoDelete( true ); + m_paragraphStyles.setAutoDelete( true ); + m_pageMasterStyles.setAutoDelete( true ); + + // create standard graphic style + GraphicStyle * graphicStyle; + graphicStyle = new GraphicStyle ( "standard", "solid", "0cm", "0x000000", + "hidden", "0.3cm", "0.3cm", "0x808080", + "0cm", "0cm", "0cm", "0cm", "0x000000", + "false", "none", "Thorndale", "24pt", + "normal", "none", "none", "normal", + "100%", "start", "solid", "0x00b8ff", + "false" ); + + m_graphicStyles.append( graphicStyle ); +} + +StyleFactory::~StyleFactory() +{ +} + +void StyleFactory::addOfficeStyles( QDomDocument & doc, QDomElement & styles ) +{ + StrokeDashStyle * sd; + for ( sd = m_strokeDashStyles.first(); sd ; sd = m_strokeDashStyles.next() ) + sd->toXML( doc, styles ); + + GradientStyle * g; + for ( g = m_gradientStyles.first(); g ; g = m_gradientStyles.next() ) + g->toXML( doc, styles ); + + MarkerStyle * m; + for ( m = m_markerStyles.first(); m ; m = m_markerStyles.next() ) + m->toXML( doc, styles ); + + HatchStyle * h; + for ( h = m_hatchStyles.first(); h ; h = m_hatchStyles.next() ) + h->toXML( doc, styles ); + + GraphicStyle * gr; + gr = m_graphicStyles.first(); // skip the "standard" style + gr->toXML( doc, styles ); +} + +void StyleFactory::addOfficeMaster( QDomDocument & doc, QDomElement & master ) +{ + PageMasterStyle * p; + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + QDomElement masterPage = doc.createElement( "style:master-page" ); + masterPage.setAttribute( "style:name", p->style() ); + masterPage.setAttribute( "style:page-master-name", p->name() ); + masterPage.setAttribute( "draw:style-name", "dp1" ); + master.appendChild( masterPage ); + } +} + +void StyleFactory::addOfficeAutomatic( QDomDocument & doc, QDomElement & automatic ) +{ + PageMasterStyle * p; + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + p->toXML( doc, automatic ); + } +} + +void StyleFactory::addAutomaticStyles( QDomDocument & doc, QDomElement & autoStyles ) +{ + ListStyle * l; + for ( l = m_listStyles.first(); l ; l = m_listStyles.next() ) + l->toXML( doc, autoStyles ); + + PageStyle * p; + for ( p = m_pageStyles.first(); p ; p = m_pageStyles.next() ) + p->toXML( doc, autoStyles ); + + TextStyle * t; + for ( t = m_textStyles.first(); t ; t = m_textStyles.next() ) + t->toXML( doc, autoStyles ); + + GraphicStyle * g; + g = m_graphicStyles.first(); // skip the "standard" style + for ( g = m_graphicStyles.next(); g ; g = m_graphicStyles.next() ) + g->toXML( doc, autoStyles ); + + ParagraphStyle * pg; + for ( pg = m_paragraphStyles.first(); pg ; pg = m_paragraphStyles.next() ) + pg->toXML( doc, autoStyles ); +} + +QString StyleFactory::createStrokeDashStyle( int style ) +{ + StrokeDashStyle * newStrokeDashStyle, * sd; + newStrokeDashStyle = new StrokeDashStyle( style ); + for ( sd = m_strokeDashStyles.first(); sd ; sd = m_strokeDashStyles.next() ) + { + if ( sd->name() == newStrokeDashStyle->name() ) + { + delete newStrokeDashStyle; + return sd->name(); + } + } + + m_strokeDashStyles.append( newStrokeDashStyle ); + return newStrokeDashStyle->name(); +} + +QString StyleFactory::createGradientStyle( QDomElement & gradient ) +{ + GradientStyle * newGradientStyle, * g; + newGradientStyle = new GradientStyle( gradient, m_gradientStyles.count() + 1 ); + for ( g = m_gradientStyles.first(); g ; g = m_gradientStyles.next() ) + { + if ( g->name() == newGradientStyle->name() ) + { + delete newGradientStyle; + return g->name(); + } + } + + m_gradientStyles.append( newGradientStyle ); + return newGradientStyle->name(); +} + +QString StyleFactory::createMarkerStyle( int style ) +{ + MarkerStyle * newMarkerStyle, * m; + newMarkerStyle = new MarkerStyle( style ); + for ( m = m_markerStyles.first(); m ; m = m_markerStyles.next() ) + { + if ( m->name() == newMarkerStyle->name() ) + { + delete newMarkerStyle; + return m->name(); + } + } + + m_markerStyles.append( newMarkerStyle ); + return newMarkerStyle->name(); +} + +QString StyleFactory::createHatchStyle( int style, QString & color ) +{ + HatchStyle * newHatchStyle, * h; + newHatchStyle = new HatchStyle( style, color ); + for ( h = m_hatchStyles.first(); h ; h = m_hatchStyles.next() ) + { + if ( h->name() == newHatchStyle->name() ) + { + delete newHatchStyle; + return h->name(); + } + } + + m_hatchStyles.append( newHatchStyle ); + return newHatchStyle->name(); +} + +QString StyleFactory::createListStyle( QDomElement & e ) +{ + ListStyle * newListStyle, * l; + newListStyle = new ListStyle( e, m_listStyles.count() + 1 ); + for ( l = m_listStyles.first(); l ; l = m_listStyles.next() ) + { + if ( *l == *newListStyle ) + { + delete newListStyle; + return l->name(); + } + } + + m_listStyles.append( newListStyle ); + return newListStyle->name(); +} + +QString StyleFactory::createPageStyle( QDomElement & e ) +{ + PageStyle * newPageStyle, * p; + newPageStyle = new PageStyle( this, e, m_pageStyles.count() + 1 ); + for ( p = m_pageStyles.first(); p ; p = m_pageStyles.next() ) + { + if ( *p == *newPageStyle ) + { + delete newPageStyle; + return p->name(); + } + } + + m_pageStyles.append( newPageStyle ); + return newPageStyle->name(); +} + +QString StyleFactory::createTextStyle( QDomElement & e ) +{ + TextStyle * newTextStyle, * t; + newTextStyle = new TextStyle( e, m_textStyles.count() + 1 ); + for ( t = m_textStyles.first(); t ; t = m_textStyles.next() ) + { + if ( *t == *newTextStyle ) + { + delete newTextStyle; + return t->name(); + } + } + + m_textStyles.append( newTextStyle ); + return newTextStyle->name(); +} + +QString StyleFactory::createGraphicStyle( QDomElement & e ) +{ + GraphicStyle * newGraphicStyle, * g; + newGraphicStyle = new GraphicStyle( this, e, m_graphicStyles.count() ); + for ( g = m_graphicStyles.first(); g ; g = m_graphicStyles.next() ) + { + if ( *g == *newGraphicStyle ) + { + delete newGraphicStyle; + return g->name(); + } + } + + m_graphicStyles.append( newGraphicStyle ); + return newGraphicStyle->name(); +} + +QString StyleFactory::createParagraphStyle( QDomElement & e ) +{ + ParagraphStyle * newParagraphStyle, * p; + newParagraphStyle = new ParagraphStyle( e, m_paragraphStyles.count() + 1 ); + for ( p = m_paragraphStyles.first(); p ; p = m_paragraphStyles.next() ) + { + if ( *p == *newParagraphStyle ) + { + delete newParagraphStyle; + return p->name(); + } + } + + m_paragraphStyles.append( newParagraphStyle ); + return newParagraphStyle->name(); +} + +QString StyleFactory::createPageMasterStyle( QDomElement & e ) +{ + PageMasterStyle * newPMStyle, * p; + newPMStyle = new PageMasterStyle( e, m_pageMasterStyles.count() ); + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + if ( *p == *newPMStyle ) + { + delete newPMStyle; + return p->style(); + } + } + + m_pageMasterStyles.append( newPMStyle ); + return newPMStyle->style(); +} + +QString StyleFactory::toCM( const QString & point ) +{ + double pt = point.toFloat(); + double cm = KoUnit::toCM( pt ); + return QString( "%1cm" ).arg ( cm ); +} + +StrokeDashStyle::StrokeDashStyle( int style ) +{ + switch ( style ) + { + case 2: + m_name = "Fine Dashed"; + m_style = "rect"; + m_dots1 = "1"; + m_dots1_length = "0.508cm"; + m_dots2 = "1"; + m_dots2_length = "0.508cm"; + m_distance = "0.508cm"; + break; + case 3: + m_name = "Fine Dotted"; + m_style = "rect"; + m_dots1 = "1"; + m_distance = "0.257cm"; + break; + case 4: + m_name = "Ultrafine 1 Dot 1 Dash"; + m_style = "rect"; + m_dots1 = "1"; + m_dots1_length = "0.051cm"; + m_dots2 = "1"; + m_dots2_length = "0.254cm"; + m_distance = "0.127cm"; + break; + case 5: + m_name = "2 Dots 1 Dash"; + m_style = "rect"; + m_dots1 = "2"; + m_dots2 = "1"; + m_dots2_length = "0.203cm"; + m_distance = "0.203cm"; + break; + } +} + +void StrokeDashStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement strokeDash = doc.createElement( "draw:stroke-dash" ); + strokeDash.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + strokeDash.setAttribute( "draw:style", m_style ); + if ( !m_dots1.isNull() ) + strokeDash.setAttribute( "draw:dots1", m_dots1 ); + if ( !m_dots1_length.isNull() ) + strokeDash.setAttribute( "draw:dots1-length", m_dots1_length ); + if ( !m_dots2.isNull() ) + strokeDash.setAttribute( "draw:dots2", m_dots2 ); + if ( !m_dots2_length.isNull() ) + strokeDash.setAttribute( "draw:dots2-length", m_dots2_length ); + if ( !m_distance.isNull() ) + strokeDash.setAttribute( "draw:distance", m_distance ); + + e.appendChild( strokeDash ); +} + +GradientStyle::GradientStyle( QDomElement & gradient, int index ) +{ + m_name = QString( "Gradient %1" ).arg( index ); + m_start_intensity = "100%"; + m_end_intensity = "100%"; + m_border = "0%"; + + int type = 1; + if ( gradient.nodeName() == "PAGE" ) + { + // gradient from page background + QDomElement backColor1 = gradient.namedItem( "BACKCOLOR1" ).toElement(); + QDomElement backColor2 = gradient.namedItem( "BACKCOLOR2" ).toElement(); + QDomElement bcType = gradient.namedItem( "BCTYPE" ).toElement(); + QDomElement bGradient = gradient.namedItem( "BGRADIENT" ).toElement(); + + if ( !backColor1.isNull() ) + m_start_color = backColor1.attribute( "color" ); + if ( !backColor2.isNull() ) + m_end_color = backColor2.attribute( "color" ); + if ( !bcType.isNull() ) + type = bcType.attribute( "value" ).toInt(); + if ( !bGradient.isNull() ) + { + if ( bGradient.attribute( "unbalanced" ) == "0" ) + { + m_cx = "50%"; + m_cy = "50%"; + } + else + { + int cx = bGradient.attribute( "xfactor" ).toInt(); + int cy = bGradient.attribute( "yfactor" ).toInt(); + m_cx = QString( "%1%" ).arg( cx / 4 + 50 ); + m_cy = QString( "%1%" ).arg( cy / 4 + 50 ); + } + } + + } + else + { + // gradient from object + if ( gradient.hasAttribute( "color1" ) ) + m_start_color = gradient.attribute( "color1" ); + if ( gradient.hasAttribute( "color2" ) ) + m_end_color = gradient.attribute( "color2" ); + if ( gradient.hasAttribute( "type" ) ) + type = gradient.attribute( "type" ).toInt(); + if ( gradient.hasAttribute( "unbalanced" ) ) + { + if ( gradient.attribute( "unbalanced" ) == "0" ) + { + m_cx = "50%"; + m_cy = "50%"; + } + else + { + int cx = gradient.attribute( "xfactor" ).toInt(); + int cy = gradient.attribute( "yfactor" ).toInt(); + m_cx = QString( "%1%" ).arg( cx / 4 + 50 ); + m_cy = QString( "%1%" ).arg( cy / 4 + 50 ); + } + } + + } + + switch ( type ) + { + case 1: + m_style = "linear"; + m_angle = "0"; + break; + case 2: + m_style = "linear"; + m_angle = "900"; + break; + case 3: + m_style = "linear"; + m_angle = "450"; + break; + case 4: + m_style = "linear"; + m_angle = "135"; + break; + case 5: + m_style = "radial"; + m_angle = "0"; + break; + case 6: + m_style = "square"; + m_angle = "0"; + break; + case 7: + m_style = "axial"; + m_angle = "0"; + break; + } +} + +void GradientStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement gradient = doc.createElement( "draw:gradient" ); + gradient.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + gradient.setAttribute( "draw:style", m_style ); + if ( !m_start_color.isNull() ) + gradient.setAttribute( "draw:start-color", m_start_color ); + if ( !m_end_color.isNull() ) + gradient.setAttribute( "draw:end-color", m_end_color ); + if ( !m_start_intensity.isNull() ) + gradient.setAttribute( "draw:start-intensity", m_start_intensity ); + if ( !m_end_intensity.isNull() ) + gradient.setAttribute( "draw:end-intensity", m_end_intensity ); + if ( !m_angle.isNull() ) + gradient.setAttribute( "draw:angle", m_angle ); + if ( !m_border.isNull() ) + gradient.setAttribute( "draw:border", m_border ); + if ( !m_cx.isNull() ) + gradient.setAttribute( "draw:cx", m_cx ); + if ( !m_cy.isNull() ) + gradient.setAttribute( "draw:cy", m_cy ); + + e.appendChild( gradient ); +} + +MarkerStyle::MarkerStyle( int style ) +{ + // Markers are not working because OOImpress depends on the sequence + // of the attributes in the draw:marker tag. svg:ViewBox has to be in + // front of svg:d in order to work. + + switch ( style ) + { + case 1: + m_name = "Arrow"; + m_viewBox = "0 0 20 30"; + m_d = "m10 0-10 30h20z"; + break; + case 2: + m_name = "Square"; + m_viewBox = "0 0 10 10"; + m_d = "m0 0h10v10h-10z"; + break; + case 3: + m_name = "Circle"; + m_viewBox = "0 0 1131 1131"; + m_d = "m462 1118-102-29-102-51-93-72-72-93-51-102-29-102-13-105 13-102 29-106 51-102 72-89 93-72 102-50 102-34 106-9 101 9 106 34 98 50 93 72 72 89 51 102 29 106 13 102-13 105-29 102-51 102-72 93-93 72-98 51-106 29-101 13z"; + break; + case 4: + m_name = "Line Arrow"; + m_viewBox = "0 0 1122 2243"; + m_d = "m0 2108v17 17l12 42 30 34 38 21 43 4 29-8 30-21 25-26 13-34 343-1532 339 1520 13 42 29 34 39 21 42 4 42-12 34-30 21-42v-39-12l-4 4-440-1998-9-42-25-39-38-25-43-8-42 8-38 25-26 39-8 42z"; + break; + case 5: + m_name = "Dimension Lines"; + m_viewBox = "0 0 836 110"; + m_d = "m0 0h278 278 280v36 36 38h-278-278-280v-36-36z"; + break; + case 6: + case 7: + m_name = "Double Arrow"; + m_viewBox = "0 0 1131 1918"; + m_d = "m737 1131h394l-564-1131-567 1131h398l-398 787h1131z"; + break; + } +} + +void MarkerStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement marker = doc.createElement( "draw:marker" ); + marker.setAttribute( "draw:name", m_name ); + if ( !m_viewBox.isNull() ) + marker.setAttribute( "svg:viewBox", m_viewBox ); + if ( !m_d.isNull() ) + marker.setAttribute( "svg:d", m_d ); + + e.appendChild( marker ); +} + +HatchStyle::HatchStyle( int style, QString & color ) +{ + m_color = color; + + switch ( style ) + { + case 9: + m_name = m_color + " 0 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "0"; + break; + case 10: + m_name = m_color + " 90 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "900"; + break; + case 11: + m_name = m_color + " Crossed 0 Degrees"; + m_style = "double"; + m_distance = "0.076cm"; + m_rotation = "900"; + break; + case 12: + m_name = m_color + " 45 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "450"; + break; + case 13: + m_name = m_color + " -45 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "3150"; + break; + case 14: + m_name = m_color + " Crossed 45 Degrees"; + m_style = "double"; + m_distance = "0.076cm"; + m_rotation = "450"; + break; + } +} + +void HatchStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement hatch = doc.createElement( "draw:hatch" ); + hatch.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + hatch.setAttribute( "draw:style", m_style ); + if ( !m_color.isNull() ) + hatch.setAttribute( "draw:color", m_color ); + if ( !m_distance.isNull() ) + hatch.setAttribute( "draw:distance", m_distance ); + if ( !m_rotation.isNull() ) + hatch.setAttribute( "draw:rotation", m_rotation ); + + e.appendChild( hatch ); +} + +FillImageStyle::FillImageStyle( QString & name ) +{ + +} + +void FillImageStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + +} + +PageMasterStyle::PageMasterStyle( QDomElement & e, const uint index ) +{ + QDomNode borders = e.namedItem( "PAPERBORDERS" ); + QDomElement b = borders.toElement(); + + m_name = QString( "PM%1" ).arg( index ); + m_style = QString( "Default%1" ).arg( index ); + m_margin_top = StyleFactory::toCM( b.attribute( "ptTop" ) ); + m_margin_bottom = StyleFactory::toCM( b.attribute( "ptBottom" ) ); + m_margin_left = StyleFactory::toCM( b.attribute( "ptLeft" ) ); + m_margin_right = StyleFactory::toCM( b.attribute( "ptRight" ) ); + m_page_width = StyleFactory::toCM( e.attribute( "ptWidth" ) ); + m_page_height = StyleFactory::toCM( e.attribute( "ptHeight" ) ); + m_orientation = "landscape"; +} + +void PageMasterStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:page-master" ); + style.setAttribute( "style:name", "PM0" ); + + QDomElement properties = doc.createElement( "style:properties" ); + properties.setAttribute( "fo:margin-top", m_margin_top ); + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + properties.setAttribute( "fo:margin-left", m_margin_left ); + properties.setAttribute( "fo:margin-right", m_margin_right ); + properties.setAttribute( "fo:page-width", m_page_width ); + properties.setAttribute( "fo:page-height", m_page_height ); + properties.setAttribute( "fo:print-orientation", m_orientation ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool PageMasterStyle::operator==( const PageMasterStyle & pageMasterStyle ) const +{ + return ( m_margin_top == pageMasterStyle.m_margin_top && + m_margin_bottom == pageMasterStyle.m_margin_bottom && + m_margin_left == pageMasterStyle.m_margin_left && + m_margin_right == pageMasterStyle.m_margin_right && + m_page_width == pageMasterStyle.m_page_width && + m_page_height == pageMasterStyle.m_page_height && + m_orientation == pageMasterStyle.m_orientation ); +} + +PageStyle::PageStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ) +{ + QDomElement backMaster = e.namedItem( "BACKMASTER" ).toElement(); + if( !backMaster.isNull()) + { + int tmp=0; + if(backMaster.hasAttribute("displayBackground")) + tmp = backMaster.attribute("displayBackground").toInt(); + m_bg_visible = (tmp==1) ? "true" : "false"; + tmp = 0; + if(backMaster.hasAttribute("displayMasterPageObject")) + tmp = backMaster.attribute("displayMasterPageObject").toInt(); + m_bg_objects_visible = (tmp==1) ? "true" : "false"; + } + else + { + m_bg_visible = "true"; + m_bg_objects_visible = "true"; + } + + m_name = QString( "dp%1" ).arg( index ); + + // check if this is an empty page tag + if ( !e.hasChildNodes() ) + return; + + QDomElement backType = e.namedItem( "BACKTYPE" ).toElement(); + if ( backType.isNull() || backType.attribute( "value" ) == "0" ) + { + // color + QDomElement bcType = e.namedItem( "BCTYPE" ).toElement(); + if ( bcType.isNull() || bcType.attribute( "value" ) == "0" ) + { + // plain + QDomElement backColor = e.namedItem( "BACKCOLOR1" ).toElement(); + m_fill = "solid"; + m_fill_color = backColor.attribute( "color" ); + } + else + { + // gradient + m_fill = "gradient"; + m_fill_gradient_name = styleFactory->createGradientStyle( e ); + } + } + else + { + // picture + } + + QDomElement pageDuration = e.namedItem( "PGTIMER" ).toElement(); + if ( !pageDuration.isNull() ) + { + + QTime time; + time = time.addSecs( pageDuration.attribute("timer").toInt() ); + QString hours( QString::number( time.hour() ).rightJustify( 2, '0' ) ); + QString ms( QString::number( time.minute() ).rightJustify( 2, '0' ) ); + QString sec( QString::number( time.second() ).rightJustify( 2, '0' ) ); + + + //ISO8601 chapter 5.5.3.2 + //QDate doesn't encode it as this format. + m_page_duration = QString( "PT%1H%2M%3S" ).arg( hours ).arg( ms ).arg( sec ); + } + + QDomElement pageEffect = e.namedItem( "PGEFFECT" ).toElement(); + if ( !pageEffect.isNull() ) + { + int tmp=0; + if(pageEffect.hasAttribute("value")) + tmp=pageEffect.attribute("value").toInt(); + kdDebug(30518)<<" tmp :"<<tmp<<endl; + switch( tmp ) + { + case -1: + m_page_effect = "random"; + break; + case 1: + m_page_effect = "close-vertical"; + break; + case 2: + m_page_effect = "close-horizontal"; + break; + case 3: + m_page_effect = "fade-to-center"; + break; + case 4: + m_page_effect = "open-vertical"; + break; + case 5: + m_page_effect = "open-horizontal"; + break; + case 6: + m_page_effect = "fade-from-center"; + break; + case 7: + case 8: + case 9: + case 10: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 11: + m_page_effect = "spiralin-left"; + break; + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 19: + m_page_effect = "fade-from-top"; + break; + case 20: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 21: + m_page_effect = "fade-from-bottom"; + break; + case 22: + m_page_effect = "roll-from-bottom"; + break; + case 23: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 24: + m_page_effect = "roll-from-right"; + break; + case 25: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 26: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 27: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 28: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 29: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 30: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 31: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 32: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 33: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 34: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + case 35: + m_page_effect = "dissolve"; + break; + case 36: + m_page_effect = "fade-from-lowerright"; + break; + case 37: + m_page_effect = "fade-from-upperright"; + break; + case 38: + m_page_effect = "fade-from-lowerleft"; + break; + case 39: + m_page_effect = "fade-from-upperleft"; + break; + case 40: + kdDebug(30518)<<" this style is not defined :"<<tmp<<endl; + break; + default: + kdDebug(30518)<<" style page effect not define : "<<tmp<<endl; + break; + } + } +} + +void PageStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "drawing-page" ); + + QDomElement properties = doc.createElement( "style:properties" ); + properties.setAttribute( "presentation:background-visible", m_bg_visible ); + properties.setAttribute( "presentation:background-objects-visible", + m_bg_objects_visible ); + if ( !m_page_duration.isEmpty() ) + { + properties.setAttribute( "presentation:duration", m_page_duration ); + properties.setAttribute( "presentation:transition-type", "automatic" ); + } + if ( !m_page_effect.isEmpty() ) + properties.setAttribute( "presentation:transition-style", + m_page_effect ); + if ( !m_fill.isNull() ) + properties.setAttribute( "draw:fill", m_fill ); + if ( !m_fill_color.isNull() ) + properties.setAttribute( "draw:fill-color", m_fill_color ); + if ( !m_fill_image_name.isNull() ) + properties.setAttribute( "draw:fill-image-name", m_fill_image_name ); + if ( !m_fill_image_width.isNull() ) + properties.setAttribute( "draw:fill-image-width", m_fill_image_width ); + if ( !m_fill_image_height.isNull() ) + properties.setAttribute( "draw:fill-image-height", m_fill_image_height ); + if ( !m_fill_image_ref_point.isNull() ) + properties.setAttribute( "draw:fill-image-ref-point", m_fill_image_ref_point ); + if ( !m_fill_gradient_name.isNull() ) + properties.setAttribute( "draw:fill-gradient-name", m_fill_gradient_name ); + if ( !m_repeat.isNull() ) + properties.setAttribute( "style:repeat", m_repeat ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool PageStyle::operator==( const PageStyle & pageStyle ) const +{ + return ( m_bg_visible == pageStyle.m_bg_visible && + m_bg_objects_visible == pageStyle.m_bg_objects_visible && + m_fill == pageStyle.m_fill && + m_fill_color == pageStyle.m_fill_color && + m_fill_image_name == pageStyle.m_fill_image_name && + m_fill_image_width == pageStyle.m_fill_image_width && + m_fill_image_height == pageStyle.m_fill_image_height && + m_fill_image_ref_point == pageStyle.m_fill_image_ref_point && + m_fill_gradient_name == pageStyle.m_fill_gradient_name && + m_repeat == pageStyle.m_repeat && + m_page_effect == pageStyle.m_page_effect && + m_page_duration == pageStyle.m_page_duration ); +} + +TextStyle::TextStyle( QDomElement & e, const uint index ) +{ + m_name = QString( "T%1" ).arg( index ); + if ( e.hasAttribute( "family" ) ) + m_font_family = e.attribute( "family" ); + if ( e.hasAttribute( "pointSize" ) ) + m_font_size = QString( "%1pt" ).arg( e.attribute( "pointSize" ) ); + if ( e.hasAttribute( "color" ) ) + m_color = e.attribute( "color" ); + if ( e.hasAttribute( "bold" ) && e.attribute( "bold" ) == "1" ) + m_font_weight = "bold"; + if ( e.hasAttribute( "italic" ) && e.attribute( "italic" ) == "1" ) + m_font_style = "italic"; + if ( e.hasAttribute( "strikeOut" ) ) + { + if ( e.attribute( "strikeOut" ) == "single" ) + m_text_crossing_out = "single-line"; + else if ( e.attribute( "strikeOut" ) == "single-bold" ) + m_text_crossing_out = "thick-line"; + else if ( e.attribute( "strikeOut" ) == "double" ) + m_text_crossing_out = "double-line"; + } + if ( e.hasAttribute( "underline" ) ) + { + QString underline = e.attribute( "underline" ); + QString style = e.attribute( "underlinestyleline" ); + m_text_underline_color = e.attribute( "underlinecolor" ); + + if ( style == "solid" ) + { + if ( underline == "1" ) + m_text_underline = "single"; + else if ( underline == "single-bold" ) + m_text_underline = "bold"; + else if ( underline == "double" ) + m_text_underline = "double"; + else if ( underline == "wave" ) + m_text_underline = "wave"; + } + else if ( style == "dot" ) + { + if ( underline == "1" ) + m_text_underline = "dotted"; + else if ( underline == "single-bold" ) + m_text_underline = "bold-dotted"; + } + else if ( style == "dash" ) + m_text_underline = "dash"; + } +} + +void TextStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "text" ); + + QDomElement properties = doc.createElement( "style:properties" ); + if ( !m_font_size.isNull() ) + properties.setAttribute( "fo:font-size", m_font_size ); + if ( !m_font_family.isNull() ) + properties.setAttribute( "fo:font-family", m_font_family ); + if ( !m_font_family_generic.isNull() ) + properties.setAttribute( "fo:font-family-generic", m_font_family_generic ); + if ( !m_color.isNull() ) + properties.setAttribute( "fo:color", m_color ); + if ( !m_font_pitch.isNull() ) + properties.setAttribute( "style:font-pitch", m_font_pitch ); + if ( !m_font_style.isNull() ) + properties.setAttribute( "fo:font-style", m_font_style ); + if ( !m_font_weight.isNull() ) + properties.setAttribute( "fo:font-weight", m_font_weight ); + if ( !m_text_shadow.isNull() ) + properties.setAttribute( "fo:text-shadow", m_text_shadow ); + if ( !m_text_underline.isNull() ) + properties.setAttribute( "style:text-underline", m_text_underline ); + if ( !m_text_underline_color.isNull() ) + properties.setAttribute( "style:text-underline-color", m_text_underline_color ); + if ( !m_text_crossing_out.isNull() ) + properties.setAttribute( "style:text-crossing-out", m_text_crossing_out ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool TextStyle::operator==( const TextStyle & textStyle ) const +{ + return ( m_font_size == textStyle.m_font_size && + m_font_family == textStyle.m_font_family && + m_font_family_generic == textStyle.m_font_family_generic && + m_color == textStyle.m_color && + m_font_pitch == textStyle.m_font_pitch && + m_font_style == textStyle.m_font_style && + m_font_weight == textStyle.m_font_weight && + m_text_shadow == textStyle.m_text_shadow && + m_text_underline == textStyle.m_text_underline && + m_text_underline_color == textStyle.m_text_underline_color && + m_text_crossing_out == textStyle.m_text_crossing_out ); +} + +GraphicStyle::GraphicStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ) +{ + QDomNode pen = e.namedItem( "PEN" ); + QDomNode brush = e.namedItem( "BRUSH" ); + QDomNode linebegin = e.namedItem( "LINEBEGIN" ); + QDomNode lineend = e.namedItem( "LINEEND" ); + QDomNode gradient = e.namedItem( "GRADIENT" ); + QDomNode shadow = e.namedItem( "SHADOW" ); + QDomNode textObject = e.namedItem( "TEXTOBJ" ); + if ( !textObject.isNull() ) + { + QDomElement textObjectElement = textObject.toElement(); + if ( textObjectElement.hasAttribute( "verticalAlign" ) ) + { + m_textAlignment = textObjectElement.attribute("verticalAlign"); + if ( m_textAlignment == "center" ) + m_textAlignment = "middle"; + } + if ( textObjectElement.hasAttribute( "bleftpt" ) ) + { + m_textMarginLeft = QString( "%1pt" ).arg( textObjectElement.attribute( "bleftpt" ) ); + } + if ( textObjectElement.hasAttribute( "bbottompt" ) ) + { + m_textMarginBottom = QString( "%1pt" ).arg( textObjectElement.attribute( "bbottompt" ) ); + } + if ( textObjectElement.hasAttribute( "btoppt" ) ) + { + m_textMarginTop = QString( "%1pt" ).arg( textObjectElement.attribute( "btoppt" ) ); + } + if ( textObjectElement.hasAttribute( "brightpt" ) ) + { + m_textMarginRight = QString( "%1pt" ).arg( textObjectElement.attribute( "brightpt" ) ); + } + + } + kdDebug(30518)<<" alignment :"<<m_textAlignment<<endl; + + m_name = QString( "gr%1" ).arg( index ); + if ( !pen.isNull() ) + { + QDomElement p = pen.toElement(); + m_stroke_width = StyleFactory::toCM( p.attribute( "width" ) ); + m_stroke_color = p.attribute( "color" ); + + int style = p.attribute( "style" ).toInt(); + if ( style == 1 ) + m_stroke = "solid"; + else if ( style >= 2 && style <= 5 ) + { + m_stroke = "dash"; + m_stroke_dash = styleFactory->createStrokeDashStyle( style ); + } + else + m_stroke = "none"; + } + + if ( !brush.isNull() ) + { + QDomElement b = brush.toElement(); + m_fill_color = b.attribute( "color" ); + + int style = b.attribute( "style" ).toInt(); + if ( style == 1 ) + m_fill = "solid"; + else if ( style >= 9 && style <= 14 ) + { + m_fill = "hatch"; + m_fill_hatch_name = styleFactory->createHatchStyle( style, m_fill_color ); + } + else if ( style >= 2 && style <= 8 ) + { + if ( style == 2 ) + m_transparency = "94%"; + else if ( style == 3 ) + m_transparency = "88%"; + else if ( style == 4 ) + m_transparency = "63%"; + else if ( style == 5 ) + m_transparency = "50%"; + else if ( style == 6 ) + m_transparency = "37%"; + else if ( style == 7 ) + m_transparency = "12%"; + else if ( style == 8 ) + m_transparency = "6%"; + } + } + else if ( !gradient.isNull() ) + { + QDomElement g = gradient.toElement(); + m_fill = "gradient"; + m_fill_gradient_name = styleFactory->createGradientStyle( g ); + } + else + m_fill = "none"; + + if ( !linebegin.isNull() ) + { + QDomElement lb = linebegin.toElement(); + m_marker_start_width = "0.25cm"; + + int style = lb.attribute( "value" ).toInt(); + m_marker_start = styleFactory->createMarkerStyle( style ); + } + + if ( !lineend.isNull() ) + { + QDomElement le = lineend.toElement(); + m_marker_end_width = "0.25cm"; + + int style = le.attribute( "value" ).toInt(); + m_marker_end = styleFactory->createMarkerStyle( style ); + } + + if ( !shadow.isNull() ) + { + QDomElement s = shadow.toElement(); + m_shadow = "visible"; + m_shadow_color = s.attribute( "color" ); + + int direction = s.attribute( "direction" ).toInt(); + QString distance = StyleFactory::toCM( s.attribute( "distance" ) ); + switch ( direction ) + { + case 1: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = "-" + distance; + break; + case 2: + m_shadow_offset_x = "0cm"; + m_shadow_offset_y = "-" + distance; + break; + case 3: + m_shadow_offset_x = distance; + m_shadow_offset_y = "-" + distance; + break; + case 4: + m_shadow_offset_x = distance; + m_shadow_offset_y = "0cm"; + break; + case 5: + m_shadow_offset_x = distance; + m_shadow_offset_y = distance; + break; + case 6: + m_shadow_offset_x = "0cm"; + m_shadow_offset_y = distance; + break; + case 7: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = distance; + break; + case 8: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = "0cm"; + break; + } + } +} + +GraphicStyle::GraphicStyle( const char * name, + const char * stroke, const char * stroke_color, + const char * stroke_width, const char * shadow, + const char * shadow_offset_x, const char * shadow_offset_y, + const char * shadow_color, const char * margin_left, + const char * margin_right, const char * margin_top, + const char * margin_bottom, const char * color, + const char * text_outline, const char * text_crossing_out, + const char * font_family, const char * font_size, + const char * font_style, const char * text_shadow, + const char * text_underline, const char * font_weight, + const char * line_height, const char * text_align, + const char * fill, const char * fill_color, + const char * enable_numbering ) + : m_name( name ) + , m_stroke( stroke ) + , m_stroke_color( stroke_color ) + , m_stroke_width( stroke_width ) + , m_shadow( shadow ) + , m_shadow_offset_x( shadow_offset_x ) + , m_shadow_offset_y( shadow_offset_y ) + , m_shadow_color( shadow_color ) + , m_margin_left( margin_left ) + , m_margin_right( margin_right ) + , m_margin_top( margin_top ) + , m_margin_bottom( margin_bottom ) + , m_color( color ) + , m_text_outline( text_outline ) + , m_text_crossing_out( text_crossing_out ) + , m_font_family( font_family ) + , m_font_size( font_size ) + , m_font_style( font_style ) + , m_text_shadow( text_shadow ) + , m_text_underline( text_underline ) + , m_font_weight( font_weight ) + , m_line_height( line_height ) + , m_text_align( text_align ) + , m_fill( fill ) + , m_fill_color( fill_color ) + , m_enable_numbering( enable_numbering ) +{ +} + + +void GraphicStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "graphics" ); + if ( m_name != "standard" ) + style.setAttribute( "style:parent-style-name", "standard" ); + + QDomElement properties = doc.createElement( "style:properties" ); + if ( !m_stroke.isNull() ) + properties.setAttribute( "draw:stroke", m_stroke ); + if ( !m_stroke_dash.isNull() ) + properties.setAttribute( "draw:stroke-dash", m_stroke_dash ); + if ( !m_stroke_color.isNull() ) + properties.setAttribute( "svg:stroke-color", m_stroke_color ); + if ( !m_stroke_width.isNull() ) + properties.setAttribute( "svg:stroke-width", m_stroke_width ); + if ( !m_shadow.isNull() ) + properties.setAttribute( "draw:shadow", m_shadow ); + if ( !m_shadow_offset_x.isNull() ) + properties.setAttribute( "draw:shadow-offset-x", m_shadow_offset_x ); + if ( !m_shadow_offset_y.isNull() ) + properties.setAttribute( "draw:shadow-offset-y", m_shadow_offset_y ); + if ( !m_shadow_color.isNull() ) + properties.setAttribute( "draw:shadow-color", m_shadow_color ); + if ( !m_margin_left.isNull() ) + properties.setAttribute( "fo:margin-left", m_margin_left ); + if ( !m_margin_right.isNull() ) + properties.setAttribute( "fo:margin-right", m_margin_right ); + if ( !m_margin_top.isNull() ) + properties.setAttribute( "fo:margin-top", m_margin_top ); + if ( !m_margin_bottom.isNull() ) + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + if ( !m_color.isNull() ) + properties.setAttribute( "fo:color", m_color ); + if ( !m_text_outline.isNull() ) + properties.setAttribute( "style:text-outline", m_text_outline ); + if ( !m_text_crossing_out.isNull() ) + properties.setAttribute( "style:text-crossing-out", m_text_crossing_out ); + if ( !m_font_family.isNull() ) + properties.setAttribute( "fo:font-family", m_font_family ); + if ( !m_font_size.isNull() ) + properties.setAttribute( "fo:font-size", m_font_size ); + if ( !m_font_style.isNull() ) + properties.setAttribute( "fo:font-style", m_font_style ); + if ( !m_text_shadow.isNull() ) + properties.setAttribute( "fo:text-shadow", m_text_shadow ); + if ( !m_text_underline.isNull() ) + properties.setAttribute( "style:text-underline", m_text_underline ); + if ( !m_font_weight.isNull() ) + properties.setAttribute( "fo:font-weight", m_font_weight ); + if ( !m_line_height.isNull() ) + properties.setAttribute( "fo:line-height", m_line_height ); + if ( !m_text_align.isNull() ) + properties.setAttribute( "fo:text-align", m_text_align ); + if ( !m_fill.isNull() ) + properties.setAttribute( "draw:fill", m_fill ); + if ( !m_fill_color.isNull() ) + properties.setAttribute( "draw:fill-color", m_fill_color ); + if ( !m_fill_hatch_name.isNull() ) + properties.setAttribute( "draw:fill-hatch-name", m_fill_hatch_name ); + if ( !m_enable_numbering.isNull() ) + properties.setAttribute( "text:enable-numbering", m_enable_numbering ); + if ( !m_marker_start.isNull() ) + properties.setAttribute( "draw:marker-start", m_marker_start ); + if ( !m_marker_start_width.isNull() ) + properties.setAttribute( "draw:marker-start-width", m_marker_start_width ); + if ( !m_marker_end.isNull() ) + properties.setAttribute( "draw:marker-end", m_marker_end ); + if ( !m_marker_end_width.isNull() ) + properties.setAttribute( "draw:marker-end-width", m_marker_end_width ); + if ( !m_fill_gradient_name.isNull() ) + properties.setAttribute( "draw:fill-gradient-name", m_fill_gradient_name ); + if ( !m_transparency.isNull() ) + properties.setAttribute( "draw:transparency", m_transparency ); + if ( !m_textAlignment.isNull() ) + properties.setAttribute( "draw:textarea-vertical-align", m_textAlignment ); + if ( !m_textMarginLeft.isNull() ) + properties.setAttribute( "fo:padding-left", m_textMarginLeft ); + if ( !m_textMarginBottom.isNull() ) + properties.setAttribute( "fo:padding-bottom", m_textMarginBottom ); + if ( !m_textMarginTop.isNull() ) + properties.setAttribute( "fo:padding-top", m_textMarginTop ); + if ( !m_textMarginRight.isNull() ) + properties.setAttribute( "fo:padding-right", m_textMarginRight ); + + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool GraphicStyle::operator==( const GraphicStyle & graphicStyle ) const +{ + return ( m_stroke == graphicStyle.m_stroke && + m_stroke_dash == graphicStyle.m_stroke_dash && + m_stroke_color == graphicStyle.m_stroke_color && + m_stroke_width == graphicStyle.m_stroke_width && + m_shadow == graphicStyle.m_shadow && + m_shadow_offset_x == graphicStyle.m_shadow_offset_x && + m_shadow_offset_y == graphicStyle.m_shadow_offset_y && + m_shadow_color == graphicStyle.m_shadow_color && + m_margin_left == graphicStyle.m_margin_left && + m_margin_right == graphicStyle.m_margin_right && + m_margin_top == graphicStyle.m_margin_top && + m_margin_bottom == graphicStyle.m_margin_bottom && + m_color == graphicStyle.m_color && + m_text_outline == graphicStyle.m_text_outline && + m_text_crossing_out == graphicStyle.m_text_crossing_out && + m_font_family == graphicStyle.m_font_family && + m_font_size == graphicStyle.m_font_size && + m_font_style == graphicStyle.m_font_style && + m_text_shadow == graphicStyle.m_text_shadow && + m_text_underline == graphicStyle.m_text_underline && + m_font_weight == graphicStyle.m_font_weight && + m_line_height == graphicStyle.m_line_height && + m_text_align == graphicStyle.m_text_align && + m_fill == graphicStyle.m_fill && + m_fill_color == graphicStyle.m_fill_color && + m_fill_hatch_name == graphicStyle.m_fill_hatch_name && + m_enable_numbering == graphicStyle.m_enable_numbering && + m_marker_start == graphicStyle.m_marker_start && + m_marker_start_width == graphicStyle.m_marker_start_width && + m_marker_end == graphicStyle.m_marker_end && + m_marker_end_width == graphicStyle.m_marker_end_width && + m_fill_gradient_name == graphicStyle.m_fill_gradient_name && + m_transparency == graphicStyle.m_transparency && + m_textAlignment == graphicStyle.m_textAlignment && + m_textMarginLeft == graphicStyle.m_textMarginLeft && + m_textMarginBottom == graphicStyle.m_textMarginBottom && + m_textMarginTop == graphicStyle.m_textMarginTop && + m_textMarginRight == graphicStyle.m_textMarginRight); +} + +ParagraphStyle::ParagraphStyle( QDomElement & e, const uint index ) +{ + // some defaults that may be overwritten + m_margin_left = "0cm"; + m_margin_right = "0cm"; + m_text_indent = "0cm"; + + QDomNode shadow = e.namedItem( "SHADOW" ); + QDomNode indents = e.namedItem( "INDENTS" ); + QDomNode offsets = e.namedItem( "OFFSETS" ); + QDomNode leftBorder = e.namedItem( "LEFTBORDER" ); + QDomNode rightBorder = e.namedItem( "RIGHTBORDER" ); + QDomNode topBorder = e.namedItem( "TOPBORDER" ); + QDomNode bottomBorder = e.namedItem( "BOTTOMBORDER" ); + QDomNode lineSpacing = e.namedItem( "LINESPACING" ); + QDomNode counter = e.namedItem( "COUNTER" ); + + m_name = QString( "P%1" ).arg( index ); + if ( e.hasAttribute( "align" ) ) + { + int align = e.attribute( "align" ).toInt(); + switch ( align ) + { + case 0: // left + m_text_align = "start"; + break; + case 2: // right + m_text_align = "end"; + break; + case 4: // center + m_text_align = "center"; + break; + case 8: // justify + m_text_align = "justify"; + break; + } + } + + if ( !shadow.isNull() ) + { + QDomElement s = shadow.toElement(); + QString distance = QString( "%1pt" ).arg( s.attribute( "distance" ) ); + m_text_shadow = distance + " " + distance; + } + + if ( !indents.isNull() ) + { + QDomElement i = indents.toElement(); + m_margin_left = StyleFactory::toCM( i.attribute( "left" ) ); + m_margin_right = StyleFactory::toCM( i.attribute( "right" ) ); + m_text_indent = StyleFactory::toCM( i.attribute( "first" ) ); + } + + if ( !offsets.isNull() ) + { + QDomElement o = offsets.toElement(); + m_margin_top = StyleFactory::toCM( o.attribute( "before" ) ); + m_margin_bottom = StyleFactory::toCM( o.attribute( "after" ) ); + } + + if ( !leftBorder.isNull() ) + m_border_left = parseBorder( leftBorder.toElement() ); + if ( !rightBorder.isNull() ) + m_border_right = parseBorder( rightBorder.toElement() ); + if ( !topBorder.isNull() ) + m_border_top = parseBorder( topBorder.toElement() ); + if ( !bottomBorder.isNull() ) + m_border_bottom = parseBorder( bottomBorder.toElement() ); + + if ( !lineSpacing.isNull() ) + { + QDomElement l = lineSpacing.toElement(); + QString type = l.attribute( "type" ); + + if ( type == "single" ) + m_line_height = "100%"; + else if ( type == "oneandhalf" ) + m_line_height = "150%"; + else if ( type == "double" ) + m_line_height = "200%"; + else if ( type == "multiple" ) + m_line_height = QString( "%1%" ).arg( l.attribute( "spacingvalue" ).toInt() * 100 ); + else if ( type == "custom" ) + m_line_spacing = StyleFactory::toCM( l.attribute( "spacingvalue" ) ); + else if ( type == "atleast" ) + m_line_height_at_least = StyleFactory::toCM( l.attribute( "spacingvalue" ) ); + } + + if ( !counter.isNull() ) + m_enable_numbering = "true"; +} + +void ParagraphStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "paragraph" ); + + QDomElement properties = doc.createElement( "style:properties" ); + if ( !m_margin_left.isNull() ) + properties.setAttribute( "fo:margin-left", m_margin_left ); + if ( !m_margin_right.isNull() ) + properties.setAttribute( "fo:margin-right", m_margin_right ); + if ( !m_text_indent.isNull() ) + properties.setAttribute( "fo:text-indent", m_text_indent ); + if ( !m_text_align.isNull() ) + properties.setAttribute( "fo:text-align", m_text_align ); + if ( !m_enable_numbering.isNull() ) + properties.setAttribute( "text:enable-numbering", m_enable_numbering ); + if ( !m_text_shadow.isNull() ) + properties.setAttribute( "fo:text-shadow", m_text_shadow ); + if ( !m_margin_top.isNull() ) + properties.setAttribute( "fo:margin-top", m_margin_top ); + if ( !m_margin_bottom.isNull() ) + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + if ( !m_border_left.isNull() ) + properties.setAttribute( "fo:border-left", m_border_left ); + if ( !m_border_right.isNull() ) + properties.setAttribute( "fo:border-right", m_border_right ); + if ( !m_border_top.isNull() ) + properties.setAttribute( "fo:border-top", m_border_top ); + if ( !m_border_bottom.isNull() ) + properties.setAttribute( "fo:border-bottom", m_border_bottom ); + if ( !m_line_height.isNull() ) + properties.setAttribute( "fo:line-height", m_line_height ); + if ( !m_line_height_at_least.isNull() ) + properties.setAttribute( "style:line-height-at-least", m_line_height_at_least ); + if ( !m_line_spacing.isNull() ) + properties.setAttribute( "style:line-spacing", m_line_spacing ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool ParagraphStyle::operator==( const ParagraphStyle & paragraphStyle ) const +{ + return ( m_margin_left == paragraphStyle.m_margin_left && + m_margin_right == paragraphStyle.m_margin_right && + m_text_indent == paragraphStyle.m_text_indent && + m_text_align == paragraphStyle.m_text_align && + m_enable_numbering == paragraphStyle.m_enable_numbering && + m_text_shadow == paragraphStyle.m_text_shadow && + m_margin_top == paragraphStyle.m_margin_top && + m_margin_bottom == paragraphStyle.m_margin_bottom && + m_border_left == paragraphStyle.m_border_left && + m_border_right == paragraphStyle.m_border_right && + m_border_top == paragraphStyle.m_border_top && + m_border_bottom == paragraphStyle.m_border_bottom && + m_line_height == paragraphStyle.m_line_height && + m_line_height_at_least == paragraphStyle.m_line_height_at_least && + m_line_spacing == paragraphStyle.m_line_spacing ); +} + +QString ParagraphStyle::parseBorder( QDomElement e ) +{ + QString style; + int _style = e.attribute( "style" ).toInt(); + if ( _style == 5 ) + style = "double"; + else + style = "solid"; + + QString width = StyleFactory::toCM( e.attribute( "width" ) ); + + QColor color( e.attribute( "red" ).toInt(), + e.attribute( "green" ).toInt(), + e.attribute( "blue" ).toInt() ); + + return QString( "%1 %2 %3" ).arg( width ).arg( style ).arg( color.name() ); +} + +ListStyle::ListStyle( QDomElement & e, const uint index ) +{ + // setting some default values + m_min_label_width = 0.6; + m_color = "#000000"; + m_font_size = "100%"; + + m_name = QString( "L%1" ).arg( index ); + + if ( e.hasAttribute( "type" ) ) + { + int type = e.attribute( "type" ).toInt(); + switch ( type ) + { + case 1: // arabic numbers + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "1"; + break; + case 2: // lower alphabetical + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "a"; + break; + case 3: // upper alphabetical + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "A"; + break; + case 4: // lower roman + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "i"; + break; + case 5: // upper roman + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "I"; + break; + case 6: // custom + m_listLevelStyle = LLS_BULLET; + if ( e.hasAttribute( "text" ) ) + m_bullet_char = e.attribute( "text" ); + break; + case 8: // circle bullet + m_listLevelStyle = LLS_BULLET; + break; + case 9: // square bullet + m_listLevelStyle = LLS_BULLET; + break; + case 10: // disc bullet + m_listLevelStyle = LLS_BULLET; + break; + case 11: // box bullet + m_listLevelStyle = LLS_BULLET; + break; + } + } + + if ( e.hasAttribute( "bulletfont" ) ) + m_font_family = e.attribute( "bulletfont" ); +} + +void ListStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "text:list-style" ); + style.setAttribute( "style:name", m_name ); + + for ( int level = 1; level <= 10; level++ ) + { + QDomElement listLevelStyle; + if ( m_listLevelStyle == LLS_NUMBER ) + { + listLevelStyle = doc.createElement( "text:list-level-style-number" ); + listLevelStyle.setAttribute( "text:level", level ); + if ( !m_num_suffix.isNull() ) + listLevelStyle.setAttribute( "style:num-suffix", m_num_suffix ); + if ( !m_num_format.isNull() ) + listLevelStyle.setAttribute( "style:num-format", m_num_format ); + } + else + { + listLevelStyle = doc.createElement( "text:list-level-style-bullet" ); + listLevelStyle.setAttribute( "text:level", level ); + if ( !m_bullet_char.isNull() ) + listLevelStyle.setAttribute( "text:bullet-char", m_bullet_char ); + } + + QDomElement properties = doc.createElement( "style:properties" ); + if ( level > 1 ) + { + properties.setAttribute( "text:min-label-width", + QString( "%1cm" ).arg( m_min_label_width ) ); + properties.setAttribute( "text:space-before", + QString( "%1cm" ).arg( m_min_label_width * ( level - 1 ) ) ); + } + + if ( !m_color.isNull() ) + properties.setAttribute( "fo:color", m_color ); + if ( !m_font_size.isNull() ) + properties.setAttribute( "fo:font-size", m_font_size ); + if ( !m_font_family.isNull() ) + properties.setAttribute( "fo:font-family", m_font_family ); + + listLevelStyle.appendChild( properties ); + style.appendChild( listLevelStyle ); + } + e.appendChild( style ); +} + +bool ListStyle::operator==( const ListStyle & listStyle ) const +{ + return ( m_listLevelStyle == listStyle.m_listLevelStyle && + m_num_suffix == listStyle.m_num_suffix && + m_num_format == listStyle.m_num_format && + m_bullet_char == listStyle.m_bullet_char && + m_min_label_width == listStyle.m_min_label_width && + m_color == listStyle.m_color && + m_font_size == listStyle.m_font_size && + m_font_family == listStyle.m_font_family ); +} diff --git a/filters/kpresenter/ooimpress/stylefactory.h b/filters/kpresenter/ooimpress/stylefactory.h new file mode 100644 index 00000000..9de6a548 --- /dev/null +++ b/filters/kpresenter/ooimpress/stylefactory.h @@ -0,0 +1,282 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#ifndef STYLEFACTORY_H +#define STYLEFACTORY_H + +#include <qptrlist.h> +#include <qstring.h> + +#include <qdom.h> + +class StyleFactory; + +class StrokeDashStyle +{ +public: + StrokeDashStyle( int style ); + ~StrokeDashStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + StrokeDashStyle() {}; + + QString m_name, m_style, m_dots1, m_dots2, m_dots1_length, m_dots2_length, + m_distance; +}; + +class GradientStyle +{ +public: + GradientStyle( QDomElement & gradient, int index ); + ~GradientStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + GradientStyle() {}; + + QString m_name, m_style, m_cx, m_cy, m_start_color, m_end_color, + m_start_intensity, m_end_intensity, m_angle, m_border; +}; + +class MarkerStyle +{ +public: + MarkerStyle( int style ); + ~MarkerStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + MarkerStyle() {}; + + QString m_name, m_viewBox, m_d; +}; + +class HatchStyle +{ +public: + HatchStyle( int style, QString & color ); + ~HatchStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + HatchStyle() {}; + + QString m_name, m_style, m_color, m_distance, m_rotation; +}; + +class FillImageStyle +{ +public: + FillImageStyle( QString & name ); + ~FillImageStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + +private: + FillImageStyle() {}; + + QString m_name, m_href, m_type, m_show, m_actuate; +}; + +class PageMasterStyle +{ +public: + PageMasterStyle( QDomElement & e, const uint index ); + ~PageMasterStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const PageMasterStyle & pageMasterStyle ) const; + QString name() const { return m_name; }; + QString style() const { return m_style; }; + +private: + PageMasterStyle() {}; + + QString m_name, m_page_width, m_page_height, m_orientation, m_style; + QString m_margin_top, m_margin_bottom, m_margin_left, m_margin_right; +}; + +class PageStyle +{ +public: + PageStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ); + ~PageStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const PageStyle & pageStyle ) const; + QString name() const { return m_name; }; + +private: + PageStyle() {}; + + QString m_name, m_bg_visible, m_bg_objects_visible, m_fill, m_fill_color, + m_fill_image_name, m_fill_image_width, m_fill_image_height, + m_fill_image_ref_point, m_fill_gradient_name, m_repeat, m_page_effect, + m_page_duration; +}; + +class TextStyle +{ +public: + TextStyle( QDomElement & e, const uint index ); + ~TextStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const TextStyle & textStyle ) const; + QString name() const { return m_name; }; + +private: + TextStyle() {}; + + QString m_name, m_font_size, m_font_family, m_font_family_generic, + m_color, m_font_pitch, m_font_style, m_font_weight, m_text_shadow, + m_text_underline, m_text_underline_color, m_text_crossing_out; +}; + +class GraphicStyle +{ +public: + GraphicStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ); + GraphicStyle( const char * name, + const char * stroke, const char * stroke_color, + const char * stroke_width, const char * shadow, + const char * shadow_offset_x, const char * shadow_offset_y, + const char * shadow_color, const char * margin_left, + const char * margin_right, const char * margin_top, + const char * margin_bottom, const char * color, + const char * text_outline, const char * text_crossing_out, + const char * font_family, const char * font_size, + const char * font_style, const char * text_shadow, + const char * text_underline, const char * font_weight, + const char * line_height, const char * text_align, + const char * fill, const char * fill_color, + const char * enable_numbering ); + ~GraphicStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const GraphicStyle & graphicStyle ) const; + QString name() const { return m_name; }; + +private: + GraphicStyle() {}; + + QString m_name, m_stroke, m_stroke_color, m_stroke_width, m_shadow, + m_shadow_offset_x, m_shadow_offset_y, m_shadow_color, m_margin_left, + m_margin_right, m_margin_top, m_margin_bottom, m_color, m_text_outline, + m_text_crossing_out, m_font_family, m_font_size, m_font_style, + m_text_shadow, m_text_underline, m_font_weight, m_line_height, + m_text_align, m_fill, m_fill_color, m_enable_numbering, m_stroke_dash, + m_fill_hatch_name, m_marker_start, m_marker_start_width, + m_marker_end, m_marker_end_width, m_fill_gradient_name, m_transparency, m_textAlignment, + m_textMarginLeft, m_textMarginBottom, m_textMarginTop, m_textMarginRight; +}; + +class ParagraphStyle +{ +public: + ParagraphStyle( QDomElement & e, const uint index ); + ~ParagraphStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const ParagraphStyle & paragraphStyle ) const; + QString name() const { return m_name; }; + +private: + ParagraphStyle() {}; + QString parseBorder( QDomElement e ); + + QString m_name, m_margin_left, m_margin_right, m_text_indent, m_text_align, + m_enable_numbering, m_text_shadow, m_margin_top, m_margin_bottom, + m_border_left, m_border_right, m_border_top, m_border_bottom, + m_line_height, m_line_height_at_least, m_line_spacing; +}; + +class ListStyle +{ +public: + ListStyle( QDomElement & e, const uint index ); + ~ListStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const ListStyle & listStyle ) const; + QString name() const { return m_name; }; + +private: + ListStyle() {}; + + typedef enum { + LLS_NUMBER, + LLS_BULLET + } list_level_style_t; + + float m_min_label_width; + list_level_style_t m_listLevelStyle; + QString m_name, m_num_suffix, m_num_format, m_bullet_char, m_color, + m_font_size, m_font_family; +}; + +class StyleFactory +{ +public: + StyleFactory(); + ~StyleFactory(); + + void addOfficeStyles( QDomDocument & doc, QDomElement & styles ); + void addOfficeMaster( QDomDocument & doc, QDomElement & master ); + void addOfficeAutomatic( QDomDocument & doc, QDomElement & automatic ); + void addAutomaticStyles( QDomDocument & doc, QDomElement & autoStyles ); + + QString createStrokeDashStyle( int style ); + QString createGradientStyle( QDomElement & gradient ); + QString createMarkerStyle( int style ); + QString createHatchStyle( int style, QString & color ); + QString createListStyle( QDomElement & e ); + QString createPageStyle( QDomElement & e ); + QString createTextStyle( QDomElement & e ); + QString createGraphicStyle( QDomElement & e ); + QString createParagraphStyle( QDomElement & e ); + QString createPageMasterStyle( QDomElement & e ); + + static QString toCM( const QString & point ); + +private: + QPtrList<StrokeDashStyle> m_strokeDashStyles; + QPtrList<GradientStyle> m_gradientStyles; + QPtrList<HatchStyle> m_hatchStyles; + QPtrList<MarkerStyle> m_markerStyles; + QPtrList<FillImageStyle> m_fillImageStyles; + QPtrList<ListStyle> m_listStyles; + QPtrList<PageStyle> m_pageStyles; + QPtrList<TextStyle> m_textStyles; + QPtrList<GraphicStyle> m_graphicStyles; + QPtrList<ParagraphStyle> m_paragraphStyles; + QPtrList<PageMasterStyle> m_pageMasterStyles; +}; + +#endif |