diff -Nru libodfgen-0.0.4/AUTHORS libodfgen-0.1.1/AUTHORS --- libodfgen-0.0.4/AUTHORS 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/AUTHORS 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,7 @@ +CREDITS + +Current maintainers and principal authors of libodfgen +------------------------------------------------------ +Fridrich Strba +Laurent Alonso +David Tardon diff -Nru libodfgen-0.0.4/build/Makefile.in libodfgen-0.1.1/build/Makefile.in --- libodfgen-0.0.4/build/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/build/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -201,8 +201,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -247,18 +245,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru libodfgen-0.0.4/build/win32/libodfgen.dsp libodfgen-0.1.1/build/win32/libodfgen.dsp --- libodfgen-0.0.4/build/win32/libodfgen.dsp 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/build/win32/libodfgen.dsp 2014-03-29 10:15:48.000000000 +0000 @@ -93,6 +93,10 @@ # End Source File # Begin Source File +SOURCE=..\..\src\GraphicStyle.cxx +# End Source File +# Begin Source File + SOURCE=..\..\src\InternalHandler.cxx # End Source File # Begin Source File @@ -105,6 +109,14 @@ # End Source File # Begin Source File +SOURCE=..\..\src\OdpGenerator.cxx +# End Source File +# Begin Source File + +SOURCE=..\..\src\OdsGenerator.cxx +# End Source File +# Begin Source File + SOURCE=..\..\src\OdtGenerator.cxx # End Source File # Begin Source File @@ -117,6 +129,10 @@ # End Source File # Begin Source File +SOURCE=..\..\src\SheetStyle.cxx +# End Source File +# Begin Source File + SOURCE=..\..\src\TableStyle.cxx # End Source File # Begin Source File @@ -141,6 +157,10 @@ # End Source File # Begin Source File +SOURCE=..\..\src\GraphicStyle.hxx +# End Source File +# Begin Source File + SOURCE=..\..\src\InternalHandler.hxx # End Source File # Begin Source File @@ -161,6 +181,14 @@ # End Source File # Begin Source File +SOURCE=..\..\inc\libodfgen\OdpGenerator.hxx +# End Source File +# Begin Source File + +SOURCE=..\..\inc\libodfgen\OdsGenerator.hxx +# End Source File +# Begin Source File + SOURCE=..\..\inc\libodfgen\OdtGenerator.hxx # End Source File # Begin Source File @@ -177,6 +205,10 @@ # End Source File # Begin Source File +SOURCE=..\..\src\SheetStyle.hxx +# End Source File +# Begin Source File + SOURCE=..\..\src\TableStyle.hxx # End Source File # Begin Source File diff -Nru libodfgen-0.0.4/build/win32/Makefile.in libodfgen-0.1.1/build/win32/Makefile.in --- libodfgen-0.0.4/build/win32/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/build/win32/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -141,8 +141,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -187,18 +185,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru libodfgen-0.0.4/ChangeLog libodfgen-0.1.1/ChangeLog --- libodfgen-0.0.4/ChangeLog 2013-12-03 19:56:45.000000000 +0000 +++ libodfgen-0.1.1/ChangeLog 2014-06-03 05:46:04.000000000 +0000 @@ -1,69 +1,790 @@ -2013-12-03 David Tardon [9490b504f488d98f40138ea3bcad01f73fea744d] +2014-06-02 David Tardon [2048cea99fc24833c7c5fc71f7807032a061c4af] + + prepare for a release + + +2014-06-01 David Tardon [1b2a8644a083fb66170e45cf482d3ede0dd1d4b8] + + coverity#1219711 out-of-bounds access + + +2014-05-30 David Tardon [00e977ed118b8a99bca68ab7998252f5ffd00909] + + remove test executables on clean + + +2014-05-30 David Tardon [52ea635cc4ac9373bb6c71dc17ec212aed38f25a] + + do not fail if the removed files do not exist + + +2014-05-30 David Tardon [37bbccf0a11b66244868c0286070fe5fef6651be] + + fix debug output + + +2014-05-24 David Tardon [431087afd938b0d9cea2f5c4b88da0746e3758a8] + + properly export API symbols + + +2014-05-23 David Tardon [4fd4c29628fe0c9a5ee17dc5104b054be061ad2b] + + prepare for a release + + +2014-05-23 David Tardon [e8d37c51a7f0f4264c07c46fd7752ddc04260fbd] + + fix build + + +2014-05-23 David Tardon [0a456471ffc2d507052adfb48ad2d5b1e344bb29] + + add support for master pages + + ... just ignoring all the content for now + +2014-05-23 Fridrich Štrba [3aabce30445b2cd385d075813f3cb085b86cab90] + + One more change in RVNGString + + +2014-05-22 David Tardon [f80779db21a84eb300bb62f860031c9c14659f95] + + add dummy defineEmbeddedFont impls + + +2014-05-22 David Tardon [9be7fd2cce9c47dbff7095060241062ff6be9f36] + + adapt to change in handling XML escaping + + +2014-05-16 Fridrich Štrba [cabbc1665c5ef9fe73ffc4e9e377d4bae3f09ba5] + + Fix build with libodfgen + + +2014-05-15 David Tardon [0b28dcea601100bc7c4d418abf5346ad47aad0fe] + + add dummy impl. for animations + + +2014-05-14 David Tardon [6f0307e8d469e873a62306da2dd80c1f97aeedfe] + + impl. newly added slide trans. function + + +2014-05-14 David Tardon [a1241ce4a2c1408bdf25c4386dba2daf44a89f0b] + + impl. newly added chart functions in pres. iface + + +2014-05-14 David Tardon [1bd1e008584f1cf311b300c3f08ef994089c9f92] + + add support for connectors to all generators + + +2014-05-13 David Tardon [e1cb4872f41375470a4436e56d1531ea69f35648] + + group functions have been renamed + + +2014-04-16 David Tardon [51fd658274eaf9ba3fd748479943d85e5a63c0ed] + + require librevenge-stream too + + +2014-03-04 osnola [b48b279a6ae8473426a96e397ae39d2a9bc8fb63] + + OdgGenerator: try to improve a little the state management(by adding a stack of states, ...) + do not allow to create textboxes inside a textbox... + + +2014-03-04 osnola [9d0a489056ef27be7bd9bea23bd1b34f80453e9d] + + OdtGenerator: try to improve a little the state management(by adding function getState, pushState, ...). + + +2014-03-03 osnola [6fe726e62366be6ba8c223f8be9b71d1cda0875c] + + OdgGenerator: allow to use different units when defining svg:x|y|height|width, ... + + +2014-02-03 osnola [6e9f997679ae5e56f9b350365bce900f86f70f97] + + OdsGenerator: add posibility to define the character's style of a number cell, ... + + +2014-01-26 osnola [aa09f17ede75ad4827e1bb4fa5061ad5f54f683f] + + OdfGenerator: add code to catch potential exceptions in OdfGenerator::insertBinaryObject which can happen when using old versions of g++ and/or boost. + + +2014-01-18 osnola [06dd13ce11f46998814f24d9ac82601b5bea05f5] + + OdsGenerator: minor corrections + + +2014-01-07 osnola [41ab21c7f046bef0895a7fb85659f8b0d39d2213] + + Remove "manifest:version" which must not appear in v1.0 document... + + +2014-01-07 osnola [fe6e0bf447fe657d28ded9b2f197255dd2bedb39] + + Od[cgpt]Generator: add functions to retrieve "Object *" files, ... Od[cp]Generator: add code to generate the manifest. + + +2014-01-07 osnola [10786b433cf00a1c17a76d29c34ea6091bfc34b8] + + OdfDocumentHandler: add a new enum ODF_MANIFEST_XML(to generate the manifest) Od[cgst]Generator: implement the creation of the manifest(if asked) OdsGenerator: add functions to create files in "Object */"(if needed, ie. when a chart is generated) OdcGenerator: style's cleaning, ... + + +2013-12-30 osnola [18847e50f9cbbe854de2de72fcdc06ee614b5ba3] + + Add a chart generator: OdcGenerator + modify OdsGenerator to use it + + +2013-12-27 osnola [6043af4b1fc2dd28e42b6c63afcc83ef3c011a94] + + Update OdsGenerator to compile with new RVNGSpreadsheetInterface... + + +2013-12-20 osnola [a8c2e4a4cc7bdf95364f3dc27afa66b36b4884cf] + + Add some comments, mainly about drawing path and odt ... + + +2013-12-19 osnola [59311687ff14e8aca7699ae329586be646f2d2f0] + + Basic merge... + + +2013-12-19 osnola [166bc394b86a7731b68e738fed1431a2f1492590] + + OdfGenerator: respect the given wrapping style when drawing a shape + do not add a draw:stroke="solid" in a frame properties' when none is given... + + +2013-12-19 Fridrich Štrba [b748f7a3ef8a84f0be44250c5323a3fabcd94c51] + + extract the doubleToString out of the dupplication pit + + +2013-12-19 Fridrich Štrba [154702bee97524f3978aeae4c9b85c28972635d6] + + Adapt to the new RVNGString comparison operators + + +2013-12-19 osnola [1415c9243e7ed011cb4e8177eee277fecd7e73ad] + + Allow to use different units when calling drawEllipse and drawPath.... + + +2013-12-18 osnola [3c1578cdf7bd3ede532c833f174349ac84925cca] + + OdfGenerator: add only need data in the frame's graphic style... + + +2013-12-18 osnola [e06046eecd0fe7fecd7a172e1e9f351408bdf8b3] + + Fix merged conflicts... + + +2013-12-18 osnola [f391c93bfa7416bd80906d5d4f729440104e9922] + + Graphic styles: try to merge the gestion of the graphic styles... + + +2013-12-18 osnola [746d0ce3770848cf85114d96aa7c3015be286e2b] + + testList1.cxx: use the new interfaces + + +2013-12-18 osnola [7edae1de135b50ddc7d4c69636f57a516d3cfd3c] + + OdfGenerator: simplify a little the list code by removing no longer used code... + + +2013-12-17 osnola [6c40d8d1d8533e5967f1bd583f4bed7942521efa] + + Remove some compilation's errors... + + +2013-12-17 Fridrich Štrba [b39c935b5599116c4c6a5c561128a68962d92669] + + Fold the list definitions into the list open callbacks + + Still the tests must be adapted + +2013-12-17 Fridrich Štrba [5dc08006b5291558c92d5737aef1ef5f7cb15f1e] + + librevenge:id -> librevenge:list-id + + +2013-12-15 osnola [39130681e05d9e8a6b12eb5f8c506978ab2468fd] + + OdtGenerator: add a graphic interface, to be continued... + + +2013-12-15 osnola [1295792dd3a706c954faaad780d780ffc0aef997] + + OdsGenerator: use the new spreadsheet interface to simplify the graphic's creation, .... + + +2013-12-15 osnola [ebd71e324cfde2509747bd5bbde608f4361a7f3e] + + OdpGenerator: use OdfGenerator's functions to draw basic shapes... + + +2013-12-15 osnola [72a7ac39fa02b48502f302bf705ad908f7b0207c] + + OdfGenerator: add functions to draw basic shapes + modify OdgGenerator to use these new functions, to be continued... + + +2013-12-15 osnola [7c4078ee818c0efec0e81666b8a59ce6ff049c69] + + Add a small file to test the construction of basic graphic shapes... + + +2013-12-14 Fridrich Štrba [634d50a4d648b2dd19670b1dfb844f5f687b2915] + + Some taste-based changes + avoid a lot of strcmp in paragraph style and make it future-proof + + +2013-12-14 Fridrich Štrba [7d3a8411fb76af411ee5a4f599cd8f574dd48e19] + + Fix compiler warnings + + +2013-12-14 osnola [e31cf7e01d7c1db1ea84b39af73ee9041a164806] + + Finish to create the GraphicStyleManager and try to also avoid duplicating similar graphic styles... + + +2013-12-13 osnola [9238d7d4e6d9f4186ec3f6aa30721ae6f4d3a74a] + + Basic merge... + + +2013-12-13 osnola [7974e817ddb51952468d68a72c96bfdbdfb610f9] + + Graphic styles' properties: try to improve a little the code, to be continued... + + +2013-12-13 Fridrich Štrba [41c34af2a74e2b3bead1f3f8ae0721a9e01b0ce6] + + De gustibus non disputandum + + +2013-12-12 Fridrich Štrba [d3609339e1d567118e64836b01f360037a2b7ff1] + + LO does not support yet the header/footer occurrence "last", so don't bother + + +2013-12-12 Fridrich Štrba [f2090e348040fec97728b9012dd01ac8086b4c0b] + + Thinko with headers/footers + + +2013-12-12 osnola [4d948c80b9c4ce846f418f5b2d7591dd5eff09fb] + + OdpGenerator: use the more <> start/endTableObject interface... + + +2013-12-12 osnola [4c5885bf271f6222a0d40936fcfde87daff8ba0c] + + Use the new startDocument interface... + + +2013-12-11 Fridrich Štrba [e81a4d3e08e688f1ed66daf687df8fa808dd5eb8] + + Re-astyle + + +2013-12-11 Fridrich Štrba [2816c7dfcaef31305301760bd0e538a14d45c42c] + + Allow equal identing of functions + + +2013-12-11 osnola [6648c046d120d5403c91ccef1b0e82b3279ca791] + + OdsGenerator: pass also the define[Un]OrderedListLevel calls to the auxilliar OdgGenerator (when it exists) ... + + +2013-12-10 Fridrich Štrba [88f0a97b672026e2ae1321a789ea2d8b85ae33c3] + + Set framework for header/footer occurrence first and eventually last + + +2013-12-10 osnola [e6968beef7e5b5b8029e6bdb531b354e2f0af82e] + + Remove some not working code concerning table and not given columns... + + +2013-12-09 osnola [f7f912c623f30084bd06dd7cfbd4ef30b6bf7f43] + + Use std::map to no longer duplicate the tables' style... + + +2013-12-09 osnola [5281cd30577588c3e9daa9897683ba95231c70cf] + + Add a TableManager to store the different tables + add functions in TableStyle to store the table state. OdfGenerator: add a warning in openLink if librevenge:type is not defined ( to prepare the addition of future type of links ).... + + +2013-12-09 osnola [4da6d57e8b97712a687e768737c84e738b1560fb] + + Basic merge... + + +2013-12-09 osnola [b7e249b4f296325b3823547326a8b6b8c56324fe] + + Try to avoid dupplicated frame's code between Od[ts]Generator, to be continued. + + +2013-12-09 Fridrich Štrba [146ad7abe75dd13a52ee0f938354ba7f6f4ef18a] + + Try to output some style if librevenge:table-columns is not present + + +2013-12-09 Fridrich Štrba [d240a7e3e6613d9b84f6844efccd9bbb7011ffea] + + astyle --options=astyle.options \*.?xx + + +2013-12-08 osnola [03710d55ab7fec3890cb4438e35dcb10387de35a] + + TextRunStyle: do not generate a named style if the style corresponds to a master-page + try to avoid creating dupplicated named styles... + + +2013-12-07 Fridrich Štrba [dddb0e8d044fa17b946c0ee31432e2fff0c35bbd] + + Fold in really alse table columns + + +2013-12-07 Fridrich Štrba [2fc172b2b30f3d9e96e2e349ba91322557caf3d4] + + Escape urls + + +2013-12-06 Fridrich Štrba [79f15c9ac945dcf6f5e7bd8248e24d324c36c440] + + Columns are in the propList alread, no need to dupplicate them + + +2013-12-06 osnola [fd235e305eee0945828afee04f3529e17c910b41] + + OdtGenerator: add code to define character/paragraph/list user styles using style:display-name to define their final names... + + +2013-12-06 osnola [e30947605f892fba4f780e1f310336d457cb70f9] + + OdgGenerator: remove some default settings in table... + + +2013-12-06 osnola [94b2b0ea71bc93240d65ad9f055cca24fda94204] + + TextRunStyle: add code to retrieve named styles in span/paragraph using style:display-name OdfGenerator: recognize lirevenge:list-id and librevenge:id ( old method ) to define a list id OdxGenerator: add "xmlns:xlink" in some document styles test: rewrite Makefile.am + add testLink1.cxx... + + +2013-12-05 osnola [44e4b59ed6daf8afe0f1f659b16c825f8e224fd8] + + basic merge... + + +2013-12-05 osnola [1b9672dfcf845ed72a61274ab0ea0d7d79cd54ee] + + OdpGenerator: use OdfGenerator's functions to generate the table) OdgGenerator: add table management (code simillar to OdpGenerator) + + +2013-12-05 Fridrich Štrba [43659dc220d55dfd705d257942cc4537eb78e0a9] + + Implement openLink and closeLink + + +2013-12-05 osnola [8bbb1e7795a8d8a7403aa311eb14153b4a5c7e08] + + OdfGenerator: begin to add code for building tables... test: add code to test the construction of textboxes and tables + + +2013-12-04 osnola [a1e13b74d6626b4b13857cd6424002911bbbdc6a] + + OdsGenerator: correct the list code... + + +2013-12-04 osnola [d53dc74ce1c35f978dbdf429a16174f198b2cd2b] + + OdpGenerator: try to use and define the list styles... + + +2013-12-04 osnola [5fab232360178ea1ec32aeffda3331fbb9f4481d] + + OdgGenerator: add the list styles in the automatic style zones... + + +2013-12-04 osnola [381a221b30251420557c72c1df936f21f36ab12e] + + update test/.gitignore + + +2013-12-04 osnola [f11bc33d9fcfffa4d70896f42b19b503b0881815] + + Add test for paragraph and list styles + begin to correct some problems... + + +2013-12-04 osnola [d9acaf193af8d40f18d33d05ae57c6d00f7d32a0] + + Create a repository <> to test libodfgen directly. + + +2013-12-04 osnola [58b0dbf45a93cbbb2f6f3ad4cb3c45ece0bbbcb9] + + astyle modifications... + + +2013-12-04 osnola [15f03958ca7b6cd298c7497c650d886fc015d484] + + Begin to move the list's code in OdfGenerator, to be continued... + + +2013-12-03 David Tardon [ce7bec26b0cd9b834bee31c97b9ca1cc914c159c] + + add heading for the current version + + +2013-12-03 David Tardon [7fdad5e121c6e500ca87cce5d1123771cfa3f106] add to NEWS - (cherry picked from commit 7fdad5e121c6e500ca87cce5d1123771cfa3f106) -2013-12-03 David Tardon [37541771318bd764874cf03a14aa6fbd9d075ab4] +2013-12-03 David Tardon [9c044f2b1305426f244784f2dbc2a8568b38eea2] odp: move annotation namespace decl. to root element -2013-12-03 David Tardon [da7a41d43ed5193c83e79ba9d63857a8e4ed15f8] +2013-12-03 David Tardon [d2d692465612add05588b5d46f28b61e6b49cffa] odp: fix annotation namespace -2013-12-03 David Tardon [d1084496b2f4101a74672cf30558505f14ae1619] +2013-12-03 David Tardon [680b51c18b303f77deb0131ab67abf963372fa16] odp: generate notes page just like libreoffice does -2013-12-03 David Tardon [d554ad155675ed3d2d548fb15a59c580de1330fb] +2013-12-03 David Tardon [ff8419a2e175ca6bc53977fbf41a95f7b2edc2a6] - odp: declare presentation namespace + declare presentation namespace -2013-12-03 David Tardon [8fb5c61f5ecd9cf7968bd2eb76c103facb853fed] +2013-12-03 David Tardon [dd18174f0d5c0a7106afe3d25868644d666bda76] odp: close notes zone -2013-12-03 David Tardon [8f36633505a2a644a9d70bba3f35c0216a1bd42c] +2013-12-03 osnola [3dc83dd623c2c09dcbc1ee39152ba7b1e15fc334] - libwpd and libetonyek are not runtime deps, hide them + Add defineParagraphStyle/defineCharacterStyle to OdpGenerator + try to simplify a little the list's code in OdtGenerator... -2013-12-02 David Tardon [00a598659754c6a88d07cb188796f020b6c5c2f7] +2013-12-03 Fridrich Štrba [838589c0dadd4da6c387f49660cc15f8f96d6d63] + + werror: uninitialized member + + +2013-12-03 osnola [31fc91c014a36f8b5d6638d29072f3016a91f112] + + Oops... + + +2013-12-03 osnola [b4d71ac8e26cd26abd5f93890c8c6eeaff9fedc6] + + Merge branch 'experimental' and resolve conflicts by hand... + + +2013-12-03 Fridrich Štrba [12b49a588f188474a4e3a8005182a0d4351bae0b] + + It is the parser library that needs to split tabs, spaces and lineBreaks + + +2013-12-03 osnola [73427677b3e2f81405c1443ab67645309197d896] + + Move in GraphicFunctions the functions to compute a path bdbox and to generate a path string. Generate the meta data block only if there is some meta data... + + +2013-12-03 osnola [73f2d3f799d6211d0fa3fdc3b7a7165a4ab1898d] + + Use more explicit attribute to define the span/paragaph id... + + +2013-12-02 osnola [9b99c57e2c80d4dade554f25905ca02f84195128] + + Try to regroup the implementation of basic text functions in a new class: OdfGenerator, ... + + +2013-12-02 David Tardon [6db6db65587e967dbf53c65d1ccf1a72b10c1753] prepare for a new release -2013-12-02 David Tardon [cddeeb913dfbd936c251a55feb4b2a767e702c21] +2013-12-02 David Tardon [97b2beaa704c7b7767938efa469bf56ff598c917] odp: do not emulate layers by groups -2013-12-02 David Tardon [50c2dd950dbd446ba7dfee3af2031594da6230c2] +2013-12-02 David Tardon [7d04f795315feebca0891b666033cd3295c932e3] odp: write out table styles in a way impress understands -2013-12-02 David Tardon [96d76f18e3118c9baf66e2f3a8e87e07d671d346] +2013-12-02 David Tardon [5c4beaeeace79c6fb0c92031f0fe1a9f4c54ec83] odp: actually write out table styles -2013-12-02 David Tardon [4553afad7dc2ca2cdf017dedef5cc657d64a9f15] +2013-12-02 David Tardon [01038a6296c35cb84a66ec7b86866c0859f5a00d] odp: add missing namespace decl. -2013-12-02 David Tardon [b059396eb16cdf530cc9f7f883fac2d811cd7b03] +2013-12-02 David Tardon [91f0805fd98edc293ffee3c9370198fc8db85ace] odg/odp tables must be inside a draw:frame +2013-11-29 osnola [e529943efa2dd96a66e08e0f8e1bed6ca553c8f2] + + OdsGenerator,OdtGenerator: add also office:font-face-decls in the content.xml part... + + +2013-11-29 osnola [a81c5031dbe4e8b61dc30e7b741efd30c6d1b8b6] + + OdtGenerator: try to send only good data to the different document handlers + try to correct one or two odf errors (pointed by http://odf-validator.rhcloud.com). + + +2013-11-29 osnola [675a023b8582e7944426f7e3f15a95c0d3daac37] + + OdgGenerator: move the generation of the handlers content in the endDocument function... + + +2013-11-29 osnola [6a4257c9f40b22f609877e001f6b2c6f8edb79db] + + Use a map to store the DocumentHandler + begin to retrieve the basic styles from wpd2odt in OdtGenerator + + +2013-11-29 osnola [25e23db97e5f9132d40b3af7ec232d667efa90f7] + + basic merge... Merge branch 'master' of ssh://git.code.sf.net/p/libwpd/libodfgen + + +2013-11-28 osnola [ed03893fe4e226675200fceaac735e9e8f9b8990] + + OdpGenerator: add a function addDocumentHandler to add new document handlers... + + +2013-11-28 osnola [5ed82565409a5f346ff1750edd0e294074926e8f] + + OdgGenerator: add a function addDocumentHandler to add new document handlers... + + +2013-11-28 osnola [f30b7f2043092208e5562efc51ab9d720710bea8] + + OdtGenerator: add a function addDocumentHandler to add new document handlers but keep the actual behavior while writerperfect is not modified (see comment REMOVE ODF_CONTENT_XML) + + +2013-11-28 David Tardon [e9285d67cadba39235ae664df0c8423f68b6858b] + + use options file for astyle + + +2013-11-28 Fridrich Štrba [bae3500a36446baa8d8569a7b27ff02194aa3065] + + modify the astyle stuff + + +2013-11-28 Fridrich Štrba [e5797e838172c0a7ae9755b216af87377dd65670] + + Use std::map to avoid several handlers per stream type + + +2013-11-28 David Tardon [2429bc9e65e049ee1aab6382c4e3312d294ecc13] + + add AUTHORS file + + +2013-11-28 David Tardon [b189a158832ae5601e46d28c130b1ae6f07bfeef] + + document the current astyle settings + + +2013-11-28 osnola [e9f022ac700453d2cad9d9d1106c86a91d4d3b26] + + OdsGenerator: duplicate the automatic-styles part in content.xml and styles.xml (to simplify the code and to avoid unseen problems) + + +2013-11-28 osnola [e38b31629236c6c48d16ae0ea56e3b6924240418] + + OdsGenerator: change the interface to try to manage correctly the content of office:document-content, office:meta, ... + + +2013-11-27 osnola [ad6a3b62b8a5e495cf89f679ff20882633edcb6a] + + OdsGenerator: implement the pageSpan functions.... + + +2013-11-25 Fridrich Štrba [29dda35a155a622d0275fa11365da1126849bed9] + + astyle -HU -A1 -k3 -y -n -t -r \*.?xx + + +2013-11-24 osnola [5909a6e02465fdd3ef46bddd64e99193a2b61783] + + Correct a comment... + + +2013-11-24 osnola [19c6fd51c9f2947dc0810d0a9cdb4061c87c56a9] + + Remove the insertSheetConditionInNumberingStyle function in OdsGenerator... + + +2013-11-23 Fridrich Štrba [1569aba3b047ca3bc09f95aca669dbe162bc38e4] + + drawPoly*: vertices -> "svg:points" + + +2013-11-23 Fridrich Štrba [42f01d71e19acd46944b9e062da6586d7e09cc13] + + Fold in gradients + + +2013-11-22 Fridrich Štrba [2b4db9442579bffe671c52d31f12ae6b89f2b0aa] + + openTable: columns -> librevenge:table-columns + fold data in insertEquation + + +2013-11-22 Fridrich Štrba [79a5065970c82c64334299f0a50fe3f35b7775a3] + + insertField: type -> librevenge:field-type + + +2013-11-22 Fridrich Štrba [0fe33789e2996007733a2ec1d5b2a3da3c823f2e] + + whitespace + + +2013-11-22 Fridrich Štrba [f2fe5767391bb3be18c37f5a5ead2a0b67ec0ce8] + + Avoid copying of SheetStyle because of pointer members + + +2013-11-22 Fridrich Štrba [006845b31cb63bcde93fc2009be01a679656c0d6] + + Folding in the section columns + + +2013-11-22 osnola [a64cb6826b11a414e0cb40ee117507ba50ed3a77] + + Dump RVNGPropertyListVector in the specific functions of RVNGSpreadsheetInterface + minor corrections... + + +2013-11-21 Fridrich Štrba [b80a7d647c177da76a8903eda8c53dce647ee9fa] + + Fold tabStops into the propList + + +2013-11-21 osnola [eb963f4ffe056f61a3d28c8f8a9afa9cc2a0dcff] + + Use the new RVNGPropertyList interface to retrieve a RVNGPropertyListVector... + + +2013-11-21 osnola [3727774bd71cc22d8323e3444d556843607d9265] + + Basic merge... + + +2013-11-20 osnola [1713c6de01939458d6adcfd0290cc4d9249b0693] + + OdsGenerator: change code to use a RVNGPropertyListVector for formula... + + +2013-11-20 Fridrich Štrba [c39119861e8eb55ceb226af5ddb86bd766b5da84] + + Folding paths into propLists + + +2013-11-20 Fridrich Štrba [c324c87e5391438b2671d729550b9d82a062bd25] + + Try to filter out properties that are actually complex children + + +2013-11-20 osnola [c9b9c765eeacb15c02c54adf7ecf2fa630c78916] + + Basic corrections in the spreadsheet part... + + +2013-11-19 Fridrich Štrba [9c9b9c14dbb130fb37d608050bd85c2ff5a2de43] + + Werror fix + + +2013-11-18 osnola [c0a6d1da3a69d48d8fa5a0dd52221909d7248cb8] + + Moves the handler definitions in OdfDocumentHandler.hxx... + + +2013-11-17 osnola [53ae427c2d60ea96aed1c85a87323d23e5d8832c] + + Add a Ods generator... + + +2013-11-14 Fridrich Štrba [7571b573e49a5890421cbf0c7ad2e98c949fea03] + + Adapt to API change in librevenge + + +2013-11-10 Fridrich Štrba [6e2018732b188914ecbda1afa3560c8df0dccaa9] + + Allow forcing string when inserting attribute value + + +2013-11-07 osnola [8fe293dc2cdefebc8920c26d80c27e74dfd6edd2] + + Move OdgGenerator's unimplemented functions in OdgGenerator.cxx + + +2013-11-07 osnola [2b4702f0e8b1e255400d46b62ee207f483dac189] + + Implement OdgGenerator::insert{LineBreak,Space,Tab} + + +2013-11-06 Fridrich Štrba [c253af844314cac4fa280288a3cf4a0b0ab38938] + + Don't crash on missing property + + +2013-11-05 Fridrich Štrba [426310b1a549429c7218a9e746f2ac633b27b606] + + namespace-related fixes + + +2013-11-05 Fridrich Štrba [2b9eee7ab7077fafc4319d70832b15b8ddefc298] + + librevenge namespace + + +2013-11-04 Fridrich Štrba [ee4e1a5390e92bbc0fbd4bfd2374eec958915bcf] + + Consolidate mime-type properties + + +2013-11-03 Fridrich Štrba [1ec68aaf53434c442f38cc35e0bc8bc85766e9c1] + + Implement the right interface + + +2013-11-03 Fridrich Štrba [a6952f5697dd64b786d6e9f432955625dad935f3] + + Branch STABLE-0-0-0 and make master use librevenge + + 2013-10-30 David Tardon [9008d84be1eb0b3def0df39b069a309d54aa73ab] use correct header for std::swap diff -Nru libodfgen-0.0.4/configure libodfgen-0.1.1/configure --- libodfgen-0.0.4/configure 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/configure 2014-06-02 17:11:58.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libodfgen 0.0.4. +# Generated by GNU Autoconf 2.69 for libodfgen 0.1.1. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='libodfgen' PACKAGE_TARNAME='libodfgen' -PACKAGE_VERSION='0.0.4' -PACKAGE_STRING='libodfgen 0.0.4' +PACKAGE_VERSION='0.1.1' +PACKAGE_STRING='libodfgen 0.1.1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -635,6 +635,8 @@ WITH_LIBEBOOK_DOCS_FALSE WITH_LIBEBOOK_DOCS_TRUE DOXYGEN +COMPILE_TEST_FALSE +COMPILE_TEST_TRUE DEBUG_CXXFLAGS WINDRES PLATFORM_WIN32_FALSE @@ -648,14 +650,9 @@ LIBODFGEN_MICRO_VERSION LIBODFGEN_MINOR_VERSION LIBODFGEN_MAJOR_VERSION -ETONYEK_LIBS -ETONYEK_CFLAGS -WPG_LIGS -WPG_LIBS -WPG_CFLAGS -WPD_LIGS -WPD_LIBS -WPD_CFLAGS +REVENGE_LIGS +REVENGE_LIBS +REVENGE_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG @@ -795,6 +792,7 @@ enable_weffc enable_wparanoic enable_debug +enable_test with_sharedptr with_docs ' @@ -814,12 +812,8 @@ PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR -WPD_CFLAGS -WPD_LIBS -WPG_CFLAGS -WPG_LIBS -ETONYEK_CFLAGS -ETONYEK_LIBS' +REVENGE_CFLAGS +REVENGE_LIBS' # Initialize some variables set by options. @@ -1360,7 +1354,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libodfgen 0.0.4 to adapt to many kinds of systems. +\`configure' configures libodfgen 0.1.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1430,7 +1424,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libodfgen 0.0.4:";; + short | recursive ) echo "Configuration of libodfgen 0.1.1:";; esac cat <<\_ACEOF @@ -1455,6 +1449,7 @@ version of gcc or of boost --enable-wparanoic Enable a lot of warnings... --enable-debug Turn on debugging + --enable-test Compile extra test executables Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1486,14 +1481,10 @@ directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path - WPD_CFLAGS C compiler flags for WPD, overriding pkg-config - WPD_LIBS linker flags for WPD, overriding pkg-config - WPG_CFLAGS C compiler flags for WPG, overriding pkg-config - WPG_LIBS linker flags for WPG, overriding pkg-config - ETONYEK_CFLAGS - C compiler flags for ETONYEK, overriding pkg-config - ETONYEK_LIBS - linker flags for ETONYEK, overriding pkg-config + REVENGE_CFLAGS + C compiler flags for REVENGE, overriding pkg-config + REVENGE_LIBS + linker flags for REVENGE, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1561,7 +1552,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libodfgen configure 0.0.4 +libodfgen configure 0.1.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1960,7 +1951,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libodfgen $as_me 0.0.4, which was +It was created by libodfgen $as_me 0.1.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2826,7 +2817,7 @@ # Define the identity of the package. PACKAGE='libodfgen' - VERSION='0.0.4' + VERSION='0.1.1' cat >>confdefs.h <<_ACEOF @@ -6883,10 +6874,10 @@ x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; - powerpcle-*linux*) + powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; - powerpc-*linux*) + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -15535,248 +15526,27 @@ # ==================== pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WPD" >&5 -$as_echo_n "checking for WPD... " >&6; } - -if test -n "$WPD_CFLAGS"; then - pkg_cv_WPD_CFLAGS="$WPD_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libwpd-0.9 -\""; } >&5 - ($PKG_CONFIG --exists --print-errors " - libwpd-0.9 -") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_WPD_CFLAGS=`$PKG_CONFIG --cflags " - libwpd-0.9 -" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$WPD_LIBS"; then - pkg_cv_WPD_LIBS="$WPD_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libwpd-0.9 -\""; } >&5 - ($PKG_CONFIG --exists --print-errors " - libwpd-0.9 -") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_WPD_LIBS=`$PKG_CONFIG --libs " - libwpd-0.9 -" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - WPD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " - libwpd-0.9 -" 2>&1` - else - WPD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " - libwpd-0.9 -" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$WPD_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements ( - libwpd-0.9 -) were not met: - -$WPD_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables WPD_CFLAGS -and WPD_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables WPD_CFLAGS -and WPD_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } -else - WPD_CFLAGS=$pkg_cv_WPD_CFLAGS - WPD_LIBS=$pkg_cv_WPD_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - - - - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WPG" >&5 -$as_echo_n "checking for WPG... " >&6; } - -if test -n "$WPG_CFLAGS"; then - pkg_cv_WPG_CFLAGS="$WPG_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libwpg-0.2 -\""; } >&5 - ($PKG_CONFIG --exists --print-errors " - libwpg-0.2 -") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_WPG_CFLAGS=`$PKG_CONFIG --cflags " - libwpg-0.2 -" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$WPG_LIBS"; then - pkg_cv_WPG_LIBS="$WPG_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libwpg-0.2 -\""; } >&5 - ($PKG_CONFIG --exists --print-errors " - libwpg-0.2 -") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_WPG_LIBS=`$PKG_CONFIG --libs " - libwpg-0.2 -" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - WPG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " - libwpg-0.2 -" 2>&1` - else - WPG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " - libwpg-0.2 -" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$WPG_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements ( - libwpg-0.2 -) were not met: - -$WPG_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables WPG_CFLAGS -and WPG_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables WPG_CFLAGS -and WPG_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } -else - WPG_CFLAGS=$pkg_cv_WPG_CFLAGS - WPG_LIBS=$pkg_cv_WPG_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -fi - - - - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ETONYEK" >&5 -$as_echo_n "checking for ETONYEK... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for REVENGE" >&5 +$as_echo_n "checking for REVENGE... " >&6; } -if test -n "$ETONYEK_CFLAGS"; then - pkg_cv_ETONYEK_CFLAGS="$ETONYEK_CFLAGS" +if test -n "$REVENGE_CFLAGS"; then + pkg_cv_REVENGE_CFLAGS="$REVENGE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libetonyek-0.0 + librevenge-0.0 + librevenge-stream-0.0 \""; } >&5 ($PKG_CONFIG --exists --print-errors " - libetonyek-0.0 + librevenge-0.0 + librevenge-stream-0.0 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ETONYEK_CFLAGS=`$PKG_CONFIG --cflags " - libetonyek-0.0 + pkg_cv_REVENGE_CFLAGS=`$PKG_CONFIG --cflags " + librevenge-0.0 + librevenge-stream-0.0 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else @@ -15785,21 +15555,24 @@ else pkg_failed=untried fi -if test -n "$ETONYEK_LIBS"; then - pkg_cv_ETONYEK_LIBS="$ETONYEK_LIBS" +if test -n "$REVENGE_LIBS"; then + pkg_cv_REVENGE_LIBS="$REVENGE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" - libetonyek-0.0 + librevenge-0.0 + librevenge-stream-0.0 \""; } >&5 ($PKG_CONFIG --exists --print-errors " - libetonyek-0.0 + librevenge-0.0 + librevenge-stream-0.0 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ETONYEK_LIBS=`$PKG_CONFIG --libs " - libetonyek-0.0 + pkg_cv_REVENGE_LIBS=`$PKG_CONFIG --libs " + librevenge-0.0 + librevenge-stream-0.0 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else @@ -15821,28 +15594,31 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - ETONYEK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " - libetonyek-0.0 + REVENGE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " + librevenge-0.0 + librevenge-stream-0.0 " 2>&1` else - ETONYEK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " - libetonyek-0.0 + REVENGE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " + librevenge-0.0 + librevenge-stream-0.0 " 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$ETONYEK_PKG_ERRORS" >&5 + echo "$REVENGE_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ( - libetonyek-0.0 + librevenge-0.0 + librevenge-stream-0.0 ) were not met: -$ETONYEK_PKG_ERRORS +$REVENGE_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. -Alternatively, you may set the environment variables ETONYEK_CFLAGS -and ETONYEK_LIBS to avoid the need to call pkg-config. +Alternatively, you may set the environment variables REVENGE_CFLAGS +and REVENGE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -15853,15 +15629,15 @@ is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. -Alternatively, you may set the environment variables ETONYEK_CFLAGS -and ETONYEK_LIBS to avoid the need to call pkg-config. +Alternatively, you may set the environment variables REVENGE_CFLAGS +and REVENGE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else - ETONYEK_CFLAGS=$pkg_cv_ETONYEK_CFLAGS - ETONYEK_LIBS=$pkg_cv_ETONYEK_LIBS + REVENGE_CFLAGS=$pkg_cv_REVENGE_CFLAGS + REVENGE_LIBS=$pkg_cv_REVENGE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -15874,17 +15650,17 @@ # ================================= LIBODFGEN_MAJOR_VERSION=0 -LIBODFGEN_MINOR_VERSION=0 +LIBODFGEN_MINOR_VERSION=1 -LIBODFGEN_MICRO_VERSION=4 +LIBODFGEN_MICRO_VERSION=1 # AC_SUBST(LT_RELEASE, [libodfgen_version_major.libodfgen_version_minor]) -LT_CURRENT=`expr 100 '*' 0 + 0` +LT_CURRENT=`expr 100 '*' 0 + 1` # For 1.0.0 comment the first line and uncomment the second LT_AGE=0 # LT_AGE=libodfgen_version_minor -LT_REVISION=4 +LT_REVISION=1 @@ -16159,6 +15935,26 @@ fi +# ============ +# Test switch +# ============ +# Check whether --enable-test was given. +if test "${enable_test+set}" = set; then : + enableval=$enable_test; enable_test="$enableval" +else + enable_test=no + +fi + + if test "x$enable_test" = "xyes"; then + COMPILE_TEST_TRUE= + COMPILE_TEST_FALSE='#' +else + COMPILE_TEST_TRUE='#' + COMPILE_TEST_FALSE= +fi + + # ======== # shared_ptr implementation # ======== @@ -16373,7 +16169,7 @@ # ===================== # Prepare all .in files # ===================== -ac_config_files="$ac_config_files libodfgen-$LIBODFGEN_MAJOR_VERSION.$LIBODFGEN_MINOR_VERSION.pc:libodfgen.pc.in Makefile build/Makefile build/win32/Makefile docs/Makefile docs/doxygen/Makefile inc/Makefile inc/libodfgen/Makefile src/Makefile src/libodfgen.rc" +ac_config_files="$ac_config_files libodfgen-$LIBODFGEN_MAJOR_VERSION.$LIBODFGEN_MINOR_VERSION.pc:libodfgen.pc.in Makefile build/Makefile build/win32/Makefile docs/Makefile docs/doxygen/Makefile inc/Makefile inc/libodfgen/Makefile src/Makefile src/libodfgen.rc test/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -16520,6 +16316,10 @@ as_fn_error $? "conditional \"PLATFORM_WIN32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${COMPILE_TEST_TRUE}" && test -z "${COMPILE_TEST_FALSE}"; then + as_fn_error $? "conditional \"COMPILE_TEST\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${WITH_LIBEBOOK_DOCS_TRUE}" && test -z "${WITH_LIBEBOOK_DOCS_FALSE}"; then as_fn_error $? "conditional \"WITH_LIBEBOOK_DOCS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -16921,7 +16721,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libodfgen $as_me 0.0.4, which was +This file was extended by libodfgen $as_me 0.1.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16987,7 +16787,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libodfgen config.status 0.0.4 +libodfgen config.status 0.1.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -17506,6 +17306,7 @@ "inc/libodfgen/Makefile") CONFIG_FILES="$CONFIG_FILES inc/libodfgen/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/libodfgen.rc") CONFIG_FILES="$CONFIG_FILES src/libodfgen.rc" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff -Nru libodfgen-0.0.4/configure.ac libodfgen-0.1.1/configure.ac --- libodfgen-0.0.4/configure.ac 2013-12-02 18:00:37.000000000 +0000 +++ libodfgen-0.1.1/configure.ac 2014-06-02 17:09:52.000000000 +0000 @@ -6,8 +6,8 @@ # Version informations # ==================== m4_define([libodfgen_version_major],[0]) -m4_define([libodfgen_version_minor],[0]) -m4_define([libodfgen_version_micro],[4]) +m4_define([libodfgen_version_minor],[1]) +m4_define([libodfgen_version_micro],[1]) m4_define([libodfgen_version],[libodfgen_version_major.libodfgen_version_minor.libodfgen_version_micro]) # ============= @@ -36,23 +36,12 @@ # ==================== # Find additional apps # ==================== -PKG_CHECK_MODULES([WPD],[ - libwpd-0.9 +PKG_CHECK_MODULES([REVENGE],[ + librevenge-0.0 + librevenge-stream-0.0 ]) -AC_SUBST([WPD_CFLAGS]) -AC_SUBST([WPD_LIGS]) - -PKG_CHECK_MODULES([WPG],[ - libwpg-0.2 -]) -AC_SUBST([WPG_CFLAGS]) -AC_SUBST([WPG_LIGS]) - -PKG_CHECK_MODULES([ETONYEK],[ - libetonyek-0.0 -]) -AC_SUBST([ETONYEK_CFLAGS]) -AC_SUBST([ETONYEK_LIBS]) +AC_SUBST([REVENGE_CFLAGS]) +AC_SUBST([REVENGE_LIGS]) # ================================= # Libtool/Version Makefile settings @@ -182,6 +171,16 @@ ]) AC_SUBST(DEBUG_CXXFLAGS) +# ============ +# Test switch +# ============ +AC_ARG_ENABLE([test], + [AS_HELP_STRING([--enable-test], [Compile extra test executables])], + [enable_test="$enableval"], + [enable_test=no] +) +AM_CONDITIONAL([COMPILE_TEST], [test "x$enable_test" = "xyes"]) + # ======== # shared_ptr implementation # ======== @@ -278,6 +277,7 @@ inc/libodfgen/Makefile src/Makefile src/libodfgen.rc +test/Makefile ]) AC_OUTPUT diff -Nru libodfgen-0.0.4/debian/changelog libodfgen-0.1.1/debian/changelog --- libodfgen-0.0.4/debian/changelog 2014-05-06 20:03:04.000000000 +0000 +++ libodfgen-0.1.1/debian/changelog 2014-07-25 17:46:58.000000000 +0000 @@ -1,3 +1,22 @@ +libodfgen (0.1.1-1~precise1) precise; urgency=medium + + * Copied from debian + * Build against boost 1.54 + + -- Rico Tzschichholz Fri, 25 Jul 2014 19:46:05 +0200 + +libodfgen (0.1.1-1) experimental; urgency=low + + * New upstream release + + -- Rene Engelhard Tue, 03 Jun 2014 18:37:17 +0200 + +libodfgen (0.1.0-1) experimental; urgency=low + + * New upstream release + + -- Rene Engelhard Fri, 23 May 2014 20:03:11 +0200 + libodfgen (0.0.4-2) unstable; urgency=low * upload to unstable diff -Nru libodfgen-0.0.4/debian/control libodfgen-0.1.1/debian/control --- libodfgen-0.0.4/debian/control 2014-01-06 15:41:49.000000000 +0000 +++ libodfgen-0.1.1/debian/control 2014-07-25 17:46:29.000000000 +0000 @@ -3,10 +3,8 @@ Maintainer: Rene Engelhard Build-Depends: debhelper (>= 9), dh-autoreconf, - libboost-dev, - libetonyek-dev, - libwpd-dev (>= 0.9.0), - libwpg-dev (>= 0.2.0), + libboost1.54-dev, + librevenge-dev, pkg-config Standards-Version: 3.9.4 Section: libs @@ -15,10 +13,8 @@ Package: libodfgen-dev Section: libdevel Architecture: any -Depends: libetonyek-dev, - libodfgen-0.0-0 (= ${binary:Version}), - libwpd-dev (>= 0.9.0), - libwpg-dev (>= 0.2.0), +Depends: librevenge-dev, + libodfgen-0.1-1 (= ${binary:Version}), ${misc:Depends} Description: library to generate ODF documents -- development Libodfgen is library providing ability to generate ODF documents from @@ -26,7 +22,7 @@ . This package contains the development files (headers, ...) -Package: libodfgen-0.0-0 +Package: libodfgen-0.1-1 Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Description: library to generate ODF documents diff -Nru libodfgen-0.0.4/debian/libodfgen-0.0-0.install libodfgen-0.1.1/debian/libodfgen-0.0-0.install --- libodfgen-0.0.4/debian/libodfgen-0.0-0.install 2013-02-27 20:33:09.000000000 +0000 +++ libodfgen-0.1.1/debian/libodfgen-0.0-0.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/lib*.so.* diff -Nru libodfgen-0.0.4/debian/libodfgen-0.1-1.install libodfgen-0.1.1/debian/libodfgen-0.1-1.install --- libodfgen-0.0.4/debian/libodfgen-0.1-1.install 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/debian/libodfgen-0.1-1.install 2013-02-27 20:33:09.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/lib*.so.* diff -Nru libodfgen-0.0.4/debian/rules libodfgen-0.1.1/debian/rules --- libodfgen-0.0.4/debian/rules 2014-01-06 15:41:29.000000000 +0000 +++ libodfgen-0.1.1/debian/rules 2014-05-23 18:09:35.000000000 +0000 @@ -9,6 +9,3 @@ override_dh_auto_configure: dh_auto_configure -- --disable-werror --libdir=/usr/lib \ --disable-silent-rules - -override_dh_makeshlibs: - dh_makeshlibs -V'libodfgen-0.0-0 (>= 0.0.3)' diff -Nru libodfgen-0.0.4/docs/doxygen/Makefile.in libodfgen-0.1.1/docs/doxygen/Makefile.in --- libodfgen-0.0.4/docs/doxygen/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/docs/doxygen/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -141,8 +141,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -187,18 +185,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru libodfgen-0.0.4/docs/Makefile.in libodfgen-0.1.1/docs/Makefile.in --- libodfgen-0.0.4/docs/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/docs/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -201,8 +201,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -247,18 +245,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru libodfgen-0.0.4/inc/libodfgen/libodfgen-api.hxx libodfgen-0.1.1/inc/libodfgen/libodfgen-api.hxx --- libodfgen-0.0.4/inc/libodfgen/libodfgen-api.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/libodfgen-api.hxx 2014-05-24 18:12:19.000000000 +0000 @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2013 Fridrich Strba + * Copyright (C) 2011 Eilidh McAdam + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#ifndef INCLUDED_LIBODFGEN_LIBODFGEN_API_HXX +#define INCLUDED_LIBODFGEN_LIBODFGEN_API_HXX + +#ifdef DLL_EXPORT +#ifdef LIBODFGEN_BUILD +#define ODFGENAPI __declspec(dllexport) +#else +#define ODFGENAPI __declspec(dllimport) +#endif +#else +#define ODFGENAPI +#endif + +#endif // INCLUDED_LIBODFGEN_LIBODFGEN_API_HXX + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/inc/libodfgen/libodfgen.hxx libodfgen-0.1.1/inc/libodfgen/libodfgen.hxx --- libodfgen-0.0.4/inc/libodfgen/libodfgen.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/libodfgen.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -23,12 +23,13 @@ #ifndef __LIBODFGEN_HXX__ #define __LIBODFGEN_HXX__ -#include -#include +#include + #include "OdfDocumentHandler.hxx" -#include "OdtGenerator.hxx" #include "OdgGenerator.hxx" #include "OdpGenerator.hxx" +#include "OdsGenerator.hxx" +#include "OdtGenerator.hxx" #endif diff -Nru libodfgen-0.0.4/inc/libodfgen/Makefile.am libodfgen-0.1.1/inc/libodfgen/Makefile.am --- libodfgen-0.0.4/inc/libodfgen/Makefile.am 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/Makefile.am 2014-05-24 18:18:28.000000000 +0000 @@ -1,5 +1,7 @@ EXTRA_DIST = \ libodfgen.hxx \ + libodfgen-api.hxx \ OdfDocumentHandler.hxx \ OdgGenerator.hxx \ + OdsGenerator.hxx \ OdtGenerator.hxx diff -Nru libodfgen-0.0.4/inc/libodfgen/Makefile.in libodfgen-0.1.1/inc/libodfgen/Makefile.in --- libodfgen-0.0.4/inc/libodfgen/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -141,8 +141,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -187,18 +185,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -254,8 +249,10 @@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ libodfgen.hxx \ + libodfgen-api.hxx \ OdfDocumentHandler.hxx \ OdgGenerator.hxx \ + OdsGenerator.hxx \ OdtGenerator.hxx all: all-am diff -Nru libodfgen-0.0.4/inc/libodfgen/OdfDocumentHandler.hxx libodfgen-0.1.1/inc/libodfgen/OdfDocumentHandler.hxx --- libodfgen-0.0.4/inc/libodfgen/OdfDocumentHandler.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/OdfDocumentHandler.hxx 2014-05-24 18:19:54.000000000 +0000 @@ -24,13 +24,33 @@ */ #ifndef _ODFDOCUMENTHANDLER_HXX_ #define _ODFDOCUMENTHANDLER_HXX_ -#include +#include + +#include "libodfgen-api.hxx" /** Type of ODF content a generator should produce. * * @sa OdgGenerator, OdpGenerator, OdtGenerator */ -enum OdfStreamType { ODF_FLAT_XML, ODF_CONTENT_XML, ODF_STYLES_XML, ODF_SETTINGS_XML, ODF_META_XML }; +enum OdfStreamType { ODF_FLAT_XML, ODF_CONTENT_XML, ODF_STYLES_XML, ODF_SETTINGS_XML, ODF_META_XML, ODF_MANIFEST_XML }; + +class OdfDocumentHandler; + +/** Handler for embedded objects. + * + * @param[in] data the object's data + * @param[in] pHandler the current OdfDocumentHandler + * @param[in] streamType type of the object + */ +typedef bool (*OdfEmbeddedObject)(const librevenge::RVNGBinaryData &data, OdfDocumentHandler *pHandler, const OdfStreamType streamType); + +/** Handler for embedded images. + * + * @param[in] input the image's data + * @param[in] output the same image in format suitable for the used + * OdfDocumentHandler. + */ +typedef bool (*OdfEmbeddedImage)(const librevenge::RVNGBinaryData &input, librevenge::RVNGBinaryData &output); /** XML writer. * @@ -39,7 +59,7 @@ * saved to a file, printed to the standard output, saved to a file * inside a package, or whatever else. */ -class OdfDocumentHandler +class ODFGENAPI OdfDocumentHandler { public: virtual ~OdfDocumentHandler() {} @@ -57,7 +77,7 @@ * @param[in] psName name of the element * @param[in] xPropList list of attributes */ - virtual void startElement(const char *psName, const WPXPropertyList &xPropList) = 0; + virtual void startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList) = 0; /** Add a end tag to the XML document. * @@ -70,7 +90,7 @@ * * @param[in] sCharacters the content */ - virtual void characters(const WPXString &sCharacters) = 0; + virtual void characters(const librevenge::RVNGString &sCharacters) = 0; }; #endif diff -Nru libodfgen-0.0.4/inc/libodfgen/OdgGenerator.hxx libodfgen-0.1.1/inc/libodfgen/OdgGenerator.hxx --- libodfgen-0.0.4/inc/libodfgen/OdgGenerator.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/OdgGenerator.hxx 2014-05-24 18:19:57.000000000 +0000 @@ -25,48 +25,107 @@ #ifndef __ODGGENERATOR_HXX__ #define __ODGGENERATOR_HXX__ -#include -#include +#include +#include "libodfgen-api.hxx" #include "OdfDocumentHandler.hxx" +class OdfGenerator; class OdgGeneratorPrivate; /** A generator for vector drawings. * - * See @c libwpg library for documentation of the - * libwpg::WPGPaintInterface interface. + * See @c librevenge library for documentation of the + * librevenge::WPGPaintInterface interface. */ -class OdgGenerator : public libwpg::WPGPaintInterface +class ODFGENAPI OdgGenerator : public librevenge::RVNGDrawingInterface { public: - OdgGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + OdgGenerator(); ~OdgGenerator(); - - void startGraphics(const ::WPXPropertyList &propList); - void endGraphics(); - void startLayer(const ::WPXPropertyList &propList); + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + librevenge::RVNGStringVector getObjectNames() const; + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); + void setDocumentMetaData(const librevenge::RVNGPropertyList &); + + void defineEmbeddedFont(const librevenge::RVNGPropertyList &propList); + + void startPage(const librevenge::RVNGPropertyList &); + void endPage(); + void startMasterPage(const librevenge::RVNGPropertyList &); + void endMasterPage(); + void startLayer(const ::librevenge::RVNGPropertyList &propList); void endLayer(); - void startEmbeddedGraphics(const ::WPXPropertyList &propList); + void openGroup(const ::librevenge::RVNGPropertyList &propList); + void closeGroup(); + void startEmbeddedGraphics(const ::librevenge::RVNGPropertyList &propList); void endEmbeddedGraphics(); - void setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &gradient); + void setStyle(const ::librevenge::RVNGPropertyList &propList); - void drawRectangle(const ::WPXPropertyList &propList); - void drawEllipse(const ::WPXPropertyList &propList); - void drawPolyline(const ::WPXPropertyListVector &vertices); - void drawPolygon(const ::WPXPropertyListVector &vertices); - void drawPath(const ::WPXPropertyListVector &path); - void drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData &binaryData); + void drawRectangle(const ::librevenge::RVNGPropertyList &propList); + void drawEllipse(const ::librevenge::RVNGPropertyList &propList); + void drawPolyline(const ::librevenge::RVNGPropertyList &propList); + void drawPolygon(const ::librevenge::RVNGPropertyList &propList); + void drawPath(const ::librevenge::RVNGPropertyList &propList); + void drawGraphicObject(const ::librevenge::RVNGPropertyList &propList); + void drawConnector(const ::librevenge::RVNGPropertyList &propList); + + void startTableObject(const ::librevenge::RVNGPropertyList &propList); + void openTableRow(const ::librevenge::RVNGPropertyList &propList); + void closeTableRow(); + void openTableCell(const ::librevenge::RVNGPropertyList &propList); + void closeTableCell(); + void insertCoveredTableCell(const ::librevenge::RVNGPropertyList &propList); + void endTableObject(); - void startTextObject(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &path); + void startTextObject(const ::librevenge::RVNGPropertyList &propList); void endTextObject(); - void startTextLine(const ::WPXPropertyList &propList); - void endTextLine(); - void startTextSpan(const ::WPXPropertyList &propList); - void endTextSpan(); - void insertText(const ::WPXString &str); + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + void openParagraph(const librevenge::RVNGPropertyList &propList); + void closeParagraph(); + + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + void openSpan(const librevenge::RVNGPropertyList &propList); + void closeSpan(); + + void openLink(const librevenge::RVNGPropertyList &propList); + void closeLink(); + + void insertText(const librevenge::RVNGString &text); + void insertTab(); + void insertSpace(); + void insertLineBreak(); + void insertField(const librevenge::RVNGPropertyList &propList); + + void openOrderedListLevel(const librevenge::RVNGPropertyList &propList); + void openUnorderedListLevel(const librevenge::RVNGPropertyList &propList); + void closeOrderedListLevel(); + void closeUnorderedListLevel(); + void openListElement(const librevenge::RVNGPropertyList &propList); + void closeListElement(); + + void startDocument(const librevenge::RVNGPropertyList &); + void endDocument(); + + /** Registers a handler for embedded images. + * + * @param[in] mimeType MIME type of the image + * @param[in] imageHandler a function that handles processing of + * the image's data and generating output + */ + void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler); + /** Registers a handler for embedded objects. + * + * @param[in] mimeType MIME type of the object + * @param[in] objectHandler a function that handles processing of + * the object's data and generating output + */ + void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler); + + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); private: OdgGenerator(OdgGenerator const &); OdgGenerator &operator=(OdgGenerator const &); diff -Nru libodfgen-0.0.4/inc/libodfgen/OdpGenerator.hxx libodfgen-0.1.1/inc/libodfgen/OdpGenerator.hxx --- libodfgen-0.0.4/inc/libodfgen/OdpGenerator.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/OdpGenerator.hxx 2014-05-24 18:20:01.000000000 +0000 @@ -25,78 +25,132 @@ #ifndef LIBODFGEN_ODPGENERATOR_HXX_INCLUDED #define LIBODFGEN_ODPGENERATOR_HXX_INCLUDED -#include +#include +#include "libodfgen-api.hxx" #include "OdfDocumentHandler.hxx" +class OdfGenerator; class OdpGeneratorPrivate; /** A generator for presentations. * - * See @c libetonyek library for documentation of the - * libetonyek::KEYPresentationInterface interface. + * See @c librevenge library for documentation of the + * librevenge::KEYPresentationInterface interface. */ -class OdpGenerator : public libetonyek::KEYPresentationInterface +class ODFGENAPI OdpGenerator : public librevenge::RVNGPresentationInterface { public: - OdpGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + OdpGenerator(); ~OdpGenerator(); + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + librevenge::RVNGStringVector getObjectNames() const; + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); - void startDocument(const ::WPXPropertyList &propList); + void startDocument(const ::librevenge::RVNGPropertyList &propList); void endDocument(); - void setDocumentMetaData(const ::WPXPropertyList &propList); - void startSlide(const ::WPXPropertyList &propList); + void setDocumentMetaData(const ::librevenge::RVNGPropertyList &propList); + void defineEmbeddedFont(const librevenge::RVNGPropertyList &propList); + void startSlide(const ::librevenge::RVNGPropertyList &propList); void endSlide(); - void startLayer(const ::WPXPropertyList &propList); + void startMasterSlide(const ::librevenge::RVNGPropertyList &propList); + void endMasterSlide(); + void setSlideTransition(const ::librevenge::RVNGPropertyList &propList); + void startLayer(const ::librevenge::RVNGPropertyList &propList); void endLayer(); - void startEmbeddedGraphics(const ::WPXPropertyList &propList); + void startEmbeddedGraphics(const ::librevenge::RVNGPropertyList &propList); void endEmbeddedGraphics(); - void startGroup(const ::WPXPropertyList &propList); - void endGroup(); + void openGroup(const ::librevenge::RVNGPropertyList &propList); + void closeGroup(); - void setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &gradient); + void setStyle(const ::librevenge::RVNGPropertyList &propList); - void drawRectangle(const ::WPXPropertyList &propList); - void drawEllipse(const ::WPXPropertyList &propList); - void drawPolyline(const ::WPXPropertyListVector &vertices); - void drawPolygon(const ::WPXPropertyListVector &vertices); - void drawPath(const ::WPXPropertyListVector &path); - void drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData &binaryData); - void drawConnector(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &path); + void drawRectangle(const ::librevenge::RVNGPropertyList &propList); + void drawEllipse(const ::librevenge::RVNGPropertyList &propList); + void drawPolyline(const ::librevenge::RVNGPropertyList &propList); + void drawPolygon(const ::librevenge::RVNGPropertyList &propList); + void drawPath(const ::librevenge::RVNGPropertyList &propList); + void drawGraphicObject(const ::librevenge::RVNGPropertyList &propList); + void drawConnector(const ::librevenge::RVNGPropertyList &propList); - void startTextObject(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &path); + void startTextObject(const ::librevenge::RVNGPropertyList &propList); void endTextObject(); - void openParagraph(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &tabStops); + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + void openParagraph(const ::librevenge::RVNGPropertyList &propList); void closeParagraph(); - void openSpan(const ::WPXPropertyList &propList); + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + void openSpan(const ::librevenge::RVNGPropertyList &propList); void closeSpan(); - void insertText(const ::WPXString &str); + + void openLink(const librevenge::RVNGPropertyList &propList); + void closeLink(); + + void insertText(const ::librevenge::RVNGString &str); void insertTab(); void insertSpace(); void insertLineBreak(); - void insertField(const WPXString &type, const ::WPXPropertyList &propList); + void insertField(const ::librevenge::RVNGPropertyList &propList); - void openOrderedListLevel(const ::WPXPropertyList &propList); - void openUnorderedListLevel(const ::WPXPropertyList &propList); + void openOrderedListLevel(const ::librevenge::RVNGPropertyList &propList); + void openUnorderedListLevel(const ::librevenge::RVNGPropertyList &propList); void closeOrderedListLevel(); void closeUnorderedListLevel(); - void openListElement(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &tabStops); + void openListElement(const ::librevenge::RVNGPropertyList &propList); void closeListElement(); - void openTable(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &columns); - void openTableRow(const ::WPXPropertyList &propList); + void startTableObject(const ::librevenge::RVNGPropertyList &propList); + void openTableRow(const ::librevenge::RVNGPropertyList &propList); void closeTableRow(); - void openTableCell(const ::WPXPropertyList &propList); + void openTableCell(const ::librevenge::RVNGPropertyList &propList); void closeTableCell(); - void insertCoveredTableCell(const ::WPXPropertyList &propList); - void closeTable(); + void insertCoveredTableCell(const ::librevenge::RVNGPropertyList &propList); + void endTableObject(); - void startComment(const ::WPXPropertyList &propList); + void startComment(const ::librevenge::RVNGPropertyList &propList); void endComment(); - void startNotes(const ::WPXPropertyList &propList); + void startNotes(const ::librevenge::RVNGPropertyList &propList); void endNotes(); + void defineChartStyle(const ::librevenge::RVNGPropertyList &propList); + void openChart(const ::librevenge::RVNGPropertyList &propList); + void closeChart(); + void openChartTextObject(const ::librevenge::RVNGPropertyList &propList); + void closeChartTextObject(); + void openChartPlotArea(const ::librevenge::RVNGPropertyList &propList); + void closeChartPlotArea(); + void insertChartAxis(const ::librevenge::RVNGPropertyList &propList); + void openChartSeries(const ::librevenge::RVNGPropertyList &propList); + void closeChartSeries(); + + void openAnimationSequence(const ::librevenge::RVNGPropertyList &propList); + void closeAnimationSequence(); + void openAnimationGroup(const ::librevenge::RVNGPropertyList &propList); + void closeAnimationGroup(); + void openAnimationIteration(const ::librevenge::RVNGPropertyList &propList); + void closeAnimationIteration(); + void insertMotionAnimation(const ::librevenge::RVNGPropertyList &propList); + void insertColorAnimation(const ::librevenge::RVNGPropertyList &propList); + void insertAnimation(const ::librevenge::RVNGPropertyList &propList); + void insertEffect(const ::librevenge::RVNGPropertyList &propList); + + /** Registers a handler for embedded images. + * + * @param[in] mimeType MIME type of the image + * @param[in] imageHandler a function that handles processing of + * the image's data and generating output + */ + void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler); + /** Registers a handler for embedded objects. + * + * @param[in] mimeType MIME type of the object + * @param[in] objectHandler a function that handles processing of + * the object's data and generating output + */ + void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler); + + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); private: // disable copying OdpGenerator(OdpGenerator const &); diff -Nru libodfgen-0.0.4/inc/libodfgen/OdsGenerator.hxx libodfgen-0.1.1/inc/libodfgen/OdsGenerator.hxx --- libodfgen-0.0.4/inc/libodfgen/OdsGenerator.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/OdsGenerator.hxx 2014-05-24 18:20:05.000000000 +0000 @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _ODSGENERATOR_HXX_ +#define _ODSGENERATOR_HXX_ + +#include + +#include "libodfgen-api.hxx" +#include "OdfDocumentHandler.hxx" + +class OdfGenerator; +class OdsGeneratorPrivate; + +/** A generator for text documents. + * + * See @c libdocumentinterface library for documentation of the librevenge::RVNGSpreadsheetInterface + * interface. + */ +class ODFGENAPI OdsGenerator : public librevenge::RVNGSpreadsheetInterface +{ +public: + OdsGenerator(); + ~OdsGenerator(); + + /** register an handler for a basic type of document */ + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + /** returns the list created embedded object (needed to create chart) */ + librevenge::RVNGStringVector getObjectNames() const; + /** retrieve an embedded object content via a document handler */ + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); + + void setDocumentMetaData(const librevenge::RVNGPropertyList &propList); + void startDocument(const librevenge::RVNGPropertyList &); + void endDocument(); + + void defineEmbeddedFont(const librevenge::RVNGPropertyList &propList); + + void definePageStyle(const librevenge::RVNGPropertyList &) {} + void openPageSpan(const librevenge::RVNGPropertyList &propList); + void closePageSpan(); + + void defineSectionStyle(const librevenge::RVNGPropertyList &) {} + void openSection(const librevenge::RVNGPropertyList &propList); + void closeSection(); + + void openHeader(const librevenge::RVNGPropertyList &propList); + void closeHeader(); + void openFooter(const librevenge::RVNGPropertyList &propList); + void closeFooter(); + + void defineSheetNumberingStyle(const librevenge::RVNGPropertyList &propList); + void openSheet(const librevenge::RVNGPropertyList &propList); + void closeSheet(); + void openSheetRow(const librevenge::RVNGPropertyList &propList); + void closeSheetRow(); + void openSheetCell(const librevenge::RVNGPropertyList &propList); + void closeSheetCell(); + + void defineChartStyle(const librevenge::RVNGPropertyList &propList); + void openChart(const librevenge::RVNGPropertyList &propList); + void closeChart(); + void openChartTextObject(const librevenge::RVNGPropertyList &propList); + void closeChartTextObject(); + void openChartPlotArea(const librevenge::RVNGPropertyList &propList); + void closeChartPlotArea(); + void insertChartAxis(const librevenge::RVNGPropertyList &axis); + void openChartSerie(const librevenge::RVNGPropertyList &series); + void closeChartSerie(); + + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + void openParagraph(const librevenge::RVNGPropertyList &propList); + void closeParagraph(); + + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + void openSpan(const librevenge::RVNGPropertyList &propList); + void closeSpan(); + + void openLink(const librevenge::RVNGPropertyList &propList); + void closeLink(); + + void insertTab(); + void insertSpace(); + void insertText(const librevenge::RVNGString &text); + void insertLineBreak(); + void insertField(const librevenge::RVNGPropertyList &propList); + + void openOrderedListLevel(const librevenge::RVNGPropertyList &propList); + void openUnorderedListLevel(const librevenge::RVNGPropertyList &propList); + void closeOrderedListLevel(); + void closeUnorderedListLevel(); + void openListElement(const librevenge::RVNGPropertyList &propList); + void closeListElement(); + + void openFootnote(const librevenge::RVNGPropertyList &propList); + void closeFootnote(); + + void openComment(const librevenge::RVNGPropertyList &propList); + void closeComment(); + void openTextBox(const librevenge::RVNGPropertyList &propList); + void closeTextBox(); + + void openTable(const librevenge::RVNGPropertyList &propList); + void openTableRow(const librevenge::RVNGPropertyList &propList); + void closeTableRow(); + void openTableCell(const librevenge::RVNGPropertyList &propList); + void closeTableCell(); + void insertCoveredTableCell(const librevenge::RVNGPropertyList &propList); + void closeTable(); + + void openFrame(const librevenge::RVNGPropertyList &propList); + void closeFrame(); + + void insertBinaryObject(const librevenge::RVNGPropertyList &propList); + + // + // simple Graphic + // + + void openGroup(const librevenge::RVNGPropertyList &propList); + void closeGroup(); + + void defineGraphicStyle(const librevenge::RVNGPropertyList &propList); + void drawRectangle(const librevenge::RVNGPropertyList &propList); + void drawEllipse(const librevenge::RVNGPropertyList &propList); + void drawPolygon(const librevenge::RVNGPropertyList &propList); + void drawPolyline(const librevenge::RVNGPropertyList &propList); + void drawPath(const librevenge::RVNGPropertyList &propList); + void drawConnector(const librevenge::RVNGPropertyList &propList); + + void insertEquation(const librevenge::RVNGPropertyList &) {} + + /** Registers a handler for embedded images. + * + * @param[in] mimeType MIME type of the image + * @param[in] imageHandler a function that handles processing of + * the image's data and generating output + */ + void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler); + /** Registers a handler for embedded objects. + * + * @param[in] mimeType MIME type of the object + * @param[in] objectHandler a function that handles processing of + * the object's data and generating output + */ + void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler); + + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); + +private: + OdsGenerator(OdsGenerator const &); + OdsGenerator &operator=(OdsGenerator const &); + + OdsGeneratorPrivate *mpImpl; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/inc/libodfgen/OdtGenerator.hxx libodfgen-0.1.1/inc/libodfgen/OdtGenerator.hxx --- libodfgen-0.0.4/inc/libodfgen/OdtGenerator.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/inc/libodfgen/OdtGenerator.hxx 2014-05-24 18:20:13.000000000 +0000 @@ -27,101 +27,108 @@ #ifndef _ODTGENERATOR_HXX_ #define _ODTGENERATOR_HXX_ -#include +#include +#include "libodfgen-api.hxx" #include "OdfDocumentHandler.hxx" -/** Handler for embedded objects. - * - * @param[in] data the object's data - * @param[in] pHandler the current OdfDocumentHandler - * @param[in] streamType type of the object - */ -typedef bool (*OdfEmbeddedObject)(const WPXBinaryData &data, OdfDocumentHandler *pHandler, const OdfStreamType streamType); - -/** Handler for embedded images. - * - * @param[in] input the image's data - * @param[in] output the same image in format suitable for the used - * OdfDocumentHandler. - */ -typedef bool (*OdfEmbeddedImage)(const WPXBinaryData &input, WPXBinaryData &output); - class OdtGeneratorPrivate; +class OdfGenerator; /** A generator for text documents. * - * See @c libwpd library for documentation of the ::WPXDocumentInterface + * See @c librevenge library for documentation of the ::librevenge::RVNGTextInterface * interface. */ -class OdtGenerator : public WPXDocumentInterface +class ODFGENAPI OdtGenerator : public librevenge::RVNGTextInterface { public: - OdtGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + OdtGenerator(); ~OdtGenerator(); + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + librevenge::RVNGStringVector getObjectNames() const; + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); - void setDocumentMetaData(const WPXPropertyList &propList); - void startDocument(); + void setDocumentMetaData(const librevenge::RVNGPropertyList &propList); + void startDocument(const librevenge::RVNGPropertyList &); void endDocument(); - void definePageStyle(const WPXPropertyList &); - void openPageSpan(const WPXPropertyList &propList); + void defineEmbeddedFont(const librevenge::RVNGPropertyList &propList); + + void definePageStyle(const librevenge::RVNGPropertyList &); + void openPageSpan(const librevenge::RVNGPropertyList &propList); void closePageSpan(); - void defineSectionStyle(const WPXPropertyList &, const WPXPropertyListVector &); - void openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns); + void defineSectionStyle(const librevenge::RVNGPropertyList &); + void openSection(const librevenge::RVNGPropertyList &propList); void closeSection(); - void openHeader(const WPXPropertyList &propList); + void openHeader(const librevenge::RVNGPropertyList &propList); void closeHeader(); - void openFooter(const WPXPropertyList &propList); + void openFooter(const librevenge::RVNGPropertyList &propList); void closeFooter(); - void defineParagraphStyle(const WPXPropertyList &, const WPXPropertyListVector &); - void openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops); + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + void openParagraph(const librevenge::RVNGPropertyList &propList); void closeParagraph(); - void defineCharacterStyle(const WPXPropertyList &); - void openSpan(const WPXPropertyList &propList); + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + void openSpan(const librevenge::RVNGPropertyList &propList); void closeSpan(); + void openLink(const librevenge::RVNGPropertyList &propList); + void closeLink(); + void insertTab(); void insertSpace(); - void insertText(const WPXString &text); + void insertText(const librevenge::RVNGString &text); void insertLineBreak(); - void insertField(const WPXString &type, const WPXPropertyList &propList); + void insertField(const librevenge::RVNGPropertyList &propList); - void defineOrderedListLevel(const WPXPropertyList &propList); - void defineUnorderedListLevel(const WPXPropertyList &propList); - void openOrderedListLevel(const WPXPropertyList &propList); - void openUnorderedListLevel(const WPXPropertyList &propList); + void openOrderedListLevel(const librevenge::RVNGPropertyList &propList); + void openUnorderedListLevel(const librevenge::RVNGPropertyList &propList); void closeOrderedListLevel(); void closeUnorderedListLevel(); - void openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops); + void openListElement(const librevenge::RVNGPropertyList &propList); void closeListElement(); - void openFootnote(const WPXPropertyList &propList); + void openFootnote(const librevenge::RVNGPropertyList &propList); void closeFootnote(); - void openEndnote(const WPXPropertyList &propList); + void openEndnote(const librevenge::RVNGPropertyList &propList); void closeEndnote(); - void openComment(const WPXPropertyList &propList); + void openComment(const librevenge::RVNGPropertyList &propList); void closeComment(); - void openTextBox(const WPXPropertyList &propList); + void openTextBox(const librevenge::RVNGPropertyList &propList); void closeTextBox(); - void openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns); - void openTableRow(const WPXPropertyList &propList); + void openTable(const librevenge::RVNGPropertyList &propList); + void openTableRow(const librevenge::RVNGPropertyList &propList); void closeTableRow(); - void openTableCell(const WPXPropertyList &propList); + void openTableCell(const librevenge::RVNGPropertyList &propList); void closeTableCell(); - void insertCoveredTableCell(const WPXPropertyList &propList); + void insertCoveredTableCell(const librevenge::RVNGPropertyList &propList); void closeTable(); - void openFrame(const WPXPropertyList &propList); + // + // simple Graphic + // + + void openGroup(const librevenge::RVNGPropertyList &propList); + void closeGroup(); + + void defineGraphicStyle(const librevenge::RVNGPropertyList &propList); + void drawRectangle(const librevenge::RVNGPropertyList &propList); + void drawEllipse(const librevenge::RVNGPropertyList &propList); + void drawPolygon(const librevenge::RVNGPropertyList &propList); + void drawPolyline(const librevenge::RVNGPropertyList &propList); + void drawPath(const librevenge::RVNGPropertyList &propList); + void drawConnector(const librevenge::RVNGPropertyList &propList); + + void openFrame(const librevenge::RVNGPropertyList &propList); void closeFrame(); - void insertBinaryObject(const WPXPropertyList &propList, const WPXBinaryData &data); - void insertEquation(const WPXPropertyList &propList, const WPXString &data); + void insertBinaryObject(const librevenge::RVNGPropertyList &propList); + void insertEquation(const librevenge::RVNGPropertyList &propList); /** Registers a handler for embedded objects. * @@ -129,7 +136,7 @@ * @param[in] objectHandler a function that handles processing of * the object's data and generating output */ - void registerEmbeddedObjectHandler(const WPXString &mimeType, OdfEmbeddedObject objectHandler); + void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler); /** Registers a handler for embedded images. * @@ -140,7 +147,9 @@ * @param[in] imageHandler a function that handles processing of * the images's data and generating output */ - void registerEmbeddedImageHandler(const WPXString &mimeType, OdfEmbeddedImage imageHandler); + void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler); + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); private: OdtGenerator(OdtGenerator const &); diff -Nru libodfgen-0.0.4/inc/Makefile.in libodfgen-0.1.1/inc/Makefile.in --- libodfgen-0.0.4/inc/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/inc/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -201,8 +201,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -247,18 +245,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru libodfgen-0.0.4/libodfgen.pc.in libodfgen-0.1.1/libodfgen.pc.in --- libodfgen-0.0.4/libodfgen.pc.in 2013-12-03 08:05:59.000000000 +0000 +++ libodfgen-0.1.1/libodfgen.pc.in 2014-04-16 17:14:01.000000000 +0000 @@ -4,9 +4,8 @@ includedir=@includedir@ Name: libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@ -Description: Library to generate ODF documents from libwpd's and libwpg's api calls +Description: Library to generate ODF documents from librevenge's api calls Version: @VERSION@ -Requires: libwpd-0.9 -Requires.private: libwpg-0.2 libetonyek-0.0 +Requires: librevenge-0.0 librevenge-stream-0.0 Libs: -L${libdir} -lodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@ Cflags: -I${includedir}/libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@ diff -Nru libodfgen-0.0.4/m4/libtool.m4 libodfgen-0.1.1/m4/libtool.m4 --- libodfgen-0.0.4/m4/libtool.m4 2013-12-01 20:55:35.000000000 +0000 +++ libodfgen-0.1.1/m4/libtool.m4 2014-03-29 10:28:47.000000000 +0000 @@ -1326,10 +1326,10 @@ x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; - powerpcle-*linux*) + powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; - powerpc-*linux*) + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) diff -Nru libodfgen-0.0.4/Makefile.am libodfgen-0.1.1/Makefile.am --- libodfgen-0.0.4/Makefile.am 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/Makefile.am 2014-03-29 10:15:48.000000000 +0000 @@ -2,10 +2,12 @@ pkgconfdir = $(libdir)/pkgconfig - - SUBDIRS = build inc src +if COMPILE_TEST +SUBDIRS += test +endif + if WITH_LIBEBOOK_DOCS SUBDIRS += docs endif @@ -16,7 +18,7 @@ autogen.sh \ config.h.in \ libodfgen.pc.in \ - NEWS README COPYING.MPL COPYING.LGPL + AUTHORS NEWS README COPYING.MPL COPYING.LGPL distclean-local: rm -rf *.cache *~ *.out *.pc diff -Nru libodfgen-0.0.4/Makefile.in libodfgen-0.1.1/Makefile.in --- libodfgen-0.0.4/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -78,12 +78,14 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_LIBEBOOK_DOCS_TRUE@am__append_1 = docs +@COMPILE_TEST_TRUE@am__append_1 = test +@WITH_LIBEBOOK_DOCS_TRUE@am__append_2 = docs subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/config.h.in $(srcdir)/libodfgen.pc.in NEWS README \ - config.guess config.sub depcomp install-sh missing ltmain.sh + $(srcdir)/config.h.in $(srcdir)/libodfgen.pc.in AUTHORS NEWS \ + README config.guess config.sub depcomp install-sh missing \ + ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ @@ -182,7 +184,7 @@ ETAGS = etags CTAGS = ctags CSCOPE = cscope -DIST_SUBDIRS = build inc src docs +DIST_SUBDIRS = build inc src test docs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -255,8 +257,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -301,18 +301,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -368,13 +365,13 @@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 pkgconfdir = $(libdir)/pkgconfig -SUBDIRS = build inc src $(am__append_1) +SUBDIRS = build inc src $(am__append_1) $(am__append_2) pkgconf_DATA = libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@.pc EXTRA_DIST = \ autogen.sh \ config.h.in \ libodfgen.pc.in \ - NEWS README COPYING.MPL COPYING.LGPL + AUTHORS NEWS README COPYING.MPL COPYING.LGPL all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff -Nru libodfgen-0.0.4/NEWS libodfgen-0.1.1/NEWS --- libodfgen-0.0.4/NEWS 2013-12-03 19:28:36.000000000 +0000 +++ libodfgen-0.1.1/NEWS 2014-06-02 17:11:43.000000000 +0000 @@ -1,3 +1,17 @@ +libodfgen 0.1.1 + +- Export API symbols on Windows. +- Fix few minor problems with debug mode. + +libodfgen 0.1.0 + +- rebase to librevenge +- add spreadsheet generator +- split common parts of all generators out to a base class +- add tests for all generators +- add chart generator +- and many other improvements + libodfgen 0.0.4 - fix handling of presentation tables diff -Nru libodfgen-0.0.4/src/DocumentElement.cxx libodfgen-0.1.1/src/DocumentElement.cxx --- libodfgen-0.0.4/src/DocumentElement.cxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/DocumentElement.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -42,9 +42,13 @@ TagElement::print(); } -void TagOpenElement::addAttribute(const WPXString &szAttributeName, const WPXString &sAttributeValue) +void TagOpenElement::addAttribute(const librevenge::RVNGString &szAttributeName, + const librevenge::RVNGString &sAttributeValue, bool forceString) { - maAttrList.insert(szAttributeName.cstr(), sAttributeValue); + if (forceString) + maAttrList.insert(szAttributeName.cstr(), librevenge::RVNGPropertyFactory::newStringProp(sAttributeValue)); + else + maAttrList.insert(szAttributeName.cstr(), sAttributeValue); } void TagCloseElement::write(OdfDocumentHandler *pHandler) const diff -Nru libodfgen-0.0.4/src/DocumentElement.hxx libodfgen-0.1.1/src/DocumentElement.hxx --- libodfgen-0.0.4/src/DocumentElement.hxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/DocumentElement.hxx 2014-05-22 18:12:24.000000000 +0000 @@ -26,11 +26,8 @@ #ifndef _DOCUMENTELEMENT_HXX_ #define _DOCUMENTELEMENT_HXX_ -#include -#include -#include #include - +#include #include class DocumentElement @@ -45,32 +42,33 @@ { public: virtual ~TagElement() {} - TagElement(const WPXString &szTagName) : msTagName(szTagName) {} - const WPXString &getTagName() const + TagElement(const librevenge::RVNGString &szTagName) : msTagName(szTagName) {} + const librevenge::RVNGString &getTagName() const { return msTagName; } virtual void print() const; private: - WPXString msTagName; + librevenge::RVNGString msTagName; }; class TagOpenElement : public TagElement { public: - TagOpenElement(const WPXString &szTagName) : TagElement(szTagName), maAttrList() {} + TagOpenElement(const librevenge::RVNGString &szTagName) : TagElement(szTagName), maAttrList() {} virtual ~TagOpenElement() {} - void addAttribute(const WPXString &szAttributeName, const WPXString &sAttributeValue); + void addAttribute(const librevenge::RVNGString &szAttributeName, + const librevenge::RVNGString &sAttributeValue, bool forceString=true); virtual void write(OdfDocumentHandler *pHandler) const; - virtual void print () const; + virtual void print() const; private: - WPXPropertyList maAttrList; + librevenge::RVNGPropertyList maAttrList; }; class TagCloseElement : public TagElement { public: - TagCloseElement(const WPXString &szTagName) : TagElement(szTagName) {} + TagCloseElement(const librevenge::RVNGString &szTagName) : TagElement(szTagName) {} virtual ~TagCloseElement() {} virtual void write(OdfDocumentHandler *pHandler) const; }; @@ -78,22 +76,22 @@ class CharDataElement : public DocumentElement { public: - CharDataElement(const WPXString &sData) : DocumentElement(), msData(sData) {} + CharDataElement(const librevenge::RVNGString &sData) : DocumentElement(), msData(sData) {} virtual ~CharDataElement() {} virtual void write(OdfDocumentHandler *pHandler) const; private: - WPXString msData; + librevenge::RVNGString msData; }; class TextElement : public DocumentElement { public: - TextElement(const WPXString &sTextBuf) : DocumentElement(), msTextBuf(sTextBuf, false) {} + TextElement(const librevenge::RVNGString &sTextBuf) : DocumentElement(), msTextBuf(sTextBuf) {} virtual ~TextElement() {} virtual void write(OdfDocumentHandler *pHandler) const; private: - WPXString msTextBuf; + librevenge::RVNGString msTextBuf; }; #endif diff -Nru libodfgen-0.0.4/src/FilterInternal.cxx libodfgen-0.1.1/src/FilterInternal.cxx --- libodfgen-0.0.4/src/FilterInternal.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/FilterInternal.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#include "FilterInternal.hxx" + +librevenge::RVNGString libodfgen::doubleToString(const double value) +{ + librevenge::RVNGProperty *prop = librevenge::RVNGPropertyFactory::newDoubleProp(value); + librevenge::RVNGString retVal = prop->getStr(); + delete prop; + return retVal; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/FilterInternal.hxx libodfgen-0.1.1/src/FilterInternal.hxx --- libodfgen-0.0.4/src/FilterInternal.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/FilterInternal.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -24,8 +24,7 @@ #include // for strcmp -#include -#include +#include #ifdef HAVE_CONFIG_H #include @@ -49,15 +48,12 @@ using boost::shared_ptr; #endif - -struct ltstr +namespace libodfgen { - bool operator()(const WPXString &s1, const WPXString &s2) const - { - return strcmp(s1.cstr(), s2.cstr()) < 0; - } -}; -#endif +librevenge::RVNGString doubleToString(const double value); +} // namespace libodfgen + +#endif /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/FontStyle.cxx libodfgen-0.1.1/src/FontStyle.cxx --- libodfgen-0.0.4/src/FontStyle.cxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/FontStyle.cxx 2014-05-22 18:20:21.000000000 +0000 @@ -30,8 +30,9 @@ #include "DocumentElement.hxx" FontStyle::FontStyle(const char *psName, const char *psFontFamily) : Style(psName), - msFontFamily(psFontFamily, true) + msFontFamily() { + msFontFamily.appendEscapedXML(psFontFamily); } FontStyle::~FontStyle() @@ -56,7 +57,7 @@ void FontStyleManager::writeFontsDeclaration(OdfDocumentHandler *pHandler) const { TagOpenElement("office:font-face-decls").write(pHandler); - std::map, ltstr>::const_iterator iter; + std::map >::const_iterator iter; for (iter = mStyleHash.begin(); iter != mStyleHash.end(); ++iter) { (iter->second)->write(pHandler); @@ -72,9 +73,9 @@ pHandler->endElement("office:font-face-decls"); } -WPXString FontStyleManager::findOrAdd(const char *psFontFamily) +librevenge::RVNGString FontStyleManager::findOrAdd(const char *psFontFamily) { - std::map, ltstr>::const_iterator iter = + std::map >::const_iterator iter = mStyleHash.find(psFontFamily); if (iter!=mStyleHash.end()) return psFontFamily; diff -Nru libodfgen-0.0.4/src/FontStyle.hxx libodfgen-0.1.1/src/FontStyle.hxx --- libodfgen-0.0.4/src/FontStyle.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/FontStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -26,7 +26,7 @@ #define _FONTSTYLE_HXX_ #include -#include +#include #include "FilterInternal.hxx" @@ -38,13 +38,13 @@ FontStyle(const char *psName, const char *psFontFamily); ~FontStyle(); virtual void write(OdfDocumentHandler *pHandler) const; - const WPXString &getFontFamily() const + const librevenge::RVNGString &getFontFamily() const { return msFontFamily; } private: - WPXString msFontFamily; + librevenge::RVNGString msFontFamily; }; class FontStyleManager : public StyleManager @@ -60,7 +60,7 @@ Note: the returned font name is actually equalled to psFontFamily */ - WPXString findOrAdd(const char *psFontFamily); + librevenge::RVNGString findOrAdd(const char *psFontFamily); virtual void clean(); virtual void write(OdfDocumentHandler *) const {} @@ -69,7 +69,7 @@ protected: // style name -> SpanStyle - std::map, ltstr> mStyleHash; + std::map > mStyleHash; }; #endif diff -Nru libodfgen-0.0.4/src/GraphicFunctions.cxx libodfgen-0.1.1/src/GraphicFunctions.cxx --- libodfgen-0.0.4/src/GraphicFunctions.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/GraphicFunctions.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -24,9 +24,16 @@ * Corel Corporation or Corel Corporation Limited." */ -#include #include +#include +#include + +#include + +// removeme for ODFGEN_DEBUG_MSG +#include "FilterInternal.hxx" + #include "GraphicFunctions.hxx" #ifndef M_PI @@ -35,10 +42,22 @@ namespace libodfgen { +double getAngle(double bx, double by); +void getEllipticalArcBBox(double x0, double y0, + double rx, double ry, double phi, bool largeArc, bool sweep, double x, double y, + double &xmin, double &ymin, double &xmax, double &ymax); +double quadraticExtreme(double t, double a, double b, double c); +double quadraticDerivative(double a, double b, double c); +void getQuadraticBezierBBox(double x0, double y0, double x1, double y1, double x, double y, + double &xmin, double &ymin, double &xmax, double &ymax); +double cubicBase(double t, double a, double b, double c, double d); +void getCubicBezierBBox(double x0, double y0, double x1, double y1, double x2, double y2, double x, double y, + double &xmin, double &ymin, double &xmax, double &ymax); + double getAngle(double bx, double by) { - return fmod(2*M_PI + (by > 0.0 ? 1.0 : -1.0) * acos( bx / sqrt(bx * bx + by * by) ), 2*M_PI); + return fmod(2*M_PI + (by > 0.0 ? 1.0 : -1.0) * acos(bx / sqrt(bx * bx + by * by)), 2*M_PI); } void getEllipticalArcBBox(double x0, double y0, @@ -51,7 +70,8 @@ if (ry < 0.0) ry *= -1.0; - if (rx == 0.0 || ry == 0.0) + double const absError=1e-5; + if ((rx>-absError && rx-absError && ry x ? x0 : x); @@ -118,7 +138,7 @@ double txmin, txmax, tymin, tymax; // First handle special cases - if (phi == 0 || phi == M_PI) + if ((phi > -absError&&phi < absError) || (phi > M_PI-absError && phi < M_PI+absError)) { xmin = cx - rx; txmin = getAngle(-rx, 0); @@ -129,7 +149,8 @@ ymax = cy + ry; tymax = getAngle(0, ry); } - else if (phi == M_PI / 2.0 || phi == 3.0*M_PI/2.0) + else if ((phi > M_PI / 2.0-absError && phi < M_PI / 2.0+absError) || + (phi > 3.0*M_PI/2.0-absError && phi < 3.0*M_PI/2.0+absError)) { xmin = cx - ry; txmin = getAngle(-ry, 0); @@ -143,7 +164,7 @@ else { txmin = -atan(ry*tan(phi)/rx); - txmax = M_PI - atan (ry*tan(phi)/rx); + txmax = M_PI - atan(ry*tan(phi)/rx); xmin = cx + rx*cos(txmin)*cos(phi) - ry*sin(txmin)*sin(phi); xmax = cx + rx*cos(txmax)*cos(phi) - ry*sin(txmax)*sin(phi); double tmpY = cy + rx*cos(txmin)*sin(phi) + ry*sin(txmin)*cos(phi); @@ -211,7 +232,7 @@ double quadraticDerivative(double a, double b, double c) { double denominator = a - 2.0*b + c; - if (fabs(denominator) != 0.0) + if (fabs(denominator)>1e-10*(a-b)) return (a - b)/denominator; return -1.0; } @@ -225,7 +246,7 @@ ymax = y0 > y ? y0 : y; double t = quadraticDerivative(x0, x1, x); - if(t>=0 && t<=1) + if (t>=0 && t<=1) { double tmpx = quadraticExtreme(t, x0, x1, x); xmin = tmpx < xmin ? tmpx : xmin; @@ -233,7 +254,7 @@ } t = quadraticDerivative(y0, y1, y); - if(t>=0 && t<=1) + if (t>=0 && t<=1) { double tmpy = quadraticExtreme(t, y0, y1, y); ymin = tmpy < ymin ? tmpy : ymin; @@ -265,6 +286,211 @@ } } +static double getInchValue(librevenge::RVNGProperty const *prop) +{ + double value=prop->getDouble(); + switch (prop->getUnit()) + { + case librevenge::RVNG_INCH: + case librevenge::RVNG_GENERIC: // assume inch + return value; + case librevenge::RVNG_POINT: + return value/72.; + case librevenge::RVNG_TWIP: + return value/1440.; + case librevenge::RVNG_PERCENT: + case librevenge::RVNG_UNIT_ERROR: + default: + { + static bool first=true; + if (first) + { + ODFGEN_DEBUG_MSG(("GraphicFunctions::getInchValue: call with no double value\n")); + first=false; + } + break; + } + } + return value; +} +bool getPathBBox(const librevenge::RVNGPropertyListVector &path, double &px, double &py, double &qx, double &qy) +{ + // This must be a mistake and we do not want to crash lower + if (!path.count() || !path[0]["librevenge:path-action"] || path[0]["librevenge:path-action"]->getStr() == "Z") + { + ODFGEN_DEBUG_MSG(("libodfgen:getPathBdBox: get a spurious path\n")); + return false; + } + + // try to find the bounding box + // this is simple convex hull technique, the bounding box might not be + // accurate but that should be enough for this purpose + bool isFirstPoint = true; + + double lastX = 0.0; + double lastY = 0.0; + double lastPrevX = 0.0; + double lastPrevY = 0.0; + px = py = qx = qy = 0.0; + + for (unsigned k = 0; k < path.count(); ++k) + { + if (!path[k]["librevenge:path-action"]) + continue; + std::string action=path[k]["librevenge:path-action"]->getStr().cstr(); + if (action.length()!=1 || action[0]=='Z') continue; + + bool coordOk=path[k]["svg:x"]&&path[k]["svg:y"]; + bool coord1Ok=coordOk && path[k]["svg:x1"]&&path[k]["svg:y1"]; + bool coord2Ok=coord1Ok && path[k]["svg:x2"]&&path[k]["svg:y2"]; + double x=lastX, y=lastY; + if (isFirstPoint) + { + if (!coordOk) + { + ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::_drawPath: the first point has no coordinate\n")); + continue; + } + qx = px = x = getInchValue(path[k]["svg:x"]); + qy = py = y = getInchValue(path[k]["svg:y"]); + lastPrevX = lastX = px; + lastPrevY = lastY = py; + isFirstPoint = false; + } + else + { + if (path[k]["svg:x"]) x=getInchValue(path[k]["svg:x"]); + if (path[k]["svg:y"]) y=getInchValue(path[k]["svg:y"]); + px = (px > x) ? x : px; + py = (py > y) ? y : py; + qx = (qx < x) ? x : qx; + qy = (qy < y) ? y : qy; + } + + double xmin=px, xmax=qx, ymin=py, ymax=qy; + bool lastPrevSet=false; + + if (action[0] == 'C' && coord2Ok) + { + getCubicBezierBBox(lastX, lastY, getInchValue(path[k]["svg:x1"]), getInchValue(path[k]["svg:y1"]), + getInchValue(path[k]["svg:x2"]), getInchValue(path[k]["svg:y2"]), + x, y, xmin, ymin, xmax, ymax); + lastPrevSet=true; + lastPrevX=2*x-getInchValue(path[k]["svg:x2"]); + lastPrevY=2*y-getInchValue(path[k]["svg:y2"]); + } + else if (action[0] == 'S' && coord1Ok) + { + getCubicBezierBBox(lastX, lastY, lastPrevX, lastPrevY, + getInchValue(path[k]["svg:x1"]), getInchValue(path[k]["svg:y1"]), + x, y, xmin, ymin, xmax, ymax); + lastPrevSet=true; + lastPrevX=2*x-getInchValue(path[k]["svg:x1"]); + lastPrevY=2*y-getInchValue(path[k]["svg:y1"]); + } + else if (action[0] == 'Q' && coord1Ok) + { + getQuadraticBezierBBox(lastX, lastY, getInchValue(path[k]["svg:x1"]), getInchValue(path[k]["svg:y1"]), + x, y, xmin, ymin, xmax, ymax); + lastPrevSet=true; + lastPrevX=2*x-getInchValue(path[k]["svg:x1"]); + lastPrevY=2*y-getInchValue(path[k]["svg:y1"]); + } + else if (action[0] == 'T' && coordOk) + { + getQuadraticBezierBBox(lastX, lastY, lastPrevX, lastPrevY, + x, y, xmin, ymin, xmax, ymax); + lastPrevSet=true; + lastPrevX=2*x-lastPrevX; + lastPrevY=2*y-lastPrevY; + } + else if (action[0] == 'A' && coordOk && path[k]["svg:rx"] && path[k]["svg:ry"]) + { + getEllipticalArcBBox(lastX, lastY, getInchValue(path[k]["svg:rx"]), getInchValue(path[k]["svg:ry"]), + path[k]["librevenge:rotate"] ? path[k]["librevenge:rotate"]->getDouble() : 0.0, + path[k]["librevenge:large-arc"] ? path[k]["librevenge:large-arc"]->getInt() : 1, + path[k]["librevenge:sweep"] ? path[k]["librevenge:sweep"]->getInt() : 1, + x, y, xmin, ymin, xmax, ymax); + } + else if (action[0] != 'M' && action[0] != 'L' && action[0] != 'H' && action[0] != 'V') + { + ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::_drawPath: problem reading a path\n")); + } + px = (px > xmin ? xmin : px); + py = (py > ymin ? ymin : py); + qx = (qx < xmax ? xmax : qx); + qy = (qy < ymax ? ymax : qy); + lastX = x; + lastY = y; + if (!lastPrevSet) + { + lastPrevX=lastX; + lastPrevY=lastY; + } + } + return true; +} + +librevenge::RVNGString convertPath(const librevenge::RVNGPropertyListVector &path, double px, double py) +{ + librevenge::RVNGString sValue(""); + for (unsigned i = 0; i < path.count(); ++i) + { + if (!path[i]["librevenge:path-action"]) + continue; + std::string action=path[i]["librevenge:path-action"]->getStr().cstr(); + if (action.length()!=1) continue; + bool coordOk=path[i]["svg:x"]&&path[i]["svg:y"]; + bool coord1Ok=coordOk && path[i]["svg:x1"]&&path[i]["svg:y1"]; + bool coord2Ok=coord1Ok && path[i]["svg:x2"]&&path[i]["svg:y2"]; + librevenge::RVNGString sElement; + // 2540 is 2.54*1000, 2.54 in = 1 inch + if (path[i]["svg:x"] && action[0] == 'H') + { + sElement.sprintf("H%i", (unsigned)((getInchValue(path[i]["svg:x"])-px)*2540)); + sValue.append(sElement); + } + else if (path[i]["svg:y"] && action[0] == 'V') + { + sElement.sprintf("V%i", (unsigned)((getInchValue(path[i]["svg:y"])-py)*2540)); + sValue.append(sElement); + } + else if (coordOk && (action[0] == 'M' || action[0] == 'L' || action[0] == 'T')) + { + sElement.sprintf("%c%i %i", action[0], (unsigned)((getInchValue(path[i]["svg:x"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y"])-py)*2540)); + sValue.append(sElement); + } + else if (coord1Ok && (action[0] == 'Q' || action[0] == 'S')) + { + sElement.sprintf("%c%i %i %i %i", action[0], (unsigned)((getInchValue(path[i]["svg:x1"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y1"])-py)*2540), (unsigned)((getInchValue(path[i]["svg:x"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y"])-py)*2540)); + sValue.append(sElement); + } + else if (coord2Ok && action[0] == 'C') + { + sElement.sprintf("C%i %i %i %i %i %i", (unsigned)((getInchValue(path[i]["svg:x1"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y1"])-py)*2540), (unsigned)((getInchValue(path[i]["svg:x2"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y2"])-py)*2540), (unsigned)((getInchValue(path[i]["svg:x"])-px)*2540), + (unsigned)((getInchValue(path[i]["svg:y"])-py)*2540)); + sValue.append(sElement); + } + else if (coordOk && path[i]["svg:rx"] && path[i]["svg:ry"] && action[0] == 'A') + { + sElement.sprintf("A%i %i %i %i %i %i %i", (unsigned)((getInchValue(path[i]["svg:rx"]))*2540), + (unsigned)((getInchValue(path[i]["svg:ry"]))*2540), (path[i]["librevenge:rotate"] ? path[i]["librevenge:rotate"]->getInt() : 0), + (path[i]["librevenge:large-arc"] ? path[i]["librevenge:large-arc"]->getInt() : 1), + (path[i]["librevenge:sweep"] ? path[i]["librevenge:sweep"]->getInt() : 1), + (unsigned)((getInchValue(path[i]["svg:x"])-px)*2540), (unsigned)((getInchValue(path[i]["svg:y"])-py)*2540)); + sValue.append(sElement); + } + else if (action[0] == 'Z') + sValue.append(" Z"); + } + return sValue; +} + } /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/GraphicFunctions.hxx libodfgen-0.1.1/src/GraphicFunctions.hxx --- libodfgen-0.0.4/src/GraphicFunctions.hxx 2013-12-01 20:54:06.000000000 +0000 +++ libodfgen-0.1.1/src/GraphicFunctions.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -27,27 +27,19 @@ #ifndef GRAPHIC_FUNCTIONS_HXX_INCLUDED #define GRAPHIC_FUNCTIONS_HXX_INCLUDED -namespace libodfgen +namespace librevenge { +class RVNGPropertyList; +class RVNGPropertyListVector; -double getAngle(double bx, double by); - -void getEllipticalArcBBox(double x0, double y0, - double rx, double ry, double phi, bool largeArc, bool sweep, double x, double y, - double &xmin, double &ymin, double &xmax, double &ymax); - -double quadraticExtreme(double t, double a, double b, double c); - -double quadraticDerivative(double a, double b, double c); - -void getQuadraticBezierBBox(double x0, double y0, double x1, double y1, double x, double y, - double &xmin, double &ymin, double &xmax, double &ymax); - -double cubicBase(double t, double a, double b, double c, double d); +class RVNGString; +} -void getCubicBezierBBox(double x0, double y0, double x1, double y1, double x2, double y2, double x, double y, - double &xmin, double &ymin, double &xmax, double &ymax); +namespace libodfgen +{ +bool getPathBBox(const librevenge::RVNGPropertyListVector &path, double &xmin, double &ymin, double &xmax, double &ymax); +librevenge::RVNGString convertPath(const librevenge::RVNGPropertyListVector &path, double xmin, double xmax); } #endif // GRAPHIC_FUNCTIONS_HXX_INCLUDED diff -Nru libodfgen-0.0.4/src/GraphicStyle.cxx libodfgen-0.1.1/src/GraphicStyle.cxx --- libodfgen-0.0.4/src/GraphicStyle.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/GraphicStyle.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,592 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#include + +#include "FilterInternal.hxx" +#include "GraphicStyle.hxx" +#include "DocumentElement.hxx" + +void GraphicStyleManager::clean() +{ + for (size_t i=0; i < mAutomaticStyles.size(); ++i) + delete mAutomaticStyles[i]; + for (size_t i=0; i < mBitmapStyles.size(); ++i) + delete mBitmapStyles[i]; + for (size_t i=0; i < mGradientStyles.size(); ++i) + delete mGradientStyles[i]; + for (size_t i=0; i < mMarkerStyles.size(); ++i) + delete mMarkerStyles[i]; + for (size_t i=0; i < mOpacityStyles.size(); ++i) + delete mOpacityStyles[i]; + for (size_t i=0; i < mStrokeDashStyles.size(); ++i) + delete mStrokeDashStyles[i]; + for (size_t i=0; i < mStyles.size(); ++i) + delete mStyles[i]; + mAutomaticStyles.resize(0); + mBitmapStyles.resize(0); + mGradientStyles.resize(0); + mMarkerStyles.resize(0); + mOpacityStyles.resize(0); + mStrokeDashStyles.resize(0); + mStyles.resize(0); + + mAutomaticNameMap.clear(); + mBitmapNameMap.clear(); + mGradientNameMap.clear(); + mMarkerNameMap.clear(); + mOpacityNameMap.clear(); + mStrokeDashNameMap.clear(); + mStyleNameMap.clear(); +} + +void GraphicStyleManager::writeStyles(OdfDocumentHandler *pHandler) const +{ + for (size_t i=0; i < mBitmapStyles.size(); ++i) + mBitmapStyles[i]->write(pHandler); + for (size_t i=0; i < mGradientStyles.size(); ++i) + mGradientStyles[i]->write(pHandler); + for (size_t i=0; i < mMarkerStyles.size(); ++i) + mMarkerStyles[i]->write(pHandler); + for (size_t i=0; i < mOpacityStyles.size(); ++i) + mOpacityStyles[i]->write(pHandler); + for (size_t i=0; iwrite(pHandler); + for (size_t i=0; iwrite(pHandler); +} + +void GraphicStyleManager::writeAutomaticStyles(OdfDocumentHandler *pHandler) const +{ + for (size_t i=0; i < mAutomaticStyles.size(); ++i) + mAutomaticStyles[i]->write(pHandler); +} + +librevenge::RVNGString GraphicStyleManager::findOrAdd(librevenge::RVNGPropertyList const &propList, bool automatic) +{ + librevenge::RVNGString hashKey = propList.getPropString(); + std::vector &styles= automatic ? mAutomaticStyles : mStyles; + std::map &nameMap= + automatic ? mAutomaticNameMap : mStyleNameMap; + + if (nameMap.find(hashKey) != nameMap.end()) + return nameMap.find(hashKey)->second; + + librevenge::RVNGString name; + if (automatic) + name.sprintf("gr_%i", (int) nameMap.size()); + else + name.sprintf("GraphicStyle_%i", (int) nameMap.size()); + nameMap[hashKey]=name; + + TagOpenElement *openElement = new TagOpenElement("style:style"); + openElement->addAttribute("style:name", name); + openElement->addAttribute("style:family", "graphic"); + if (propList["style:parent-style-name"]) + openElement->addAttribute("style:parent-style-name", propList["style:parent-style-name"]->getStr()); + else + openElement->addAttribute("style:parent-style-name", "standard"); + if (!automatic && propList["style:display-name"]) + openElement->addAttribute("style:display-name", propList["style:display-name"]->getStr()); + styles.push_back(openElement); + + TagOpenElement *graphicElement = new TagOpenElement("style:graphic-properties"); + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (strcmp(i.key(), "style:display-name") && strcmp(i.key(), "style:parent-style-name")) + graphicElement->addAttribute(i.key(),i()->getStr()); + } + styles.push_back(graphicElement); + styles.push_back(new TagCloseElement("style:graphic-properties")); + + styles.push_back(new TagCloseElement("style:style")); + + return name; +} +//////////////////////////////////////////////////////////// +// +//////////////////////////////////////////////////////////// +librevenge::RVNGString GraphicStyleManager::getStyleNameForBitmap(librevenge::RVNGString const &bitmap) +{ + if (bitmap.empty()) + return ""; + if (mBitmapNameMap.find(bitmap) != mBitmapNameMap.end()) + return mBitmapNameMap.find(bitmap)->second; + + librevenge::RVNGString name; + name.sprintf("Bitmap_%i", (int) mBitmapNameMap.size()); + mBitmapNameMap[bitmap]=name; + + TagOpenElement *openElement = new TagOpenElement("draw:fill-image"); + openElement->addAttribute("draw:name", name); + mBitmapStyles.push_back(openElement); + mBitmapStyles.push_back(new TagOpenElement("office:binary-data")); + mBitmapStyles.push_back(new CharDataElement(bitmap)); + mBitmapStyles.push_back(new TagCloseElement("office:binary-data")); + mBitmapStyles.push_back(new TagCloseElement("draw:fill-image")); + return name; +} + +librevenge::RVNGString GraphicStyleManager::getStyleNameForGradient(librevenge::RVNGPropertyList const &style, + bool &needCreateOpacityStyle) +{ + needCreateOpacityStyle=false; + + librevenge::RVNGPropertyList pList; + // default value + pList.insert("draw:style", "linear"); + pList.insert("draw:border", "0%"); + pList.insert("draw:start-intensity", "100%"); + pList.insert("draw:end-intensity", "100%"); + // property rename + if (style["svg:cx"]) + pList.insert("draw:cx", style["svg:cx"]->getStr()); + if (style["svg:cy"]) + pList.insert("draw:cy", style["svg:cy"]->getStr()); + // prepare angle: ODG angle unit is 0.1 degree + double angle = style["draw:angle"] ? style["draw:angle"]->getDouble() : 0.0; + while (angle < 0) + angle += 360; + while (angle > 360) + angle -= 360; + librevenge::RVNGString sValue; + sValue.sprintf("%i", (unsigned)(angle*10)); + pList.insert("draw:angle", sValue); + // gradient vector + const librevenge::RVNGPropertyListVector *gradient = style.child("svg:linearGradient"); + if (!gradient) + gradient = style.child("svg:radialGradient"); + if (gradient) pList.insert("svg:linearGradient", *gradient); + static char const *(wh[]) = + { + "draw:border", "draw:cx", "draw:cy", "draw:end-color", "draw:end-intensity", + "draw:start-color", "draw:start-intensity", "draw:style" + }; + for (int i=0; i<8; ++i) + { + if (style[wh[i]]) + pList.insert(wh[i], style[wh[i]]->getStr()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + if (mGradientNameMap.find(hashKey) != mGradientNameMap.end()) + return mGradientNameMap.find(hashKey)->second; + + librevenge::RVNGString name; + name.sprintf("Gradient_%i", (int) mGradientNameMap.size()); + mGradientNameMap[hashKey]=name; + + TagOpenElement *openElement = new TagOpenElement("draw:gradient"); + openElement->addAttribute("draw:name", name); + openElement->addAttribute("draw:style", pList["draw:style"]->getStr()); + openElement->addAttribute("draw:angle", sValue); + if (pList["draw:cx"]) + openElement->addAttribute("draw:cx", pList["draw:cx"]->getStr()); + if (pList["draw:cy"]) + openElement->addAttribute("draw:cy", pList["draw:cy"]->getStr()); + + if (!gradient || !gradient->count()) + { + if (pList["draw:start-color"]) + openElement->addAttribute("draw:start-color", pList["draw:start-color"]->getStr()); + if (pList["draw:end-color"]) + openElement->addAttribute("draw:end-color", pList["draw:end-color"]->getStr()); + openElement->addAttribute("draw:border", pList["draw:border"]->getStr()); + + openElement->addAttribute("draw:start-intensity", pList["draw:start-intensity"]->getStr()); + openElement->addAttribute("draw:end-intensity", pList["draw:end-intensity"]->getStr()); + + // Work around a mess in LibreOffice where both opacities of 100% are interpreted as complete transparency + // Nevertheless, when one is different, immediately, they are interpreted correctly + if (style["librevenge:start-opacity"] && style["librevenge:end-opacity"] + && (style["librevenge:start-opacity"]->getDouble() != 1.0 || style["librevenge:end-opacity"]->getDouble() != 1.0)) + needCreateOpacityStyle=true; + } + else if (gradient->count() >= 2) + { + if ((*gradient)[1]["svg:stop-color"]) + openElement->addAttribute("draw:start-color", (*gradient)[1]["svg:stop-color"]->getStr()); + if ((*gradient)[0]["svg:stop-color"]) + openElement->addAttribute("draw:end-color", (*gradient)[0]["svg:stop-color"]->getStr()); + if ((*gradient)[0]["svg:stop-opacity"] || (*gradient)[1]["svg:stop-opacity"]) + needCreateOpacityStyle=true; + openElement->addAttribute("draw:border", "0%"); + } + else + { + delete openElement; + return ""; + } + + mGradientStyles.push_back(openElement); + mGradientStyles.push_back(new TagCloseElement("draw:gradient")); + return name; +} + +librevenge::RVNGString GraphicStyleManager::getStyleNameForMarker(librevenge::RVNGPropertyList const &style, bool startMarker) +{ + librevenge::RVNGPropertyList pList; + if (startMarker) + { + if (!style["draw:marker-start-path"]) + return ""; + pList.insert("svg:d", style["draw:marker-start-path"]->getStr()); + if (style["draw:marker-start-viewbox"]) + pList.insert("svg:viewBox", style["draw:marker-start-viewbox"]->getStr()); + } + else + { + if (!style["draw:marker-end-path"]) + return ""; + pList.insert("svg:d", style["draw:marker-end-path"]->getStr()); + if (style["draw:marker-end-viewbox"]) + pList.insert("svg:viewBox", style["draw:marker-end-viewbox"]->getStr()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + if (mMarkerNameMap.find(hashKey) != mMarkerNameMap.end()) + return mMarkerNameMap.find(hashKey)->second; + + librevenge::RVNGString name; + name.sprintf("Marker_%i", (int) mMarkerNameMap.size()); + mMarkerNameMap[hashKey]=name; + + TagOpenElement *openElement = new TagOpenElement("draw:marker"); + openElement->addAttribute("draw:name", name); + if (pList["svg:viewBox"]) + openElement->addAttribute("svg:viewBox", pList["svg:viewBox"]->getStr()); + openElement->addAttribute("svg:d", pList["svg:d"]->getStr()); + mMarkerStyles.push_back(openElement); + mMarkerStyles.push_back(new TagCloseElement("draw:marker")); + return name; +} + +librevenge::RVNGString GraphicStyleManager::getStyleNameForOpacity(librevenge::RVNGPropertyList const &style) +{ + librevenge::RVNGPropertyList pList; + // default value + pList.insert("draw:border", "0%"); + pList.insert("draw:start", "100%"); + pList.insert("draw:end", "100%"); + // property rename + if (style["svg:cx"]) + pList.insert("draw:cx", style["svg:cx"]->getStr()); + if (style["svg:cy"]) + pList.insert("draw:cy", style["svg:cy"]->getStr()); + if (style["draw:start-intensity"]) + pList.insert("draw:start", style["draw:start-intensity"]->getStr()); + if (style["draw:end-intensity"]) + pList.insert("draw:end", style["draw:end-intensity"]->getStr()); + // data in gradient vector + const librevenge::RVNGPropertyListVector *gradient = style.child("svg:linearGradient"); + if (!gradient) + gradient = style.child("svg:radialGradient"); + if (gradient && gradient->count() >= 2) + { + if ((*gradient)[1]["svg:stop-opacity"]) + pList.insert("draw:start", (*gradient)[1]["svg:stop-opacity"]->getStr()); + if ((*gradient)[0]["svg:stop-opacity"]) + pList.insert("draw:end", (*gradient)[0]["svg:stop-opacity"]->getStr()); + } + // prepare angle: ODG angle unit is 0.1 degree + double angle = style["draw:angle"] ? style["draw:angle"]->getDouble() : 0.0; + while (angle < 0) + angle += 360; + while (angle > 360) + angle -= 360; + librevenge::RVNGString sValue; + sValue.sprintf("%i", (unsigned)(angle*10)); + pList.insert("draw:angle", sValue); + // basic data + static char const *(wh[]) = { "draw:border", "draw:cx", "draw:cy" }; + for (int i=0; i<3; ++i) + { + if (style[wh[i]]) + pList.insert(wh[i], style[wh[i]]->getStr()); + } + + librevenge::RVNGString hashKey = pList.getPropString(); + if (mOpacityNameMap.find(hashKey) != mOpacityNameMap.end()) + return mOpacityNameMap.find(hashKey)->second; + + librevenge::RVNGString name; + name.sprintf("Transparency_%i", (int) mOpacityNameMap.size()); + mOpacityNameMap[hashKey]=name; + + TagOpenElement *openElement = new TagOpenElement("draw:opacity"); + openElement->addAttribute("draw:name", name); + openElement->addAttribute("draw:angle", sValue); + if (pList["draw:border"]) + openElement->addAttribute("draw:border", pList["draw:border"]->getStr()); + if (pList["draw:cx"]) + openElement->addAttribute("draw:cx", pList["draw:cx"]->getStr()); + if (pList["draw:cy"]) + openElement->addAttribute("draw:cy", pList["draw:cy"]->getStr()); + if (pList["draw:start"]) + openElement->addAttribute("draw:start", pList["draw:start"]->getStr()); + if (pList["draw:end"]) + openElement->addAttribute("draw:end", pList["draw:end"]->getStr()); + + mOpacityStyles.push_back(openElement); + mOpacityStyles.push_back(new TagCloseElement("draw:opacity")); + return name; +} + +librevenge::RVNGString GraphicStyleManager::getStyleNameForStrokeDash(librevenge::RVNGPropertyList const &style) +{ + librevenge::RVNGPropertyList pList; + if (style["svg:stoke-linecap"]) + pList.insert("draw:style", style["svg:stroke-linecap"]->getStr()); + else + pList.insert("draw:style", "rect"); + if (style["draw:distance"]) + pList.insert("draw:distance", style["draw:distance"]->getStr()); + if (style["draw:dots1"]) + pList.insert("draw:dots1", style["draw:dots1"]->getStr()); + if (style["draw:dots1-length"]) + pList.insert("draw:dots1-length", style["draw:dots1-length"]->getStr()); + if (style["draw:dots2"]) + pList.insert("draw:dots2", style["draw:dots2"]->getStr()); + if (style["draw:dots2-length"]) + pList.insert("draw:dots2-length", style["draw:dots2-length"]->getStr()); + librevenge::RVNGString hashKey = pList.getPropString(); + if (mStrokeDashNameMap.find(hashKey) != mStrokeDashNameMap.end()) + return mStrokeDashNameMap.find(hashKey)->second; + + librevenge::RVNGString name; + name.sprintf("Dash_%i", (int) mStrokeDashNameMap.size()); + mStrokeDashNameMap[hashKey]=name; + + TagOpenElement *openElement = new TagOpenElement("draw:stroke-dash"); + openElement->addAttribute("draw:name", name); + openElement->addAttribute("draw:style", pList["draw:style"]->getStr()); + if (pList["draw:distance"]) + openElement->addAttribute("draw:distance", pList["draw:distance"]->getStr()); + if (pList["draw:dots1"]) + openElement->addAttribute("draw:dots1", pList["draw:dots1"]->getStr()); + if (pList["draw:dots1-length"]) + openElement->addAttribute("draw:dots1-length", pList["draw:dots1-length"]->getStr()); + if (pList["draw:dots2"]) + openElement->addAttribute("draw:dots2", pList["draw:dots2"]->getStr()); + if (pList["draw:dots2-length"]) + openElement->addAttribute("draw:dots2-length", pList["draw:dots2-length"]->getStr()); + mStrokeDashStyles.push_back(openElement); + mStrokeDashStyles.push_back(new TagCloseElement("draw:stroke-dash")); + return name; +} + +void GraphicStyleManager::addGraphicProperties(librevenge::RVNGPropertyList const &style, librevenge::RVNGPropertyList &element) +{ + if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "none") + element.insert("draw:stroke", "none"); + else + { + if (style["svg:stroke-width"]) + element.insert("svg:stroke-width", style["svg:stroke-width"]->getStr()); + if (style["svg:stroke-color"]) + element.insert("svg:stroke-color", style["svg:stroke-color"]->getStr()); + if (style["svg:stroke-opacity"]) + element.insert("svg:stroke-opacity", style["svg:stroke-opacity"]->getStr()); + if (style["svg:stroke-linejoin"]) + element.insert("draw:stroke-linejoin", style["svg:stroke-linejoin"]->getStr()); + if (style["svg:stroke-linecap"]) + element.insert("svg:stoke-linecap", style["svg:stroke-linecap"]->getStr()); + + librevenge::RVNGString name(""); + if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "dash") + name=getStyleNameForStrokeDash(style); + if (!name.empty()) + { + element.insert("draw:stroke", "dash"); + element.insert("draw:stroke-dash", name); + } + else + element.insert("draw:stroke", "solid"); + } + + if (style["draw:color-mode"] && style["draw:color-mode"]->getStr().len() > 0) + element.insert("draw:color-mode", style["draw:color-mode"]->getStr()); + if (style["draw:luminance"] && style["draw:luminance"]->getStr().len() > 0) + element.insert("draw:luminance", style["draw:luminance"]->getStr()); + if (style["draw:contrast"] && style["draw:contrast"]->getStr().len() > 0) + element.insert("draw:contrast", style["draw:contrast"]->getStr()); + if (style["draw:gamma"] && style["draw:gamma"]->getStr().len() > 0) + element.insert("draw:gamma", style["draw:gamma"]->getStr()); + if (style["draw:red"] && style["draw:red"]->getStr().len() > 0) + element.insert("draw:red", style["draw:red"]->getStr()); + if (style["draw:green"] && style["draw:green"]->getStr().len() > 0) + element.insert("draw:green", style["draw:green"]->getStr()); + if (style["draw:blue"] && style["draw:blue"]->getStr().len() > 0) + element.insert("draw:blue", style["draw:blue"]->getStr()); + + if (style["draw:fill"] && style["draw:fill"]->getStr() == "none") + element.insert("draw:fill", "none"); + else + { + if (style["draw:shadow"]) + element.insert("draw:shadow", style["draw:shadow"]->getStr()); + else + element.insert("draw:shadow", "hidden"); + if (style["draw:shadow-offset-x"]) + element.insert("draw:shadow-offset-x", style["draw:shadow-offset-x"]->getStr()); + if (style["draw:shadow-offset-y"]) + element.insert("draw:shadow-offset-y", style["draw:shadow-offset-y"]->getStr()); + if (style["draw:shadow-color"]) + element.insert("draw:shadow-color", style["draw:shadow-color"]->getStr()); + if (style["draw:shadow-opacity"]) + element.insert("draw:shadow-opacity", style["draw:shadow-opacity"]->getStr()); + if (style["svg:fill-rule"]) + element.insert("svg:fill-rule", style["svg:fill-rule"]->getStr()); + } + + if (style["draw:fill"] && style["draw:fill"]->getStr() == "bitmap" && + style["draw:fill-image"] && style["librevenge:mime-type"]) + { + librevenge::RVNGString name=getStyleNameForBitmap(style["draw:fill-image"]->getStr()); + if (!name.empty()) + { + element.insert("draw:fill", "bitmap"); + element.insert("draw:fill-image-name", name); + if (style["draw:fill-image-width"]) + element.insert("draw:fill-image-width", style["draw:fill-image-width"]->getStr()); + else if (style["svg:width"]) + element.insert("draw:fill-image-width", style["svg:width"]->getStr()); + if (style["draw:fill-image-height"]) + element.insert("draw:fill-image-height", style["draw:fill-image-height"]->getStr()); + else if (style["svg:height"]) + element.insert("draw:fill-image-height", style["svg:height"]->getStr()); + if (style["style:repeat"]) + element.insert("style:repeat", style["style:repeat"]->getStr()); + if (style["draw:fill-image-ref-point"]) + element.insert("draw:fill-image-ref-point", style["draw:fill-image-ref-point"]->getStr()); + if (style["draw:fill-image-ref-point-x"]) + element.insert("draw:fill-image-ref-point-x", style["draw:fill-image-ref-point-x"]->getStr()); + if (style["draw:fill-image-ref-point-y"]) + element.insert("draw:fill-image-ref-point-y", style["draw:fill-image-ref-point-y"]->getStr()); + } + else + element.insert("draw:fill", "none"); + } + else if (style["draw:fill"] && style["draw:fill"]->getStr() == "gradient") + { + librevenge::RVNGString gradientName(""), opacityName(""); + bool bUseOpacityGradient = false; + gradientName=getStyleNameForGradient(style, bUseOpacityGradient); + if (!gradientName.empty()) + { + element.insert("draw:fill", "gradient"); + element.insert("draw:fill-gradient-name", gradientName); + if (bUseOpacityGradient) + { + opacityName=getStyleNameForOpacity(style); + if (!opacityName.empty()) + element.insert("draw:opacity-name", opacityName); + } + } + else + { + element.insert("draw:fill", "solid"); + // try to use the gradient to define the color + const librevenge::RVNGPropertyListVector *gradient = style.child("svg:linearGradient"); + if (!gradient) + gradient = style.child("svg:radialGradient"); + if (gradient && gradient->count() >= 1 && (*gradient)[0]["svg:stop-color"]) + element.insert("draw:fill-color", (*gradient)[0]["svg:stop-color"]->getStr()); + } + } + else if (style["draw:fill"] && style["draw:fill"]->getStr() == "solid") + { + element.insert("draw:fill", "solid"); + if (style["draw:fill-color"]) + element.insert("draw:fill-color", style["draw:fill-color"]->getStr()); + if (style["draw:opacity"]) + element.insert("draw:opacity", style["draw:opacity"]->getStr()); + } + + // marker + if (style["draw:marker-start-path"]) + { + librevenge::RVNGString marker=getStyleNameForMarker(style, true); + if (!marker.empty()) + { + element.insert("draw:marker-start", marker); + if (style["draw:marker-start-center"]) + element.insert("draw:marker-start-center", style["draw:marker-start-center"]->getStr()); + if (style["draw:marker-start-width"]) + element.insert("draw:marker-start-width", style["draw:marker-start-width"]->getStr()); + else + element.insert("draw:marker-start-width", "0.118in"); + } + } + if (style["draw:marker-end-path"]) + { + librevenge::RVNGString marker=getStyleNameForMarker(style, false); + if (!marker.empty()) + { + element.insert("draw:marker-end", marker); + if (style["draw:marker-end-center"]) + element.insert("draw:marker-end-center", style["draw:marker-end-center"]->getStr()); + if (style["draw:marker-end-width"]) + element.insert("draw:marker-end-width", style["draw:marker-end-width"]->getStr()); + else + element.insert("draw:marker-end-width", "0.118in"); + } + } + // other + static char const *(others[])= + { + "draw:ole-draw-aspect", + "fo:background-color", + "fo:border","fo:border-top","fo:border-left","fo:border-bottom","fo:border-right", + "fo:clip", + "style:background-transparency", + "style:border-line-width","style:border-line-width-top","style:border-line-width-left", + "style:border-line-width-bottom","style:border-line-width-right", + "style:mirror", "style:parent-style-name", + "style:run-through", "style:wrap" + }; + for (int b = 0; b < 18; b++) + { + if (style[others[b]]) + element.insert(others[b], style[others[b]]->getStr()); + } +} + +void GraphicStyleManager::addFrameProperties(librevenge::RVNGPropertyList const &propList, librevenge::RVNGPropertyList &element) +{ + element.insert("fo:min-width", "1in"); + static char const *attrib[]= + { + "fo:min-width", "fo:min-height", "fo:max-width", "fo:max-height", "fo:padding-top", "fo:padding-bottom", + "fo:padding-left", "fo:padding-right", "draw:textarea-vertical-align" + // checkme + // "draw:z-index", + // "svg:x", "svg:y", "svg:width", "svg:height", "style:wrap", "style:run-through", + // "text:anchor-type", "text:anchor-page-number" + }; + for (int i=0; i<9; ++i) + { + if (propList[attrib[i]]) + element.insert(attrib[i], propList[attrib[i]]->getStr()); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/GraphicStyle.hxx libodfgen-0.1.1/src/GraphicStyle.hxx --- libodfgen-0.0.4/src/GraphicStyle.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/GraphicStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#ifndef _GRAPHICSTYLE_HXX_ +#define _GRAPHICSTYLE_HXX_ + +#include +#include + +#include + +#include "FilterInternal.hxx" + +#include "Style.hxx" + +class OdfDocumentHandler; + +class GraphicStyleManager : public StyleManager +{ +public: + GraphicStyleManager() : mAutomaticStyles(), mBitmapStyles(), mGradientStyles(), mMarkerStyles(), mOpacityStyles(), + mStrokeDashStyles(), mStyles(), mAutomaticNameMap(), mBitmapNameMap(), mGradientNameMap(), mMarkerNameMap(), + mOpacityNameMap(), mStrokeDashNameMap(), mStyleNameMap() {} + virtual ~GraphicStyleManager() + { + clean(); + } + void clean(); + void write(OdfDocumentHandler *) const {} + // write basic style + void writeStyles(OdfDocumentHandler *pHandler) const; + // write automatic styles + void writeAutomaticStyles(OdfDocumentHandler *pHandler) const; + + /** find a style ( or add it to the stored styles) and returns the style name */ + librevenge::RVNGString findOrAdd(librevenge::RVNGPropertyList const &propList, bool automatic=true); + + /** append the graphic in the element, ie. the stroke, pattern, bitmap, marker properties */ + void addGraphicProperties(librevenge::RVNGPropertyList const &style, librevenge::RVNGPropertyList &element); + /** append the frame, ... properties in the element, ie. all properties excepted the graphic properties */ + void addFrameProperties(librevenge::RVNGPropertyList const &propList, librevenge::RVNGPropertyList &element); + +protected: + // return a bitmap + librevenge::RVNGString getStyleNameForBitmap(librevenge::RVNGString const &bitmap); + librevenge::RVNGString getStyleNameForGradient(librevenge::RVNGPropertyList const &style, + bool &needCreateOpacityStyle); + librevenge::RVNGString getStyleNameForMarker(librevenge::RVNGPropertyList const &style, bool startMarker); + librevenge::RVNGString getStyleNameForOpacity(librevenge::RVNGPropertyList const &style); + librevenge::RVNGString getStyleNameForStrokeDash(librevenge::RVNGPropertyList const &style); + // graphics styles + std::vector mAutomaticStyles; + std::vector mBitmapStyles; + std::vector mGradientStyles; + std::vector mMarkerStyles; + std::vector mOpacityStyles; + std::vector mStrokeDashStyles; + std::vector mStyles; + + // automatic hash -> style name + std::map mAutomaticNameMap; + // bitmap content -> style name + std::map mBitmapNameMap; + // gradient hash -> style name + std::map mGradientNameMap; + // marker hash -> style name + std::map mMarkerNameMap; + // opacity hash -> style name + std::map mOpacityNameMap; + // stroke dash hash -> style name + std::map mStrokeDashNameMap; + // style hash -> style name + std::map mStyleNameMap; +}; + + + +#endif +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/InternalHandler.cxx libodfgen-0.1.1/src/InternalHandler.cxx --- libodfgen-0.0.4/src/InternalHandler.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/InternalHandler.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -32,14 +32,14 @@ { } -void InternalHandler::startElement(const char *psName, const WPXPropertyList &xPropList) +void InternalHandler::startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList) { TagOpenElement *element = new TagOpenElement(psName); - WPXPropertyList::Iter i(xPropList); - for (i.rewind(); i.next(); ) + librevenge::RVNGPropertyList::Iter i(xPropList); + for (i.rewind(); i.next();) { - // filter out libwpd elements - if (strncmp(i.key(), "libwpd", 6) != 0) + // filter out librevenge elements + if (strncmp(i.key(), "librevenge:", 11)) element->addAttribute(i.key(), i()->getStr()); } mpElements->push_back(element); @@ -50,7 +50,7 @@ mpElements->push_back(new TagCloseElement(psName)); } -void InternalHandler::characters(const WPXString &sCharacters) +void InternalHandler::characters(const librevenge::RVNGString &sCharacters) { mpElements->push_back(new CharDataElement(sCharacters.cstr())); } diff -Nru libodfgen-0.0.4/src/InternalHandler.hxx libodfgen-0.1.1/src/InternalHandler.hxx --- libodfgen-0.0.4/src/InternalHandler.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/InternalHandler.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -26,9 +26,7 @@ #ifndef _INTERNALHANDLER_HXX_ #define _INTERNALHANDLER_HXX_ -#include -#include -#include +#include #include #include "DocumentElement.hxx" @@ -40,9 +38,9 @@ void startDocument() {}; void endDocument() {}; - void startElement(const char *psName, const WPXPropertyList &xPropList); + void startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList); void endElement(const char *psName); - void characters(const WPXString &sCharacters); + void characters(const librevenge::RVNGString &sCharacters); private: InternalHandler(const InternalHandler &); InternalHandler &operator=(const InternalHandler &); diff -Nru libodfgen-0.0.4/src/libodfgen.rc.in libodfgen-0.1.1/src/libodfgen.rc.in --- libodfgen-0.0.4/src/libodfgen.rc.in 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/libodfgen.rc.in 2014-03-29 10:15:48.000000000 +0000 @@ -13,7 +13,7 @@ BEGIN BLOCK "040904B0" BEGIN - VALUE "CompanyName", "The libwpd developer community" + VALUE "CompanyName", "The librevenge developer community" VALUE "FileDescription", "libodfgen" VALUE "FileVersion", "@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@.@LIBODFGEN_MICRO_VERSION@.BUILDNUMBER" VALUE "InternalName", "libodfgen" diff -Nru libodfgen-0.0.4/src/ListStyle.cxx libodfgen-0.1.1/src/ListStyle.cxx --- libodfgen-0.0.4/src/ListStyle.cxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/ListStyle.cxx 2014-05-22 18:16:15.000000000 +0000 @@ -26,14 +26,14 @@ #include "ListStyle.hxx" #include "DocumentElement.hxx" -OrderedListLevelStyle::OrderedListLevelStyle(const WPXPropertyList &xPropList) : +OrderedListLevelStyle::OrderedListLevelStyle(const librevenge::RVNGPropertyList &xPropList) : mPropList(xPropList) { } void OrderedListLevelStyle::write(OdfDocumentHandler *pHandler, int iLevel) const { - WPXString sLevel; + librevenge::RVNGString sLevel; sLevel.sprintf("%i", (iLevel+1)); TagOpenElement listLevelStyleOpen("text:list-level-style-number"); @@ -41,12 +41,14 @@ listLevelStyleOpen.addAttribute("text:style-name", "Numbering_Symbols"); if (mPropList["style:num-prefix"]) { - WPXString sEscapedString(mPropList["style:num-prefix"]->getStr(), true); + librevenge::RVNGString sEscapedString; + sEscapedString.appendEscapedXML(mPropList["style:num-prefix"]->getStr()); listLevelStyleOpen.addAttribute("style:num-prefix", sEscapedString); } if (mPropList["style:num-suffix"]) { - WPXString sEscapedString(mPropList["style:num-suffix"]->getStr(), true); + librevenge::RVNGString sEscapedString; + sEscapedString.appendEscapedXML(mPropList["style:num-suffix"]->getStr()); listLevelStyleOpen.addAttribute("style:num-suffix", sEscapedString); } if (mPropList["style:num-format"]) @@ -78,14 +80,14 @@ pHandler->endElement("text:list-level-style-number"); } -UnorderedListLevelStyle::UnorderedListLevelStyle(const WPXPropertyList &xPropList) +UnorderedListLevelStyle::UnorderedListLevelStyle(const librevenge::RVNGPropertyList &xPropList) : mPropList(xPropList) { } void UnorderedListLevelStyle::write(OdfDocumentHandler *pHandler, int iLevel) const { - WPXString sLevel; + librevenge::RVNGString sLevel; sLevel.sprintf("%i", (iLevel+1)); TagOpenElement listLevelStyleOpen("text:list-level-style-bullet"); listLevelStyleOpen.addAttribute("text:level", sLevel); @@ -93,11 +95,13 @@ if (mPropList["text:bullet-char"] && (mPropList["text:bullet-char"]->getStr().len())) { // The following is needed because the ODF format does not accept bullet chars longer than one character - WPXString::Iter i(mPropList["text:bullet-char"]->getStr()); + librevenge::RVNGString::Iter i(mPropList["text:bullet-char"]->getStr()); i.rewind(); - WPXString sEscapedString("."); + librevenge::RVNGString sEscapedString; if (i.next()) - sEscapedString = WPXString(i(), true); + sEscapedString.appendEscapedXML(i()); + else + sEscapedString.append('.'); listLevelStyleOpen.addAttribute("text:bullet-char", sEscapedString); } @@ -125,6 +129,7 @@ ListStyle::ListStyle(const char *psName, const int iListID) : Style(psName), + mDisplayName(""), mxListLevels(), miListID(iListID) { @@ -159,7 +164,7 @@ mxListLevels[iLevel] = iListLevelStyle; } -void ListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList, bool ordered) +void ListStyle::updateListLevel(const int iLevel, const librevenge::RVNGPropertyList &xPropList, bool ordered) { if (iLevel < 0) return; @@ -176,6 +181,8 @@ { TagOpenElement listStyleOpenElement("text:list-style"); listStyleOpenElement.addAttribute("style:name", getName()); + if (!mDisplayName.empty()) + listStyleOpenElement.addAttribute("style:display-name", mDisplayName); listStyleOpenElement.write(pHandler); for (std::map::const_iterator iter = mxListLevels.begin(); diff -Nru libodfgen-0.0.4/src/ListStyle.hxx libodfgen-0.1.1/src/ListStyle.hxx --- libodfgen-0.0.4/src/ListStyle.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/ListStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -26,7 +26,7 @@ #define _LISTSTYLE_HXX_ #include -#include +#include #include "Style.hxx" @@ -40,19 +40,19 @@ class OrderedListLevelStyle : public ListLevelStyle { public: - OrderedListLevelStyle(const WPXPropertyList &xPropList); + OrderedListLevelStyle(const librevenge::RVNGPropertyList &xPropList); void write(OdfDocumentHandler *pHandler, int iLevel) const; private: - WPXPropertyList mPropList; + librevenge::RVNGPropertyList mPropList; }; class UnorderedListLevelStyle : public ListLevelStyle { public: - UnorderedListLevelStyle(const WPXPropertyList &xPropList); + UnorderedListLevelStyle(const librevenge::RVNGPropertyList &xPropList); void write(OdfDocumentHandler *pHandler, int iLevel) const; private: - WPXPropertyList mPropList; + librevenge::RVNGPropertyList mPropList; }; class ListStyle : public Style @@ -60,13 +60,28 @@ public: ListStyle(const char *psName, const int iListID); virtual ~ListStyle(); - void updateListLevel(const int iLevel, const WPXPropertyList &xPropList, bool ordered); + void updateListLevel(const int iLevel, const librevenge::RVNGPropertyList &xPropList, bool ordered); virtual void write(OdfDocumentHandler *pHandler) const; int getListID() { return miListID; } bool isListLevelDefined(int iLevel) const; + librevenge::RVNGString getDisplayName() const + { + return mDisplayName; + } + bool hasDisplayName() const + { + return !mDisplayName.empty(); + } + void setDisplayName(const char *displayName=0) + { + if (!displayName || !*displayName) + mDisplayName=""; + else + mDisplayName = displayName; + } protected: void setListLevel(int iLevel, ListLevelStyle *iListLevelStyle); @@ -74,6 +89,7 @@ private: ListStyle(const ListStyle &); ListStyle &operator=(const ListStyle &); + librevenge::RVNGString mDisplayName; std::map mxListLevels; const int miListID; }; diff -Nru libodfgen-0.0.4/src/Makefile.am libodfgen-0.1.1/src/Makefile.am --- libodfgen-0.0.4/src/Makefile.am 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/Makefile.am 2014-05-24 18:18:13.000000000 +0000 @@ -11,26 +11,30 @@ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_include_HEADERS = \ $(top_srcdir)/inc/libodfgen/OdfDocumentHandler.hxx \ - $(top_srcdir)/inc/libodfgen/OdtGenerator.hxx \ $(top_srcdir)/inc/libodfgen/OdgGenerator.hxx \ $(top_srcdir)/inc/libodfgen/OdpGenerator.hxx \ - $(top_srcdir)/inc/libodfgen/libodfgen.hxx + $(top_srcdir)/inc/libodfgen/OdsGenerator.hxx \ + $(top_srcdir)/inc/libodfgen/OdtGenerator.hxx \ + $(top_srcdir)/inc/libodfgen/libodfgen.hxx \ + $(top_srcdir)/inc/libodfgen/libodfgen-api.hxx -AM_CXXFLAGS = -I$(top_srcdir)/inc/ $(WPD_CFLAGS) $(WPG_CFLAGS) $(ETONYEK_CFLAGS) $(DEBUG_CXXFLAGS) +AM_CXXFLAGS = -I$(top_srcdir)/inc/ $(REVENGE_CFLAGS) $(DEBUG_CXXFLAGS) -DLIBODFGEN_BUILD -libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LIBADD = @LIBODFGEN_WIN32_RESOURCE@ $(WPD_LIBS) +libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LIBADD = @LIBODFGEN_WIN32_RESOURCE@ $(REVENGE_LIBS) libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_DEPENDENCIES = @LIBODFGEN_WIN32_RESOURCE@ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_SOURCES = \ - FilterInternal.hxx \ - Style.hxx \ DocumentElement.cxx \ DocumentElement.hxx \ + FilterInternal.cxx \ + FilterInternal.hxx \ FontStyle.cxx \ FontStyle.hxx \ GraphicFunctions.cxx \ GraphicFunctions.hxx \ + GraphicStyle.cxx \ + GraphicStyle.hxx \ InternalHandler.cxx \ InternalHandler.hxx \ ListStyle.cxx \ @@ -39,13 +43,21 @@ PageSpan.hxx \ SectionStyle.cxx \ SectionStyle.hxx \ + SheetStyle.cxx \ + SheetStyle.hxx \ TableStyle.cxx \ TableStyle.hxx \ TextRunStyle.cxx \ TextRunStyle.hxx \ + OdcGenerator.cxx \ + OdcGenerator.hxx \ + OdfGenerator.cxx \ + OdfGenerator.hxx \ + OdgGenerator.cxx \ OdpGenerator.cxx \ + OdsGenerator.cxx \ OdtGenerator.cxx \ - OdgGenerator.cxx + Style.hxx if OS_WIN32 diff -Nru libodfgen-0.0.4/src/Makefile.in libodfgen-0.1.1/src/Makefile.in --- libodfgen-0.0.4/src/Makefile.in 2013-12-02 20:20:46.000000000 +0000 +++ libodfgen-0.1.1/src/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -126,10 +126,12 @@ LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = am_libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_OBJECTS = \ - DocumentElement.lo FontStyle.lo GraphicFunctions.lo \ - InternalHandler.lo ListStyle.lo PageSpan.lo SectionStyle.lo \ - TableStyle.lo TextRunStyle.lo OdpGenerator.lo OdtGenerator.lo \ - OdgGenerator.lo + DocumentElement.lo FilterInternal.lo FontStyle.lo \ + GraphicFunctions.lo GraphicStyle.lo InternalHandler.lo \ + ListStyle.lo PageSpan.lo SectionStyle.lo SheetStyle.lo \ + TableStyle.lo TextRunStyle.lo OdcGenerator.lo OdfGenerator.lo \ + OdgGenerator.lo OdpGenerator.lo OdsGenerator.lo \ + OdtGenerator.lo libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_OBJECTS = $(am_libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -233,8 +235,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ETONYEK_CFLAGS = @ETONYEK_CFLAGS@ -ETONYEK_LIBS = @ETONYEK_LIBS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ @@ -279,18 +279,15 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ -WPD_CFLAGS = @WPD_CFLAGS@ -WPD_LIBS = @WPD_LIBS@ -WPD_LIGS = @WPD_LIGS@ -WPG_CFLAGS = @WPG_CFLAGS@ -WPG_LIBS = @WPG_LIBS@ -WPG_LIGS = @WPG_LIGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -352,24 +349,28 @@ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_include_HEADERS = \ $(top_srcdir)/inc/libodfgen/OdfDocumentHandler.hxx \ - $(top_srcdir)/inc/libodfgen/OdtGenerator.hxx \ $(top_srcdir)/inc/libodfgen/OdgGenerator.hxx \ $(top_srcdir)/inc/libodfgen/OdpGenerator.hxx \ - $(top_srcdir)/inc/libodfgen/libodfgen.hxx + $(top_srcdir)/inc/libodfgen/OdsGenerator.hxx \ + $(top_srcdir)/inc/libodfgen/OdtGenerator.hxx \ + $(top_srcdir)/inc/libodfgen/libodfgen.hxx \ + $(top_srcdir)/inc/libodfgen/libodfgen-api.hxx -AM_CXXFLAGS = -I$(top_srcdir)/inc/ $(WPD_CFLAGS) $(WPG_CFLAGS) $(ETONYEK_CFLAGS) $(DEBUG_CXXFLAGS) -libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LIBADD = @LIBODFGEN_WIN32_RESOURCE@ $(WPD_LIBS) +AM_CXXFLAGS = -I$(top_srcdir)/inc/ $(REVENGE_CFLAGS) $(DEBUG_CXXFLAGS) -DLIBODFGEN_BUILD +libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LIBADD = @LIBODFGEN_WIN32_RESOURCE@ $(REVENGE_LIBS) libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_DEPENDENCIES = @LIBODFGEN_WIN32_RESOURCE@ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_SOURCES = \ - FilterInternal.hxx \ - Style.hxx \ DocumentElement.cxx \ DocumentElement.hxx \ + FilterInternal.cxx \ + FilterInternal.hxx \ FontStyle.cxx \ FontStyle.hxx \ GraphicFunctions.cxx \ GraphicFunctions.hxx \ + GraphicStyle.cxx \ + GraphicStyle.hxx \ InternalHandler.cxx \ InternalHandler.hxx \ ListStyle.cxx \ @@ -378,13 +379,21 @@ PageSpan.hxx \ SectionStyle.cxx \ SectionStyle.hxx \ + SheetStyle.cxx \ + SheetStyle.hxx \ TableStyle.cxx \ TableStyle.hxx \ TextRunStyle.cxx \ TextRunStyle.hxx \ + OdcGenerator.cxx \ + OdcGenerator.hxx \ + OdfGenerator.cxx \ + OdfGenerator.hxx \ + OdgGenerator.cxx \ OdpGenerator.cxx \ + OdsGenerator.cxx \ OdtGenerator.cxx \ - OdgGenerator.cxx + Style.hxx # These may be in the builddir too @@ -473,15 +482,21 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DocumentElement.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FilterInternal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontStyle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GraphicFunctions.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GraphicStyle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InternalHandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListStyle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdcGenerator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdfGenerator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdgGenerator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdpGenerator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdsGenerator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OdtGenerator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PageSpan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SectionStyle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SheetStyle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TableStyle.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TextRunStyle.Plo@am__quote@ diff -Nru libodfgen-0.0.4/src/OdcGenerator.cxx libodfgen-0.1.1/src/OdcGenerator.cxx --- libodfgen-0.0.4/src/OdcGenerator.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/OdcGenerator.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,1002 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include +#include +#include +#include + +#include + +#include "DocumentElement.hxx" +#include "TextRunStyle.hxx" +#include "FontStyle.hxx" +#include "ListStyle.hxx" +#include "TableStyle.hxx" +#include "FilterInternal.hxx" +#include "InternalHandler.hxx" +#include "OdfGenerator.hxx" +#include "SheetStyle.hxx" + +#include "OdcGenerator.hxx" + +// the state we use for writing the final document +struct ChartDocumentState +{ + ChartDocumentState(); + + bool mbChartOpened; + bool mbChartPlotAreaOpened; + bool mbChartSerieOpened; + bool mbChartTextObjectOpened; + bool mbTableCellOpened; + + std::string mCharTextObjectType; +}; + +ChartDocumentState::ChartDocumentState() : + mbChartOpened(false), mbChartPlotAreaOpened(false), mbChartSerieOpened(false), mbChartTextObjectOpened(false), + mbTableCellOpened(false), + mCharTextObjectType("") +{ +} + +class OdcGeneratorPrivate : public OdfGenerator +{ +public: + OdcGeneratorPrivate(); + ~OdcGeneratorPrivate(); + + bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeStyles(OdfDocumentHandler *pHandler); + void _writeAutomaticStyles(OdfDocumentHandler *pHandler); + + bool canWriteText() const + { + return mChartDocumentStates.top().mbChartTextObjectOpened || + mChartDocumentStates.top().mbTableCellOpened; + } + + librevenge::RVNGString getChartStyleName(int id); + void writeChartStyle(librevenge::RVNGPropertyList const &style, OdfDocumentHandler *pHandler); + librevenge::RVNGString getAddressString(librevenge::RVNGPropertyListVector const *vector) const; + std::stack mChartDocumentStates; + +protected: + // hash key -> name + std::map mHashChartNameMap; + // style name -> chart style + std::map mChartStyleHash; + +private: + OdcGeneratorPrivate(const OdcGeneratorPrivate &); + OdcGeneratorPrivate &operator=(const OdcGeneratorPrivate &); + +}; + +OdcGeneratorPrivate::OdcGeneratorPrivate() : + mChartDocumentStates(), mHashChartNameMap(), mChartStyleHash() +{ + mChartDocumentStates.push(ChartDocumentState()); +} + +OdcGeneratorPrivate::~OdcGeneratorPrivate() +{ + // clean up the mess we made + ODFGEN_DEBUG_MSG(("OdcGenerator: Cleaning up our mess..\n")); +} + +librevenge::RVNGString OdcGeneratorPrivate::getChartStyleName(int id) +{ + if (mIdChartNameMap.find(id)!=mIdChartNameMap.end()) + return mIdChartNameMap.find(id)->second; + + librevenge::RVNGPropertyList pList; + if (mIdChartMap.find(id)!=mIdChartMap.end()) + pList=mIdChartMap.find(id)->second; + else + { + ODFGEN_DEBUG_MSG(("OdcGeneratorPrivate::getChartStyleName: can not find the style %d\n", id)); + pList.clear(); + } + + librevenge::RVNGString hashKey = pList.getPropString(); + std::map::const_iterator iter = + mHashChartNameMap.find(hashKey); + if (iter!=mHashChartNameMap.end()) + { + mIdChartNameMap[id]=iter->second; + return iter->second; + } + + // ok create a new list + librevenge::RVNGString sName(""); + sName.sprintf("Chart%i", mChartStyleHash.size()); + pList.insert("style:name", sName); + mChartStyleHash[sName] =pList; + mHashChartNameMap[hashKey] = sName; + + return sName; +} + +void OdcGeneratorPrivate::writeChartStyle(librevenge::RVNGPropertyList const &style, OdfDocumentHandler *pHandler) +{ + if (!style["style:name"]) + { + ODFGEN_DEBUG_MSG(("OdcGeneratorPrivate::writeChartStyle: can not find the style name\n")); + return; + } + + librevenge::RVNGPropertyList styleOpenList; + styleOpenList.insert("style:name", style["style:name"]->clone()); + if (style["style:display-name"]) + styleOpenList.insert("style:display-name", style["style:display-name"]->clone()); + styleOpenList.insert("style:family", "chart"); + pHandler->startElement("style:style", styleOpenList); + + librevenge::RVNGPropertyList chartProp; + librevenge::RVNGPropertyList::Iter i(style); + for (i.rewind(); i.next();) + { + if (i.child()) continue; + if (!strncmp(i.key(), "chart:", 6) || !strcmp(i.key(), "style:direction") || + !strcmp(i.key(), "style:rotation-angle") || !strcmp(i.key(), "text:line-break")) + chartProp.insert(i.key(),i()->clone()); + } + if (!chartProp.empty()) + { + pHandler->startElement("style:chart-properties", chartProp); + pHandler->endElement("style:chart-properties"); + } + librevenge::RVNGPropertyList textProp; + SpanStyleManager::addSpanProperties(style, textProp); + if (!textProp.empty()) + { + if (textProp["style:font-name"]) + mFontManager.findOrAdd(textProp["style:font-name"]->getStr().cstr()); + pHandler->startElement("style:text-properties", textProp); + pHandler->endElement("style:text-properties"); + } + librevenge::RVNGPropertyList graphProp; + mGraphicManager.addGraphicProperties(style,graphProp); + mGraphicManager.addFrameProperties(style,graphProp); + if (!graphProp.empty()) + { + pHandler->startElement("style:graphic-properties", graphProp); + pHandler->endElement("style:graphic-properties"); + } + pHandler->endElement("style:style"); + +} + +librevenge::RVNGString OdcGeneratorPrivate::getAddressString(librevenge::RVNGPropertyListVector const *vector) const +{ + librevenge::RVNGString res(""); + if (!vector || vector->count()!=1) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::getAddressString: can not find the address propertyList..\n")); + return res; + } + if ((*vector)[0]["librevenge:row"]) + res=SheetManager::convertCellRange((*vector)[0]); + else + res=SheetManager::convertCellsRange((*vector)[0]); + return res; +} + +void OdcGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:automatic-styles").write(pHandler); + mFontManager.write(pHandler); // do nothing + mSpanManager.writeAutomaticStyles(pHandler); + mParagraphManager.writeAutomaticStyles(pHandler); + mGraphicManager.writeAutomaticStyles(pHandler); + + // writing out the lists styles + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + { + if (!(*iterListStyles)->hasDisplayName()) + (*iterListStyles)->write(pHandler); + } + mTableManager.write(pHandler); + std::map::const_iterator iterChartStyles; + for (iterChartStyles=mChartStyleHash.begin(); iterChartStyles!=mChartStyleHash.end(); ++iterChartStyles) + writeChartStyle(iterChartStyles->second,pHandler); + pHandler->endElement("office:automatic-styles"); +} + +void OdcGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:styles").write(pHandler); + + // style:default-style + + // graphic + TagOpenElement defaultGraphicStyleOpenElement("style:default-style"); + defaultGraphicStyleOpenElement.addAttribute("style:family", "graphic"); + defaultGraphicStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // paragraph + TagOpenElement defaultParagraphStyleOpenElement("style:default-style"); + defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph"); + defaultParagraphStyleOpenElement.write(pHandler); + TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:use-window-font-color", "true"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:line-break", "strict"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:text-autospace", "ideograph-alpha"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:punctuation-wrap", "hanging"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:writing-mode", "page"); + defaultParagraphStylePropertiesOpenElement.write(pHandler); + pHandler->endElement("style:paragraph-properties"); + pHandler->endElement("style:default-style"); + + // table + TagOpenElement defaultTableStyleOpenElement("style:default-style"); + defaultTableStyleOpenElement.addAttribute("style:family", "table"); + defaultTableStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // table-row + TagOpenElement defaultTableRowStyleOpenElement("style:default-style"); + defaultTableRowStyleOpenElement.addAttribute("style:family", "table-row"); + defaultTableRowStyleOpenElement.write(pHandler); + TagOpenElement defaultTableRowPropertiesOpenElement("style:table-row-properties"); + defaultTableRowPropertiesOpenElement.addAttribute("fo:keep-together", "auto"); + defaultTableRowPropertiesOpenElement.write(pHandler); + pHandler->endElement("style:table-row-properties"); + pHandler->endElement("style:default-style"); + + // table-column + TagOpenElement defaultTableColumnStyleOpenElement("style:default-style"); + defaultTableColumnStyleOpenElement.addAttribute("style:family", "table-column"); + defaultTableColumnStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // table-cell + TagOpenElement defaultTableCellStyleOpenElement("style:default-style"); + defaultTableCellStyleOpenElement.addAttribute("style:family", "table-cell"); + defaultTableCellStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // basic style + + TagOpenElement standardStyleOpenElement("style:style"); + standardStyleOpenElement.addAttribute("style:name", "Standard"); + standardStyleOpenElement.addAttribute("style:family", "paragraph"); + standardStyleOpenElement.addAttribute("style:class", "text"); + standardStyleOpenElement.write(pHandler); + pHandler->endElement("style:style"); + + static char const *(s_paraStyle[4*4]) = + { + "Text_Body", "Text Body", "Standard", "text", + "Table_Contents", "Table Contents", "Text_Body", "extra", + "Table_Heading", "Table Heading", "Table_Contents", "extra", + "List", "List", "Text_Body", "list" + }; + for (int i=0; i<4; ++i) + { + TagOpenElement paraOpenElement("style:style"); + paraOpenElement.addAttribute("style:name", s_paraStyle[4*i]); + paraOpenElement.addAttribute("style:display-name", s_paraStyle[4*i+1]); + paraOpenElement.addAttribute("style:family", "paragraph"); + paraOpenElement.addAttribute("style:parent-style-name", s_paraStyle[4*i+2]); + paraOpenElement.addAttribute("style:class", s_paraStyle[4*i+3]); + paraOpenElement.write(pHandler); + pHandler->endElement("style:style"); + } + + mSpanManager.writeNamedStyles(pHandler); + mParagraphManager.writeNamedStyles(pHandler); + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + { + if ((*iterListStyles)->hasDisplayName()) + (*iterListStyles)->write(pHandler); + } + mGraphicManager.writeStyles(pHandler); + pHandler->endElement("office:styles"); +} + +bool OdcGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) +{ + if (streamType == ODF_MANIFEST_XML) + { + pHandler->startDocument(); + TagOpenElement manifestElement("manifest:manifest"); + manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"); + manifestElement.addAttribute("manifest:version", "1.2", true); + manifestElement.write(pHandler); + + TagOpenElement mainFile("manifest:file-entry"); + mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.chart"); + mainFile.addAttribute("manifest:full-path", "/"); + mainFile.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + appendFilesInManifest(pHandler); + + TagCloseElement("manifest:manifest").write(pHandler); + pHandler->endDocument(); + return true; + } + + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: Printing out the header stuff..\n")); + + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: Start Document\n")); + pHandler->startDocument(); + + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: preamble\n")); + std::string const documentType=getDocumentType(streamType); + librevenge::RVNGPropertyList docContentPropList; + docContentPropList.insert("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); + docContentPropList.insert("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0"); + docContentPropList.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/"); + docContentPropList.insert("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); + docContentPropList.insert("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); + docContentPropList.insert("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); + docContentPropList.insert("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); + docContentPropList.insert("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); + docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink"); + docContentPropList.insert("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"); + docContentPropList.insert("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); + docContentPropList.insert("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0"); + docContentPropList.insert("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"); + docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML"); + docContentPropList.insert("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0"); + docContentPropList.insert("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0"); + docContentPropList.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); + docContentPropList.insert("office:version", librevenge::RVNGPropertyFactory::newStringProp("1.2")); + if (streamType == ODF_FLAT_XML) + docContentPropList.insert("office:mimetype", "application/vnd.oasis.opendocument.chart"); + pHandler->startElement(documentType.c_str(), docContentPropList); + + // write out the metadata + if (streamType == ODF_FLAT_XML || streamType == ODF_META_XML) + writeDocumentMetaData(pHandler); + + // write out the font styles + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + mFontManager.writeFontsDeclaration(pHandler); + + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: Writing out the styles..\n")); + + // write default styles + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML) + _writeStyles(pHandler); + + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + _writeAutomaticStyles(pHandler); + + if (streamType == ODF_FLAT_XML || streamType == ODF_CONTENT_XML) + { + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: Writing out the document..\n")); + // writing out the document + TagOpenElement("office:body").write(pHandler); + TagOpenElement("office:chart").write(pHandler); + sendStorage(&mBodyStorage, pHandler); + ODFGEN_DEBUG_MSG(("OdcGenerator: Document Body: Finished writing all doc els..\n")); + + pHandler->endElement("office:chart"); + pHandler->endElement("office:body"); + } + + pHandler->endElement(documentType.c_str()); + + pHandler->endDocument(); + + return true; +} + +OdcGenerator::OdcGenerator() : mpImpl(new OdcGeneratorPrivate) +{ +} + +OdcGenerator::~OdcGenerator() +{ + if (mpImpl) + delete mpImpl; +} + +void OdcGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (mpImpl) + mpImpl->addDocumentHandler(pHandler, streamType); +} + +librevenge::RVNGStringVector OdcGenerator::getObjectNames() const +{ + if (mpImpl) + return mpImpl->getObjectNames(); + return librevenge::RVNGStringVector(); +} + +bool OdcGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!mpImpl) + return false; + return mpImpl->getObjectContent(objectName, pHandler); +} + +void OdcGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->setDocumentMetaData(propList); +} + +void OdcGenerator::defineParagraphStyle(librevenge::RVNGPropertyList const &propList) +{ + mpImpl->defineParagraphStyle(propList); +} + +void OdcGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->openParagraph(propList); +} + +void OdcGenerator::closeParagraph() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeParagraph(); +} + +void OdcGenerator::defineCharacterStyle(librevenge::RVNGPropertyList const &propList) +{ + mpImpl->defineCharacterStyle(propList); +} + +void OdcGenerator::openSpan(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText() || mpImpl->mChartDocumentStates.top().mbChartTextObjectOpened) return; + mpImpl->openSpan(propList); +} + +void OdcGenerator::closeSpan() +{ + if (!mpImpl->canWriteText() || mpImpl->mChartDocumentStates.top().mbChartTextObjectOpened) return; + mpImpl->closeSpan(); +} + +void OdcGenerator::openLink(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->openLink(propList); +} + +void OdcGenerator::closeLink() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeLink(); +} + +// ------------------------------- +// list +// ------------------------------- +void OdcGenerator::openOrderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->openListLevel(propList, true); +} + +void OdcGenerator::openUnorderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->openListLevel(propList, false); +} + +void OdcGenerator::closeOrderedListLevel() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeListLevel(); +} + +void OdcGenerator::closeUnorderedListLevel() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeListLevel(); +} + +void OdcGenerator::openListElement(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->openListElement(propList); +} + +void OdcGenerator::closeListElement() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeListElement(); +} + +// ------------------------------- +// chart +// ------------------------------- + +void OdcGenerator::defineChartStyle(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->defineChartStyle(propList); +} + +void OdcGenerator::openChart(const librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mChartDocumentStates.top().mbChartOpened) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChart: a chart is already opened\n")); + return; + } + mpImpl->mChartDocumentStates.push(ChartDocumentState()); + mpImpl->mChartDocumentStates.top().mbChartOpened=true; + + TagOpenElement *openElement = new TagOpenElement("chart:chart"); + for (int i=0; i<8; ++i) + { + static char const *(wh[8]) = + { + "chart:class", "chart:column-mapping", "chart:row-mapping", + "svg:height", "svg:width", "xlink:href", "xlink:type", "xml:id" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + if (!propList["xlink:href"]) + { + openElement->addAttribute("xlink:href",".."); + openElement->addAttribute("xlink:type", "simple"); + } + + if (propList["librevenge:chart-id"]) + openElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(propList["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(openElement); +} + +void OdcGenerator::closeChart() +{ + if (!mpImpl->mChartDocumentStates.top().mbChartOpened) + return; + mpImpl->mChartDocumentStates.pop(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:chart")); +} + +void OdcGenerator::openChartTextObject(const librevenge::RVNGPropertyList &propList) +{ + ChartDocumentState state=mpImpl->mChartDocumentStates.top(); + std::string type(""); + if (propList["librevenge:zone-type"]) type=propList["librevenge:zone-type"]->getStr().cstr(); + if (type!="footer" && type!="legend" && type!="subtitle" && type!="title") + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartTextObject: unknown zone type\n")); + return; + } + if (!state.mbChartOpened || state.mbChartTextObjectOpened || + (type!="label" && state.mbChartPlotAreaOpened) || + (type=="label" && !state.mbChartSerieOpened)) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartTextObject: can not open a text zone\n")); + return; + } + + std::string what="chart:"+type; + state.mbChartTextObjectOpened=true; + state.mCharTextObjectType=what; + mpImpl->mChartDocumentStates.push(state); + + TagOpenElement *openElement = new TagOpenElement(what.c_str()); + for (int i=0; i<2; ++i) + { + static char const *(wh[2]) = + { + "svg:x", "svg:y" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + if (propList["librevenge:chart-id"]) + openElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(propList["librevenge:chart-id"]->getInt())); + + if (type=="legend") + { + for (int i=0; i<4; ++i) + { + static char const *(wh[4]) = + { + "chart:legend-align", "chart:legend-position", + "style:legend-expansion", "style:legend-expansion-aspect-ratio" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + } + else if (type!="label") + { + if (propList.child("table:cell-range")) + { + librevenge::RVNGString range= + mpImpl->getAddressString(propList.child("table:cell-range")); + if (!range.empty()) + openElement->addAttribute("table:cell-range", range); + } + } + mpImpl->getCurrentStorage()->push_back(openElement); +} + +void OdcGenerator::closeChartTextObject() +{ + if (!mpImpl->mChartDocumentStates.top().mbChartTextObjectOpened) + return; + std::string wh = mpImpl->mChartDocumentStates.top().mCharTextObjectType; + mpImpl->mChartDocumentStates.pop(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement(wh.c_str())); +} + +void OdcGenerator::openChartPlotArea(const librevenge::RVNGPropertyList &propList) +{ + ChartDocumentState state=mpImpl->mChartDocumentStates.top(); + if (!state.mbChartOpened || state.mbChartTextObjectOpened || state.mbChartPlotAreaOpened) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartPlotArea: can not open the plot area\n")); + return; + } + state.mbChartPlotAreaOpened=true; + mpImpl->mChartDocumentStates.push(state); + + TagOpenElement *openElement = new TagOpenElement("chart:plot-area"); + for (int i=0; i<17; ++i) + { + static char const *(wh[17]) = + { + "chart:data-source-has-labels", + "dr3d:ambient-color", "dr3d:distance", "dr3d:focal-length", "dr3d:lighting-mode", + "dr3d:projection", "dr3d:shade-mode", "dr3d:shadow-slant", "dr3d:transform", + "dr3d:vpn", "dr3d:vrp", + "dr3d:vup", "svg:height", "svg:width", "svg:x", "svg:y", + "xml:id" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + if (propList.child("table:cell-range-address")) + { + librevenge::RVNGString range= + mpImpl->getAddressString(propList.child("table:cell-range-address")); + if (!range.empty()) + openElement->addAttribute("table:cell-range-address", range); + } + if (propList["librevenge:chart-id"]) + openElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(propList["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(openElement); + + const librevenge::RVNGPropertyListVector *childs=propList.child("librevenge:childs"); + for (unsigned long c=0; c<(childs ? childs->count() : 0); ++c) + { + const librevenge::RVNGPropertyList &child=(*childs)[c]; + std::string type(""); + if (child["librevenge:type"]) + type=child["librevenge:type"]->getStr().cstr(); + if (type=="stock-gain-marker" || type=="stock-loss-marker" || type=="stock-range-line") + { + std::string what="chart:"+type; + TagOpenElement *childElement = new TagOpenElement(what.c_str()); + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:categories")); + } + else if (type=="floor" || type=="wall") + { + std::string what="chart:"+type; + TagOpenElement *childElement = new TagOpenElement(what.c_str()); + if (child["svg:width"]) + childElement->addAttribute("svg:width",child["svg:width"]->getStr()); + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement(what.c_str())); + } + else + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartPlotArea: can not find type of child %d\n", int(c))); + } + } +} + +void OdcGenerator::closeChartPlotArea() +{ + if (!mpImpl->mChartDocumentStates.top().mbChartPlotAreaOpened) + return; + mpImpl->mChartDocumentStates.pop(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:plot-area")); +} + +void OdcGenerator::insertChartAxis(const librevenge::RVNGPropertyList &propList) +{ + ChartDocumentState state=mpImpl->mChartDocumentStates.top(); + if (!state.mbChartPlotAreaOpened) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::insertChartAxis: can not insert axis outside the plot area\n")); + return; + } + TagOpenElement *openElement = new TagOpenElement("chart:axis"); + for (int i=0; i<2; ++i) + { + static char const *(wh[2]) = + { + "chart:dimension", "chart:name" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + if (propList["librevenge:chart-id"]) + openElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(propList["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(openElement); + const librevenge::RVNGPropertyListVector *childs=propList.child("librevenge:childs"); + for (unsigned long c=0; c<(childs ? childs->count() : 0); ++c) + { + const librevenge::RVNGPropertyList &child=(*childs)[c]; + std::string type(""); + if (child["librevenge:type"]) + type=child["librevenge:type"]->getStr().cstr(); + if (type=="categories") + { + TagOpenElement *childElement = new TagOpenElement("chart:categories"); + if (child.child("table:cell-range")) + { + librevenge::RVNGString range= + mpImpl->getAddressString(child.child("table:cell-range")); + if (!range.empty()) + childElement->addAttribute("table:cell-range", range); + } + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:categories")); + } + else if (type=="grid") + { + TagOpenElement *childElement = new TagOpenElement("chart:grid"); + if (child["chart:class"]) + childElement->addAttribute("chart:class",child["chart:class"]->getStr()); + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:grid")); + } + else if (type=="title") + { + TagOpenElement *childElement = new TagOpenElement("chart:title"); + for (int i=0; i<2; ++i) + { + static char const *(wh[2]) = + { + "svg:x", "svg:y" + }; + if (child[wh[i]]) + childElement->addAttribute(wh[i], child[wh[i]]->getStr()); + } + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:title")); + } + else + { + ODFGEN_DEBUG_MSG(("OdcGenerator::insertChartAxis: can not find type of child %d\n", int(c))); + } + } + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:axis")); +} + +void OdcGenerator::openChartSerie(const librevenge::RVNGPropertyList &propList) +{ + ChartDocumentState &state=mpImpl->mChartDocumentStates.top(); + if (!state.mbChartPlotAreaOpened || state.mbChartSerieOpened) + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartSerie: can not insert serie outside the plot area\n")); + return; + } + state.mbChartSerieOpened=true; + TagOpenElement *openElement = new TagOpenElement("chart:series"); + for (int i=0; i<3; ++i) + { + static char const *(wh[3]) = + { + "chart:attached-axis", "chart:class", "xml:id" + }; + if (propList[wh[i]]) + openElement->addAttribute(wh[i], propList[wh[i]]->getStr()); + } + if (propList["librevenge:chart-id"]) + openElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(propList["librevenge:chart-id"]->getInt())); + for (int i=0; i<2; ++i) + { + static char const *(wh[2]) = + { + "chart:label-cell-address", "chart:values-cell-range-address" + }; + if (propList.child(wh[i])) + { + librevenge::RVNGString range= + mpImpl->getAddressString(propList.child(wh[i])); + if (!range.empty()) + openElement->addAttribute(wh[i], range); + } + } + mpImpl->getCurrentStorage()->push_back(openElement); + const librevenge::RVNGPropertyListVector *childs=propList.child("librevenge:childs"); + for (unsigned long c=0; c<(childs ? childs->count() : 0); ++c) + { + const librevenge::RVNGPropertyList &child=(*childs)[c]; + std::string type(""); + if (child["librevenge:type"]) + type=child["librevenge:type"]->getStr().cstr(); + if (type=="data-point") + { + TagOpenElement *childElement = new TagOpenElement("chart:data-point"); + for (int i=0; i<2; ++i) + { + static char const *(wh[2]) = + { + "chart:repeated", "xml:id" + }; + if (child[wh[i]]) + childElement->addAttribute(wh[i], child[wh[i]]->getStr()); + } + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:data-point")); + } + else if (type=="domain") + { + TagOpenElement *childElement = new TagOpenElement("chart:domain"); + if (child.child("table:cell-range")) + { + librevenge::RVNGString range= + mpImpl->getAddressString(child.child("table:cell-range")); + if (!range.empty()) + childElement->addAttribute("table:cell-range", range); + } + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:domain")); + } + else if (type=="error-indicator") + { + TagOpenElement *childElement = new TagOpenElement("chart:error-indicator"); + if (child["chart:dimension"]) + childElement->addAttribute("chart:dimension", child["chart:dimension"]->getStr()); + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:error-indicator")); + } + else if (type=="mean-value") + { + TagOpenElement *childElement = new TagOpenElement("chart:mean-value"); + if (child["librevenge:chart-id"]) + childElement->addAttribute("chart:style-name",mpImpl->getChartStyleName(child["librevenge:chart-id"]->getInt())); + mpImpl->getCurrentStorage()->push_back(childElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:mean-value")); + } + else + { + ODFGEN_DEBUG_MSG(("OdcGenerator::openChartSerie: can not find type of child %d\n", int(c))); + } + } +} + +void OdcGenerator::closeChartSerie() +{ + ChartDocumentState &state=mpImpl->mChartDocumentStates.top(); + if (!state.mbChartSerieOpened) + return; + state.mbChartSerieOpened=false; + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("chart:series")); +} + +// ------------------------------- +// table +// ------------------------------- +void OdcGenerator::openTable(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openTable(propList); +} + +void OdcGenerator::closeTable() +{ + mpImpl->closeTable(); +} + +void OdcGenerator::openTableRow(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openTableRow(propList); +} + +void OdcGenerator::closeTableRow() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->closeTableRow(); +} + +void OdcGenerator::openTableCell(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->mChartDocumentStates.top().mbTableCellOpened = mpImpl->openTableCell(propList); +} + +void OdcGenerator::closeTableCell() +{ + mpImpl->closeTableCell(); + mpImpl->mChartDocumentStates.top().mbTableCellOpened = false; +} + +void OdcGenerator::insertCoveredTableCell(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->insertCoveredTableCell(propList); +} + +void OdcGenerator::insertTab() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->insertTab(); +} + +void OdcGenerator::insertSpace() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->insertSpace(); +} + +void OdcGenerator::insertLineBreak() +{ + if (!mpImpl->canWriteText()) return; + mpImpl->insertLineBreak(); +} + +void OdcGenerator::insertField(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->insertField(propList); +} + +void OdcGenerator::insertText(const librevenge::RVNGString &text) +{ + if (!mpImpl->canWriteText()) return; + mpImpl->insertText(text); +} + +void OdcGenerator::endDocument() +{ + // Write out the collected document + mpImpl->writeTargetDocuments(); +} + +void OdcGenerator::startDocument(const librevenge::RVNGPropertyList &) +{ +} + +void OdcGenerator::initStateWith(OdfGenerator const &orig) +{ + mpImpl->initStateWith(orig); +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdcGenerator.hxx libodfgen-0.1.1/src/OdcGenerator.hxx --- libodfgen-0.0.4/src/OdcGenerator.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/OdcGenerator.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef __ODCGENERATOR_HXX__ +#define __ODCGENERATOR_HXX__ + +#include + +#include + +class OdfGenerator; +class OdcGeneratorPrivate; + +/** A generator for chart generation. + * + * See @c librevenge library for documentation of the + * librevenge::RVNGSpreadsheetInterface interface. + */ +class OdcGenerator +{ +public: + OdcGenerator(); + ~OdcGenerator(); + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + librevenge::RVNGStringVector getObjectNames() const; + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); + + void setDocumentMetaData(const librevenge::RVNGPropertyList &); + void startDocument(const librevenge::RVNGPropertyList &); + void endDocument(); + + void defineChartStyle(const librevenge::RVNGPropertyList &propList); + void openChart(const librevenge::RVNGPropertyList &propList); + void closeChart(); + void openChartTextObject(const librevenge::RVNGPropertyList &propList); + void closeChartTextObject(); + void openChartPlotArea(const librevenge::RVNGPropertyList &propList); + void closeChartPlotArea(); + void insertChartAxis(const librevenge::RVNGPropertyList &axis); + void openChartSerie(const librevenge::RVNGPropertyList &series); + void closeChartSerie(); + + void openTable(const ::librevenge::RVNGPropertyList &propList); + void closeTable(); + void openTableRow(const ::librevenge::RVNGPropertyList &propList); + void closeTableRow(); + void openTableCell(const ::librevenge::RVNGPropertyList &propList); + void closeTableCell(); + void insertCoveredTableCell(const librevenge::RVNGPropertyList &propList); + + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + void openParagraph(const librevenge::RVNGPropertyList &propList); + void closeParagraph(); + + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + void openSpan(const librevenge::RVNGPropertyList &propList); + void closeSpan(); + + void openLink(const librevenge::RVNGPropertyList &propList); + void closeLink(); + + void insertText(const librevenge::RVNGString &text); + void insertTab(); + void insertSpace(); + void insertLineBreak(); + void insertField(const librevenge::RVNGPropertyList &propList); + + void openOrderedListLevel(const librevenge::RVNGPropertyList &propList); + void openUnorderedListLevel(const librevenge::RVNGPropertyList &propList); + void closeOrderedListLevel(); + void closeUnorderedListLevel(); + void openListElement(const librevenge::RVNGPropertyList &propList); + void closeListElement(); + + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); +private: + OdcGenerator(OdcGenerator const &); + OdcGenerator &operator=(OdcGenerator const &); + + OdcGeneratorPrivate *mpImpl; +}; + +#endif // __ODCGENERATOR_HXX__ + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdfGenerator.cxx libodfgen-0.1.1/src/OdfGenerator.cxx --- libodfgen-0.0.4/src/OdfGenerator.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/OdfGenerator.cxx 2014-05-22 18:17:53.000000000 +0000 @@ -0,0 +1,1325 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include + +#include + +#include + +#include "DocumentElement.hxx" +#include "GraphicFunctions.hxx" +#include "InternalHandler.hxx" +#include "ListStyle.hxx" +#include "TableStyle.hxx" + +#include "OdfGenerator.hxx" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +using namespace libodfgen; + +namespace +{ + +static bool getInchValue(librevenge::RVNGProperty const &prop, double &value) +{ + value=prop.getDouble(); + switch (prop.getUnit()) + { + case librevenge::RVNG_INCH: + case librevenge::RVNG_GENERIC: // assume inch + return true; + case librevenge::RVNG_POINT: + value /= 72.; + return true; + case librevenge::RVNG_TWIP: + value /= 1440.; + return true; + case librevenge::RVNG_PERCENT: + case librevenge::RVNG_UNIT_ERROR: + default: + { + static bool first=true; + if (first) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::getInchValue: call with no double value\n")); + first=false; + } + break; + } + } + return false; +} +} // anonymous namespace + + +OdfGenerator::OdfGenerator() : + mpCurrentStorage(&mBodyStorage), mStorageStack(), mMetaDataStorage(), mBodyStorage(), + mFontManager(), mGraphicManager(), mSpanManager(), mParagraphManager(), mTableManager(), + mIdSpanMap(), mIdSpanNameMap(), mLastSpanName(""), + mIdParagraphMap(), mIdParagraphNameMap(), mLastParagraphName(""), + miNumListStyles(0), mListStyles(), mListStates(), mIdListStyleMap(), + miFrameNumber(0), mFrameNameIdMap(), + mGraphicStyle(), + mIdChartMap(), mIdChartNameMap(), + mDocumentStreamHandlers(), + miObjectNumber(1), mNameObjectMap(), + mImageHandlers(), mObjectHandlers() +{ + mListStates.push(ListState()); +} + +OdfGenerator::~OdfGenerator() +{ + mParagraphManager.clean(); + mSpanManager.clean(); + mFontManager.clean(); + mGraphicManager.clean(); + mTableManager.clean(); + emptyStorage(&mMetaDataStorage); + emptyStorage(&mBodyStorage); + for (std::vector::iterator iterListStyles = mListStyles.begin(); + iterListStyles != mListStyles.end(); ++iterListStyles) + delete(*iterListStyles); + std::map::iterator it; + for (it=mNameObjectMap.begin(); it!=mNameObjectMap.end(); ++it) + { + if (it->second) + delete it->second; + } +} + +std::string OdfGenerator::getDocumentType(OdfStreamType streamType) +{ + switch (streamType) + { + case ODF_FLAT_XML: + return "office:document"; + case ODF_CONTENT_XML: + return "office:document-content"; + case ODF_STYLES_XML: + return "office:document-styles"; + case ODF_SETTINGS_XML: + return "office:document-settings"; + case ODF_META_XML: + return "office:document-meta"; + case ODF_MANIFEST_XML: + default: + return "office:document"; + } +} + +void OdfGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList) +{ + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + // filter out librevenge elements + if (strncmp(i.key(), "librevenge:", 11) && strncmp(i.key(), "dcterms:", 8)) + { + mMetaDataStorage.push_back(new TagOpenElement(i.key())); + librevenge::RVNGString sStringValue; + sStringValue.appendEscapedXML(i()->getStr()); + mMetaDataStorage.push_back(new CharDataElement(sStringValue.cstr())); + mMetaDataStorage.push_back(new TagCloseElement(i.key())); + } + } +} + +void OdfGenerator::writeDocumentMetaData(OdfDocumentHandler *pHandler) +{ + if (mMetaDataStorage.empty()) return; + TagOpenElement("office:meta").write(pHandler); + sendStorage(&mMetaDataStorage, pHandler); + pHandler->endElement("office:meta"); +} + +void OdfGenerator::appendFilesInManifest(OdfDocumentHandler *pHandler) +{ + std::map::const_iterator iter = mDocumentStreamHandlers.begin(); + for (; iter != mDocumentStreamHandlers.end(); ++iter) + { + std::string name(""); + switch (iter->first) + { + case ODF_CONTENT_XML: + name="content.xml"; + break; + case ODF_META_XML: + name="meta.xml"; + break; + case ODF_STYLES_XML: + name="styles.xml"; + break; + case ODF_SETTINGS_XML: + name="settings.xml"; + break; + case ODF_FLAT_XML: + case ODF_MANIFEST_XML: + default: + break; + } + if (name.empty()) + continue; + + TagOpenElement file("manifest:file-entry"); + file.addAttribute("manifest:media-type","text/xml"); + file.addAttribute("manifest:full-path", name.c_str()); + file.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + } + std::map::const_iterator oIt; + for (oIt=mNameObjectMap.begin(); oIt!=mNameObjectMap.end(); ++oIt) + { + if (!oIt->second) continue; + + TagOpenElement file("manifest:file-entry"); + file.addAttribute("manifest:media-type",oIt->second->mType); + file.addAttribute("manifest:full-path", oIt->first); + file.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + } + +} + +void OdfGenerator::initStateWith(OdfGenerator const &orig) +{ + mImageHandlers=orig.mImageHandlers; + mObjectHandlers=orig.mObjectHandlers; + mIdSpanMap=orig.mIdSpanMap; + mIdParagraphMap=orig.mIdParagraphMap; + mIdChartMap=orig.mIdChartMap; +} + +//////////////////////////////////////////////////////////// +// object +//////////////////////////////////////////////////////////// +OdfGenerator::ObjectContainer::~ObjectContainer() +{ + for (size_t i=0; i::const_iterator it; + for (it=mNameObjectMap.begin(); it!=mNameObjectMap.end(); ++it) + { + if (!it->second || it->second->mIsDir) continue; + res.append(it->first); + } + return res; +} + +bool OdfGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!pHandler) return false; + std::map::iterator it=mNameObjectMap.find(objectName); + if (it==mNameObjectMap.end() || !it->second) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::getObjectContent: can not find object %s\n", objectName.cstr())); + return false; + } + pHandler->startDocument(); + ObjectContainer &object=*(it->second); + for (size_t i=0; iwrite(pHandler); + } + pHandler->endDocument(); + return true; +} + +//////////////////////////////////////////////////////////// +// storage +//////////////////////////////////////////////////////////// +void OdfGenerator::emptyStorage(Storage *storage) +{ + if (!storage) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::sendStorage: called without storage\n")); + return; + } + for (size_t i=0; isize(); ++i) + { + if ((*storage)[i]) delete(*storage)[i]; + } + storage->resize(0); +} + +void OdfGenerator::sendStorage(Storage const *storage, OdfDocumentHandler *pHandler) +{ + if (!storage) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::sendStorage: called without storage\n")); + return; + } + for (size_t i=0; isize(); ++i) + { + if ((*storage)[i])(*storage)[i]->write(pHandler); + } +} + +void OdfGenerator::pushStorage(Storage *newStorage) +{ + if (!newStorage) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::pushStorage: called without storage\n")); + return; + } + mStorageStack.push(mpCurrentStorage); + mpCurrentStorage=newStorage; +} + +bool OdfGenerator::popStorage() +{ + if (mStorageStack.empty()) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::popStorage: the stack is empty\n")); + return false; + } + mpCurrentStorage=mStorageStack.top(); + mStorageStack.pop(); + return false; +} + +//////////////////////////////////////////////////////////// +// document handler +//////////////////////////////////////////////////////////// +void OdfGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (!pHandler) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::addDocumentHandler: called without handler\n")); + return; + } + mDocumentStreamHandlers[streamType] = pHandler; +} + +void OdfGenerator::writeTargetDocuments() +{ + std::map::const_iterator iter = mDocumentStreamHandlers.begin(); + for (; iter != mDocumentStreamHandlers.end(); ++iter) + writeTargetDocument(iter->second, iter->first); +} + +//////////////////////////////////////////////////////////// +// embedded +//////////////////////////////////////////////////////////// +OdfEmbeddedObject OdfGenerator::findEmbeddedObjectHandler(const librevenge::RVNGString &mimeType) const +{ + std::map::const_iterator i = mObjectHandlers.find(mimeType); + if (i != mObjectHandlers.end()) + return i->second; + + return 0; +} + +OdfEmbeddedImage OdfGenerator::findEmbeddedImageHandler(const librevenge::RVNGString &mimeType) const +{ + std::map::const_iterator i = mImageHandlers.find(mimeType); + if (i != mImageHandlers.end()) + return i->second; + + return 0; +} + +void OdfGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler) +{ + mObjectHandlers[mimeType]=objectHandler; +} + +void OdfGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler) +{ + mImageHandlers[mimeType]=imageHandler; +} + +//////////////////////////////////////////////////////////// +// frame/group +//////////////////////////////////////////////////////////// +void OdfGenerator::openFrame(const librevenge::RVNGPropertyList &propList) +{ + // First, let's create a basic Style for this box + librevenge::RVNGPropertyList style; + if (propList["style:horizontal-pos"]) + style.insert("style:horizontal-pos", propList["style:horizontal-pos"]->getStr()); + else + style.insert("style:horizontal-rel", "left"); + if (propList["style:horizontal-rel"]) + style.insert("style:horizontal-rel", propList["style:horizontal-rel"]->getStr()); + else + style.insert("style:horizontal-rel", "paragraph"); + if (propList["style:vertical-pos"]) + style.insert("style:vertical-pos", propList["style:vertical-pos"]->getStr()); + else + style.insert("style:vertical-rel", "top"); + if (propList["style:vertical-rel"]) + style.insert("style:vertical-rel", propList["style:vertical-rel"]->getStr()); + else + style.insert("style:vertical-rel", "page-content"); + librevenge::RVNGString frameStyleName=mGraphicManager.findOrAdd(style, false); + + librevenge::RVNGPropertyList graphic; + mGraphicManager.addGraphicProperties(propList, graphic); + // we do not want to add the default solid stroke if there are some double/... borders + if (!propList["draw:stroke"]) + graphic.remove("draw:stroke"); + mGraphicManager.addFrameProperties(propList, graphic); + graphic.insert("style:parent-style-name", frameStyleName); + graphic.insert("draw:ole-draw-aspect", "1"); + librevenge::RVNGString frameAutomaticStyleName=mGraphicManager.findOrAdd(graphic); + + // And write the frame itself + unsigned objectId = 0; + if (propList["librevenge:frame-name"]) + objectId= getFrameId(propList["librevenge:frame-name"]->getStr()); + else + objectId= getFrameId(""); + TagOpenElement *drawFrameOpenElement = new TagOpenElement("draw:frame"); + drawFrameOpenElement->addAttribute("draw:style-name", frameAutomaticStyleName); + librevenge::RVNGString objectName; + objectName.sprintf("Object%i", objectId); + drawFrameOpenElement->addAttribute("draw:name", objectName); + if (propList["svg:x"]) + drawFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr()); + if (propList["svg:y"]) + drawFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr()); + addFrameProperties(propList, *drawFrameOpenElement); + mpCurrentStorage->push_back(drawFrameOpenElement); +} + +void OdfGenerator::closeFrame() +{ + mpCurrentStorage->push_back(new TagCloseElement("draw:frame")); +} + +void OdfGenerator::addFrameProperties(const librevenge::RVNGPropertyList &propList, TagOpenElement &element) const +{ + static char const *(frameAttrib[])= + { + "draw:z-index", + "fo:max-width", "fo:max-height", + "style:rel-width", "style:rel-height", // checkme + "text:anchor-page-number", "text:anchor-type" + }; + for (int i=0; i<7; ++i) + { + if (propList[frameAttrib[i]]) + element.addAttribute(frameAttrib[i], propList[frameAttrib[i]]->getStr()); + } + + if (propList["svg:width"]) + element.addAttribute("svg:width", propList["svg:width"]->getStr()); + else if (propList["fo:min-width"]) // fixme: must be an attribute of draw:text-box + element.addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); + if (propList["svg:height"]) + element.addAttribute("svg:height", propList["svg:height"]->getStr()); + else if (propList["fo:min-height"]) // fixme: must be an attribute of draw:text-box + element.addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); +} + +unsigned OdfGenerator::getFrameId(librevenge::RVNGString val) +{ + bool hasLabel = val.cstr() && val.len(); + if (hasLabel && mFrameNameIdMap.find(val) != mFrameNameIdMap.end()) + return mFrameNameIdMap.find(val)->second; + unsigned id=miFrameNumber++; + if (hasLabel) + mFrameNameIdMap[val]=id; + return id; +} + +void OdfGenerator::openGroup(const librevenge::RVNGPropertyList &propList) +{ + TagOpenElement *groupElement=new TagOpenElement("draw:g"); + addFrameProperties(propList, *groupElement); + mpCurrentStorage->push_back(groupElement); +} + +void OdfGenerator::closeGroup() +{ + mpCurrentStorage->push_back(new TagCloseElement("draw:g")); +} + +//////////////////////////////////////////////////////////// +// span/paragraph +//////////////////////////////////////////////////////////// +void OdfGenerator::insertTab() +{ + mpCurrentStorage->push_back(new TagOpenElement("text:tab")); + mpCurrentStorage->push_back(new TagCloseElement("text:tab")); +} + +void OdfGenerator::insertSpace() +{ + mpCurrentStorage->push_back(new TagOpenElement("text:s")); + mpCurrentStorage->push_back(new TagCloseElement("text:s")); +} + +void OdfGenerator::insertLineBreak(bool forceParaClose) +{ + if (!forceParaClose) + { + mpCurrentStorage->push_back(new TagOpenElement("text:line-break")); + mpCurrentStorage->push_back(new TagCloseElement("text:line-break")); + return; + } + closeSpan(); + closeParagraph(); + + TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); + if (!mLastParagraphName.empty()) + pParagraphOpenElement->addAttribute("text:style-name", mLastParagraphName.cstr()); + mpCurrentStorage->push_back(pParagraphOpenElement); + + TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); + if (!mLastSpanName.empty()) + pSpanOpenElement->addAttribute("text:style-name", mLastSpanName.cstr()); + mpCurrentStorage->push_back(pSpanOpenElement); + +} + +void OdfGenerator::insertField(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["librevenge:field-type"] || propList["librevenge:field-type"]->getStr().empty()) + return; + + const librevenge::RVNGString &type = propList["librevenge:field-type"]->getStr(); + + TagOpenElement *openElement = new TagOpenElement(type); + if (type == "text:page-number") + openElement->addAttribute("text:select-page", "current"); + + if (propList["style:num-format"]) + openElement->addAttribute("style:num-format", propList["style:num-format"]->getStr()); + + mpCurrentStorage->push_back(openElement); + mpCurrentStorage->push_back(new TagCloseElement(type)); +} + +void OdfGenerator::insertText(const librevenge::RVNGString &text) +{ + if (!text.empty()) + mpCurrentStorage->push_back(new TextElement(text)); +} + +void OdfGenerator::defineCharacterStyle(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["librevenge:span-id"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::defineCharacterStyle: called without id\n")); + return; + } + mIdSpanMap[propList["librevenge:span-id"]->getInt()]=propList; +} + +void OdfGenerator::openSpan(const librevenge::RVNGPropertyList &propList) +{ + librevenge::RVNGString sName(""); + librevenge::RVNGPropertyList pList(propList); + if (pList["librevenge:span-id"]) + { + int id=pList["librevenge:span-id"]->getInt(); + if (mIdSpanNameMap.find(id)!=mIdSpanNameMap.end()) + sName=mIdSpanNameMap.find(id)->second; + else if (mIdSpanMap.find(id)!=mIdSpanMap.end()) + pList=mIdSpanMap.find(id)->second; + else + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openSpan: can not find the style %d\n", id)); + pList.clear(); + } + } + + if (sName.empty()) + { + if (pList["style:font-name"]) + mFontManager.findOrAdd(pList["style:font-name"]->getStr().cstr()); + sName = mSpanManager.findOrAdd(pList); + if (pList["librevenge:span-id"]) + mIdSpanNameMap[pList["librevenge:span-id"]->getInt()]=sName; + } + TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); + pSpanOpenElement->addAttribute("text:style-name", sName.cstr()); + mpCurrentStorage->push_back(pSpanOpenElement); + mLastSpanName=sName; +} + +void OdfGenerator::closeSpan() +{ + mpCurrentStorage->push_back(new TagCloseElement("text:span")); +} + +void OdfGenerator::openLink(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["librevenge:type"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openLink: linked type is not defined, assume link\n")); + } + TagOpenElement *pLinkOpenElement = new TagOpenElement("text:a"); + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (!i.child()) // write out simple properties only + // The string we get here might be url decoded, so + // sscape characters that might mess up the resulting xml + pLinkOpenElement->addAttribute(i.key(), librevenge::RVNGString::escapeXML(i()->getStr())); + } + mpCurrentStorage->push_back(pLinkOpenElement); +} + +void OdfGenerator::closeLink() +{ + mpCurrentStorage->push_back(new TagCloseElement("text:a")); +} + +void OdfGenerator::defineParagraphStyle(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["librevenge:paragraph-id"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::defineParagraphStyle: called without id\n")); + return; + } + mIdParagraphMap[propList["librevenge:paragraph-id"]->getInt()]=propList; +} + +void OdfGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) +{ + librevenge::RVNGPropertyList pList(propList); + librevenge::RVNGString paragraphName(""); + if (pList["librevenge:paragraph-id"]) + { + int id=pList["librevenge:paragraph-id"]->getInt(); + if (mIdParagraphNameMap.find(id)!=mIdParagraphNameMap.end()) + paragraphName=mIdParagraphNameMap.find(id)->second; + else if (mIdParagraphMap.find(id)!=mIdParagraphMap.end()) + pList=mIdParagraphMap.find(id)->second; + else + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openParagraph: can not find the style %d\n", id)); + pList.clear(); + } + } + + if (paragraphName.empty()) + { + if (pList["style:font-name"]) + mFontManager.findOrAdd(pList["style:font-name"]->getStr().cstr()); + paragraphName = mParagraphManager.findOrAdd(pList); + if (pList["librevenge:paragraph-id"]) + mIdParagraphNameMap[pList["librevenge:paragraph-id"]->getInt()]=paragraphName; + } + + // create a document element corresponding to the paragraph, and append it to our list of document elements + TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); + pParagraphOpenElement->addAttribute("text:style-name", paragraphName); + mpCurrentStorage->push_back(pParagraphOpenElement); + mLastParagraphName=paragraphName; +} + +void OdfGenerator::closeParagraph() +{ + mpCurrentStorage->push_back(new TagCloseElement("text:p")); +} + +//////////////////////////////////////////////////////////// +// list +//////////////////////////////////////////////////////////// +OdfGenerator::ListState::ListState() : + mpCurrentListStyle(0), + miCurrentListLevel(0), + miLastListLevel(0), + miLastListNumber(0), + mbListContinueNumbering(false), + mbListElementParagraphOpened(false), + mbListElementOpened() +{ +} + +OdfGenerator::ListState::ListState(const OdfGenerator::ListState &state) : + mpCurrentListStyle(state.mpCurrentListStyle), + miCurrentListLevel(state.miCurrentListLevel), + miLastListLevel(state.miCurrentListLevel), + miLastListNumber(state.miLastListNumber), + mbListContinueNumbering(state.mbListContinueNumbering), + mbListElementParagraphOpened(state.mbListElementParagraphOpened), + mbListElementOpened(state.mbListElementOpened) +{ +} + +OdfGenerator::ListState &OdfGenerator::getListState() +{ + if (!mListStates.empty()) return mListStates.top(); + ODFGEN_DEBUG_MSG(("OdfGenerator::getListState: call with no state\n")); + static OdfGenerator::ListState bad; + return bad; +} + +void OdfGenerator::popListState() +{ + if (mListStates.size()>1) + mListStates.pop(); +} + +void OdfGenerator::pushListState() +{ + mListStates.push(ListState()); +} + +void OdfGenerator::defineListLevel(const librevenge::RVNGPropertyList &propList, bool ordered) +{ + int id = -1; + if (propList["librevenge:list-id"]) + id = propList["librevenge:list-id"]->getInt(); + + ListStyle *pListStyle = 0; + ListState &state=getListState(); + // as all direct list have the same id:-1, we reused the last list + // excepted at level 0 where we force the redefinition of a new list + if ((id!=-1 || !state.mbListElementOpened.empty()) && + state.mpCurrentListStyle && state.mpCurrentListStyle->getListID() == id) + pListStyle = state.mpCurrentListStyle; + + // this rather appalling conditional makes sure we only start a + // new list (rather than continue an old one) if: (1) we have no + // prior list or the prior list has another listId OR (2) we can + // tell that the user actually is starting a new list at level 1 + // (and only level 1) + if (pListStyle == 0 || + (ordered && propList["librevenge:level"] && propList["librevenge:level"]->getInt()==1 && + (propList["text:start-value"] && propList["text:start-value"]->getInt() != int(state.miLastListNumber+1)))) + { + // first retrieve the displayname + librevenge::RVNGString displayName(""); + if (propList["style:display-name"]) + displayName=propList["style:display-name"]->getStr(); + else if (pListStyle) + displayName=pListStyle->getDisplayName(); + + ODFGEN_DEBUG_MSG(("OdfGenerator: Attempting to create a new list style (listid: %i)\n", id)); + librevenge::RVNGString sName; + if (ordered) + sName.sprintf("OL%i", miNumListStyles); + else + sName.sprintf("UL%i", miNumListStyles); + miNumListStyles++; + + pListStyle = new ListStyle(sName.cstr(), id); + if (!displayName.empty()) + pListStyle->setDisplayName(displayName.cstr()); + storeListStyle(pListStyle); + if (ordered) + { + state.mbListContinueNumbering = false; + state.miLastListNumber = 0; + } + } + else if (ordered) + state.mbListContinueNumbering = true; + + if (!propList["librevenge:level"]) + return; + // Iterate through ALL list styles with the same WordPerfect list id and define a level if it is not already defined + // This solves certain problems with lists that start and finish without reaching certain levels and then begin again + // and reach those levels. See gradguide0405_PC.wpd in the regression suite + for (std::vector::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + { + if ((* iterListStyles) && (* iterListStyles)->getListID() == id) + (* iterListStyles)->updateListLevel((propList["librevenge:level"]->getInt() - 1), propList, ordered); + } +} + +void OdfGenerator::openListLevel(const librevenge::RVNGPropertyList &propList, bool ordered) +{ + ListState &state=getListState(); + if (state.mbListElementParagraphOpened) + { + closeParagraph(); + state.mbListElementParagraphOpened = false; + } + librevenge::RVNGPropertyList pList(propList); + if (!pList["librevenge:level"]) + pList.insert("librevenge:level", int(state.mbListElementOpened.size())+1); + defineListLevel(pList, ordered); + + TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list"); + if (!state.mbListElementOpened.empty() && !state.mbListElementOpened.top()) + { + mpCurrentStorage->push_back(new TagOpenElement("text:list-item")); + state.mbListElementOpened.top() = true; + } + + state.mbListElementOpened.push(false); + if (state.mbListElementOpened.size() == 1) + { + // add a sanity check ( to avoid a crash if mpCurrentListStyle is NULL) + if (state.mpCurrentListStyle) + pListLevelOpenElement->addAttribute("text:style-name", state.mpCurrentListStyle->getName()); + } + + if (ordered && state.mbListContinueNumbering) + pListLevelOpenElement->addAttribute("text:continue-numbering", "true"); + mpCurrentStorage->push_back(pListLevelOpenElement); +} + +void OdfGenerator::closeListLevel() +{ + ListState &state=getListState(); + if (state.mbListElementOpened.empty()) + { + // this implies that openListLevel was not called, so it is better to stop here + ODFGEN_DEBUG_MSG(("OdfGenerator: Attempting to close an unexisting level\n")); + return; + } + if (state.mbListElementOpened.top()) + { + mpCurrentStorage->push_back(new TagCloseElement("text:list-item")); + state.mbListElementOpened.top() = false; + } + + mpCurrentStorage->push_back(new TagCloseElement("text:list")); + state.mbListElementOpened.pop(); +} + +void OdfGenerator::openListElement(const librevenge::RVNGPropertyList &propList) +{ + ListState &state=getListState(); + state.miLastListLevel = state.miCurrentListLevel; + if (state.miCurrentListLevel == 1) + state.miLastListNumber++; + + if (state.mbListElementOpened.top()) + { + mpCurrentStorage->push_back(new TagCloseElement("text:list-item")); + state.mbListElementOpened.top() = false; + } + + librevenge::RVNGPropertyList finalPropList(propList); +#if 0 + // this property is ignored in TextRunStyle.c++ + if (state.mpCurrentListStyle) + finalPropList.insert("style:list-style-name", state.mpCurrentListStyle->getName()); +#endif + finalPropList.insert("style:parent-style-name", "Standard"); + librevenge::RVNGString paragName =mParagraphManager.findOrAdd(finalPropList); + + TagOpenElement *pOpenListItem = new TagOpenElement("text:list-item"); + if (propList["text:start-value"] && propList["text:start-value"]->getInt() > 0) + pOpenListItem->addAttribute("text:start-value", propList["text:start-value"]->getStr()); + mpCurrentStorage->push_back(pOpenListItem); + + TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p"); + pOpenListElementParagraph->addAttribute("text:style-name", paragName); + mpCurrentStorage->push_back(pOpenListElementParagraph); + + state.mbListElementOpened.top() = true; + state.mbListElementParagraphOpened = true; + state.mbListContinueNumbering = false; +} + +void OdfGenerator::closeListElement() +{ + // this code is kind of tricky, because we don't actually close the list element (because this list element + // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel + // code (or when we open another list element) + if (getListState().mbListElementParagraphOpened) + { + closeParagraph(); + getListState().mbListElementParagraphOpened = false; + } +} + +void OdfGenerator::storeListStyle(ListStyle *listStyle) +{ + if (!listStyle || listStyle == getListState().mpCurrentListStyle) + return; + mListStyles.push_back(listStyle); + getListState().mpCurrentListStyle = listStyle; + mIdListStyleMap[listStyle->getListID()]=listStyle; +} + +void OdfGenerator::retrieveListStyle(int id) +{ + // first look if the current style is ok + if (getListState().mpCurrentListStyle && + id == getListState().mpCurrentListStyle->getListID()) + return; + + // use the global map + if (mIdListStyleMap.find(id) != mIdListStyleMap.end()) + { + getListState().mpCurrentListStyle = mIdListStyleMap.find(id)->second; + return; + } + + ODFGEN_DEBUG_MSG(("OdfGenerator: impossible to find a list with id=%d\n",id)); +} + +//////////////////////////////////////////////////////////// +// table +//////////////////////////////////////////////////////////// +void OdfGenerator::openTable(const librevenge::RVNGPropertyList &propList) +{ + mTableManager.openTable(propList); + + Table *table=mTableManager.getActualTable(); + if (!table) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openTable: can not retrieve the table data\n")); + return; + } + librevenge::RVNGString tableName=table->getName(); + + TagOpenElement *pTableOpenElement = new TagOpenElement("table:table"); + pTableOpenElement->addAttribute("table:name", tableName.cstr()); + pTableOpenElement->addAttribute("table:style-name", tableName.cstr()); + mpCurrentStorage->push_back(pTableOpenElement); + + for (int i=0; igetNumColumns(); ++i) + { + TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column"); + librevenge::RVNGString sColumnStyleName; + sColumnStyleName.sprintf("%s.Column%i", tableName.cstr(), (i+1)); + pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr()); + mpCurrentStorage->push_back(pTableColumnOpenElement); + + TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column"); + mpCurrentStorage->push_back(pTableColumnCloseElement); + } +} + +void OdfGenerator::closeTable() +{ + if (!mTableManager.getActualTable()) + return; + mTableManager.closeTable(); + mpCurrentStorage->push_back(new TagCloseElement("table:table")); +} + +bool OdfGenerator::openTableRow(const librevenge::RVNGPropertyList &propList) +{ + Table *table=mTableManager.getActualTable(); + if (!table) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openTableRow called with no table\n")); + return false; + } + librevenge::RVNGString rowName=table->openRow(propList); + if (rowName.empty()) + return false; + bool inHeader=false; + if (table->isRowOpened(inHeader) && inHeader) + mpCurrentStorage->push_back(new TagOpenElement("table:table-header-rows")); + + TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row"); + pTableRowOpenElement->addAttribute("table:style-name", rowName); + mpCurrentStorage->push_back(pTableRowOpenElement); + return true; +} + +void OdfGenerator::closeTableRow() +{ + Table *table=mTableManager.getActualTable(); + if (!table) return; + bool inHeader=false; + if (!table->isRowOpened(inHeader) || !table->closeRow()) return; + mpCurrentStorage->push_back(new TagCloseElement("table:table-row")); + if (inHeader) + mpCurrentStorage->push_back(new TagCloseElement("table:table-header-rows")); +} + +bool OdfGenerator::isInTableRow(bool &inHeaderRow) const +{ + Table const *table=mTableManager.getActualTable(); + if (!table) return false; + return table->isRowOpened(inHeaderRow); +} + +bool OdfGenerator::openTableCell(const librevenge::RVNGPropertyList &propList) +{ + Table *table=mTableManager.getActualTable(); + if (!table) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::openTableCell called with no table\n")); + return false; + } + + librevenge::RVNGString cellName = table->openCell(propList); + if (cellName.empty()) + return false; + + TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell"); + pTableCellOpenElement->addAttribute("table:style-name", cellName); + if (propList["table:number-columns-spanned"]) + pTableCellOpenElement->addAttribute("table:number-columns-spanned", + propList["table:number-columns-spanned"]->getStr().cstr()); + if (propList["table:number-rows-spanned"]) + pTableCellOpenElement->addAttribute("table:number-rows-spanned", + propList["table:number-rows-spanned"]->getStr().cstr()); + // pTableCellOpenElement->addAttribute("table:value-type", "string"); + mpCurrentStorage->push_back(pTableCellOpenElement); + return true; +} + +void OdfGenerator::closeTableCell() +{ + if (!mTableManager.getActualTable() || !mTableManager.getActualTable()->closeCell()) + return; + + mpCurrentStorage->push_back(new TagCloseElement("table:table-cell")); +} + +void OdfGenerator::insertCoveredTableCell(const librevenge::RVNGPropertyList &propList) +{ + if (!mTableManager.getActualTable() || + !mTableManager.getActualTable()->insertCoveredCell(propList)) + return; + + mpCurrentStorage->push_back(new TagOpenElement("table:covered-table-cell")); + mpCurrentStorage->push_back(new TagCloseElement("table:covered-table-cell")); +} + +//////////////////////////////////////////////////////////// +// image/embedded +//////////////////////////////////////////////////////////// +void OdfGenerator::insertBinaryObject(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["office:binary-data"] || !propList["librevenge:mime-type"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::addDocumentHandler: can not find data or mimetype\n")); + return; + } + + OdfEmbeddedObject tmpObjectHandler = findEmbeddedObjectHandler(propList["librevenge:mime-type"]->getStr()); + OdfEmbeddedImage tmpImageHandler = findEmbeddedImageHandler(propList["librevenge:mime-type"]->getStr()); + + if (tmpObjectHandler || tmpImageHandler) + { + try + { + librevenge::RVNGBinaryData data(propList["office:binary-data"]->getStr()); + if (tmpObjectHandler) + { + std::vector tmpContentElements; + InternalHandler tmpHandler(&tmpContentElements); + + + if (tmpObjectHandler(data, &tmpHandler, ODF_FLAT_XML) && !tmpContentElements.empty()) + { + mpCurrentStorage->push_back(new TagOpenElement("draw:object")); + for (std::vector::const_iterator iter = tmpContentElements.begin(); iter != tmpContentElements.end(); ++iter) + mpCurrentStorage->push_back(*iter); + mpCurrentStorage->push_back(new TagCloseElement("draw:object")); + } + } + if (tmpImageHandler) + { + librevenge::RVNGBinaryData output; + if (tmpImageHandler(data, output)) + { + mpCurrentStorage->push_back(new TagOpenElement("draw:image")); + + mpCurrentStorage->push_back(new TagOpenElement("office:binary-data")); + + librevenge::RVNGString binaryBase64Data = output.getBase64Data(); + + mpCurrentStorage->push_back(new CharDataElement(binaryBase64Data.cstr())); + + mpCurrentStorage->push_back(new TagCloseElement("office:binary-data")); + + mpCurrentStorage->push_back(new TagCloseElement("draw:image")); + } + } + } + catch (...) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::insertBinaryObject: ARGHH, catch an exception when decoding data!!!\n")); + } + } + else + // assuming we have a binary image or a object_ole that we can just insert as it is + { + if (propList["librevenge:mime-type"]->getStr() == "object/ole") + mpCurrentStorage->push_back(new TagOpenElement("draw:object-ole")); + else + mpCurrentStorage->push_back(new TagOpenElement("draw:image")); + + mpCurrentStorage->push_back(new TagOpenElement("office:binary-data")); + try + { + mpCurrentStorage->push_back(new CharDataElement(propList["office:binary-data"]->getStr().cstr())); + } + catch (...) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::insertBinaryObject: ARGHH, catch an exception when decoding picture!!!\n")); + } + mpCurrentStorage->push_back(new TagCloseElement("office:binary-data")); + + if (propList["librevenge:mime-type"]->getStr() == "object/ole") + mpCurrentStorage->push_back(new TagCloseElement("draw:object-ole")); + else + mpCurrentStorage->push_back(new TagCloseElement("draw:image")); + } +} + +//////////////////////////////////////////////////////////// +// graphic +//////////////////////////////////////////////////////////// +void OdfGenerator::defineGraphicStyle(const librevenge::RVNGPropertyList &propList) +{ + mGraphicStyle=propList; +} + +librevenge::RVNGString OdfGenerator::getCurrentGraphicStyleName() +{ + librevenge::RVNGPropertyList styleList; + mGraphicManager.addGraphicProperties(mGraphicStyle,styleList); + return mGraphicManager.findOrAdd(styleList); +} + +librevenge::RVNGString OdfGenerator::getCurrentGraphicStyleName(const librevenge::RVNGPropertyList &shapeList) +{ + librevenge::RVNGPropertyList styleList; + mGraphicManager.addGraphicProperties(shapeList,styleList); + mGraphicManager.addGraphicProperties(mGraphicStyle,styleList); + return mGraphicManager.findOrAdd(styleList); +} + +void OdfGenerator::drawEllipse(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["svg:rx"] || !propList["svg:ry"] || !propList["svg:cx"] || !propList["svg:cy"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::drawEllipse: position undefined\n")); + return; + } + double rx=0, ry=0, cx=0, cy=0; + if (!getInchValue(*propList["svg:rx"], rx) || !getInchValue(*propList["svg:ry"], ry) || + !getInchValue(*propList["svg:cx"], cx) || !getInchValue(*propList["svg:cy"], cy)) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::drawEllipse: can not read position\n")); + return; + } + librevenge::RVNGString sValue=getCurrentGraphicStyleName(propList); + TagOpenElement *pDrawEllipseElement = new TagOpenElement("draw:ellipse"); + pDrawEllipseElement->addAttribute("draw:style-name", sValue); + addFrameProperties(propList, *pDrawEllipseElement); + sValue = doubleToString(2 * rx); + sValue.append("in"); + pDrawEllipseElement->addAttribute("svg:width", sValue); + sValue = doubleToString(2 * ry); + sValue.append("in"); + pDrawEllipseElement->addAttribute("svg:height", sValue); + if (propList["librevenge:rotate"] && propList["librevenge:rotate"]->getDouble() != 0.0) + { + double rotation = propList["librevenge:rotate"]->getDouble(); + while (rotation < -180) + rotation += 360; + while (rotation > 180) + rotation -= 360; + double radrotation = rotation*M_PI/180.0; + double deltax = sqrt(pow(rx, 2.0) + pow(ry, 2.0))*cos(atan(ry/rx)-radrotation) - rx; + double deltay = sqrt(pow(rx, 2.0) + pow(ry, 2.0))*sin(atan(ry/rx)- radrotation) - ry; + sValue = "rotate("; + sValue.append(doubleToString(radrotation)); + sValue.append(") "); + sValue.append("translate("); + sValue.append(doubleToString(cx - rx - deltax)); + sValue.append("in, "); + sValue.append(doubleToString(cy - ry - deltay)); + sValue.append("in)"); + pDrawEllipseElement->addAttribute("draw:transform", sValue); + } + else + { + sValue = doubleToString(cx-rx); + sValue.append("in"); + pDrawEllipseElement->addAttribute("svg:x", sValue); + sValue = doubleToString(cy-ry); + sValue.append("in"); + pDrawEllipseElement->addAttribute("svg:y", sValue); + } + mpCurrentStorage->push_back(pDrawEllipseElement); + mpCurrentStorage->push_back(new TagCloseElement("draw:ellipse")); +} + +void OdfGenerator::drawPath(const librevenge::RVNGPropertyList &propList) +{ + const librevenge::RVNGPropertyListVector *path = propList.child("svg:d"); + if (!path) return; + drawPath(*path, propList); +} + +void OdfGenerator::drawPath(const librevenge::RVNGPropertyListVector &path, const librevenge::RVNGPropertyList &propList) +{ + if (!path.count()) + return; + + double px = 0.0, py = 0.0, qx = 0.0, qy = 0.0; + if (!libodfgen::getPathBBox(path, px, py, qx, qy)) + return; + + librevenge::RVNGString sValue=getCurrentGraphicStyleName(propList); + TagOpenElement *pDrawPathElement = new TagOpenElement("draw:path"); + pDrawPathElement->addAttribute("draw:style-name", sValue); + addFrameProperties(propList, *pDrawPathElement); + pDrawPathElement->addAttribute("draw:layer", "layout"); + sValue = doubleToString(px); + sValue.append("in"); + pDrawPathElement->addAttribute("svg:x", sValue); + sValue = doubleToString(py); + sValue.append("in"); + pDrawPathElement->addAttribute("svg:y", sValue); + sValue = doubleToString((qx - px)); + sValue.append("in"); + pDrawPathElement->addAttribute("svg:width", sValue); + sValue = doubleToString((qy - py)); + sValue.append("in"); + pDrawPathElement->addAttribute("svg:height", sValue); + sValue.sprintf("%i %i %i %i", 0, 0, (unsigned)(2540*(qx - px)), (unsigned)(2540*(qy - py))); + pDrawPathElement->addAttribute("svg:viewBox", sValue); + + pDrawPathElement->addAttribute("svg:d", libodfgen::convertPath(path, px, py)); + mpCurrentStorage->push_back(pDrawPathElement); + mpCurrentStorage->push_back(new TagCloseElement("draw:path")); +} + +void OdfGenerator::drawPolySomething(const librevenge::RVNGPropertyList &propList, bool isClosed) +{ + const ::librevenge::RVNGPropertyListVector *vertices = propList.child("svg:points"); + if (!vertices || vertices->count() < 2) + return; + + if (vertices->count() == 2) + { + if (!(*vertices)[0]["svg:x"]||!(*vertices)[0]["svg:y"]||!(*vertices)[1]["svg:x"]||!(*vertices)[1]["svg:y"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::drawPolySomething: some vertices are not defined\n")); + return; + } + librevenge::RVNGString sValue=getCurrentGraphicStyleName(propList); + TagOpenElement *pDrawLineElement = new TagOpenElement("draw:line"); + addFrameProperties(propList, *pDrawLineElement); + pDrawLineElement->addAttribute("draw:style-name", sValue); + pDrawLineElement->addAttribute("draw:layer", "layout"); + pDrawLineElement->addAttribute("svg:x1", (*vertices)[0]["svg:x"]->getStr()); + pDrawLineElement->addAttribute("svg:y1", (*vertices)[0]["svg:y"]->getStr()); + pDrawLineElement->addAttribute("svg:x2", (*vertices)[1]["svg:x"]->getStr()); + pDrawLineElement->addAttribute("svg:y2", (*vertices)[1]["svg:y"]->getStr()); + mpCurrentStorage->push_back(pDrawLineElement); + mpCurrentStorage->push_back(new TagCloseElement("draw:line")); + } + else + { + librevenge::RVNGPropertyListVector path; + librevenge::RVNGPropertyList element; + + for (unsigned long ii = 0; ii < vertices->count(); ++ii) + { + element = (*vertices)[ii]; + if (ii == 0) + element.insert("librevenge:path-action", "M"); + else + element.insert("librevenge:path-action", "L"); + path.append(element); + element.clear(); + } + if (isClosed) + { + element.insert("librevenge:path-action", "Z"); + path.append(element); + } + drawPath(path,propList); + } +} + +void OdfGenerator::drawRectangle(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["svg:x"] || !propList["svg:y"] || + !propList["svg:width"] || !propList["svg:height"]) + { + ODFGEN_DEBUG_MSG(("OdfGenerator::drawRectangle: position undefined\n")); + return; + } + librevenge::RVNGString sValue=getCurrentGraphicStyleName(propList); + librevenge::RVNGPropertyList frame(propList); + frame.remove("svg:height"); + frame.remove("svg:width"); + TagOpenElement *pDrawRectElement = new TagOpenElement("draw:rect"); + addFrameProperties(frame, *pDrawRectElement); + pDrawRectElement->addAttribute("draw:style-name", sValue); + pDrawRectElement->addAttribute("svg:x", propList["svg:x"]->getStr()); + pDrawRectElement->addAttribute("svg:y", propList["svg:y"]->getStr()); + pDrawRectElement->addAttribute("svg:width", propList["svg:width"]->getStr()); + pDrawRectElement->addAttribute("svg:height", propList["svg:height"]->getStr()); + // FIXME: what to do when rx != ry ? + if (propList["svg:rx"]) + pDrawRectElement->addAttribute("draw:corner-radius", propList["svg:rx"]->getStr()); + else + pDrawRectElement->addAttribute("draw:corner-radius", "0.0000in"); + mpCurrentStorage->push_back(pDrawRectElement); + mpCurrentStorage->push_back(new TagCloseElement("draw:rect")); +} + +void OdfGenerator::drawConnector(const librevenge::RVNGPropertyList &propList) +{ + const librevenge::RVNGPropertyListVector *path = propList.child("svg:d"); + if (!path) return; + drawPath(*path, propList); +} + +//////////////////////////////////////////////////////////// +// chart +//////////////////////////////////////////////////////////// +void OdfGenerator::defineChartStyle(const librevenge::RVNGPropertyList &propList) +{ + int chartId=-1; + if (propList["librevenge:chart-id"]) + chartId=propList["librevenge:chart-id"]->getInt(); + else + { + ODFGEN_DEBUG_MSG(("OdfGenerator::defineChartStyle: called without id\n")); + } + mIdChartMap[chartId]=propList; + mIdChartNameMap.erase(chartId); +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdfGenerator.hxx libodfgen-0.1.1/src/OdfGenerator.hxx --- libodfgen-0.0.4/src/OdfGenerator.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/OdfGenerator.hxx 2014-05-14 13:32:22.000000000 +0000 @@ -0,0 +1,407 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _ODFGENERATOR_HXX_ +#define _ODFGENERATOR_HXX_ + +#include +#include +#include +#include + +#include + +#include "libodfgen/OdfDocumentHandler.hxx" + +#include "FilterInternal.hxx" +#include "FontStyle.hxx" +#include "GraphicStyle.hxx" +#include "InternalHandler.hxx" +#include "TableStyle.hxx" +#include "TextRunStyle.hxx" + +class DocumentElement; +class ListStyle; + +class OdfGenerator +{ +public: + typedef std::vector Storage; + + //! constructor + OdfGenerator(); + //! destructor + virtual ~OdfGenerator(); + //! retrieve data from another odfgenerator ( the list and the embedded handler) + void initStateWith(OdfGenerator const &orig); + + // + // general + // + + //! returns the document type corresponding to stream type + static std::string getDocumentType(OdfStreamType streamType); + //! store the document meta data + void setDocumentMetaData(const librevenge::RVNGPropertyList &propList); + //! write the document meta data + void writeDocumentMetaData(OdfDocumentHandler *pHandler); + + // + // document handler + // + + //! basic container used to store objects of not flat odf files + struct ObjectContainer + { + //! constructor + ObjectContainer(librevenge::RVNGString const &type, bool isDir) + : mType(type), mIsDir(isDir), mStorage(), mInternalHandler(&mStorage) + { + } + //! destructor + ~ObjectContainer(); + //! the file type + librevenge::RVNGString mType; + //! true if the file is not a plain file + bool mIsDir; + //! the contain storage + Storage mStorage; + //! the handler + InternalHandler mInternalHandler; + private: + ObjectContainer(ObjectContainer const &orig); + ObjectContainer &operator=(ObjectContainer const &orig); + }; + /** creates a new object */ + ObjectContainer &createObjectFile(librevenge::RVNGString const &objectName, + librevenge::RVNGString const &objectType, + bool isDir=false); + /** returns the list created embedded object (needed to create chart) */ + librevenge::RVNGStringVector getObjectNames() const; + /** retrieve an embedded object content via a document handler */ + bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler); + + //! add a document handler + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + //! calls writeTargetDocument on each document handler + void writeTargetDocuments(); + //! appends local files in the manifest + void appendFilesInManifest(OdfDocumentHandler *pHandler); + //! a virtual function used to write final data + virtual bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) = 0; + + // + // embedded image/object handler + // + + //! register an embedded object handler + void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler); + //! register an embedded image handler + void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler); + //! returns a embedded object handler if it exists + OdfEmbeddedObject findEmbeddedObjectHandler(const librevenge::RVNGString &mimeType) const; + //! returns a embedded image handler if it exists + OdfEmbeddedImage findEmbeddedImageHandler(const librevenge::RVNGString &mimeType) const; + + // + // storage + // + + //! returns the current storage + Storage *getCurrentStorage() + { + return mpCurrentStorage; + } + //! push a storage + void pushStorage(Storage *newStorage); + /** pop a storage */ + bool popStorage(); + //! returns the body storage + Storage &getBodyStorage() + { + return mBodyStorage; + } + //! returns the meta data storage + Storage &getMetaDataStorage() + { + return mMetaDataStorage; + } + //! delete the storage content ( but not the Storage pointer ) + static void emptyStorage(Storage *storage); + //! write the storage data to a document handler + static void sendStorage(Storage const *storage, OdfDocumentHandler *pHandler); + + // + // basic to the font/paragraph/span manager + // + + void insertTab(); + void insertSpace(); + void insertLineBreak(bool forceParaClose=false); + void insertField(const librevenge::RVNGPropertyList &field); + void insertText(const librevenge::RVNGString &text); + + //! open a link + void openLink(const librevenge::RVNGPropertyList &propList); + //! close a link + void closeLink(); + + //! return the font manager + FontStyleManager &getFontManager() + { + return mFontManager; + } + + //! define a character style + void defineCharacterStyle(const librevenge::RVNGPropertyList &propList); + //! open a span + void openSpan(const librevenge::RVNGPropertyList &propList); + //! close a span + void closeSpan(); + + //! define a paragraph style + void defineParagraphStyle(const librevenge::RVNGPropertyList &propList); + //! open a paragraph + void openParagraph(const librevenge::RVNGPropertyList &propList); + //! close a paragraph + void closeParagraph(); + + // + // list function + // + + /// pop the list state (if possible) + void popListState(); + /// push the list state by adding an empty value + void pushListState(); + + /// call to define a list level + void defineListLevel(const librevenge::RVNGPropertyList &propList, bool ordered); + /// call to open a list level + void openListLevel(const librevenge::RVNGPropertyList &propList, bool ordered); + /// call to close a list level + void closeListLevel(); + /// call to open a list element + void openListElement(const librevenge::RVNGPropertyList &propList); + /// call to close a list element + void closeListElement(); + + // + // table + // + + /// call to open a table + void openTable(const librevenge::RVNGPropertyList &propList); + /// call to close a table + void closeTable(); + /// call to open a table row + bool openTableRow(const librevenge::RVNGPropertyList &propList); + /// call to close a table row + void closeTableRow(); + /// returns true if a table row is opened + bool isInTableRow(bool &inHeaderRow) const; + /// call to open a table cell + bool openTableCell(const librevenge::RVNGPropertyList &propList); + /// call to close a table cell + void closeTableCell(); + void insertCoveredTableCell(const librevenge::RVNGPropertyList &propList); + + // + // frame/group + // + + /// call to open a frame + void openFrame(const librevenge::RVNGPropertyList &propList); + /// call to close a frame + void closeFrame(); + //! return a frame id corresponding to a name ( or a new frame id) + unsigned getFrameId(librevenge::RVNGString name=""); + /// call to open a group + void openGroup(const librevenge::RVNGPropertyList &propList); + /// call to close a group + void closeGroup(); + + // + // image + // + + //! inserts a binary object + void insertBinaryObject(const librevenge::RVNGPropertyList &propList); + + // + // graphic + // + + //! call to define a graphic style + void defineGraphicStyle(const librevenge::RVNGPropertyList &propList); + //! returns the last graphic style (REMOVEME) + librevenge::RVNGPropertyList const &getGraphicStyle() const + { + return mGraphicStyle; + } + + //! call to draw an ellipse + void drawEllipse(const librevenge::RVNGPropertyList &propList); + //! call to draw a path + void drawPath(const librevenge::RVNGPropertyList &propList); + //! call to draw a polygon or a polyline + void drawPolySomething(const librevenge::RVNGPropertyList &vertices, bool isClosed); + //! call to draw a rectangle + void drawRectangle(const librevenge::RVNGPropertyList &propList); + //! call to draw a connector + void drawConnector(const ::librevenge::RVNGPropertyList &propList); + + // + // chart + // + + //! define a chart style + void defineChartStyle(const librevenge::RVNGPropertyList &propList); + +protected: + + // + // list + // + + // list state + struct ListState + { + ListState(); + ListState(const ListState &state); + + ListStyle *mpCurrentListStyle; + unsigned int miCurrentListLevel; + unsigned int miLastListLevel; + unsigned int miLastListNumber; + bool mbListContinueNumbering; + bool mbListElementParagraphOpened; + std::stack mbListElementOpened; + private: + ListState &operator=(const ListState &state); + }; + + /// access to the current list state + ListState &getListState(); + + /** stores a list style: update mListStyles, + mWriterListStates.top().mpCurrentListStyle and the different + maps + */ + void storeListStyle(ListStyle *listStyle); + /** retrieves the list style corresponding to a given id. */ + void retrieveListStyle(int id); + + // + // frame/graphic + // + + //! returns the list of properties which must be add to a frame, shape, ... + void addFrameProperties(const librevenge::RVNGPropertyList &propList, TagOpenElement &element) const; + //! call to draw a path + void drawPath(const librevenge::RVNGPropertyListVector &path, const librevenge::RVNGPropertyList &propList); + //! returns the current graphic style name ( MODIFYME) + librevenge::RVNGString getCurrentGraphicStyleName(const librevenge::RVNGPropertyList &shapeList); + //! returns the current graphic style name ( MODIFYME) + librevenge::RVNGString getCurrentGraphicStyleName(); + + // the current set of elements that we're writing to + Storage *mpCurrentStorage; + // the stack of all storage + std::stack mStorageStack; + // the meta data elements + Storage mMetaDataStorage; + // content elements + Storage mBodyStorage; + + // font manager + FontStyleManager mFontManager; + // graphic manager + GraphicStyleManager mGraphicManager; + // span manager + SpanStyleManager mSpanManager; + // paragraph manager + ParagraphStyleManager mParagraphManager; + // table manager + TableManager mTableManager; + + // id to span map + std::map mIdSpanMap; + // id to span name map + std::map mIdSpanNameMap; + // the last span name + librevenge::RVNGString mLastSpanName; + + // id to paragraph map + std::map mIdParagraphMap; + // id to paragraph name map + std::map mIdParagraphNameMap; + // the last paragraph name + librevenge::RVNGString mLastParagraphName; + + // list styles + unsigned int miNumListStyles; + // list styles + std::vector mListStyles; + // list states + std::stack mListStates; + // a map id -> last list style defined with id + std::map mIdListStyleMap; + + // the number of created frame + unsigned miFrameNumber; + // the list of frame seens + std::map mFrameNameIdMap; + + // the last graphic style + librevenge::RVNGPropertyList mGraphicStyle; + + // id to chart map + std::map mIdChartMap; + // id to chart name map + std::map mIdChartNameMap; + + // the document handlers + std::map mDocumentStreamHandlers; + + // the number of created object + int miObjectNumber; + // name to object map + std::map mNameObjectMap; + + // embedded image handlers + std::map mImageHandlers; + // embedded object handlers + std::map mObjectHandlers; + +private: + // copy constructor (unimplemented) + OdfGenerator(OdfGenerator const &); + // copy operator (unimplemented) + OdfGenerator &operator=(OdfGenerator const &); +}; +#endif +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdgGenerator.cxx libodfgen-0.1.1/src/OdgGenerator.cxx --- libodfgen-0.0.4/src/OdgGenerator.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/OdgGenerator.cxx 2014-05-23 13:40:44.000000000 +0000 @@ -28,9 +28,12 @@ #include "FilterInternal.hxx" #include "DocumentElement.hxx" -#include "GraphicFunctions.hxx" -#include "TextRunStyle.hxx" #include "FontStyle.hxx" +#include "GraphicStyle.hxx" +#include "ListStyle.hxx" +#include "OdfGenerator.hxx" +#include "TableStyle.hxx" +#include "TextRunStyle.hxx" #include #include #include @@ -45,75 +48,114 @@ // remove this #define MULTIPAGE_WORKAROUND 1 -using namespace libodfgen; - namespace { - -static WPXString doubleToString(const double value) +static bool getInchValue(librevenge::RVNGProperty const &prop, double &value) { - WPXProperty *prop = WPXPropertyFactory::newDoubleProp(value); - WPXString retVal = prop->getStr(); - delete prop; - return retVal; + value=prop.getDouble(); + switch (prop.getUnit()) + { + case librevenge::RVNG_GENERIC: // assume inch + case librevenge::RVNG_INCH: + return true; + case librevenge::RVNG_POINT: + value /= 72.; + return true; + case librevenge::RVNG_TWIP: + value /= 1440.; + return true; + case librevenge::RVNG_PERCENT: + case librevenge::RVNG_UNIT_ERROR: + default: + { + static bool first=true; + if (first) + { + ODFGEN_DEBUG_MSG(("::getInchValue[OdgGenerator.cxx]: call with no double value\n")); + first=false; + } + break; + } + } + return false; } - } // anonymous namespace -class OdgGeneratorPrivate +using namespace libodfgen; + +class OdgGeneratorPrivate : public OdfGenerator { public: - OdgGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + OdgGeneratorPrivate(); ~OdgGeneratorPrivate(); - /** update a graphic style element */ - void _updateGraphicPropertiesElement(TagOpenElement &element, ::WPXPropertyList const &style, ::WPXPropertyListVector const &gradient); - void _writeGraphicsStyle(); - void _drawPolySomething(const ::WPXPropertyListVector &vertices, bool isClosed); - void _drawPath(const WPXPropertyListVector &path); + + GraphicStyleManager &getGraphicManager() + { + return mGraphicManager; + } + //! returns the document type - std::string getDocumentType() const; - // body elements - std::vector mBodyElements; - - // graphics styles - std::vector mGraphicsStrokeDashStyles; - std::vector mGraphicsGradientStyles; - std::vector mGraphicsBitmapStyles; - std::vector mGraphicsMarkerStyles; - std::vector mGraphicsAutomaticStyles; + bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeSettings(OdfDocumentHandler *pHandler); + void _writeStyles(OdfDocumentHandler *pHandler); + void _writeAutomaticStyles(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeMasterPages(OdfDocumentHandler *pHandler); + void _writePageLayouts(OdfDocumentHandler *pHandler); - // page styles - std::vector mPageAutomaticStyles; - std::vector mPageMasterStyles; + // + // state gestion + // - // paragraph styles - ParagraphStyleManager mParagraphManager; + // the state we use for writing the final document + struct State + { + State() : mbIsTextBox(false), miIntricatedTextBox(0), mbInTableCell(false) + { + } + /** flag to know if a text box is opened */ + bool mbIsTextBox; + /** number of intricated text box, in case a textbox is called inside a text box */ + int miIntricatedTextBox; + /** flag to know if a table cell is opened */ + bool mbInTableCell; + }; - // span styles - SpanStyleManager mSpanManager; + // returns the actual state + State &getState() + { + if (mStateStack.empty()) + { + ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::getState: no state\n")); + mStateStack.push(State()); + } + return mStateStack.top(); + } + // push a state + void pushState() + { + mStateStack.push(State()); + } + // pop a state + void popState() + { + if (!mStateStack.empty()) + mStateStack.pop(); + else + { + ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::popState: no state\n")); + } + } + std::stack mStateStack; - // font styles - FontStyleManager mFontManager; + // page styles + std::vector mPageAutomaticStyles; + std::vector mPageMasterStyles; - OdfDocumentHandler *mpHandler; - - ::WPXPropertyList mxStyle; - ::WPXPropertyListVector mxGradient; - int miGradientIndex; - int miBitmapIndex; - int miStartMarkerIndex; - int miEndMarkerIndex; - int miDashIndex; - int miGraphicsStyleIndex; int miPageIndex; double mfWidth, mfMaxWidth; double mfHeight, mfMaxHeight; - const OdfStreamType mxStreamType; - - bool mbIsTextBox; - bool mbIsTextLine; - bool mbIsTextOnPath; + Storage mDummyMasterSlideStorage; private: OdgGeneratorPrivate(const OdgGeneratorPrivate &); @@ -121,332 +163,273 @@ }; -OdgGeneratorPrivate::OdgGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType): - mBodyElements(), - mGraphicsStrokeDashStyles(), - mGraphicsGradientStyles(), - mGraphicsBitmapStyles(), - mGraphicsMarkerStyles(), - mGraphicsAutomaticStyles(), +OdgGeneratorPrivate::OdgGeneratorPrivate() : OdfGenerator(), + mStateStack(), mPageAutomaticStyles(), mPageMasterStyles(), - mParagraphManager(), - mSpanManager(), - mFontManager(), - mpHandler(pHandler), - mxStyle(), mxGradient(), - miGradientIndex(1), - miBitmapIndex(1), - miStartMarkerIndex(1), - miEndMarkerIndex(1), - miDashIndex(1), - miGraphicsStyleIndex(1), miPageIndex(1), mfWidth(0.0), mfMaxWidth(0.0), mfHeight(0.0), mfMaxHeight(0.0), - mxStreamType(streamType), - mbIsTextBox(false), - mbIsTextLine(false), - mbIsTextOnPath(false) + mDummyMasterSlideStorage() { + pushState(); } OdgGeneratorPrivate::~OdgGeneratorPrivate() { + emptyStorage(&mPageAutomaticStyles); + emptyStorage(&mPageMasterStyles); +} - for (std::vector::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); ++iterBody) - { - delete (*iterBody); - (*iterBody) = 0; - } +void OdgGeneratorPrivate::_writeSettings(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:settings").write(pHandler); - for (std::vector::iterator iterGraphicsAutomaticStyles = mGraphicsAutomaticStyles.begin(); - iterGraphicsAutomaticStyles != mGraphicsAutomaticStyles.end(); ++iterGraphicsAutomaticStyles) - { - delete((*iterGraphicsAutomaticStyles)); - } + TagOpenElement configItemSetOpenElement("config:config-item-set"); + configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings"); + configItemSetOpenElement.write(pHandler); - for (std::vector::iterator iterGraphicsStrokeDashStyles = mGraphicsStrokeDashStyles.begin(); - iterGraphicsStrokeDashStyles != mGraphicsStrokeDashStyles.end(); ++iterGraphicsStrokeDashStyles) - { - delete((*iterGraphicsStrokeDashStyles)); - } + TagOpenElement configItemOpenElement("config:config-item"); - for (std::vector::iterator iterGraphicsGradientStyles = mGraphicsGradientStyles.begin(); - iterGraphicsGradientStyles != mGraphicsGradientStyles.end(); ++iterGraphicsGradientStyles) - { - delete((*iterGraphicsGradientStyles)); - } + configItemOpenElement.addAttribute("config:name", "VisibleAreaTop"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + pHandler->characters("0"); + pHandler->endElement("config:config-item"); - for (std::vector::iterator iterGraphicsBitmapStyles = mGraphicsBitmapStyles.begin(); - iterGraphicsBitmapStyles != mGraphicsBitmapStyles.end(); ++iterGraphicsBitmapStyles) - { - delete((*iterGraphicsBitmapStyles)); - } + configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + pHandler->characters("0"); + pHandler->endElement("config:config-item"); - for (std::vector::iterator iterGraphicsMarkerStyles = mGraphicsMarkerStyles.begin(); - iterGraphicsMarkerStyles != mGraphicsMarkerStyles.end(); ++iterGraphicsMarkerStyles) - { - delete((*iterGraphicsMarkerStyles)); - } + configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + librevenge::RVNGString sWidth; + sWidth.sprintf("%li", (unsigned long)(2540 * mfMaxWidth)); + pHandler->characters(sWidth); + pHandler->endElement("config:config-item"); - for (std::vector::iterator iterPageAutomaticStyles = mPageAutomaticStyles.begin(); - iterPageAutomaticStyles != mPageAutomaticStyles.end(); ++iterPageAutomaticStyles) - { - delete((*iterPageAutomaticStyles)); - } + configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + librevenge::RVNGString sHeight; + sHeight.sprintf("%li", (unsigned long)(2540 * mfMaxHeight)); + pHandler->characters(sHeight); + pHandler->endElement("config:config-item"); - for (std::vector::iterator iterPageMasterStyles = mPageMasterStyles.begin(); - iterPageMasterStyles != mPageMasterStyles.end(); ++iterPageMasterStyles) - { - delete((*iterPageMasterStyles)); - } + pHandler->endElement("config:config-item-set"); - mParagraphManager.clean(); - mSpanManager.clean(); - mFontManager.clean(); + pHandler->endElement("office:settings"); } -std::string OdgGeneratorPrivate::getDocumentType() const +void OdgGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler, OdfStreamType streamType) { - switch(mxStreamType) + TagOpenElement("office:automatic-styles").write(pHandler); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML)) { - case ODF_FLAT_XML: - return "office:document"; - case ODF_CONTENT_XML: - return "office:document-content"; - case ODF_STYLES_XML: - return "office:document-styles"; - case ODF_SETTINGS_XML: - return "office:document-settings"; - case ODF_META_XML: - return "office:document-meta"; - default: - return "office:document"; + mGraphicManager.writeAutomaticStyles(pHandler); + mParagraphManager.write(pHandler); + mSpanManager.write(pHandler); + // writing out the lists styles + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + (*iterListStyles)->write(pHandler); + mTableManager.write(pHandler, true); } + + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML)) + _writePageLayouts(pHandler); + + pHandler->endElement("office:automatic-styles"); } -OdgGenerator::OdgGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType): - mpImpl(new OdgGeneratorPrivate(pHandler, streamType)) +void OdgGeneratorPrivate::_writeMasterPages(OdfDocumentHandler *pHandler) { - mpImpl->mpHandler->startDocument(); - TagOpenElement tmpOfficeDocumentContent(mpImpl->getDocumentType().c_str()); - tmpOfficeDocumentContent.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); - tmpOfficeDocumentContent.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office"); - tmpOfficeDocumentContent.addAttribute("office:version", "1.0"); - if (mpImpl->mxStreamType == ODF_FLAT_XML) - tmpOfficeDocumentContent.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.graphics"); - tmpOfficeDocumentContent.write(mpImpl->mpHandler); + TagOpenElement("office:master-styles").write(pHandler); + sendStorage(&mPageMasterStyles, pHandler); + pHandler->endElement("office:master-styles"); } -OdgGenerator::~OdgGenerator() +void OdgGeneratorPrivate::_writePageLayouts(OdfDocumentHandler *pHandler) { - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_SETTINGS_XML)) - { - TagOpenElement("office:settings").write(mpImpl->mpHandler); - - TagOpenElement configItemSetOpenElement("config:config-item-set"); - configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings"); - configItemSetOpenElement.write(mpImpl->mpHandler); - - TagOpenElement configItemOpenElement("config:config-item"); - - configItemOpenElement.addAttribute("config:name", "VisibleAreaTop"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - mpImpl->mpHandler->characters("0"); - mpImpl->mpHandler->endElement("config:config-item"); - - configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - mpImpl->mpHandler->characters("0"); - mpImpl->mpHandler->endElement("config:config-item"); +#ifdef MULTIPAGE_WORKAROUND + TagOpenElement tmpStylePageLayoutOpenElement("style:page-layout"); + tmpStylePageLayoutOpenElement.addAttribute("style:name", "PM0"); + tmpStylePageLayoutOpenElement.write(pHandler); + + TagOpenElement tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-top", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0in"); + librevenge::RVNGString sValue; + sValue = doubleToString(mfMaxWidth); + sValue.append("in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue); + sValue = doubleToString(mfMaxHeight); + sValue.append("in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait"); + tmpStylePageLayoutPropertiesOpenElement.write(pHandler); + + pHandler->endElement("style:page-layout-properties"); + + pHandler->endElement("style:page-layout"); + + TagOpenElement tmpStyleStyleOpenElement("style:style"); + tmpStyleStyleOpenElement.addAttribute("style:name", "dp1"); + tmpStyleStyleOpenElement.addAttribute("style:family", "drawing-page"); + tmpStyleStyleOpenElement.write(pHandler); + + TagOpenElement tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties"); + // tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:background-size", "border"); + tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:fill", "none"); + tmpStyleDrawingPagePropertiesOpenElement.write(pHandler); + pHandler->endElement("style:drawing-page-properties"); - configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - WPXString sWidth; - sWidth.sprintf("%li", (unsigned long)(2540 * mpImpl->mfMaxWidth)); - mpImpl->mpHandler->characters(sWidth); - mpImpl->mpHandler->endElement("config:config-item"); + pHandler->endElement("style:style"); +#else + sendStorage(&mPageAutomaticStyles, pHandler); +#endif - configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - WPXString sHeight; - sHeight.sprintf("%li", (unsigned long)(2540 * mpImpl->mfMaxHeight)); - mpImpl->mpHandler->characters(sHeight); - mpImpl->mpHandler->endElement("config:config-item"); +} - mpImpl->mpHandler->endElement("config:config-item-set"); +void OdgGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:styles").write(pHandler); + mGraphicManager.writeStyles(pHandler); + pHandler->endElement("office:styles"); +} - mpImpl->mpHandler->endElement("office:settings"); +bool OdgGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) +{ + if (streamType == ODF_MANIFEST_XML) + { + TagOpenElement manifestElement("manifest:manifest"); + manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"); + manifestElement.write(pHandler); + TagOpenElement mainFile("manifest:file-entry"); + mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.graphics"); + mainFile.addAttribute("manifest:full-path", "/"); + mainFile.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + appendFilesInManifest(pHandler); + TagCloseElement("manifest:manifest").write(pHandler); + return true; } + pHandler->startDocument(); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - TagOpenElement("office:styles").write(mpImpl->mpHandler); - - for (std::vector::const_iterator iterGraphicsStrokeDashStyles = mpImpl->mGraphicsStrokeDashStyles.begin(); - iterGraphicsStrokeDashStyles != mpImpl->mGraphicsStrokeDashStyles.end(); ++iterGraphicsStrokeDashStyles) - { - (*iterGraphicsStrokeDashStyles)->write(mpImpl->mpHandler); - } + std::string const documentType=getDocumentType(streamType); + TagOpenElement docContentPropList(documentType.c_str()); + docContentPropList.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); + docContentPropList.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); + docContentPropList.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); + docContentPropList.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); + docContentPropList.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); + docContentPropList.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + docContentPropList.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); + docContentPropList.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); + docContentPropList.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); + docContentPropList.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); + docContentPropList.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office"); + docContentPropList.addAttribute("office:version", "1.0", true); + if (streamType == ODF_FLAT_XML) + docContentPropList.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.graphics"); + docContentPropList.write(pHandler); - for (std::vector::const_iterator iterGraphicsGradientStyles = mpImpl->mGraphicsGradientStyles.begin(); - iterGraphicsGradientStyles != mpImpl->mGraphicsGradientStyles.end(); ++iterGraphicsGradientStyles) - { - (*iterGraphicsGradientStyles)->write(mpImpl->mpHandler); - } + if (streamType == ODF_FLAT_XML || streamType == ODF_META_XML) + writeDocumentMetaData(pHandler); - for (std::vector::const_iterator iterGraphicsBitmapStyles = mpImpl->mGraphicsBitmapStyles.begin(); - iterGraphicsBitmapStyles != mpImpl->mGraphicsBitmapStyles.end(); ++iterGraphicsBitmapStyles) - { - (*iterGraphicsBitmapStyles)->write(mpImpl->mpHandler); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_SETTINGS_XML)) + _writeSettings(pHandler); - for (std::vector::const_iterator iterGraphicsMarkerStyles = mpImpl->mGraphicsMarkerStyles.begin(); - iterGraphicsMarkerStyles != mpImpl->mGraphicsMarkerStyles.end(); ++iterGraphicsMarkerStyles) - { - (*iterGraphicsMarkerStyles)->write(mpImpl->mpHandler); - } - mpImpl->mpHandler->endElement("office:styles"); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML)) + mFontManager.writeFontsDeclaration(pHandler); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML)) + _writeStyles(pHandler); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - mpImpl->mFontManager.writeFontsDeclaration(mpImpl->mpHandler); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML)) + _writeAutomaticStyles(pHandler, streamType); - TagOpenElement("office:automatic-styles").write(mpImpl->mpHandler); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML)) + _writeMasterPages(pHandler); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML)) + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML)) { - // writing out the graphics automatic styles - for (std::vector::iterator iterGraphicsAutomaticStyles = mpImpl->mGraphicsAutomaticStyles.begin(); - iterGraphicsAutomaticStyles != mpImpl->mGraphicsAutomaticStyles.end(); ++iterGraphicsAutomaticStyles) - { - (*iterGraphicsAutomaticStyles)->write(mpImpl->mpHandler); - } - mpImpl->mParagraphManager.write(mpImpl->mpHandler); - mpImpl->mSpanManager.write(mpImpl->mpHandler); + TagOpenElement("office:body").write(pHandler); + TagOpenElement("office:drawing").write(pHandler); + sendStorage(&mBodyStorage, pHandler); + pHandler->endElement("office:drawing"); + pHandler->endElement("office:body"); } -#ifdef MULTIPAGE_WORKAROUND - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - TagOpenElement tmpStylePageLayoutOpenElement("style:page-layout"); - tmpStylePageLayoutOpenElement.addAttribute("style:name", "PM0"); - tmpStylePageLayoutOpenElement.write(mpImpl->mpHandler); - - TagOpenElement tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-top", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0in"); - WPXString sValue; - sValue = doubleToString(mpImpl->mfMaxWidth); - sValue.append("in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue); - sValue = doubleToString(mpImpl->mfMaxHeight); - sValue.append("in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait"); - tmpStylePageLayoutPropertiesOpenElement.write(mpImpl->mpHandler); - - mpImpl->mpHandler->endElement("style:page-layout-properties"); - - mpImpl->mpHandler->endElement("style:page-layout"); - - TagOpenElement tmpStyleStyleOpenElement("style:style"); - tmpStyleStyleOpenElement.addAttribute("style:name", "dp1"); - tmpStyleStyleOpenElement.addAttribute("style:family", "drawing-page"); - tmpStyleStyleOpenElement.write(mpImpl->mpHandler); - - TagOpenElement tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties"); - // tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:background-size", "border"); - tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:fill", "none"); - tmpStyleDrawingPagePropertiesOpenElement.write(mpImpl->mpHandler); - mpImpl->mpHandler->endElement("style:drawing-page-properties"); + pHandler->endElement(documentType.c_str()); - mpImpl->mpHandler->endElement("style:style"); - } -#else - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - // writing out the page automatic styles - for (std::vector::iterator iterPageAutomaticStyles = mpImpl->mPageAutomaticStyles.begin(); - iterPageAutomaticStyles != mpImpl->mPageAutomaticStyles.end(); ++iterPageAutomaticStyles) - { - (*iterPageAutomaticStyles)->write(mpImpl->mpHandler); - } - } -#endif - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - mpImpl->mpHandler->endElement("office:automatic-styles"); - } + pHandler->endDocument(); + return true; +} - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - TagOpenElement("office:master-styles").write(mpImpl->mpHandler); +OdgGenerator::OdgGenerator() : mpImpl(new OdgGeneratorPrivate) +{ +} - for (std::vector::const_iterator pageMasterIter = mpImpl->mPageMasterStyles.begin(); - pageMasterIter != mpImpl->mPageMasterStyles.end(); ++pageMasterIter) - { - (*pageMasterIter)->write(mpImpl->mpHandler); - } - mpImpl->mpHandler->endElement("office:master-styles"); - } +OdgGenerator::~OdgGenerator() +{ + delete mpImpl; +} - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML)) - { - TagOpenElement("office:body").write(mpImpl->mpHandler); +void OdgGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (mpImpl) + mpImpl->addDocumentHandler(pHandler, streamType); +} - TagOpenElement("office:drawing").write(mpImpl->mpHandler); +librevenge::RVNGStringVector OdgGenerator::getObjectNames() const +{ + if (mpImpl) + return mpImpl->getObjectNames(); + return librevenge::RVNGStringVector(); +} - for (std::vector::const_iterator bodyIter = mpImpl->mBodyElements.begin(); - bodyIter != mpImpl->mBodyElements.end(); ++bodyIter) - { - (*bodyIter)->write(mpImpl->mpHandler); - } +bool OdgGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!mpImpl) + return false; + return mpImpl->getObjectContent(objectName, pHandler); +} - mpImpl->mpHandler->endElement("office:drawing"); - mpImpl->mpHandler->endElement("office:body"); - } +void OdgGenerator::startDocument(const librevenge::RVNGPropertyList &) +{ +} - mpImpl->mpHandler->endElement(mpImpl->getDocumentType().c_str()); +void OdgGenerator::endDocument() +{ + // Write out the collected document + mpImpl->writeTargetDocuments(); +} - mpImpl->mpHandler->endDocument(); +void OdgGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->setDocumentMetaData(propList); +} - delete mpImpl; +void OdgGenerator::defineEmbeddedFont(const librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me } -void OdgGenerator::startGraphics(const ::WPXPropertyList &propList) +void OdgGenerator::startPage(const ::librevenge::RVNGPropertyList &propList) { - if (propList["svg:width"]) - { - mpImpl->mfWidth = propList["svg:width"]->getDouble(); + if (propList["svg:width"] && getInchValue(*propList["svg:width"], mpImpl->mfWidth)) mpImpl->mfMaxWidth = mpImpl->mfMaxWidth < mpImpl->mfWidth ? mpImpl->mfWidth : mpImpl->mfMaxWidth; - } - if (propList["svg:height"]) - { - mpImpl->mfHeight = propList["svg:height"]->getDouble(); + if (propList["svg:height"] && getInchValue(*propList["svg:height"], mpImpl->mfHeight)) mpImpl->mfMaxHeight = mpImpl->mfMaxHeight < mpImpl->mfHeight ? mpImpl->mfHeight : mpImpl->mfMaxHeight; - } TagOpenElement *pStyleMasterPageOpenElement = new TagOpenElement("style:master-page"); @@ -454,9 +437,9 @@ TagOpenElement *pStylePageLayoutOpenElement = new TagOpenElement("style:page-layout"); - WPXString sValue; + librevenge::RVNGString sValue; if (propList["draw:name"]) - sValue = WPXString(propList["draw:name"]->getStr(), true); // escape special xml characters + sValue.appendEscapedXML(propList["draw:name"]->getStr()); else sValue.sprintf("page%i", mpImpl->miPageIndex); pDrawPageOpenElement->addAttribute("draw:name", sValue); @@ -510,12 +493,11 @@ pStyleMasterPageOpenElement->addAttribute("style:name", sValue); #endif - mpImpl->mBodyElements.push_back(pDrawPageOpenElement); + mpImpl->getCurrentStorage()->push_back(pDrawPageOpenElement); mpImpl->mPageMasterStyles.push_back(pStyleMasterPageOpenElement); mpImpl->mPageMasterStyles.push_back(new TagCloseElement("style:master-page")); - TagOpenElement *pStyleDrawingPagePropertiesOpenElement = new TagOpenElement("style:drawing-page-properties"); pStyleDrawingPagePropertiesOpenElement->addAttribute("draw:fill", "none"); mpImpl->mPageAutomaticStyles.push_back(pStyleDrawingPagePropertiesOpenElement); @@ -525,406 +507,111 @@ mpImpl->mPageAutomaticStyles.push_back(new TagCloseElement("style:style")); } -void OdgGenerator::endGraphics() +void OdgGenerator::endPage() { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:page")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:page")); mpImpl->miPageIndex++; } -void OdgGenerator::setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &gradient) +void OdgGenerator::startMasterPage(const ::librevenge::RVNGPropertyList &/*propList*/) { - mpImpl->mxStyle.clear(); - mpImpl->mxStyle = propList; - mpImpl->mxGradient = gradient; + mpImpl->pushStorage(&mpImpl->mDummyMasterSlideStorage); } -void OdgGenerator::startLayer(const ::WPXPropertyList & /* propList */) +void OdgGenerator::endMasterPage() { - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:g")); + mpImpl->popStorage(); + mpImpl->mDummyMasterSlideStorage.clear(); } -void OdgGenerator::endLayer() +void OdgGenerator::setStyle(const ::librevenge::RVNGPropertyList &propList) { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:g")); + mpImpl->defineGraphicStyle(propList); } -void OdgGenerator::drawRectangle(const ::WPXPropertyList &propList) +void OdgGenerator::startLayer(const ::librevenge::RVNGPropertyList & /* propList */) { - if (!propList["svg:x"] || !propList["svg:y"] || - !propList["svg:width"] || !propList["svg:height"]) - { - ODFGEN_DEBUG_MSG(("OdgGenerator::drawRectangle: position undefined\n")); - return; - } - mpImpl->_writeGraphicsStyle(); - TagOpenElement *pDrawRectElement = new TagOpenElement("draw:rect"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawRectElement->addAttribute("draw:style-name", sValue); - pDrawRectElement->addAttribute("svg:x", propList["svg:x"]->getStr()); - pDrawRectElement->addAttribute("svg:y", propList["svg:y"]->getStr()); - pDrawRectElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - pDrawRectElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - // FIXME: what to do when rx != ry ? - if (propList["svg:rx"]) - pDrawRectElement->addAttribute("draw:corner-radius", propList["svg:rx"]->getStr()); - else - pDrawRectElement->addAttribute("draw:corner-radius", "0.0000in"); - mpImpl->mBodyElements.push_back(pDrawRectElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:rect")); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("draw:g")); } -void OdgGenerator::drawEllipse(const ::WPXPropertyList &propList) +void OdgGenerator::endLayer() { - if (!propList["svg:rx"] || !propList["svg:ry"] || !propList["svg:cx"] || !propList["svg:cy"]) - { - ODFGEN_DEBUG_MSG(("OdgGenerator::drawEllipse: position undefined\n")); - return; - } - mpImpl->_writeGraphicsStyle(); - TagOpenElement *pDrawEllipseElement = new TagOpenElement("draw:ellipse"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawEllipseElement->addAttribute("draw:style-name", sValue); - sValue = doubleToString(2 * propList["svg:rx"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:width", sValue); - sValue = doubleToString(2 * propList["svg:ry"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:height", sValue); - if (propList["libwpg:rotate"] && propList["libwpg:rotate"]->getDouble() != 0.0) - { - double rotation = propList["libwpg:rotate"]->getDouble(); - while(rotation < -180) - rotation += 360; - while(rotation > 180) - rotation -= 360; - double radrotation = rotation*M_PI/180.0; - double deltax = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0) - + pow(propList["svg:ry"]->getDouble(), 2.0))*cos(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble()) - - radrotation ) - propList["svg:rx"]->getDouble(); - double deltay = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0) - + pow(propList["svg:ry"]->getDouble(), 2.0))*sin(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble()) - - radrotation ) - propList["svg:ry"]->getDouble(); - sValue = "rotate("; - sValue.append(doubleToString(radrotation)); - sValue.append(") "); - sValue.append("translate("); - sValue.append(doubleToString(propList["svg:cx"]->getDouble() - propList["svg:rx"]->getDouble() - deltax)); - sValue.append("in, "); - sValue.append(doubleToString(propList["svg:cy"]->getDouble() - propList["svg:ry"]->getDouble() - deltay)); - sValue.append("in)"); - pDrawEllipseElement->addAttribute("draw:transform", sValue); - } - else - { - sValue = doubleToString(propList["svg:cx"]->getDouble()-propList["svg:rx"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:x", sValue); - sValue = doubleToString(propList["svg:cy"]->getDouble()-propList["svg:ry"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:y", sValue); - } - mpImpl->mBodyElements.push_back(pDrawEllipseElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:ellipse")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:g")); } -void OdgGenerator::drawPolyline(const ::WPXPropertyListVector &vertices) +void OdgGenerator::openGroup(const ::librevenge::RVNGPropertyList & /* propList */) { - mpImpl->_drawPolySomething(vertices, false); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("draw:g")); } -void OdgGenerator::drawPolygon(const ::WPXPropertyListVector &vertices) +void OdgGenerator::closeGroup() { - mpImpl->_drawPolySomething(vertices, true); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:g")); } -void OdgGeneratorPrivate::_drawPolySomething(const ::WPXPropertyListVector &vertices, bool isClosed) +void OdgGenerator::drawRectangle(const ::librevenge::RVNGPropertyList &propList) { - if(vertices.count() < 2) - return; - - if(vertices.count() == 2) - { - if (!vertices[0]["svg:x"]||!vertices[0]["svg:y"]||!vertices[1]["svg:x"]||!vertices[1]["svg:y"]) - { - ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::_drawPolySomething: some vertices are not defined\n")); - return; - } - _writeGraphicsStyle(); - TagOpenElement *pDrawLineElement = new TagOpenElement("draw:line"); - WPXString sValue; - sValue.sprintf("gr%i", miGraphicsStyleIndex-1); - pDrawLineElement->addAttribute("draw:style-name", sValue); - pDrawLineElement->addAttribute("draw:layer", "layout"); - pDrawLineElement->addAttribute("svg:x1", vertices[0]["svg:x"]->getStr()); - pDrawLineElement->addAttribute("svg:y1", vertices[0]["svg:y"]->getStr()); - pDrawLineElement->addAttribute("svg:x2", vertices[1]["svg:x"]->getStr()); - pDrawLineElement->addAttribute("svg:y2", vertices[1]["svg:y"]->getStr()); - mBodyElements.push_back(pDrawLineElement); - mBodyElements.push_back(new TagCloseElement("draw:line")); - } - else - { - ::WPXPropertyListVector path; - ::WPXPropertyList element; - - for (unsigned long ii = 0; ii < vertices.count(); ++ii) - { - element = vertices[ii]; - if (ii == 0) - element.insert("libwpg:path-action", "M"); - else - element.insert("libwpg:path-action", "L"); - path.append(element); - element.clear(); - } - if (isClosed) - { - element.insert("libwpg:path-action", "Z"); - path.append(element); - } - _drawPath(path); - } + mpImpl->drawRectangle(propList); } -void OdgGeneratorPrivate::_drawPath(const WPXPropertyListVector &path) +void OdgGenerator::drawEllipse(const ::librevenge::RVNGPropertyList &propList) { - if(path.count() == 0) - return; - // This must be a mistake and we do not want to crash lower - if(path[0]["libwpg:path-action"]->getStr() == "Z") - return; - - // try to find the bounding box - // this is simple convex hull technique, the bounding box might not be - // accurate but that should be enough for this purpose - bool isFirstPoint = true; - - double px = 0.0, py = 0.0, qx = 0.0, qy = 0.0; - double lastX = 0.0; - double lastY = 0.0; - double lastPrevX = 0.0; - double lastPrevY = 0.0; - - for(unsigned k = 0; k < path.count(); ++k) - { - if (!path[k]["libwpg:path-action"]) - continue; - std::string action=path[k]["libwpg:path-action"]->getStr().cstr(); - if (action.length()!=1 || action[0]=='Z') continue; - - bool coordOk=path[k]["svg:x"]&&path[k]["svg:y"]; - bool coord1Ok=coordOk && path[k]["svg:x1"]&&path[k]["svg:y1"]; - bool coord2Ok=coord1Ok && path[k]["svg:x2"]&&path[k]["svg:y2"]; - double x=lastX, y=lastY; - if (isFirstPoint) - { - if (!coordOk) - { - ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::_drawPath: the first point has no coordinate\n")); - continue; - } - qx = px = x = path[k]["svg:x"]->getDouble(); - qy = py = y = path[k]["svg:y"]->getDouble(); - lastPrevX = lastX = px; - lastPrevY = lastY = py; - isFirstPoint = false; - } - else - { - if (path[k]["svg:x"]) x=path[k]["svg:x"]->getDouble(); - if (path[k]["svg:y"]) y=path[k]["svg:y"]->getDouble(); - px = (px > x) ? x : px; - py = (py > y) ? y : py; - qx = (qx < x) ? x : qx; - qy = (qy < y) ? y : qy; - } - - double xmin=px, xmax=qx, ymin=py, ymax=qy; - bool lastPrevSet=false; - - if(action[0] == 'C' && coord2Ok) - { - getCubicBezierBBox(lastX, lastY, path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - path[k]["svg:x2"]->getDouble(), path[k]["svg:y2"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x2"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y2"]->getDouble(); - } - else if(action[0] == 'S' && coord1Ok) - { - getCubicBezierBBox(lastX, lastY, lastPrevX, lastPrevY, - path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x1"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y1"]->getDouble(); - } - else if(action[0] == 'Q' && coord1Ok) - { - getQuadraticBezierBBox(lastX, lastY, path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x1"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y1"]->getDouble(); - } - else if(action[0] == 'T' && coordOk) - { - getQuadraticBezierBBox(lastX, lastY, lastPrevX, lastPrevY, - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-lastPrevX; - lastPrevY=2*y-lastPrevY; - } - else if(action[0] == 'A' && coordOk && path[k]["svg:rx"] && path[k]["svg:ry"]) - { - getEllipticalArcBBox(lastX, lastY, path[k]["svg:rx"]->getDouble(), path[k]["svg:ry"]->getDouble(), - path[k]["libwpg:rotate"] ? path[k]["libwpg:rotate"]->getDouble() : 0.0, - path[k]["libwpg:large-arc"] ? path[k]["libwpg:large-arc"]->getInt() : 1, - path[k]["libwpg:sweep"] ? path[k]["libwpg:sweep"]->getInt() : 1, - x, y, xmin, ymin, xmax, ymax); - } - else if (action[0] != 'M' && action[0] != 'L' && action[0] != 'H' && action[0] != 'V') - { - ODFGEN_DEBUG_MSG(("OdgGeneratorPrivate::_drawPath: problem reading a path\n")); - } - px = (px > xmin ? xmin : px); - py = (py > ymin ? ymin : py); - qx = (qx < xmax ? xmax : qx); - qy = (qy < ymax ? ymax : qy); - lastX = x; - lastY = y; - if (!lastPrevSet) - { - lastPrevX=lastX; - lastPrevY=lastY; - } - } + mpImpl->drawEllipse(propList); +} +void OdgGenerator::drawPolyline(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawPolySomething(propList, false); +} - WPXString sValue; - _writeGraphicsStyle(); - TagOpenElement *pDrawPathElement = new TagOpenElement("draw:path"); - sValue.sprintf("gr%i", miGraphicsStyleIndex-1); - pDrawPathElement->addAttribute("draw:style-name", sValue); - pDrawPathElement->addAttribute("draw:layer", "layout"); - sValue = doubleToString(px); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:x", sValue); - sValue = doubleToString(py); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:y", sValue); - sValue = doubleToString((qx - px)); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:width", sValue); - sValue = doubleToString((qy - py)); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:height", sValue); - sValue.sprintf("%i %i %i %i", 0, 0, (unsigned)(2540*(qx - px)), (unsigned)(2540*(qy - py))); - pDrawPathElement->addAttribute("svg:viewBox", sValue); - - sValue.clear(); - for(unsigned i = 0; i < path.count(); ++i) - { - if (!path[i]["libwpg:path-action"]) - continue; - std::string action=path[i]["libwpg:path-action"]->getStr().cstr(); - if (action.length()!=1) continue; - bool coordOk=path[i]["svg:x"]&&path[i]["svg:y"]; - bool coord1Ok=coordOk && path[i]["svg:x1"]&&path[i]["svg:y1"]; - bool coord2Ok=coord1Ok && path[i]["svg:x2"]&&path[i]["svg:y2"]; - WPXString sElement; - // 2540 is 2.54*1000, 2.54 in = 1 inch - if (path[i]["svg:x"] && action[0] == 'H') - { - sElement.sprintf("H%i", (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540)); - sValue.append(sElement); - } - else if (path[i]["svg:y"] && action[0] == 'V') - { - sElement.sprintf("V%i", (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coordOk && (action[0] == 'M' || action[0] == 'L' || action[0] == 'T')) - { - sElement.sprintf("%c%i %i", action[0], (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coord1Ok && (action[0] == 'Q' || action[0] == 'S')) - { - sElement.sprintf("%c%i %i %i %i", action[0], (unsigned)((path[i]["svg:x1"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y1"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coord2Ok && action[0] == 'C') - { - sElement.sprintf("C%i %i %i %i %i %i", (unsigned)((path[i]["svg:x1"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y1"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x2"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y2"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coordOk && path[i]["svg:rx"] && path[i]["svg:ry"] && action[0] == 'A') - { - sElement.sprintf("A%i %i %i %i %i %i %i", (unsigned)((path[i]["svg:rx"]->getDouble())*2540), - (unsigned)((path[i]["svg:ry"]->getDouble())*2540), (path[i]["libwpg:rotate"] ? path[i]["libwpg:rotate"]->getInt() : 0), - (path[i]["libwpg:large-arc"] ? path[i]["libwpg:large-arc"]->getInt() : 1), - (path[i]["libwpg:sweep"] ? path[i]["libwpg:sweep"]->getInt() : 1), - (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (action[0] == 'Z') - sValue.append(" Z"); - } - pDrawPathElement->addAttribute("svg:d", sValue); - mBodyElements.push_back(pDrawPathElement); - mBodyElements.push_back(new TagCloseElement("draw:path")); +void OdgGenerator::drawPolygon(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawPolySomething(propList, true); } -void OdgGenerator::drawPath(const WPXPropertyListVector &path) +void OdgGenerator::drawPath(const librevenge::RVNGPropertyList &propList) { - mpImpl->_drawPath(path); + mpImpl->drawPath(propList); } -void OdgGenerator::drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData &binaryData) +void OdgGenerator::drawGraphicObject(const ::librevenge::RVNGPropertyList &propList) { - if (!propList["libwpg:mime-type"] || propList["libwpg:mime-type"]->getStr().len() <= 0) + if (!propList["librevenge:mime-type"] || propList["librevenge:mime-type"]->getStr().len() <= 0) + return; + if (!propList["office:binary-data"]) return; if (!propList["svg:x"] || !propList["svg:y"] || !propList["svg:width"] || !propList["svg:height"]) return; bool flipX(propList["draw:mirror-horizontal"] && propList["draw:mirror-horizontal"]->getInt()); bool flipY(propList["draw:mirror-vertical"] && propList["draw:mirror-vertical"]->getInt()); + + librevenge::RVNGPropertyList style=mpImpl->getGraphicStyle(); if ((flipX && !flipY) || (!flipX && flipY)) - mpImpl->mxStyle.insert("style:mirror", "horizontal"); + style.insert("style:mirror", "horizontal"); else - mpImpl->mxStyle.insert("style:mirror", "none"); + style.insert("style:mirror", "none"); if (propList["draw:color-mode"]) - mpImpl->mxStyle.insert("draw:color-mode", propList["draw:color-mode"]->getStr()); + style.insert("draw:color-mode", propList["draw:color-mode"]->getStr()); if (propList["draw:luminance"]) - mpImpl->mxStyle.insert("draw:luminance", propList["draw:luminance"]->getStr()); + style.insert("draw:luminance", propList["draw:luminance"]->getStr()); if (propList["draw:contrast"]) - mpImpl->mxStyle.insert("draw:contrast", propList["draw:contrast"]->getStr()); + style.insert("draw:contrast", propList["draw:contrast"]->getStr()); if (propList["draw:gamma"]) - mpImpl->mxStyle.insert("draw:gamma", propList["draw:gamma"]->getStr()); + style.insert("draw:gamma", propList["draw:gamma"]->getStr()); if (propList["draw:red"]) - mpImpl->mxStyle.insert("draw:red", propList["draw:red"]->getStr()); + style.insert("draw:red", propList["draw:red"]->getStr()); if (propList["draw:green"]) - mpImpl->mxStyle.insert("draw:green", propList["draw:green"]->getStr()); + style.insert("draw:green", propList["draw:green"]->getStr()); if (propList["draw:blue"]) - mpImpl->mxStyle.insert("draw:blue", propList["draw:blue"]->getStr()); - + style.insert("draw:blue", propList["draw:blue"]->getStr()); - mpImpl->_writeGraphicsStyle(); - - double x = propList["svg:x"]->getDouble(); - double y = propList["svg:y"]->getDouble(); - double height = propList["svg:height"]->getDouble(); - double width = propList["svg:width"]->getDouble(); + double x, y; + double height, width; + getInchValue(*propList["svg:x"], x); + getInchValue(*propList["svg:y"], y); + getInchValue(*propList["svg:height"], height); + getInchValue(*propList["svg:width"], width); if (flipY) { @@ -934,7 +621,7 @@ height *= -1.0; } - double angle(propList["libwpg:rotate"] ? - M_PI * propList["libwpg:rotate"]->getDouble() / 180.0 : 0.0); + double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0); if (angle != 0.0) { double deltax((width*cos(angle)+height*sin(angle)-width)/2.0); @@ -943,7 +630,7 @@ y -= deltay; } - WPXPropertyList framePropList; + librevenge::RVNGPropertyList framePropList; framePropList.insert("svg:x", x); framePropList.insert("svg:y", y); @@ -952,18 +639,19 @@ TagOpenElement *pDrawFrameElement = new TagOpenElement("draw:frame"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawFrameElement->addAttribute("draw:style-name", sValue); + librevenge::RVNGPropertyList finalStyle; + mpImpl->getGraphicManager().addGraphicProperties(style, finalStyle); + pDrawFrameElement->addAttribute("draw:style-name", mpImpl->getGraphicManager().findOrAdd(finalStyle)); pDrawFrameElement->addAttribute("svg:height", framePropList["svg:height"]->getStr()); pDrawFrameElement->addAttribute("svg:width", framePropList["svg:width"]->getStr()); if (angle != 0.0) { - framePropList.insert("libwpg:rotate", angle, WPX_GENERIC); + framePropList.insert("librevenge:rotate", angle, librevenge::RVNG_GENERIC); + librevenge::RVNGString sValue; sValue.sprintf("rotate (%s) translate(%s, %s)", - framePropList["libwpg:rotate"]->getStr().cstr(), + framePropList["librevenge:rotate"]->getStr().cstr(), framePropList["svg:x"]->getStr().cstr(), framePropList["svg:y"]->getStr().cstr()); pDrawFrameElement->addAttribute("draw:transform", sValue); @@ -973,417 +661,19 @@ pDrawFrameElement->addAttribute("svg:x", framePropList["svg:x"]->getStr()); pDrawFrameElement->addAttribute("svg:y", framePropList["svg:y"]->getStr()); } - mpImpl->mBodyElements.push_back(pDrawFrameElement); - - if (propList["libwpg:mime-type"]->getStr() == "object/ole") - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:object-ole")); - else - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:image")); - - mpImpl->mBodyElements.push_back(new TagOpenElement("office:binary-data")); - - ::WPXString base64Binary = binaryData.getBase64Data(); - mpImpl->mBodyElements.push_back(new CharDataElement(base64Binary.cstr())); + mpImpl->getCurrentStorage()->push_back(pDrawFrameElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("office:binary-data")); + mpImpl->insertBinaryObject(propList); - if (propList["libwpg:mime-type"]->getStr() == "object/ole") - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:object-ole")); - else - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:image")); - - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); } -void OdgGeneratorPrivate::_writeGraphicsStyle() +void OdgGenerator::drawConnector(const ::librevenge::RVNGPropertyList &propList) { - TagOpenElement *pStyleStyleElement = new TagOpenElement("style:style"); - WPXString sValue; - sValue.sprintf("gr%i", miGraphicsStyleIndex); - pStyleStyleElement->addAttribute("style:name", sValue); - pStyleStyleElement->addAttribute("style:family", "graphic"); - pStyleStyleElement->addAttribute("style:parent-style-name", "standard"); - mGraphicsAutomaticStyles.push_back(pStyleStyleElement); - - TagOpenElement *pStyleGraphicsPropertiesElement = new TagOpenElement("style:graphic-properties"); - _updateGraphicPropertiesElement(*pStyleGraphicsPropertiesElement, mxStyle, mxGradient); - mGraphicsAutomaticStyles.push_back(pStyleGraphicsPropertiesElement); - mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties")); - - mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:style")); - miGraphicsStyleIndex++; + mpImpl->drawConnector(propList); } -void OdgGeneratorPrivate::_updateGraphicPropertiesElement(TagOpenElement &element, ::WPXPropertyList const &style, ::WPXPropertyListVector const &gradient) -{ - bool bUseOpacityGradient = false; - - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "dash") - { - TagOpenElement *pDrawStrokeDashElement = new TagOpenElement("draw:stroke-dash"); - WPXString sValue; - sValue.sprintf("Dash_%i", miDashIndex++); - pDrawStrokeDashElement->addAttribute("draw:name", sValue); - if (style["svg:stoke-linecap"]) - pDrawStrokeDashElement->addAttribute("draw:style", style["svg:stroke-linecap"]->getStr()); - else - pDrawStrokeDashElement->addAttribute("draw:style", "rect"); - if (style["draw:distance"]) - pDrawStrokeDashElement->addAttribute("draw:distance", style["draw:distance"]->getStr()); - if (style["draw:dots1"]) - pDrawStrokeDashElement->addAttribute("draw:dots1", style["draw:dots1"]->getStr()); - if (style["draw:dots1-length"]) - pDrawStrokeDashElement->addAttribute("draw:dots1-length", style["draw:dots1-length"]->getStr()); - if (style["draw:dots2"]) - pDrawStrokeDashElement->addAttribute("draw:dots2", style["draw:dots2"]->getStr()); - if (style["draw:dots2-length"]) - pDrawStrokeDashElement->addAttribute("draw:dots2-length", style["draw:dots2-length"]->getStr()); - mGraphicsStrokeDashStyles.push_back(pDrawStrokeDashElement); - mGraphicsStrokeDashStyles.push_back(new TagCloseElement("draw:stroke-dash")); - } - - if (style["draw:marker-start-path"]) - { - WPXString sValue; - TagOpenElement *pDrawMarkerElement = new TagOpenElement("draw:marker"); - sValue.sprintf("StartMarker_%i", miStartMarkerIndex); - pDrawMarkerElement->addAttribute("draw:name", sValue); - if (style["draw:marker-start-viewbox"]) - pDrawMarkerElement->addAttribute("svg:viewBox", style["draw:marker-start-viewbox"]->getStr()); - pDrawMarkerElement->addAttribute("svg:d", style["draw:marker-start-path"]->getStr()); - mGraphicsMarkerStyles.push_back(pDrawMarkerElement); - mGraphicsMarkerStyles.push_back(new TagCloseElement("draw:marker")); - } - if(style["draw:marker-end-path"]) - { - WPXString sValue; - TagOpenElement *pDrawMarkerElement = new TagOpenElement("draw:marker"); - sValue.sprintf("EndMarker_%i", miEndMarkerIndex); - pDrawMarkerElement->addAttribute("draw:name", sValue); - if (style["draw:marker-end-viewbox"]) - pDrawMarkerElement->addAttribute("svg:viewBox", style["draw:marker-end-viewbox"]->getStr()); - pDrawMarkerElement->addAttribute("svg:d", style["draw:marker-end-path"]->getStr()); - mGraphicsMarkerStyles.push_back(pDrawMarkerElement); - mGraphicsMarkerStyles.push_back(new TagCloseElement("draw:marker")); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "gradient") - { - TagOpenElement *pDrawGradientElement = new TagOpenElement("draw:gradient"); - TagOpenElement *pDrawOpacityElement = new TagOpenElement("draw:opacity"); - if (style["draw:style"]) - { - pDrawGradientElement->addAttribute("draw:style", style["draw:style"]->getStr()); - pDrawOpacityElement->addAttribute("draw:style", style["draw:style"]->getStr()); - } - else - { - pDrawGradientElement->addAttribute("draw:style", "linear"); - pDrawOpacityElement->addAttribute("draw:style", "linear"); - } - WPXString sValue; - sValue.sprintf("Gradient_%i", miGradientIndex); - pDrawGradientElement->addAttribute("draw:name", sValue); - sValue.sprintf("Transparency_%i", miGradientIndex++); - pDrawOpacityElement->addAttribute("draw:name", sValue); - - // ODG angle unit is 0.1 degree - double angle = style["draw:angle"] ? style["draw:angle"]->getDouble() : 0.0; - while(angle < 0) - angle += 360; - while(angle > 360) - angle -= 360; - sValue.sprintf("%i", (unsigned)(angle*10)); - pDrawGradientElement->addAttribute("draw:angle", sValue); - pDrawOpacityElement->addAttribute("draw:angle", sValue); - - if (!gradient.count()) - { - if (style["draw:start-color"]) - pDrawGradientElement->addAttribute("draw:start-color", style["draw:start-color"]->getStr()); - if (style["draw:end-color"]) - pDrawGradientElement->addAttribute("draw:end-color", style["draw:end-color"]->getStr()); - - if (style["draw:border"]) - { - pDrawGradientElement->addAttribute("draw:border", style["draw:border"]->getStr()); - pDrawOpacityElement->addAttribute("draw:border", style["draw:border"]->getStr()); - } - else - { - pDrawGradientElement->addAttribute("draw:border", "0%"); - pDrawOpacityElement->addAttribute("draw:border", "0%"); - } - - if (style["svg:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - } - else if (style["draw:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["draw:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["draw:cx"]->getStr()); - } - - if (style["svg:cy"]) - { - pDrawGradientElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - } - else if (style["draw:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - } - - if (style["draw:start-intensity"]) - pDrawGradientElement->addAttribute("draw:start-intensity", style["draw:start-intensity"]->getStr()); - else - pDrawGradientElement->addAttribute("draw:start-intensity", "100%"); - - if (style["draw:end-intensity"]) - pDrawGradientElement->addAttribute("draw:end-intensity", style["draw:end-intensity"]->getStr()); - else - pDrawGradientElement->addAttribute("draw:end-intensity", "100%"); - - if (style["libwpg:start-opacity"]) - pDrawOpacityElement->addAttribute("draw:start", style["libwpg:start-opacity"]->getStr()); - else - pDrawOpacityElement->addAttribute("draw:start", "100%"); - - if (style["libwpg:end-opacity"]) - pDrawOpacityElement->addAttribute("draw:end", style["libwpg:end-opacity"]->getStr()); - else - pDrawOpacityElement->addAttribute("draw:end", "100%"); - - mGraphicsGradientStyles.push_back(pDrawGradientElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:gradient")); - - // Work around a mess in LibreOffice where both opacities of 100% are interpreted as complete transparency - // Nevertheless, when one is different, immediately, they are interpreted correctly - if (style["libwpg:start-opacity"] && style["libwpg:end-opacity"] - && (style["libwpg:start-opacity"]->getDouble() != 1.0 || style["libwpg:end-opacity"]->getDouble() != 1.0)) - { - bUseOpacityGradient = true; - mGraphicsGradientStyles.push_back(pDrawOpacityElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:opacity")); - } - } - else if(gradient.count() >= 2) - { - sValue.sprintf("%i", (unsigned)(angle*10)); - pDrawGradientElement->addAttribute("draw:angle", sValue); - - pDrawGradientElement->addAttribute("draw:start-color", gradient[1]["svg:stop-color"]->getStr()); - pDrawGradientElement->addAttribute("draw:end-color", gradient[0]["svg:stop-color"]->getStr()); - if (style["svg:cx"]) - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - if (style["svg:cy"]) - pDrawGradientElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - if (gradient[1]["svg:stop-opacity"]) - { - pDrawOpacityElement->addAttribute("draw:start", gradient[1]["svg:stop-opacity"]->getStr()); - bUseOpacityGradient = true; - } - else - pDrawOpacityElement->addAttribute("draw:start", "100%"); - if (gradient[0]["svg:stop-opacity"]) - { - pDrawOpacityElement->addAttribute("draw:end", gradient[0]["svg:stop-opacity"]->getStr()); - bUseOpacityGradient = true; - } - else - pDrawOpacityElement->addAttribute("draw:end", "100%"); - pDrawGradientElement->addAttribute("draw:border", "0%"); - mGraphicsGradientStyles.push_back(pDrawGradientElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:gradient")); - if (bUseOpacityGradient) - { - mGraphicsGradientStyles.push_back(pDrawOpacityElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:opacity")); - } - } - else - { - /* if gradient.count() == 1 for some reason we would leak - * pDrawGradientElement - */ - delete pDrawGradientElement; - } - if(!bUseOpacityGradient) - delete pDrawOpacityElement; - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "bitmap" && - style["draw:fill-image"] && style["libwpg:mime-type"]) - { - TagOpenElement *pDrawBitmapElement = new TagOpenElement("draw:fill-image"); - WPXString sValue; - sValue.sprintf("Bitmap_%i", miBitmapIndex++); - pDrawBitmapElement->addAttribute("draw:name", sValue); - mGraphicsBitmapStyles.push_back(pDrawBitmapElement); - mGraphicsBitmapStyles.push_back(new TagOpenElement("office:binary-data")); - mGraphicsBitmapStyles.push_back(new CharDataElement(style["draw:fill-image"]->getStr())); - mGraphicsBitmapStyles.push_back(new TagCloseElement("office:binary-data")); - mGraphicsBitmapStyles.push_back(new TagCloseElement("draw:fill-image")); - } - - if (style["draw:color-mode"] && style["draw:color-mode"]->getStr().len() > 0) - element.addAttribute("draw:color-mode", style["draw:color-mode"]->getStr()); - if (style["draw:luminance"] && style["draw:luminance"]->getStr().len() > 0) - element.addAttribute("draw:luminance", style["draw:luminance"]->getStr()); - if (style["draw:contrast"] && style["draw:contrast"]->getStr().len() > 0) - element.addAttribute("draw:contrast", style["draw:contrast"]->getStr()); - if (style["draw:gamma"] && style["draw:gamma"]->getStr().len() > 0) - element.addAttribute("draw:gamma", style["draw:gamma"]->getStr()); - if (style["draw:red"] && style["draw:red"]->getStr().len() > 0) - element.addAttribute("draw:red", style["draw:red"]->getStr()); - if (style["draw:green"] && style["draw:green"]->getStr().len() > 0) - element.addAttribute("draw:green", style["draw:green"]->getStr()); - if (style["draw:blue"] && style["draw:blue"]->getStr().len() > 0) - element.addAttribute("draw:blue", style["draw:blue"]->getStr()); - - WPXString sValue; - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "none") - element.addAttribute("draw:stroke", "none"); - else - { - if (style["svg:stroke-width"]) - element.addAttribute("svg:stroke-width", style["svg:stroke-width"]->getStr()); - - if (style["svg:stroke-color"]) - element.addAttribute("svg:stroke-color", style["svg:stroke-color"]->getStr()); - - if (style["svg:stroke-opacity"]) - element.addAttribute("svg:stroke-opacity", style["svg:stroke-opacity"]->getStr()); - - if (style["svg:stroke-linejoin"]) - element.addAttribute("draw:stroke-linejoin", style["svg:stroke-linejoin"]->getStr()); - - if (style["svg:stroke-linecap"]) - element.addAttribute("svg:stoke-linecap", style["svg:stroke-linecap"]->getStr()); - - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "dash") - { - element.addAttribute("draw:stroke", "dash"); - sValue.sprintf("Dash_%i", miDashIndex-1); - element.addAttribute("draw:stroke-dash", sValue); - } - else - element.addAttribute("draw:stroke", "solid"); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "none") - element.addAttribute("draw:fill", "none"); - else - { - if (style["draw:shadow"]) - element.addAttribute("draw:shadow", style["draw:shadow"]->getStr()); - else - element.addAttribute("draw:shadow", "hidden"); - if (style["draw:shadow-offset-x"]) - element.addAttribute("draw:shadow-offset-x", style["draw:shadow-offset-x"]->getStr()); - if (style["draw:shadow-offset-y"]) - element.addAttribute("draw:shadow-offset-y", style["draw:shadow-offset-y"]->getStr()); - if (style["draw:shadow-color"]) - element.addAttribute("draw:shadow-color", style["draw:shadow-color"]->getStr()); - if (style["draw:shadow-opacity"]) - element.addAttribute("draw:shadow-opacity", style["draw:shadow-opacity"]->getStr()); - if (style["svg:fill-rule"]) - element.addAttribute("svg:fill-rule", style["svg:fill-rule"]->getStr()); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "solid") - { - element.addAttribute("draw:fill", "solid"); - if (style["draw:fill-color"]) - element.addAttribute("draw:fill-color", style["draw:fill-color"]->getStr()); - if (style["draw:opacity"]) - element.addAttribute("draw:opacity", style["draw:opacity"]->getStr()); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "gradient") - { - if (!gradient.count() || gradient.count() >= 2) - { - element.addAttribute("draw:fill", "gradient"); - sValue.sprintf("Gradient_%i", miGradientIndex-1); - element.addAttribute("draw:fill-gradient-name", sValue); - if (bUseOpacityGradient) - { - sValue.sprintf("Transparency_%i", miGradientIndex-1); - element.addAttribute("draw:opacity-name", sValue); - } - } - else - { - if (gradient[0]["svg:stop-color"]) - { - element.addAttribute("draw:fill", "solid"); - element.addAttribute("draw:fill-color", gradient[0]["svg:stop-color"]->getStr()); - } - else - element.addAttribute("draw:fill", "solid"); - } - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "bitmap") - { - if (style["draw:fill-image"] && style["libwpg:mime-type"]) - { - element.addAttribute("draw:fill", "bitmap"); - sValue.sprintf("Bitmap_%i", miBitmapIndex-1); - element.addAttribute("draw:fill-image-name", sValue); - if (style["draw:fill-image-width"]) - element.addAttribute("draw:fill-image-width", style["draw:fill-image-width"]->getStr()); - else if (style["svg:width"]) - element.addAttribute("draw:fill-image-width", style["svg:width"]->getStr()); - if (style["draw:fill-image-height"]) - element.addAttribute("draw:fill-image-height", style["draw:fill-image-height"]->getStr()); - else if (style["svg:height"]) - element.addAttribute("draw:fill-image-height", style["svg:height"]->getStr()); - if (style["style:repeat"]) - element.addAttribute("style:repeat", style["style:repeat"]->getStr()); - if (style["draw:fill-image-ref-point"]) - element.addAttribute("draw:fill-image-ref-point", style["draw:fill-image-ref-point"]->getStr()); - if (style["draw:fill-image-ref-point-x"]) - element.addAttribute("draw:fill-image-ref-point-x", style["draw:fill-image-ref-point-x"]->getStr()); - if (style["draw:fill-image-ref-point-y"]) - element.addAttribute("draw:fill-image-ref-point-y", style["draw:fill-image-ref-point-y"]->getStr()); - } - else - element.addAttribute("draw:fill", "none"); - } - - - if(style["draw:marker-start-path"]) - { - sValue.sprintf("StartMarker_%i", miStartMarkerIndex++); - element.addAttribute("draw:marker-start", sValue); - if (style["draw:marker-start-center"]) - element.addAttribute("draw:marker-start-center", style["draw:marker-start-center"]->getStr()); - if (style["draw:marker-start-width"]) - element.addAttribute("draw:marker-start-width", style["draw:marker-start-width"]->getStr()); - else - element.addAttribute("draw:marker-start-width", "0.118in"); - } - if (style["draw:marker-end-path"]) - { - sValue.sprintf("EndMarker_%i", miEndMarkerIndex++); - element.addAttribute("draw:marker-end", sValue); - if (style["draw:marker-end-center"]) - element.addAttribute("draw:marker-end-center", style["draw:marker-end-center"]->getStr()); - if (style["draw:marker-end-width"]) - element.addAttribute("draw:marker-end-width", style["draw:marker-end-width"]->getStr()); - else - element.addAttribute("draw:marker-end-width", "0.118in"); - } - if (style["style:mirror"]) - element.addAttribute("style:mirror", style["style:mirror"]->getStr()); -} - -void OdgGenerator::startEmbeddedGraphics(const WPXPropertyList &) +void OdgGenerator::startEmbeddedGraphics(const librevenge::RVNGPropertyList &) { } @@ -1391,129 +681,91 @@ { } -void OdgGenerator::startTextObject(const WPXPropertyList &propList, const WPXPropertyListVector &/*path*/) +void OdgGenerator::startTextObject(const librevenge::RVNGPropertyList &propList) { - TagOpenElement *pDrawFrameOpenElement = new TagOpenElement("draw:frame"); - TagOpenElement *pStyleStyleOpenElement = new TagOpenElement("style:style"); - - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex++); - pStyleStyleOpenElement->addAttribute("style:name", sValue); - pStyleStyleOpenElement->addAttribute("style:family", "graphic"); - pStyleStyleOpenElement->addAttribute("style:parent-style-name", "standard"); - mpImpl->mGraphicsAutomaticStyles.push_back(pStyleStyleOpenElement); + if (mpImpl->getState().mbIsTextBox) + { + // this seems to make LibreOffice crash, so ... + ODFGEN_DEBUG_MSG(("OdgGenerator::startTextObject: sending intricated text box is not implemented\n")); + ++mpImpl->getState().miIntricatedTextBox; + return; + } + librevenge::RVNGPropertyList tmpList(propList), graphicStyle; + if (!propList["draw:stroke"]) + tmpList.insert("draw:stroke", "none"); + if (!propList["draw:fill"]) + tmpList.insert("draw:fill", "none"); + mpImpl->getGraphicManager().addGraphicProperties(tmpList, graphicStyle); + mpImpl->getGraphicManager().addFrameProperties(propList, graphicStyle); + librevenge::RVNGString sValue=mpImpl->getGraphicManager().findOrAdd(graphicStyle); + TagOpenElement *pDrawFrameOpenElement = new TagOpenElement("draw:frame"); pDrawFrameOpenElement->addAttribute("draw:style-name", sValue); pDrawFrameOpenElement->addAttribute("draw:layer", "layout"); - TagOpenElement *pStyleGraphicPropertiesOpenElement = new TagOpenElement("style:graphic-properties"); - WPXPropertyList styleList(propList); - if (!propList["draw:stroke"]) - styleList.insert("draw:stroke", "none"); - if (!propList["draw:fill"]) - styleList.insert("draw:fill", "none"); - // the transformation is managed latter, so even if this changes nothing... - if (propList["libwpg:rotate"]) - styleList.insert("libwpg:rotate", 0); - mpImpl->_updateGraphicPropertiesElement(*pStyleGraphicPropertiesOpenElement, styleList, WPXPropertyListVector()); - if (!propList["svg:width"] && !propList["svg:height"]) { - if (!propList["fo:min-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:min-width", "1in"); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-width", "1in"); - } pDrawFrameOpenElement->addAttribute("svg:width", "10in"); + pDrawFrameOpenElement->addAttribute("fo:min-width", "1in"); } else { - if(propList["svg:width"]) + if (propList["svg:width"]) pDrawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - if(propList["svg:height"]) + if (propList["svg:height"]) pDrawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); } - if (propList["fo:min-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - } - if (propList["fo:min-height"]) + static char const *attrib[]= { - pDrawFrameOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - } - if (propList["fo:max-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:max-width", propList["fo:max-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr()); - } - if (propList["fo:max-height"]) - { - pDrawFrameOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - } - if (propList["fo:padding-top"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-top", propList["fo:padding-top"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-top", propList["fo:padding-top"]->getStr()); - } - if (propList["fo:padding-bottom"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-bottom", propList["fo:padding-bottom"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-bottom", propList["fo:padding-bottom"]->getStr()); - } - if (propList["fo:padding-left"]) + "fo:min-width", "fo:min-height", "fo:max-width", "fo:max-height", "fo:padding-top", "fo:padding-bottom", + "fo:padding-left", "fo:padding-right", "draw:textarea-vertical-align" + }; + for (int i=0; i<9; ++i) { - pDrawFrameOpenElement->addAttribute("fo:padding-left", propList["fo:padding-left"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-left", propList["fo:padding-left"]->getStr()); - } - if (propList["fo:padding-right"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-right", propList["fo:padding-right"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-right", propList["fo:padding-right"]->getStr()); - } - if (propList["draw:textarea-vertical-align"]) - { - pDrawFrameOpenElement->addAttribute("draw:textarea-vertical-align", propList["draw:textarea-vertical-align"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("draw:textarea-vertical-align", propList["draw:textarea-vertical-align"]->getStr()); + if (propList[attrib[i]]) + pDrawFrameOpenElement->addAttribute(attrib[i], propList[attrib[i]]->getStr()); } double x = 0.0; double y = 0.0; if (propList["svg:x"]) - x = propList["svg:x"]->getDouble(); + getInchValue(*propList["svg:x"],x); if (propList["svg:y"]) - y = propList["svg:y"]->getDouble(); - double angle(propList["libwpg:rotate"] ? - M_PI * propList["libwpg:rotate"]->getDouble() / 180.0 : 0.0); + getInchValue(*propList["svg:y"],y); + double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0); if (angle != 0.0) { // compute position: make sure that the center position remains invariant double width = 0.0; double height = 0.0; - if (propList["libwpg:rotate-cx"]) - width = 2.0*(propList["libwpg:rotate-cx"]->getDouble()-x); + if (propList["librevenge:rotate-cx"]) + { + getInchValue(*propList["librevenge:rotate-cx"],width); + width = 2.0*(width-x); + } else if (propList["svg:width"]) - width = propList["svg:width"]->getDouble(); - if (propList["libwpg:rotate-cy"]) - height = 2.0*(propList["libwpg:rotate-cy"]->getDouble()-y); + getInchValue(*propList["svg:width"],width); + if (propList["librevenge:rotate-cy"]) + { + getInchValue(*propList["librevenge:rotate-cy"],height); + height = 2.0*(height-y); + } else if (propList["svg:height"]) - height = propList["svg:height"]->getDouble(); + getInchValue(*propList["svg:height"],height); double deltax((width*cos(angle)+height*sin(angle)-width)/2.0); double deltay((-width*sin(angle)+height*cos(angle)-height)/2.0); x -= deltax; y -= deltay; } - WPXProperty *svg_x = WPXPropertyFactory::newInchProp(x); - WPXProperty *svg_y = WPXPropertyFactory::newInchProp(y); + shared_ptr svg_x(librevenge::RVNGPropertyFactory::newInchProp(x)); + shared_ptr svg_y(librevenge::RVNGPropertyFactory::newInchProp(y)); if (angle != 0.0) { - WPXProperty *libwpg_rotate = WPXPropertyFactory::newDoubleProp(angle); + shared_ptr librevenge_rotate(librevenge::RVNGPropertyFactory::newDoubleProp(angle)); sValue.sprintf("rotate (%s) translate(%s, %s)", - libwpg_rotate->getStr().cstr(), + librevenge_rotate->getStr().cstr(), svg_x->getStr().cstr(), svg_y->getStr().cstr()); - delete libwpg_rotate; pDrawFrameOpenElement->addAttribute("draw:transform", sValue); } else @@ -1523,96 +775,220 @@ if (propList["svg:y"]) pDrawFrameOpenElement->addAttribute("svg:y", svg_y->getStr()); } - delete svg_x; - delete svg_y; - mpImpl->mBodyElements.push_back(pDrawFrameOpenElement); - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:text-box")); - mpImpl->mGraphicsAutomaticStyles.push_back(pStyleGraphicPropertiesOpenElement); - mpImpl->mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties")); - mpImpl->mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:style")); - mpImpl->mbIsTextBox = true; + mpImpl->getCurrentStorage()->push_back(pDrawFrameOpenElement); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("draw:text-box")); + + // push the different states + mpImpl->pushState(); + mpImpl->pushListState(); + mpImpl->getState().mbIsTextBox = true; } void OdgGenerator::endTextObject() { - if (mpImpl->mbIsTextBox) + OdgGeneratorPrivate::State &state=mpImpl->getState(); + if (!state.mbIsTextBox) return; + if (state.miIntricatedTextBox) { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:text-box")); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); - mpImpl->mbIsTextBox = false; + // we did not open textbox when seeing intricated text box + --state.miIntricatedTextBox; + return; } + // pop the different state + mpImpl->popListState(); + mpImpl->popState(); + + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:text-box")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); } -void OdgGenerator::startTextLine(const WPXPropertyList &propList) +void OdgGenerator::startTableObject(const ::librevenge::RVNGPropertyList &propList) { - WPXPropertyList finalPropList(propList); - finalPropList.insert("style:parent-style-name", "Standard"); - WPXString paragName = mpImpl->mParagraphManager.findOrAdd(finalPropList, WPXPropertyListVector()); + // table must be inside a frame + TagOpenElement *pFrameOpenElement = new TagOpenElement("draw:frame"); + + pFrameOpenElement->addAttribute("draw:style-name", "standard"); + if (propList["svg:x"]) + pFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr()); + if (propList["svg:y"]) + pFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr()); + if (propList["svg:width"]) + pFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); + if (propList["svg:height"]) + pFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); + mpImpl->getCurrentStorage()->push_back(pFrameOpenElement); + mpImpl->openTable(propList); - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); - pParagraphOpenElement->addAttribute("text:style-name", paragName); - mpImpl->mBodyElements.push_back(pParagraphOpenElement); + mpImpl->pushListState(); + mpImpl->pushState(); } -void OdgGenerator::endTextLine() +void OdgGenerator::endTableObject() { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:p")); + mpImpl->popState(); + mpImpl->popListState(); + + mpImpl->closeTable(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); } -void OdgGenerator::startTextSpan(const WPXPropertyList &propList) +void OdgGenerator::openTableRow(const ::librevenge::RVNGPropertyList &propList) { - if (propList["style:font-name"]) - mpImpl->mFontManager.findOrAdd(propList["style:font-name"]->getStr().cstr()); - - WPXString sName = mpImpl->mSpanManager.findOrAdd(propList); - - TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); - pSpanOpenElement->addAttribute("text:style-name", sName.cstr()); - mpImpl->mBodyElements.push_back(pSpanOpenElement); + mpImpl->openTableRow(propList); } -void OdgGenerator::endTextSpan() +void OdgGenerator::closeTableRow() { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:span")); + mpImpl->closeTableRow(); } -void OdgGenerator::insertText(const WPXString &text) +void OdgGenerator::openTableCell(const ::librevenge::RVNGPropertyList &propList) { - WPXString out; - WPXString::Iter i(text); - for (i.rewind(); i.next();) + if (mpImpl->getState().mbInTableCell) { - if ((*i()) == '\n' || (*i()) == '\t') - { - if (out.len() != 0) - { - DocumentElement *pText = new TextElement(out); - mpImpl->mBodyElements.push_back(pText); - out.clear(); - } - if ((*i()) == '\n') - { - mpImpl->mBodyElements.push_back(new TagOpenElement("text:line-break")); - mpImpl->mBodyElements.push_back(new TagCloseElement("text:line-break")); - } - else if ((*i()) == '\t') - { - mpImpl->mBodyElements.push_back(new TagOpenElement("text:tab")); - mpImpl->mBodyElements.push_back(new TagCloseElement("text:tab")); - } - } - else - { - out.append(i()); - } + ODFGEN_DEBUG_MSG(("OdgGenerator::openTableCell: a table cell in a table cell?!\n")); + return; } - if (out.len() != 0) + librevenge::RVNGPropertyList pList(propList); + if (pList["fo:background-color"]) { - DocumentElement *pText = new TextElement(out); - mpImpl->mBodyElements.push_back(pText); + pList.insert("draw:fill", "solid"); + pList.insert("draw:fill-color", pList["fo:background-color"]->getStr()); } + else if (!pList["draw:fill"]) + pList.insert("draw:fill", "none"); + mpImpl->getState().mbInTableCell = mpImpl->openTableCell(pList); +} + +void OdgGenerator::closeTableCell() +{ + if (!mpImpl->getState().mbInTableCell) + { + ODFGEN_DEBUG_MSG(("OdgGenerator::closeTableCell: no table cell is opened\n")); + return; + } + + mpImpl->closeTableCell(); + mpImpl->getState().mbInTableCell = false; +} + +void OdgGenerator::insertCoveredTableCell(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->insertCoveredTableCell(propList); +} + +void OdgGenerator::openOrderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openListLevel(propList, true); +} + +void OdgGenerator::openUnorderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openListLevel(propList, false); +} + +void OdgGenerator::closeOrderedListLevel() +{ + mpImpl->closeListLevel(); +} + +void OdgGenerator::closeUnorderedListLevel() +{ + mpImpl->closeListLevel(); +} + +void OdgGenerator::openListElement(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openListElement(propList); +} + +void OdgGenerator::closeListElement() +{ + mpImpl->closeListElement(); +} + +void OdgGenerator::defineParagraphStyle(librevenge::RVNGPropertyList const &propList) +{ + mpImpl->defineParagraphStyle(propList); +} + +void OdgGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) +{ + librevenge::RVNGPropertyList finalPropList(propList); + finalPropList.insert("style:parent-style-name", "Standard"); + mpImpl->openParagraph(finalPropList); +} + +void OdgGenerator::closeParagraph() +{ + mpImpl->closeParagraph(); +} + +void OdgGenerator::defineCharacterStyle(librevenge::RVNGPropertyList const &propList) +{ + mpImpl->defineCharacterStyle(propList); +} + + +void OdgGenerator::openSpan(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openSpan(propList); +} + +void OdgGenerator::closeSpan() +{ + mpImpl->closeSpan(); +} + +void OdgGenerator::openLink(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openLink(propList); +} + +void OdgGenerator::closeLink() +{ + mpImpl->closeLink(); +} + +void OdgGenerator::insertTab() +{ + mpImpl->insertTab(); +} + +void OdgGenerator::insertSpace() +{ + mpImpl->insertSpace(); +} + +void OdgGenerator::insertLineBreak() +{ + mpImpl->insertLineBreak(); +} + +void OdgGenerator::insertField(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->insertField(propList); +} + +void OdgGenerator::insertText(const librevenge::RVNGString &text) +{ + mpImpl->insertText(text); +} + +void OdgGenerator::initStateWith(OdfGenerator const &orig) +{ + mpImpl->initStateWith(orig); +} + +void OdgGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler) +{ + mpImpl->registerEmbeddedObjectHandler(mimeType, objectHandler); +} + +void OdgGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler) +{ + mpImpl->registerEmbeddedImageHandler(mimeType, imageHandler); } /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdpGenerator.cxx libodfgen-0.1.1/src/OdpGenerator.cxx --- libodfgen-0.0.4/src/OdpGenerator.cxx 2013-12-03 19:17:04.000000000 +0000 +++ libodfgen-0.1.1/src/OdpGenerator.cxx 2014-05-23 13:40:44.000000000 +0000 @@ -26,13 +26,14 @@ #include -#include "FilterInternal.hxx" #include "DocumentElement.hxx" -#include "GraphicFunctions.hxx" +#include "FilterInternal.hxx" +#include "FontStyle.hxx" +#include "GraphicStyle.hxx" #include "ListStyle.hxx" +#include "OdfGenerator.hxx" #include "TableStyle.hxx" #include "TextRunStyle.hxx" -#include "FontStyle.hxx" #include #include #include @@ -53,26 +54,12 @@ namespace { -static WPXString doubleToString(const double value) -{ - WPXProperty *prop = WPXPropertyFactory::newDoubleProp(value); - WPXString retVal = prop->getStr(); - delete prop; - return retVal; -} - -} // anonymous namespace - -namespace -{ - struct GeneratorState { bool mbIsTextBox; - bool mbIsTextLine; + bool mbIsParagraph; bool mbIsTextOnPath; bool mInComment; - bool mHeaderRow; bool mTableCellOpened; bool mInNotes; @@ -81,10 +68,9 @@ GeneratorState::GeneratorState() : mbIsTextBox(false) - , mbIsTextLine(false) + , mbIsParagraph(false) , mbIsTextOnPath(false) , mInComment(false) - , mHeaderRow(false) , mTableCellOpened(false) , mInNotes(false) { @@ -92,159 +78,42 @@ } -namespace -{ - -// list state -struct ListState -{ - ListState(); - ListState(const ListState &state); - - ListStyle *mpCurrentListStyle; - bool mbListElementParagraphOpened; - std::stack mbListElementOpened; -private: - ListState &operator=(const ListState &state); -}; - -ListState::ListState() : - mpCurrentListStyle(0), - mbListElementParagraphOpened(false), - mbListElementOpened() -{ -} - -ListState::ListState(const ListState &state) : - mpCurrentListStyle(state.mpCurrentListStyle), - mbListElementParagraphOpened(state.mbListElementParagraphOpened), - mbListElementOpened(state.mbListElementOpened) -{ -} - -} - -namespace -{ - -class GraphicTableCellStyle : public TableCellStyle +class OdpGeneratorPrivate : public OdfGenerator { public: - GraphicTableCellStyle(const WPXPropertyList &xPropList, const char *psName); - virtual ~GraphicTableCellStyle(); - -private: - virtual void writeCompat(OdfDocumentHandler *pHandler, const WPXPropertyList &propList) const; -}; - -GraphicTableCellStyle::GraphicTableCellStyle(const WPXPropertyList &xPropList, const char *const psName) - : TableCellStyle(xPropList, psName) -{ -} - -GraphicTableCellStyle::~GraphicTableCellStyle() -{ -} - -void GraphicTableCellStyle::writeCompat(OdfDocumentHandler *const pHandler, const WPXPropertyList &propList) const -{ - WPXPropertyList stylePropList; - WPXPropertyList::Iter i(propList); + OdpGeneratorPrivate(); + ~OdpGeneratorPrivate(); - /* first set padding, so that mPropList can redefine, if - mPropList["fo:padding"] is defined */ - stylePropList.insert("fo:padding", "0.0382in"); - stylePropList.insert("draw:fill", "none"); - stylePropList.insert("draw:textarea-horizontal-align", "center"); + void openTextBoxFrame(const ::librevenge::RVNGPropertyList &propList); + void closeTextBoxFrame(); - for (i.rewind(); i.next();) + GraphicStyleManager &getGraphicManager() { - if (strcmp(i.key(), "fo:background-color") == 0) - { - stylePropList.insert("draw:fill", "solid"); - stylePropList.insert("draw:fill-color", i()->clone()); - } - else if (strcmp(i.key(), "style:vertical-align")==0) - stylePropList.insert("draw:textarea-vertical-align", i()->clone()); + return mGraphicManager; } - pHandler->startElement("style:graphic-properties", stylePropList); - pHandler->endElement("style:graphic-properties"); - - // HACK to get visible borders - WPXPropertyList paraPropList; - paraPropList.insert("fo:border", "0.03pt solid #000000"); - - pHandler->startElement("style:paragraph-properties", paraPropList); - pHandler->endElement("style:paragraph-properties"); -} - -} - -class OdpGeneratorPrivate -{ -public: - OdpGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType); - ~OdpGeneratorPrivate(); - /** update a graphic style element */ - void _updateGraphicPropertiesElement(TagOpenElement &element, ::WPXPropertyList const &style, ::WPXPropertyListVector const &gradient); - void _writeGraphicsStyle(); - void writeNotesStyles(); - void _drawPolySomething(const ::WPXPropertyListVector &vertices, bool isClosed); - void _drawPath(const WPXPropertyListVector &path); - - void openListLevel(TagOpenElement *pListLevelOpenElement); - void closeListLevel(); + void writeNotesStyles(OdfDocumentHandler *pHandler); //! returns the document type - std::string getDocumentType() const; - - // body elements - std::vector mBodyElements; - - // graphics styles - std::vector mGraphicsStrokeDashStyles; - std::vector mGraphicsGradientStyles; - std::vector mGraphicsBitmapStyles; - std::vector mGraphicsMarkerStyles; - std::vector mGraphicsAutomaticStyles; + bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeSettings(OdfDocumentHandler *pHandler); + void _writeStyles(OdfDocumentHandler *pHandler); + void _writeAutomaticStyles(OdfDocumentHandler *pHandler); + void _writeMasterPages(OdfDocumentHandler *pHandler); + void _writePageLayouts(OdfDocumentHandler *pHandler); // page styles std::vector mPageAutomaticStyles; std::vector mPageMasterStyles; - // paragraph styles - ParagraphStyleManager mParagraphManager; - - // span styles - SpanStyleManager mSpanManager; - - // font styles - FontStyleManager mFontManager; - - // table styles - std::vector mTableStyles; - TableStyle *mpCurrentTableStyle; - - OdfDocumentHandler *mpHandler; - - ::WPXPropertyList mxStyle; - ::WPXPropertyListVector mxGradient; - int miGradientIndex; - int miBitmapIndex; - int miStartMarkerIndex; - int miEndMarkerIndex; - int miDashIndex; - int miGraphicsStyleIndex; int miPageIndex; double mfWidth, mfMaxWidth; double mfHeight, mfMaxHeight; - const OdfStreamType mxStreamType; - // generator state GeneratorState mState; - std::stack mListStates; + + Storage mDummyMasterSlideStorage; private: OdpGeneratorPrivate(const OdpGeneratorPrivate &); @@ -252,446 +121,429 @@ }; -OdpGeneratorPrivate::OdpGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType): - mBodyElements(), - mGraphicsStrokeDashStyles(), - mGraphicsGradientStyles(), - mGraphicsBitmapStyles(), - mGraphicsMarkerStyles(), - mGraphicsAutomaticStyles(), +OdpGeneratorPrivate::OdpGeneratorPrivate() : mPageAutomaticStyles(), mPageMasterStyles(), - mParagraphManager(), - mSpanManager(), - mFontManager(), - mTableStyles(), - mpCurrentTableStyle(0), - mpHandler(pHandler), - mxStyle(), mxGradient(), - miGradientIndex(1), - miBitmapIndex(1), - miStartMarkerIndex(1), - miEndMarkerIndex(1), - miDashIndex(1), - miGraphicsStyleIndex(1), miPageIndex(1), mfWidth(0.0), mfMaxWidth(0.0), mfHeight(0.0), mfMaxHeight(0.0), - mxStreamType(streamType), mState(), - mListStates() + mDummyMasterSlideStorage() { } OdpGeneratorPrivate::~OdpGeneratorPrivate() { + emptyStorage(&mPageAutomaticStyles); + emptyStorage(&mPageMasterStyles); +} - for (std::vector::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); ++iterBody) - { - delete (*iterBody); - (*iterBody) = 0; - } +void OdpGeneratorPrivate::openTextBoxFrame(const ::librevenge::RVNGPropertyList &propList) +{ + librevenge::RVNGPropertyList tmpList(propList), graphicStyle; + if (!propList["draw:stroke"]) + tmpList.insert("draw:stroke", "none"); + if (!propList["draw:fill"]) + tmpList.insert("draw:fill", "none"); + mGraphicManager.addGraphicProperties(tmpList, graphicStyle); + mGraphicManager.addFrameProperties(propList, graphicStyle); + librevenge::RVNGString sValue=mGraphicManager.findOrAdd(graphicStyle); - for (std::vector::iterator iterGraphicsAutomaticStyles = mGraphicsAutomaticStyles.begin(); - iterGraphicsAutomaticStyles != mGraphicsAutomaticStyles.end(); ++iterGraphicsAutomaticStyles) - { - delete((*iterGraphicsAutomaticStyles)); - } + TagOpenElement *pDrawFrameOpenElement = new TagOpenElement("draw:frame"); + pDrawFrameOpenElement->addAttribute("draw:style-name", sValue); + pDrawFrameOpenElement->addAttribute("draw:layer", "layout"); - for (std::vector::iterator iterGraphicsStrokeDashStyles = mGraphicsStrokeDashStyles.begin(); - iterGraphicsStrokeDashStyles != mGraphicsStrokeDashStyles.end(); ++iterGraphicsStrokeDashStyles) + if (!propList["svg:width"] && !propList["svg:height"]) { - delete((*iterGraphicsStrokeDashStyles)); + pDrawFrameOpenElement->addAttribute("fo:min-width", "1in"); + pDrawFrameOpenElement->addAttribute("svg:width", "10in"); } - - for (std::vector::iterator iterGraphicsGradientStyles = mGraphicsGradientStyles.begin(); - iterGraphicsGradientStyles != mGraphicsGradientStyles.end(); ++iterGraphicsGradientStyles) + else { - delete((*iterGraphicsGradientStyles)); + if (propList["svg:width"]) + pDrawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); + if (propList["svg:height"]) + pDrawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); } - - for (std::vector::iterator iterGraphicsBitmapStyles = mGraphicsBitmapStyles.begin(); - iterGraphicsBitmapStyles != mGraphicsBitmapStyles.end(); ++iterGraphicsBitmapStyles) + static char const *attrib[]= { - delete((*iterGraphicsBitmapStyles)); + "fo:min-width", "fo:min-height", "fo:max-width", "fo:max-height", "fo:padding-top", "fo:padding-bottom", + "fo:padding-left", "fo:padding-right", "draw:textarea-vertical-align" + }; + for (int i=0; i<9; ++i) + { + if (propList[attrib[i]]) + pDrawFrameOpenElement->addAttribute(attrib[i], propList[attrib[i]]->getStr()); } - for (std::vector::iterator iterGraphicsMarkerStyles = mGraphicsMarkerStyles.begin(); - iterGraphicsMarkerStyles != mGraphicsMarkerStyles.end(); ++iterGraphicsMarkerStyles) + double x = 0.0; + double y = 0.0; + if (propList["svg:x"]) + x = propList["svg:x"]->getDouble(); + if (propList["svg:y"]) + y = propList["svg:y"]->getDouble(); + double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0); + if (angle != 0.0) { - delete((*iterGraphicsMarkerStyles)); + // compute position: make sure that the center position remains invariant + double width = 0.0; + double height = 0.0; + if (propList["librevenge:rotate-cx"]) + width = 2.0*(propList["librevenge:rotate-cx"]->getDouble()-x); + else if (propList["svg:width"]) + width = propList["svg:width"]->getDouble(); + if (propList["librevenge:rotate-cy"]) + height = 2.0*(propList["librevenge:rotate-cy"]->getDouble()-y); + else if (propList["svg:height"]) + height = propList["svg:height"]->getDouble(); + double deltax((width*cos(angle)+height*sin(angle)-width)/2.0); + double deltay((-width*sin(angle)+height*cos(angle)-height)/2.0); + x -= deltax; + y -= deltay; } - - for (std::vector::iterator iterPageAutomaticStyles = mPageAutomaticStyles.begin(); - iterPageAutomaticStyles != mPageAutomaticStyles.end(); ++iterPageAutomaticStyles) + shared_ptr svg_x(librevenge::RVNGPropertyFactory::newInchProp(x)); + shared_ptr svg_y(librevenge::RVNGPropertyFactory::newInchProp(y)); + if (angle != 0.0) { - delete((*iterPageAutomaticStyles)); + shared_ptr librevenge_rotate(librevenge::RVNGPropertyFactory::newDoubleProp(angle)); + sValue.sprintf("rotate (%s) translate(%s, %s)", + librevenge_rotate->getStr().cstr(), + svg_x->getStr().cstr(), + svg_y->getStr().cstr()); + pDrawFrameOpenElement->addAttribute("draw:transform", sValue); } - - for (std::vector::iterator iterPageMasterStyles = mPageMasterStyles.begin(); - iterPageMasterStyles != mPageMasterStyles.end(); ++iterPageMasterStyles) + else { - delete((*iterPageMasterStyles)); + if (propList["svg:x"]) + pDrawFrameOpenElement->addAttribute("svg:x", svg_x->getStr()); + if (propList["svg:y"]) + pDrawFrameOpenElement->addAttribute("svg:y", svg_y->getStr()); } + getCurrentStorage()->push_back(pDrawFrameOpenElement); +} - mParagraphManager.clean(); - mSpanManager.clean(); - mFontManager.clean(); +void OdpGeneratorPrivate::closeTextBoxFrame() +{ + getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); } -void OdpGeneratorPrivate::writeNotesStyles() +void OdpGeneratorPrivate::writeNotesStyles(OdfDocumentHandler *pHandler) { { - WPXPropertyList styleProps; + librevenge::RVNGPropertyList styleProps; styleProps.insert("style:name", "PresentationNotesPage"); styleProps.insert("style:family", "drawing-page"); - mpHandler->startElement("style:style", styleProps); + pHandler->startElement("style:style", styleProps); - WPXPropertyList pageProps; + librevenge::RVNGPropertyList pageProps; pageProps.insert("presentation:display-header", "true"); pageProps.insert("presentation:display-footer", "true"); pageProps.insert("presentation:display-date-time", "true"); pageProps.insert("presentation:display-page-number", "false"); - mpHandler->startElement("style:drawing-page-properties", pageProps); - mpHandler->endElement("style:drawing-page-properties"); + pHandler->startElement("style:drawing-page-properties", pageProps); + pHandler->endElement("style:drawing-page-properties"); - mpHandler->endElement("style:style"); + pHandler->endElement("style:style"); } { - WPXPropertyList styleProps; + librevenge::RVNGPropertyList styleProps; styleProps.insert("style:name", "PresentationNotesFrame"); styleProps.insert("style:family", "presentation"); - mpHandler->startElement("style:style", styleProps); + pHandler->startElement("style:style", styleProps); - WPXPropertyList graphicProps; + librevenge::RVNGPropertyList graphicProps; graphicProps.insert("draw:fill", "none"); graphicProps.insert("fo:min-height", "5in"); - mpHandler->startElement("style:graphic-properties", graphicProps); - mpHandler->endElement("style:graphic-properties"); + pHandler->startElement("style:graphic-properties", graphicProps); + pHandler->endElement("style:graphic-properties"); - WPXPropertyList paraProps; + librevenge::RVNGPropertyList paraProps; paraProps.insert("fo:margin-left", "0.24in"); paraProps.insert("fo:margin-right", "0in"); paraProps.insert("fo:text-indent", "0in"); - mpHandler->startElement("style:para-properties", paraProps); - mpHandler->endElement("style:para-properties"); + pHandler->startElement("style:para-properties", paraProps); + pHandler->endElement("style:para-properties"); - mpHandler->endElement("style:style"); + pHandler->endElement("style:style"); } { - WPXPropertyList styleProps; + librevenge::RVNGPropertyList styleProps; styleProps.insert("style:name", "PresentationNotesTextBox"); styleProps.insert("style:family", "graphic"); - mpHandler->startElement("style:style", styleProps); + pHandler->startElement("style:style", styleProps); - WPXPropertyList graphicProps; + librevenge::RVNGPropertyList graphicProps; graphicProps.insert("draw:fill", "none"); - mpHandler->startElement("style:graphic-properties", graphicProps); - mpHandler->endElement("style:graphic-properties"); - - mpHandler->endElement("style:style"); - } -} - -void OdpGeneratorPrivate::openListLevel(TagOpenElement *pListLevelOpenElement) -{ - if (!mListStates.top().mbListElementOpened.empty() && - !mListStates.top().mbListElementOpened.top()) - { - mBodyElements.push_back(new TagOpenElement("text:list-item")); - mListStates.top().mbListElementOpened.top() = true; - } + pHandler->startElement("style:graphic-properties", graphicProps); + pHandler->endElement("style:graphic-properties"); - mListStates.top().mbListElementOpened.push(false); - if (mListStates.top().mbListElementOpened.size() == 1) - { - // add a sanity check ( to avoid a crash if mpCurrentListStyle is NULL) - if (mListStates.top().mpCurrentListStyle) - { - pListLevelOpenElement->addAttribute("text:style-name", mListStates.top().mpCurrentListStyle->getName()); - } + pHandler->endElement("style:style"); } } -void OdpGeneratorPrivate::closeListLevel() +void OdpGeneratorPrivate::_writeSettings(OdfDocumentHandler *pHandler) { - if (mListStates.top().mbListElementOpened.empty()) - { - // this implies that openListLevel was not called, so it is better to stop here - ODFGEN_DEBUG_MSG(("OdtGenerator: Attempting to close an unexisting level\n")); - return; - } - if (mListStates.top().mbListElementOpened.top()) - { - mBodyElements.push_back(new TagCloseElement("text:list-item")); - mListStates.top().mbListElementOpened.top() = false; - } + TagOpenElement("office:settings").write(pHandler); - mBodyElements.push_back(new TagCloseElement("text:list")); - mListStates.top().mbListElementOpened.pop(); -} + TagOpenElement configItemSetOpenElement("config:config-item-set"); + configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings"); + configItemSetOpenElement.write(pHandler); -std::string OdpGeneratorPrivate::getDocumentType() const -{ - switch(mxStreamType) - { - case ODF_FLAT_XML: - return "office:document"; - case ODF_CONTENT_XML: - return "office:document-content"; - case ODF_STYLES_XML: - return "office:document-styles"; - case ODF_SETTINGS_XML: - return "office:document-settings"; - case ODF_META_XML: - return "office:document-meta"; - default: - return "office:document"; - } -} + TagOpenElement configItemOpenElement("config:config-item"); -OdpGenerator::OdpGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType): - mpImpl(new OdpGeneratorPrivate(pHandler, streamType)) -{ - mpImpl->mpHandler->startDocument(); - TagOpenElement tmpOfficeDocumentContent(mpImpl->getDocumentType().c_str()); - tmpOfficeDocumentContent.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); - tmpOfficeDocumentContent.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); - tmpOfficeDocumentContent.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); - // WARNING: this is not ODF! - tmpOfficeDocumentContent.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office"); - tmpOfficeDocumentContent.addAttribute("xmlns:officeooo", "http://openoffice.org/2009/office"); - tmpOfficeDocumentContent.addAttribute("office:version", "1.0"); - if (mpImpl->mxStreamType == ODF_FLAT_XML) - tmpOfficeDocumentContent.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.presentation"); - tmpOfficeDocumentContent.write(mpImpl->mpHandler); -} + configItemOpenElement.addAttribute("config:name", "VisibleAreaTop"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + pHandler->characters("0"); + pHandler->endElement("config:config-item"); -OdpGenerator::~OdpGenerator() -{ - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_SETTINGS_XML)) - { - TagOpenElement("office:settings").write(mpImpl->mpHandler); + configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + pHandler->characters("0"); + pHandler->endElement("config:config-item"); - TagOpenElement configItemSetOpenElement("config:config-item-set"); - configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings"); - configItemSetOpenElement.write(mpImpl->mpHandler); + configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + librevenge::RVNGString sWidth; + sWidth.sprintf("%li", (unsigned long)(2540 * mfMaxWidth)); + pHandler->characters(sWidth); + pHandler->endElement("config:config-item"); - TagOpenElement configItemOpenElement("config:config-item"); + configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight"); + configItemOpenElement.addAttribute("config:type", "int"); + configItemOpenElement.write(pHandler); + librevenge::RVNGString sHeight; + sHeight.sprintf("%li", (unsigned long)(2540 * mfMaxHeight)); + pHandler->characters(sHeight); + pHandler->endElement("config:config-item"); - configItemOpenElement.addAttribute("config:name", "VisibleAreaTop"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - mpImpl->mpHandler->characters("0"); - mpImpl->mpHandler->endElement("config:config-item"); + pHandler->endElement("config:config-item-set"); - configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - mpImpl->mpHandler->characters("0"); - mpImpl->mpHandler->endElement("config:config-item"); + pHandler->endElement("office:settings"); +} - configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - WPXString sWidth; - sWidth.sprintf("%li", (unsigned long)(2540 * mpImpl->mfMaxWidth)); - mpImpl->mpHandler->characters(sWidth); - mpImpl->mpHandler->endElement("config:config-item"); +void OdpGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:automatic-styles").write(pHandler); - configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight"); - configItemOpenElement.addAttribute("config:type", "int"); - configItemOpenElement.write(mpImpl->mpHandler); - WPXString sHeight; - sHeight.sprintf("%li", (unsigned long)(2540 * mpImpl->mfMaxHeight)); - mpImpl->mpHandler->characters(sHeight); - mpImpl->mpHandler->endElement("config:config-item"); + // CHECKME: previously, this part was not done in STYLES - mpImpl->mpHandler->endElement("config:config-item-set"); + // writing out the graphics automatic styles + mGraphicManager.writeAutomaticStyles(pHandler); - mpImpl->mpHandler->endElement("office:settings"); - } + mParagraphManager.write(pHandler); + mSpanManager.write(pHandler); + // writing out the lists styles + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + (*iterListStyles)->write(pHandler); + mTableManager.write(pHandler, true); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - TagOpenElement("office:styles").write(mpImpl->mpHandler); + writeNotesStyles(pHandler); - for (std::vector::const_iterator iterGraphicsStrokeDashStyles = mpImpl->mGraphicsStrokeDashStyles.begin(); - iterGraphicsStrokeDashStyles != mpImpl->mGraphicsStrokeDashStyles.end(); ++iterGraphicsStrokeDashStyles) - { - (*iterGraphicsStrokeDashStyles)->write(mpImpl->mpHandler); - } + // CHECKME: previously, this part was not done in CONTENT + _writePageLayouts(pHandler); - for (std::vector::const_iterator iterGraphicsGradientStyles = mpImpl->mGraphicsGradientStyles.begin(); - iterGraphicsGradientStyles != mpImpl->mGraphicsGradientStyles.end(); ++iterGraphicsGradientStyles) - { - (*iterGraphicsGradientStyles)->write(mpImpl->mpHandler); - } + pHandler->endElement("office:automatic-styles"); +} - for (std::vector::const_iterator iterGraphicsBitmapStyles = mpImpl->mGraphicsBitmapStyles.begin(); - iterGraphicsBitmapStyles != mpImpl->mGraphicsBitmapStyles.end(); ++iterGraphicsBitmapStyles) - { - (*iterGraphicsBitmapStyles)->write(mpImpl->mpHandler); - } +void OdpGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:styles").write(pHandler); + mGraphicManager.writeStyles(pHandler); + pHandler->endElement("office:styles"); +} - for (std::vector::const_iterator iterGraphicsMarkerStyles = mpImpl->mGraphicsMarkerStyles.begin(); - iterGraphicsMarkerStyles != mpImpl->mGraphicsMarkerStyles.end(); ++iterGraphicsMarkerStyles) - { - (*iterGraphicsMarkerStyles)->write(mpImpl->mpHandler); - } - mpImpl->mpHandler->endElement("office:styles"); - } +void OdpGeneratorPrivate::_writePageLayouts(OdfDocumentHandler *pHandler) +{ +#ifdef MULTIPAGE_WORKAROUND + TagOpenElement tmpStylePageLayoutOpenElement("style:page-layout"); + tmpStylePageLayoutOpenElement.addAttribute("style:name", "PM0"); + tmpStylePageLayoutOpenElement.write(pHandler); + + TagOpenElement tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-top", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0in"); + librevenge::RVNGString sValue; + sValue = doubleToString(mfMaxWidth); + sValue.append("in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue); + sValue = doubleToString(mfMaxHeight); + sValue.append("in"); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue); + tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait"); + tmpStylePageLayoutPropertiesOpenElement.write(pHandler); + + pHandler->endElement("style:page-layout-properties"); + pHandler->endElement("style:page-layout"); + + TagOpenElement tmpStyleStyleOpenElement("style:style"); + tmpStyleStyleOpenElement.addAttribute("style:name", "dp1"); + tmpStyleStyleOpenElement.addAttribute("style:family", "drawing-page"); + tmpStyleStyleOpenElement.write(pHandler); + + TagOpenElement tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties"); + // tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:background-size", "border"); + tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:fill", "none"); + tmpStyleDrawingPagePropertiesOpenElement.write(pHandler); + pHandler->endElement("style:drawing-page-properties"); + pHandler->endElement("style:style"); +#else + // writing out the page automatic styles + sendStorage(&mPageAutomaticStyles, pHandler); +#endif +} - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - mpImpl->mFontManager.writeFontsDeclaration(mpImpl->mpHandler); +void OdpGeneratorPrivate::_writeMasterPages(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:master-styles").write(pHandler); + sendStorage(&mPageMasterStyles, pHandler); + pHandler->endElement("office:master-styles"); +} + +bool OdpGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) +{ + if (streamType == ODF_MANIFEST_XML) + { + pHandler->startDocument(); + TagOpenElement manifestElement("manifest:manifest"); + manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"); + manifestElement.write(pHandler); + + TagOpenElement mainFile("manifest:file-entry"); + mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.presentation"); + mainFile.addAttribute("manifest:full-path", "/"); + mainFile.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + appendFilesInManifest(pHandler); + + TagCloseElement("manifest:manifest").write(pHandler); + pHandler->endDocument(); + return true; + } + + pHandler->startDocument(); + + std::string const documentType=getDocumentType(streamType); + TagOpenElement docContentPropList(documentType.c_str()); + docContentPropList.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); + docContentPropList.addAttribute("xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"); + docContentPropList.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); + docContentPropList.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); + docContentPropList.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); + docContentPropList.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); + docContentPropList.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); + docContentPropList.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); + docContentPropList.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); + docContentPropList.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); + docContentPropList.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + // WARNING: this is not ODF! + docContentPropList.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office"); + docContentPropList.addAttribute("xmlns:officeooo", "http://openoffice.org/2009/office"); + docContentPropList.addAttribute("office:version", "1.0", true); + if (streamType == ODF_FLAT_XML) + docContentPropList.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.presentation"); + docContentPropList.write(pHandler); - TagOpenElement("office:automatic-styles").write(mpImpl->mpHandler); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_META_XML)) + writeDocumentMetaData(pHandler); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML)) - { - // writing out the graphics automatic styles - for (std::vector::iterator iterGraphicsAutomaticStyles = mpImpl->mGraphicsAutomaticStyles.begin(); - iterGraphicsAutomaticStyles != mpImpl->mGraphicsAutomaticStyles.end(); ++iterGraphicsAutomaticStyles) - { - (*iterGraphicsAutomaticStyles)->write(mpImpl->mpHandler); - } - mpImpl->mParagraphManager.write(mpImpl->mpHandler); - mpImpl->mSpanManager.write(mpImpl->mpHandler); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_SETTINGS_XML)) + _writeSettings(pHandler); - // writing out the table styles - for (std::vector::const_iterator iterTableStyles = mpImpl->mTableStyles.begin(); iterTableStyles != mpImpl->mTableStyles.end(); ++iterTableStyles) - { - (*iterTableStyles)->write(mpImpl->mpHandler); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML)) + mFontManager.writeFontsDeclaration(pHandler); - mpImpl->writeNotesStyles(); - } -#ifdef MULTIPAGE_WORKAROUND - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - TagOpenElement tmpStylePageLayoutOpenElement("style:page-layout"); - tmpStylePageLayoutOpenElement.addAttribute("style:name", "PM0"); - tmpStylePageLayoutOpenElement.write(mpImpl->mpHandler); - - TagOpenElement tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-top", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0in"); - WPXString sValue; - sValue = doubleToString(mpImpl->mfMaxWidth); - sValue.append("in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue); - sValue = doubleToString(mpImpl->mfMaxHeight); - sValue.append("in"); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue); - tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait"); - tmpStylePageLayoutPropertiesOpenElement.write(mpImpl->mpHandler); - - mpImpl->mpHandler->endElement("style:page-layout-properties"); - - mpImpl->mpHandler->endElement("style:page-layout"); - - TagOpenElement tmpStyleStyleOpenElement("style:style"); - tmpStyleStyleOpenElement.addAttribute("style:name", "dp1"); - tmpStyleStyleOpenElement.addAttribute("style:family", "drawing-page"); - tmpStyleStyleOpenElement.write(mpImpl->mpHandler); - - TagOpenElement tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties"); - // tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:background-size", "border"); - tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:fill", "none"); - tmpStyleDrawingPagePropertiesOpenElement.write(mpImpl->mpHandler); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML)) + _writeStyles(pHandler); - mpImpl->mpHandler->endElement("style:drawing-page-properties"); + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML)) + _writeAutomaticStyles(pHandler); - mpImpl->mpHandler->endElement("style:style"); - } -#else - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - // writing out the page automatic styles - for (std::vector::iterator iterPageAutomaticStyles = mpImpl->mPageAutomaticStyles.begin(); - iterPageAutomaticStyles != mpImpl->mPageAutomaticStyles.end(); ++iterPageAutomaticStyles) - { - (*iterPageAutomaticStyles)->write(mpImpl->mpHandler); - } - } -#endif - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) - { - mpImpl->mpHandler->endElement("office:automatic-styles"); - } + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML)) + _writeMasterPages(pHandler); - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_STYLES_XML)) + if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML)) { - TagOpenElement("office:master-styles").write(mpImpl->mpHandler); - - for (std::vector::const_iterator pageMasterIter = mpImpl->mPageMasterStyles.begin(); - pageMasterIter != mpImpl->mPageMasterStyles.end(); ++pageMasterIter) - { - (*pageMasterIter)->write(mpImpl->mpHandler); - } - mpImpl->mpHandler->endElement("office:master-styles"); + TagOpenElement("office:body").write(pHandler); + TagOpenElement("office:presentation").write(pHandler); + sendStorage(&mBodyStorage, pHandler); + pHandler->endElement("office:presentation"); + pHandler->endElement("office:body"); } - if ((mpImpl->mxStreamType == ODF_FLAT_XML) || (mpImpl->mxStreamType == ODF_CONTENT_XML)) - { - TagOpenElement("office:body").write(mpImpl->mpHandler); + pHandler->endElement(documentType.c_str()); - TagOpenElement("office:presentation").write(mpImpl->mpHandler); + pHandler->endDocument(); + return true; +} - for (std::vector::const_iterator bodyIter = mpImpl->mBodyElements.begin(); - bodyIter != mpImpl->mBodyElements.end(); ++bodyIter) - { - (*bodyIter)->write(mpImpl->mpHandler); - } +OdpGenerator::OdpGenerator(): mpImpl(new OdpGeneratorPrivate) +{ +} - mpImpl->mpHandler->endElement("office:presentation"); - mpImpl->mpHandler->endElement("office:body"); - } +OdpGenerator::~OdpGenerator() +{ + delete mpImpl; +} - mpImpl->mpHandler->endElement(mpImpl->getDocumentType().c_str()); +void OdpGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (mpImpl) + mpImpl->addDocumentHandler(pHandler, streamType); +} - mpImpl->mpHandler->endDocument(); +librevenge::RVNGStringVector OdpGenerator::getObjectNames() const +{ + if (mpImpl) + return mpImpl->getObjectNames(); + return librevenge::RVNGStringVector(); +} - delete mpImpl; +bool OdpGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!mpImpl) + return false; + return mpImpl->getObjectContent(objectName, pHandler); } -void OdpGenerator::startDocument(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::startDocument(const ::librevenge::RVNGPropertyList &/*propList*/) { } void OdpGenerator::endDocument() { + // Write out the collected document + mpImpl->writeTargetDocuments(); } -void OdpGenerator::setDocumentMetaData(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::setDocumentMetaData(const ::librevenge::RVNGPropertyList &propList) { + mpImpl->setDocumentMetaData(propList); } -void OdpGenerator::startSlide(const ::WPXPropertyList &propList) +void OdpGenerator::defineEmbeddedFont(const librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::startSlide(const ::librevenge::RVNGPropertyList &propList) { if (propList["svg:width"]) { @@ -711,9 +563,9 @@ TagOpenElement *pStylePageLayoutOpenElement = new TagOpenElement("style:page-layout"); - WPXString sValue; + librevenge::RVNGString sValue; if (propList["draw:name"]) - sValue = WPXString(propList["draw:name"]->getStr(), true); // escape special xml characters + sValue.appendEscapedXML(propList["draw:name"]->getStr()); else sValue.sprintf("page%i", mpImpl->miPageIndex); pDrawPageOpenElement->addAttribute("draw:name", sValue); @@ -767,7 +619,7 @@ pStyleMasterPageOpenElement->addAttribute("style:name", sValue); #endif - mpImpl->mBodyElements.push_back(pDrawPageOpenElement); + mpImpl->getCurrentStorage()->push_back(pDrawPageOpenElement); mpImpl->mPageMasterStyles.push_back(pStyleMasterPageOpenElement); mpImpl->mPageMasterStyles.push_back(new TagCloseElement("style:master-page")); @@ -784,398 +636,97 @@ void OdpGenerator::endSlide() { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:page")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:page")); mpImpl->miPageIndex++; } -void OdpGenerator::setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &gradient) +void OdpGenerator::startMasterSlide(const ::librevenge::RVNGPropertyList &/*propList*/) { - mpImpl->mxStyle.clear(); - mpImpl->mxStyle = propList; - mpImpl->mxGradient = gradient; + mpImpl->pushStorage(&mpImpl->mDummyMasterSlideStorage); } -void OdpGenerator::startLayer(const ::WPXPropertyList & /* propList */) +void OdpGenerator::endMasterSlide() { + mpImpl->popStorage(); + mpImpl->mDummyMasterSlideStorage.clear(); } -void OdpGenerator::endLayer() +void OdpGenerator::setStyle(const ::librevenge::RVNGPropertyList &propList) { + mpImpl->defineGraphicStyle(propList); } -void OdpGenerator::drawRectangle(const ::WPXPropertyList &propList) +void OdpGenerator::setSlideTransition(const ::librevenge::RVNGPropertyList &/*propList*/) { - if (!propList["svg:x"] || !propList["svg:y"] || - !propList["svg:width"] || !propList["svg:height"]) - { - ODFGEN_DEBUG_MSG(("OdpGenerator::drawRectangle: position undefined\n")); - return; - } - mpImpl->_writeGraphicsStyle(); - TagOpenElement *pDrawRectElement = new TagOpenElement("draw:rect"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawRectElement->addAttribute("draw:style-name", sValue); - pDrawRectElement->addAttribute("svg:x", propList["svg:x"]->getStr()); - pDrawRectElement->addAttribute("svg:y", propList["svg:y"]->getStr()); - pDrawRectElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - pDrawRectElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - // FIXME: what to do when rx != ry ? - if (propList["svg:rx"]) - pDrawRectElement->addAttribute("draw:corner-radius", propList["svg:rx"]->getStr()); - else - pDrawRectElement->addAttribute("draw:corner-radius", "0.0000in"); - mpImpl->mBodyElements.push_back(pDrawRectElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:rect")); + // TODO: implement me } -void OdpGenerator::drawEllipse(const ::WPXPropertyList &propList) +void OdpGenerator::startLayer(const ::librevenge::RVNGPropertyList & /* propList */) { - if (!propList["svg:rx"] || !propList["svg:ry"] || !propList["svg:cx"] || !propList["svg:cy"]) - { - ODFGEN_DEBUG_MSG(("OdpGenerator::drawEllipse: position undefined\n")); - return; - } - mpImpl->_writeGraphicsStyle(); - TagOpenElement *pDrawEllipseElement = new TagOpenElement("draw:ellipse"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawEllipseElement->addAttribute("draw:style-name", sValue); - sValue = doubleToString(2 * propList["svg:rx"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:width", sValue); - sValue = doubleToString(2 * propList["svg:ry"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:height", sValue); - if (propList["libwpg:rotate"] && propList["libwpg:rotate"]->getDouble() != 0.0) - { - double rotation = propList["libwpg:rotate"]->getDouble(); - while(rotation < -180) - rotation += 360; - while(rotation > 180) - rotation -= 360; - double radrotation = rotation*M_PI/180.0; - double deltax = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0) - + pow(propList["svg:ry"]->getDouble(), 2.0))*cos(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble()) - - radrotation ) - propList["svg:rx"]->getDouble(); - double deltay = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0) - + pow(propList["svg:ry"]->getDouble(), 2.0))*sin(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble()) - - radrotation ) - propList["svg:ry"]->getDouble(); - sValue = "rotate("; - sValue.append(doubleToString(radrotation)); - sValue.append(") "); - sValue.append("translate("); - sValue.append(doubleToString(propList["svg:cx"]->getDouble() - propList["svg:rx"]->getDouble() - deltax)); - sValue.append("in, "); - sValue.append(doubleToString(propList["svg:cy"]->getDouble() - propList["svg:ry"]->getDouble() - deltay)); - sValue.append("in)"); - pDrawEllipseElement->addAttribute("draw:transform", sValue); - } - else - { - sValue = doubleToString(propList["svg:cx"]->getDouble()-propList["svg:rx"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:x", sValue); - sValue = doubleToString(propList["svg:cy"]->getDouble()-propList["svg:ry"]->getDouble()); - sValue.append("in"); - pDrawEllipseElement->addAttribute("svg:y", sValue); - } - mpImpl->mBodyElements.push_back(pDrawEllipseElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:ellipse")); } -void OdpGenerator::drawPolyline(const ::WPXPropertyListVector &vertices) +void OdpGenerator::endLayer() { - mpImpl->_drawPolySomething(vertices, false); } -void OdpGenerator::drawPolygon(const ::WPXPropertyListVector &vertices) +void OdpGenerator::drawRectangle(const ::librevenge::RVNGPropertyList &propList) { - mpImpl->_drawPolySomething(vertices, true); + mpImpl->drawRectangle(propList); } -void OdpGeneratorPrivate::_drawPolySomething(const ::WPXPropertyListVector &vertices, bool isClosed) +void OdpGenerator::drawEllipse(const ::librevenge::RVNGPropertyList &propList) { - if(vertices.count() < 2) - return; - - if(vertices.count() == 2) - { - if (!vertices[0]["svg:x"]||!vertices[0]["svg:y"]||!vertices[1]["svg:x"]||!vertices[1]["svg:y"]) - { - ODFGEN_DEBUG_MSG(("OdpGeneratorPrivate::_drawPolySomething: some vertices are not defined\n")); - return; - } - _writeGraphicsStyle(); - TagOpenElement *pDrawLineElement = new TagOpenElement("draw:line"); - WPXString sValue; - sValue.sprintf("gr%i", miGraphicsStyleIndex-1); - pDrawLineElement->addAttribute("draw:style-name", sValue); - pDrawLineElement->addAttribute("draw:layer", "layout"); - pDrawLineElement->addAttribute("svg:x1", vertices[0]["svg:x"]->getStr()); - pDrawLineElement->addAttribute("svg:y1", vertices[0]["svg:y"]->getStr()); - pDrawLineElement->addAttribute("svg:x2", vertices[1]["svg:x"]->getStr()); - pDrawLineElement->addAttribute("svg:y2", vertices[1]["svg:y"]->getStr()); - mBodyElements.push_back(pDrawLineElement); - mBodyElements.push_back(new TagCloseElement("draw:line")); - } - else - { - ::WPXPropertyListVector path; - ::WPXPropertyList element; - - for (unsigned long ii = 0; ii < vertices.count(); ++ii) - { - element = vertices[ii]; - if (ii == 0) - element.insert("libwpg:path-action", "M"); - else - element.insert("libwpg:path-action", "L"); - path.append(element); - element.clear(); - } - if (isClosed) - { - element.insert("libwpg:path-action", "Z"); - path.append(element); - } - _drawPath(path); - } + mpImpl->drawEllipse(propList); } -void OdpGeneratorPrivate::_drawPath(const WPXPropertyListVector &path) +void OdpGenerator::drawPolyline(const ::librevenge::RVNGPropertyList &propList) { - if(path.count() == 0) - return; - // This must be a mistake and we do not want to crash lower - if(path[0]["libwpg:path-action"]->getStr() == "Z") - return; + mpImpl->drawPolySomething(propList, false); +} - // try to find the bounding box - // this is simple convex hull technique, the bounding box might not be - // accurate but that should be enough for this purpose - bool isFirstPoint = true; - - double px = 0.0, py = 0.0, qx = 0.0, qy = 0.0; - double lastX = 0.0; - double lastY = 0.0; - double lastPrevX = 0.0; - double lastPrevY = 0.0; - - for(unsigned k = 0; k < path.count(); ++k) - { - if (!path[k]["libwpg:path-action"]) - continue; - std::string action=path[k]["libwpg:path-action"]->getStr().cstr(); - if (action.length()!=1 || action[0]=='Z') continue; - - bool coordOk=path[k]["svg:x"]&&path[k]["svg:y"]; - bool coord1Ok=coordOk && path[k]["svg:x1"]&&path[k]["svg:y1"]; - bool coord2Ok=coord1Ok && path[k]["svg:x2"]&&path[k]["svg:y2"]; - double x=lastX, y=lastY; - if (isFirstPoint) - { - if (!coordOk) - { - ODFGEN_DEBUG_MSG(("OdpGeneratorPrivate::_drawPath: the first point has no coordinate\n")); - continue; - } - qx = px = x = path[k]["svg:x"]->getDouble(); - qy = py = y = path[k]["svg:y"]->getDouble(); - lastPrevX = lastX = px; - lastPrevY = lastY = py; - isFirstPoint = false; - } - else - { - if (path[k]["svg:x"]) x=path[k]["svg:x"]->getDouble(); - if (path[k]["svg:y"]) y=path[k]["svg:y"]->getDouble(); - px = (px > x) ? x : px; - py = (py > y) ? y : py; - qx = (qx < x) ? x : qx; - qy = (qy < y) ? y : qy; - } - - double xmin=px, xmax=qx, ymin=py, ymax=qy; - bool lastPrevSet=false; - - if(action[0] == 'C' && coord2Ok) - { - getCubicBezierBBox(lastX, lastY, path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - path[k]["svg:x2"]->getDouble(), path[k]["svg:y2"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x2"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y2"]->getDouble(); - } - else if(action[0] == 'S' && coord1Ok) - { - getCubicBezierBBox(lastX, lastY, lastPrevX, lastPrevY, - path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x1"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y1"]->getDouble(); - } - else if(action[0] == 'Q' && coord1Ok) - { - getQuadraticBezierBBox(lastX, lastY, path[k]["svg:x1"]->getDouble(), path[k]["svg:y1"]->getDouble(), - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-path[k]["svg:x1"]->getDouble(); - lastPrevY=2*y-path[k]["svg:y1"]->getDouble(); - } - else if(action[0] == 'T' && coordOk) - { - getQuadraticBezierBBox(lastX, lastY, lastPrevX, lastPrevY, - x, y, xmin, ymin, xmax, ymax); - lastPrevSet=true; - lastPrevX=2*x-lastPrevX; - lastPrevY=2*y-lastPrevY; - } - else if(action[0] == 'A' && coordOk && path[k]["svg:rx"] && path[k]["svg:ry"]) - { - getEllipticalArcBBox(lastX, lastY, path[k]["svg:rx"]->getDouble(), path[k]["svg:ry"]->getDouble(), - path[k]["libwpg:rotate"] ? path[k]["libwpg:rotate"]->getDouble() : 0.0, - path[k]["libwpg:large-arc"] ? path[k]["libwpg:large-arc"]->getInt() : 1, - path[k]["libwpg:sweep"] ? path[k]["libwpg:sweep"]->getInt() : 1, - x, y, xmin, ymin, xmax, ymax); - } - else if (action[0] != 'M' && action[0] != 'L' && action[0] != 'H' && action[0] != 'V') - { - ODFGEN_DEBUG_MSG(("OdpGeneratorPrivate::_drawPath: problem reading a path\n")); - } - px = (px > xmin ? xmin : px); - py = (py > ymin ? ymin : py); - qx = (qx < xmax ? xmax : qx); - qy = (qy < ymax ? ymax : qy); - lastX = x; - lastY = y; - if (!lastPrevSet) - { - lastPrevX=lastX; - lastPrevY=lastY; - } - } - - - WPXString sValue; - _writeGraphicsStyle(); - TagOpenElement *pDrawPathElement = new TagOpenElement("draw:path"); - sValue.sprintf("gr%i", miGraphicsStyleIndex-1); - pDrawPathElement->addAttribute("draw:style-name", sValue); - pDrawPathElement->addAttribute("draw:layer", "layout"); - sValue = doubleToString(px); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:x", sValue); - sValue = doubleToString(py); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:y", sValue); - sValue = doubleToString((qx - px)); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:width", sValue); - sValue = doubleToString((qy - py)); - sValue.append("in"); - pDrawPathElement->addAttribute("svg:height", sValue); - sValue.sprintf("%i %i %i %i", 0, 0, (unsigned)(2540*(qx - px)), (unsigned)(2540*(qy - py))); - pDrawPathElement->addAttribute("svg:viewBox", sValue); - - sValue.clear(); - for(unsigned i = 0; i < path.count(); ++i) - { - if (!path[i]["libwpg:path-action"]) - continue; - std::string action=path[i]["libwpg:path-action"]->getStr().cstr(); - if (action.length()!=1) continue; - bool coordOk=path[i]["svg:x"]&&path[i]["svg:y"]; - bool coord1Ok=coordOk && path[i]["svg:x1"]&&path[i]["svg:y1"]; - bool coord2Ok=coord1Ok && path[i]["svg:x2"]&&path[i]["svg:y2"]; - WPXString sElement; - // 2540 is 2.54*1000, 2.54 in = 1 inch - if (path[i]["svg:x"] && action[0] == 'H') - { - sElement.sprintf("H%i", (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540)); - sValue.append(sElement); - } - else if (path[i]["svg:y"] && action[0] == 'V') - { - sElement.sprintf("V%i", (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coordOk && (action[0] == 'M' || action[0] == 'L' || action[0] == 'T')) - { - sElement.sprintf("%c%i %i", action[0], (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coord1Ok && (action[0] == 'Q' || action[0] == 'S')) - { - sElement.sprintf("%c%i %i %i %i", action[0], (unsigned)((path[i]["svg:x1"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y1"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coord2Ok && action[0] == 'C') - { - sElement.sprintf("C%i %i %i %i %i %i", (unsigned)((path[i]["svg:x1"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y1"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x2"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y2"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), - (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (coordOk && path[i]["svg:rx"] && path[i]["svg:ry"] && action[0] == 'A') - { - sElement.sprintf("A%i %i %i %i %i %i %i", (unsigned)((path[i]["svg:rx"]->getDouble())*2540), - (unsigned)((path[i]["svg:ry"]->getDouble())*2540), (path[i]["libwpg:rotate"] ? path[i]["libwpg:rotate"]->getInt() : 0), - (path[i]["libwpg:large-arc"] ? path[i]["libwpg:large-arc"]->getInt() : 1), - (path[i]["libwpg:sweep"] ? path[i]["libwpg:sweep"]->getInt() : 1), - (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540)); - sValue.append(sElement); - } - else if (action[0] == 'Z') - sValue.append(" Z"); - } - pDrawPathElement->addAttribute("svg:d", sValue); - mBodyElements.push_back(pDrawPathElement); - mBodyElements.push_back(new TagCloseElement("draw:path")); +void OdpGenerator::drawPolygon(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawPolySomething(propList, true); } -void OdpGenerator::drawPath(const WPXPropertyListVector &path) +void OdpGenerator::drawPath(const librevenge::RVNGPropertyList &propList) { - mpImpl->_drawPath(path); + mpImpl->drawPath(propList); } -void OdpGenerator::drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData &binaryData) +void OdpGenerator::drawGraphicObject(const ::librevenge::RVNGPropertyList &propList) { - if (!propList["libwpg:mime-type"] || propList["libwpg:mime-type"]->getStr().len() <= 0) + if (!propList["librevenge:mime-type"] || propList["librevenge:mime-type"]->getStr().len() <= 0) + return; + if (!propList["office:binary-data"]) return; if (!propList["svg:x"] || !propList["svg:y"] || !propList["svg:width"] || !propList["svg:height"]) return; bool flipX(propList["draw:mirror-horizontal"] && propList["draw:mirror-horizontal"]->getInt()); bool flipY(propList["draw:mirror-vertical"] && propList["draw:mirror-vertical"]->getInt()); + + librevenge::RVNGPropertyList style=mpImpl->getGraphicStyle(); if ((flipX && !flipY) || (!flipX && flipY)) - mpImpl->mxStyle.insert("style:mirror", "horizontal"); + style.insert("style:mirror", "horizontal"); else - mpImpl->mxStyle.insert("style:mirror", "none"); + style.insert("style:mirror", "none"); if (propList["draw:color-mode"]) - mpImpl->mxStyle.insert("draw:color-mode", propList["draw:color-mode"]->getStr()); + style.insert("draw:color-mode", propList["draw:color-mode"]->getStr()); if (propList["draw:luminance"]) - mpImpl->mxStyle.insert("draw:luminance", propList["draw:luminance"]->getStr()); + style.insert("draw:luminance", propList["draw:luminance"]->getStr()); if (propList["draw:contrast"]) - mpImpl->mxStyle.insert("draw:contrast", propList["draw:contrast"]->getStr()); + style.insert("draw:contrast", propList["draw:contrast"]->getStr()); if (propList["draw:gamma"]) - mpImpl->mxStyle.insert("draw:gamma", propList["draw:gamma"]->getStr()); + style.insert("draw:gamma", propList["draw:gamma"]->getStr()); if (propList["draw:red"]) - mpImpl->mxStyle.insert("draw:red", propList["draw:red"]->getStr()); + style.insert("draw:red", propList["draw:red"]->getStr()); if (propList["draw:green"]) - mpImpl->mxStyle.insert("draw:green", propList["draw:green"]->getStr()); + style.insert("draw:green", propList["draw:green"]->getStr()); if (propList["draw:blue"]) - mpImpl->mxStyle.insert("draw:blue", propList["draw:blue"]->getStr()); + style.insert("draw:blue", propList["draw:blue"]->getStr()); - mpImpl->_writeGraphicsStyle(); - double x = propList["svg:x"]->getDouble(); double y = propList["svg:y"]->getDouble(); double height = propList["svg:height"]->getDouble(); @@ -1189,7 +740,7 @@ height *= -1.0; } - double angle(propList["libwpg:rotate"] ? - M_PI * propList["libwpg:rotate"]->getDouble() / 180.0 : 0.0); + double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0); if (angle != 0.0) { double deltax((width*cos(angle)+height*sin(angle)-width)/2.0); @@ -1198,7 +749,7 @@ y -= deltay; } - WPXPropertyList framePropList; + librevenge::RVNGPropertyList framePropList; framePropList.insert("svg:x", x); framePropList.insert("svg:y", y); @@ -1207,18 +758,19 @@ TagOpenElement *pDrawFrameElement = new TagOpenElement("draw:frame"); - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex-1); - pDrawFrameElement->addAttribute("draw:style-name", sValue); + librevenge::RVNGPropertyList finalStyle; + mpImpl->getGraphicManager().addGraphicProperties(style, finalStyle); + pDrawFrameElement->addAttribute("draw:style-name", mpImpl->getGraphicManager().findOrAdd(finalStyle)); pDrawFrameElement->addAttribute("svg:height", framePropList["svg:height"]->getStr()); pDrawFrameElement->addAttribute("svg:width", framePropList["svg:width"]->getStr()); if (angle != 0.0) { - framePropList.insert("libwpg:rotate", angle, WPX_GENERIC); + framePropList.insert("librevenge:rotate", angle, librevenge::RVNG_GENERIC); + librevenge::RVNGString sValue; sValue.sprintf("rotate (%s) translate(%s, %s)", - framePropList["libwpg:rotate"]->getStr().cstr(), + framePropList["librevenge:rotate"]->getStr().cstr(), framePropList["svg:x"]->getStr().cstr(), framePropList["svg:y"]->getStr().cstr()); pDrawFrameElement->addAttribute("draw:transform", sValue); @@ -1228,421 +780,19 @@ pDrawFrameElement->addAttribute("svg:x", framePropList["svg:x"]->getStr()); pDrawFrameElement->addAttribute("svg:y", framePropList["svg:y"]->getStr()); } - mpImpl->mBodyElements.push_back(pDrawFrameElement); - - if (propList["libwpg:mime-type"]->getStr() == "object/ole") - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:object-ole")); - else - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:image")); + mpImpl->getCurrentStorage()->push_back(pDrawFrameElement); - mpImpl->mBodyElements.push_back(new TagOpenElement("office:binary-data")); + mpImpl->insertBinaryObject(propList); - ::WPXString base64Binary = binaryData.getBase64Data(); - mpImpl->mBodyElements.push_back(new CharDataElement(base64Binary.cstr())); - - mpImpl->mBodyElements.push_back(new TagCloseElement("office:binary-data")); - - if (propList["libwpg:mime-type"]->getStr() == "object/ole") - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:object-ole")); - else - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:image")); - - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); } -void OdpGenerator::drawConnector(const ::WPXPropertyList &/*propList*/, const ::WPXPropertyListVector &/*path*/) +void OdpGenerator::drawConnector(const ::librevenge::RVNGPropertyList &propList) { + mpImpl->drawConnector(propList); } -void OdpGeneratorPrivate::_writeGraphicsStyle() -{ - TagOpenElement *pStyleStyleElement = new TagOpenElement("style:style"); - WPXString sValue; - sValue.sprintf("gr%i", miGraphicsStyleIndex); - pStyleStyleElement->addAttribute("style:name", sValue); - pStyleStyleElement->addAttribute("style:family", "graphic"); - pStyleStyleElement->addAttribute("style:parent-style-name", "standard"); - mGraphicsAutomaticStyles.push_back(pStyleStyleElement); - - TagOpenElement *pStyleGraphicsPropertiesElement = new TagOpenElement("style:graphic-properties"); - _updateGraphicPropertiesElement(*pStyleGraphicsPropertiesElement, mxStyle, mxGradient); - mGraphicsAutomaticStyles.push_back(pStyleGraphicsPropertiesElement); - mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties")); - - mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:style")); - miGraphicsStyleIndex++; -} - -void OdpGeneratorPrivate::_updateGraphicPropertiesElement(TagOpenElement &element, ::WPXPropertyList const &style, ::WPXPropertyListVector const &gradient) -{ - bool bUseOpacityGradient = false; - - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "dash") - { - TagOpenElement *pDrawStrokeDashElement = new TagOpenElement("draw:stroke-dash"); - WPXString sValue; - sValue.sprintf("Dash_%i", miDashIndex++); - pDrawStrokeDashElement->addAttribute("draw:name", sValue); - if (style["svg:stoke-linecap"]) - pDrawStrokeDashElement->addAttribute("draw:style", style["svg:stroke-linecap"]->getStr()); - else - pDrawStrokeDashElement->addAttribute("draw:style", "rect"); - if (style["draw:distance"]) - pDrawStrokeDashElement->addAttribute("draw:distance", style["draw:distance"]->getStr()); - if (style["draw:dots1"]) - pDrawStrokeDashElement->addAttribute("draw:dots1", style["draw:dots1"]->getStr()); - if (style["draw:dots1-length"]) - pDrawStrokeDashElement->addAttribute("draw:dots1-length", style["draw:dots1-length"]->getStr()); - if (style["draw:dots2"]) - pDrawStrokeDashElement->addAttribute("draw:dots2", style["draw:dots2"]->getStr()); - if (style["draw:dots2-length"]) - pDrawStrokeDashElement->addAttribute("draw:dots2-length", style["draw:dots2-length"]->getStr()); - mGraphicsStrokeDashStyles.push_back(pDrawStrokeDashElement); - mGraphicsStrokeDashStyles.push_back(new TagCloseElement("draw:stroke-dash")); - } - - if (style["draw:marker-start-path"]) - { - WPXString sValue; - TagOpenElement *pDrawMarkerElement = new TagOpenElement("draw:marker"); - sValue.sprintf("StartMarker_%i", miStartMarkerIndex); - pDrawMarkerElement->addAttribute("draw:name", sValue); - if (style["draw:marker-start-viewbox"]) - pDrawMarkerElement->addAttribute("svg:viewBox", style["draw:marker-start-viewbox"]->getStr()); - pDrawMarkerElement->addAttribute("svg:d", style["draw:marker-start-path"]->getStr()); - mGraphicsMarkerStyles.push_back(pDrawMarkerElement); - mGraphicsMarkerStyles.push_back(new TagCloseElement("draw:marker")); - } - if(style["draw:marker-end-path"]) - { - WPXString sValue; - TagOpenElement *pDrawMarkerElement = new TagOpenElement("draw:marker"); - sValue.sprintf("EndMarker_%i", miEndMarkerIndex); - pDrawMarkerElement->addAttribute("draw:name", sValue); - if (style["draw:marker-end-viewbox"]) - pDrawMarkerElement->addAttribute("svg:viewBox", style["draw:marker-end-viewbox"]->getStr()); - pDrawMarkerElement->addAttribute("svg:d", style["draw:marker-end-path"]->getStr()); - mGraphicsMarkerStyles.push_back(pDrawMarkerElement); - mGraphicsMarkerStyles.push_back(new TagCloseElement("draw:marker")); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "gradient") - { - TagOpenElement *pDrawGradientElement = new TagOpenElement("draw:gradient"); - TagOpenElement *pDrawOpacityElement = new TagOpenElement("draw:opacity"); - if (style["draw:style"]) - { - pDrawGradientElement->addAttribute("draw:style", style["draw:style"]->getStr()); - pDrawOpacityElement->addAttribute("draw:style", style["draw:style"]->getStr()); - } - else - { - pDrawGradientElement->addAttribute("draw:style", "linear"); - pDrawOpacityElement->addAttribute("draw:style", "linear"); - } - WPXString sValue; - sValue.sprintf("Gradient_%i", miGradientIndex); - pDrawGradientElement->addAttribute("draw:name", sValue); - sValue.sprintf("Transparency_%i", miGradientIndex++); - pDrawOpacityElement->addAttribute("draw:name", sValue); - - // ODG angle unit is 0.1 degree - double angle = style["draw:angle"] ? style["draw:angle"]->getDouble() : 0.0; - while(angle < 0) - angle += 360; - while(angle > 360) - angle -= 360; - sValue.sprintf("%i", (unsigned)(angle*10)); - pDrawGradientElement->addAttribute("draw:angle", sValue); - pDrawOpacityElement->addAttribute("draw:angle", sValue); - - if (!gradient.count()) - { - if (style["draw:start-color"]) - pDrawGradientElement->addAttribute("draw:start-color", style["draw:start-color"]->getStr()); - if (style["draw:end-color"]) - pDrawGradientElement->addAttribute("draw:end-color", style["draw:end-color"]->getStr()); - - if (style["draw:border"]) - { - pDrawGradientElement->addAttribute("draw:border", style["draw:border"]->getStr()); - pDrawOpacityElement->addAttribute("draw:border", style["draw:border"]->getStr()); - } - else - { - pDrawGradientElement->addAttribute("draw:border", "0%"); - pDrawOpacityElement->addAttribute("draw:border", "0%"); - } - - if (style["svg:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - } - else if (style["draw:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["draw:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["draw:cx"]->getStr()); - } - - if (style["svg:cy"]) - { - pDrawGradientElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - } - else if (style["draw:cx"]) - { - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - pDrawOpacityElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - } - - if (style["draw:start-intensity"]) - pDrawGradientElement->addAttribute("draw:start-intensity", style["draw:start-intensity"]->getStr()); - else - pDrawGradientElement->addAttribute("draw:start-intensity", "100%"); - - if (style["draw:end-intensity"]) - pDrawGradientElement->addAttribute("draw:end-intensity", style["draw:end-intensity"]->getStr()); - else - pDrawGradientElement->addAttribute("draw:end-intensity", "100%"); - - if (style["libwpg:start-opacity"]) - pDrawOpacityElement->addAttribute("draw:start", style["libwpg:start-opacity"]->getStr()); - else - pDrawOpacityElement->addAttribute("draw:start", "100%"); - - if (style["libwpg:end-opacity"]) - pDrawOpacityElement->addAttribute("draw:end", style["libwpg:end-opacity"]->getStr()); - else - pDrawOpacityElement->addAttribute("draw:end", "100%"); - - mGraphicsGradientStyles.push_back(pDrawGradientElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:gradient")); - - // Work around a mess in LibreOffice where both opacities of 100% are interpreted as complete transparency - // Nevertheless, when one is different, immediately, they are interpreted correctly - if (style["libwpg:start-opacity"] && style["libwpg:end-opacity"] - && (style["libwpg:start-opacity"]->getDouble() != 1.0 || style["libwpg:end-opacity"]->getDouble() != 1.0)) - { - bUseOpacityGradient = true; - mGraphicsGradientStyles.push_back(pDrawOpacityElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:opacity")); - } - } - else if(gradient.count() >= 2) - { - sValue.sprintf("%i", (unsigned)(angle*10)); - pDrawGradientElement->addAttribute("draw:angle", sValue); - - pDrawGradientElement->addAttribute("draw:start-color", gradient[1]["svg:stop-color"]->getStr()); - pDrawGradientElement->addAttribute("draw:end-color", gradient[0]["svg:stop-color"]->getStr()); - if (style["svg:cx"]) - pDrawGradientElement->addAttribute("draw:cx", style["svg:cx"]->getStr()); - if (style["svg:cy"]) - pDrawGradientElement->addAttribute("draw:cy", style["svg:cy"]->getStr()); - if (gradient[1]["svg:stop-opacity"]) - { - pDrawOpacityElement->addAttribute("draw:start", gradient[1]["svg:stop-opacity"]->getStr()); - bUseOpacityGradient = true; - } - else - pDrawOpacityElement->addAttribute("draw:start", "100%"); - if (gradient[0]["svg:stop-opacity"]) - { - pDrawOpacityElement->addAttribute("draw:end", gradient[0]["svg:stop-opacity"]->getStr()); - bUseOpacityGradient = true; - } - else - pDrawOpacityElement->addAttribute("draw:end", "100%"); - pDrawGradientElement->addAttribute("draw:border", "0%"); - mGraphicsGradientStyles.push_back(pDrawGradientElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:gradient")); - if (bUseOpacityGradient) - { - mGraphicsGradientStyles.push_back(pDrawOpacityElement); - mGraphicsGradientStyles.push_back(new TagCloseElement("draw:opacity")); - } - } - else - { - /* if gradient.count() == 1 for some reason we would leak - * pDrawGradientElement - */ - delete pDrawGradientElement; - } - if(!bUseOpacityGradient) - delete pDrawOpacityElement; - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "bitmap" && - style["draw:fill-image"] && style["libwpg:mime-type"]) - { - TagOpenElement *pDrawBitmapElement = new TagOpenElement("draw:fill-image"); - WPXString sValue; - sValue.sprintf("Bitmap_%i", miBitmapIndex++); - pDrawBitmapElement->addAttribute("draw:name", sValue); - mGraphicsBitmapStyles.push_back(pDrawBitmapElement); - mGraphicsBitmapStyles.push_back(new TagOpenElement("office:binary-data")); - mGraphicsBitmapStyles.push_back(new CharDataElement(style["draw:fill-image"]->getStr())); - mGraphicsBitmapStyles.push_back(new TagCloseElement("office:binary-data")); - mGraphicsBitmapStyles.push_back(new TagCloseElement("draw:fill-image")); - } - - if (style["draw:color-mode"] && style["draw:color-mode"]->getStr().len() > 0) - element.addAttribute("draw:color-mode", style["draw:color-mode"]->getStr()); - if (style["draw:luminance"] && style["draw:luminance"]->getStr().len() > 0) - element.addAttribute("draw:luminance", style["draw:luminance"]->getStr()); - if (style["draw:contrast"] && style["draw:contrast"]->getStr().len() > 0) - element.addAttribute("draw:contrast", style["draw:contrast"]->getStr()); - if (style["draw:gamma"] && style["draw:gamma"]->getStr().len() > 0) - element.addAttribute("draw:gamma", style["draw:gamma"]->getStr()); - if (style["draw:red"] && style["draw:red"]->getStr().len() > 0) - element.addAttribute("draw:red", style["draw:red"]->getStr()); - if (style["draw:green"] && style["draw:green"]->getStr().len() > 0) - element.addAttribute("draw:green", style["draw:green"]->getStr()); - if (style["draw:blue"] && style["draw:blue"]->getStr().len() > 0) - element.addAttribute("draw:blue", style["draw:blue"]->getStr()); - - WPXString sValue; - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "none") - element.addAttribute("draw:stroke", "none"); - else - { - if (style["svg:stroke-width"]) - element.addAttribute("svg:stroke-width", style["svg:stroke-width"]->getStr()); - - if (style["svg:stroke-color"]) - element.addAttribute("svg:stroke-color", style["svg:stroke-color"]->getStr()); - - if (style["svg:stroke-opacity"]) - element.addAttribute("svg:stroke-opacity", style["svg:stroke-opacity"]->getStr()); - - if (style["svg:stroke-linejoin"]) - element.addAttribute("draw:stroke-linejoin", style["svg:stroke-linejoin"]->getStr()); - - if (style["svg:stroke-linecap"]) - element.addAttribute("svg:stoke-linecap", style["svg:stroke-linecap"]->getStr()); - - if (style["draw:stroke"] && style["draw:stroke"]->getStr() == "dash") - { - element.addAttribute("draw:stroke", "dash"); - sValue.sprintf("Dash_%i", miDashIndex-1); - element.addAttribute("draw:stroke-dash", sValue); - } - else - element.addAttribute("draw:stroke", "solid"); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "none") - element.addAttribute("draw:fill", "none"); - else - { - if (style["draw:shadow"]) - element.addAttribute("draw:shadow", style["draw:shadow"]->getStr()); - else - element.addAttribute("draw:shadow", "hidden"); - if (style["draw:shadow-offset-x"]) - element.addAttribute("draw:shadow-offset-x", style["draw:shadow-offset-x"]->getStr()); - if (style["draw:shadow-offset-y"]) - element.addAttribute("draw:shadow-offset-y", style["draw:shadow-offset-y"]->getStr()); - if (style["draw:shadow-color"]) - element.addAttribute("draw:shadow-color", style["draw:shadow-color"]->getStr()); - if (style["draw:shadow-opacity"]) - element.addAttribute("draw:shadow-opacity", style["draw:shadow-opacity"]->getStr()); - if (style["svg:fill-rule"]) - element.addAttribute("svg:fill-rule", style["svg:fill-rule"]->getStr()); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "solid") - { - element.addAttribute("draw:fill", "solid"); - if (style["draw:fill-color"]) - element.addAttribute("draw:fill-color", style["draw:fill-color"]->getStr()); - if (style["draw:opacity"]) - element.addAttribute("draw:opacity", style["draw:opacity"]->getStr()); - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "gradient") - { - if (!gradient.count() || gradient.count() >= 2) - { - element.addAttribute("draw:fill", "gradient"); - sValue.sprintf("Gradient_%i", miGradientIndex-1); - element.addAttribute("draw:fill-gradient-name", sValue); - if (bUseOpacityGradient) - { - sValue.sprintf("Transparency_%i", miGradientIndex-1); - element.addAttribute("draw:opacity-name", sValue); - } - } - else - { - if (gradient[0]["svg:stop-color"]) - { - element.addAttribute("draw:fill", "solid"); - element.addAttribute("draw:fill-color", gradient[0]["svg:stop-color"]->getStr()); - } - else - element.addAttribute("draw:fill", "solid"); - } - } - - if(style["draw:fill"] && style["draw:fill"]->getStr() == "bitmap") - { - if (style["draw:fill-image"] && style["libwpg:mime-type"]) - { - element.addAttribute("draw:fill", "bitmap"); - sValue.sprintf("Bitmap_%i", miBitmapIndex-1); - element.addAttribute("draw:fill-image-name", sValue); - if (style["draw:fill-image-width"]) - element.addAttribute("draw:fill-image-width", style["draw:fill-image-width"]->getStr()); - else if (style["svg:width"]) - element.addAttribute("draw:fill-image-width", style["svg:width"]->getStr()); - if (style["draw:fill-image-height"]) - element.addAttribute("draw:fill-image-height", style["draw:fill-image-height"]->getStr()); - else if (style["svg:height"]) - element.addAttribute("draw:fill-image-height", style["svg:height"]->getStr()); - if (style["style:repeat"]) - element.addAttribute("style:repeat", style["style:repeat"]->getStr()); - if (style["draw:fill-image-ref-point"]) - element.addAttribute("draw:fill-image-ref-point", style["draw:fill-image-ref-point"]->getStr()); - if (style["draw:fill-image-ref-point-x"]) - element.addAttribute("draw:fill-image-ref-point-x", style["draw:fill-image-ref-point-x"]->getStr()); - if (style["draw:fill-image-ref-point-y"]) - element.addAttribute("draw:fill-image-ref-point-y", style["draw:fill-image-ref-point-y"]->getStr()); - } - else - element.addAttribute("draw:fill", "none"); - } - - - if(style["draw:marker-start-path"]) - { - sValue.sprintf("StartMarker_%i", miStartMarkerIndex++); - element.addAttribute("draw:marker-start", sValue); - if (style["draw:marker-start-center"]) - element.addAttribute("draw:marker-start-center", style["draw:marker-start-center"]->getStr()); - if (style["draw:marker-start-width"]) - element.addAttribute("draw:marker-start-width", style["draw:marker-start-width"]->getStr()); - else - element.addAttribute("draw:marker-start-width", "0.118in"); - } - if (style["draw:marker-end-path"]) - { - sValue.sprintf("EndMarker_%i", miEndMarkerIndex++); - element.addAttribute("draw:marker-end", sValue); - if (style["draw:marker-end-center"]) - element.addAttribute("draw:marker-end-center", style["draw:marker-end-center"]->getStr()); - if (style["draw:marker-end-width"]) - element.addAttribute("draw:marker-end-width", style["draw:marker-end-width"]->getStr()); - else - element.addAttribute("draw:marker-end-width", "0.118in"); - } - if (style["style:mirror"]) - element.addAttribute("style:mirror", style["style:mirror"]->getStr()); -} - -void OdpGenerator::startEmbeddedGraphics(const WPXPropertyList &) +void OdpGenerator::startEmbeddedGraphics(const librevenge::RVNGPropertyList &) { } @@ -1650,255 +800,108 @@ { } -void OdpGenerator::startGroup(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::openGroup(const ::librevenge::RVNGPropertyList &propList) { - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:g")); + mpImpl->openGroup(propList); } -void OdpGenerator::endGroup() +void OdpGenerator::closeGroup() { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:g")); + mpImpl->closeGroup(); } -void OdpGenerator::startTextObject(const WPXPropertyList &propList, const WPXPropertyListVector &/*path*/) +void OdpGenerator::startTextObject(const librevenge::RVNGPropertyList &propList) { - TagOpenElement *pDrawFrameOpenElement = new TagOpenElement("draw:frame"); - TagOpenElement *pStyleStyleOpenElement = new TagOpenElement("style:style"); - - WPXString sValue; - sValue.sprintf("gr%i", mpImpl->miGraphicsStyleIndex++); - pStyleStyleOpenElement->addAttribute("style:name", sValue); - pStyleStyleOpenElement->addAttribute("style:family", "graphic"); - pStyleStyleOpenElement->addAttribute("style:parent-style-name", "standard"); - mpImpl->mGraphicsAutomaticStyles.push_back(pStyleStyleOpenElement); - - pDrawFrameOpenElement->addAttribute("draw:style-name", sValue); - pDrawFrameOpenElement->addAttribute("draw:layer", "layout"); - - TagOpenElement *pStyleGraphicPropertiesOpenElement = new TagOpenElement("style:graphic-properties"); - WPXPropertyList styleList(propList); - if (!propList["draw:stroke"]) - styleList.insert("draw:stroke", "none"); - if (!propList["draw:fill"]) - styleList.insert("draw:fill", "none"); - // the transformation is managed latter, so even if this changes nothing... - if (propList["libwpg:rotate"]) - styleList.insert("libwpg:rotate", 0); - mpImpl->_updateGraphicPropertiesElement(*pStyleGraphicPropertiesOpenElement, styleList, WPXPropertyListVector()); - - if (!propList["svg:width"] && !propList["svg:height"]) - { - if (!propList["fo:min-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:min-width", "1in"); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-width", "1in"); - } - pDrawFrameOpenElement->addAttribute("svg:width", "10in"); - } - else - { - if(propList["svg:width"]) - pDrawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - if(propList["svg:height"]) - pDrawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - } - if (propList["fo:min-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - } - if (propList["fo:min-height"]) - { - pDrawFrameOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - } - if (propList["fo:max-width"]) - { - pDrawFrameOpenElement->addAttribute("fo:max-width", propList["fo:max-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr()); - } - if (propList["fo:max-height"]) - { - pDrawFrameOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - } - if (propList["fo:padding-top"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-top", propList["fo:padding-top"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-top", propList["fo:padding-top"]->getStr()); - } - if (propList["fo:padding-bottom"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-bottom", propList["fo:padding-bottom"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-bottom", propList["fo:padding-bottom"]->getStr()); - } - if (propList["fo:padding-left"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-left", propList["fo:padding-left"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-left", propList["fo:padding-left"]->getStr()); - } - if (propList["fo:padding-right"]) - { - pDrawFrameOpenElement->addAttribute("fo:padding-right", propList["fo:padding-right"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("fo:padding-right", propList["fo:padding-right"]->getStr()); - } - if (propList["draw:textarea-vertical-align"]) - { - pDrawFrameOpenElement->addAttribute("draw:textarea-vertical-align", propList["draw:textarea-vertical-align"]->getStr()); - pStyleGraphicPropertiesOpenElement->addAttribute("draw:textarea-vertical-align", propList["draw:textarea-vertical-align"]->getStr()); - } - - double x = 0.0; - double y = 0.0; - if (propList["svg:x"]) - x = propList["svg:x"]->getDouble(); - if (propList["svg:y"]) - y = propList["svg:y"]->getDouble(); - double angle(propList["libwpg:rotate"] ? - M_PI * propList["libwpg:rotate"]->getDouble() / 180.0 : 0.0); - if (angle != 0.0) - { - // compute position: make sure that the center position remains invariant - double width = 0.0; - double height = 0.0; - if (propList["libwpg:rotate-cx"]) - width = 2.0*(propList["libwpg:rotate-cx"]->getDouble()-x); - else if (propList["svg:width"]) - width = propList["svg:width"]->getDouble(); - if (propList["libwpg:rotate-cy"]) - height = 2.0*(propList["libwpg:rotate-cy"]->getDouble()-y); - else if (propList["svg:height"]) - height = propList["svg:height"]->getDouble(); - double deltax((width*cos(angle)+height*sin(angle)-width)/2.0); - double deltay((-width*sin(angle)+height*cos(angle)-height)/2.0); - x -= deltax; - y -= deltay; - } - WPXProperty *svg_x = WPXPropertyFactory::newInchProp(x); - WPXProperty *svg_y = WPXPropertyFactory::newInchProp(y); - if (angle != 0.0) - { - WPXProperty *libwpg_rotate = WPXPropertyFactory::newDoubleProp(angle); - sValue.sprintf("rotate (%s) translate(%s, %s)", - libwpg_rotate->getStr().cstr(), - svg_x->getStr().cstr(), - svg_y->getStr().cstr()); - delete libwpg_rotate; - pDrawFrameOpenElement->addAttribute("draw:transform", sValue); - } - else - { - if (propList["svg:x"]) - pDrawFrameOpenElement->addAttribute("svg:x", svg_x->getStr()); - if (propList["svg:y"]) - pDrawFrameOpenElement->addAttribute("svg:y", svg_y->getStr()); - } - delete svg_x; - delete svg_y; - mpImpl->mBodyElements.push_back(pDrawFrameOpenElement); - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:text-box")); - mpImpl->mGraphicsAutomaticStyles.push_back(pStyleGraphicPropertiesOpenElement); - mpImpl->mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties")); - mpImpl->mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:style")); + mpImpl->openTextBoxFrame(propList); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("draw:text-box")); mpImpl->mState.mbIsTextBox = true; + mpImpl->pushListState(); } void OdpGenerator::endTextObject() { - if (mpImpl->mState.mbIsTextBox) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:text-box")); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); - mpImpl->mState.mbIsTextBox = false; - } + if (!mpImpl->mState.mbIsTextBox) + return; + + mpImpl->popListState(); + mpImpl->mState.mbIsTextBox = false; + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:text-box")); + mpImpl->closeTextBoxFrame(); } -void OdpGenerator::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &/*tabStops*/) +void OdpGenerator::defineParagraphStyle(const librevenge::RVNGPropertyList &propList) { - WPXPropertyList finalPropList(propList); - finalPropList.insert("style:parent-style-name", "Standard"); - WPXString paragName = mpImpl->mParagraphManager.findOrAdd(finalPropList, WPXPropertyListVector()); - + mpImpl->defineParagraphStyle(propList); +} - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); - pParagraphOpenElement->addAttribute("text:style-name", paragName); - mpImpl->mBodyElements.push_back(pParagraphOpenElement); +void OdpGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openParagraph(propList); } void OdpGenerator::closeParagraph() { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:p")); + mpImpl->closeParagraph(); } -void OdpGenerator::openSpan(const WPXPropertyList &propList) +void OdpGenerator::defineCharacterStyle(const librevenge::RVNGPropertyList &propList) { - if (propList["style:font-name"]) - mpImpl->mFontManager.findOrAdd(propList["style:font-name"]->getStr().cstr()); - - WPXString sName = mpImpl->mSpanManager.findOrAdd(propList); + mpImpl->defineCharacterStyle(propList); +} - TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); - pSpanOpenElement->addAttribute("text:style-name", sName.cstr()); - mpImpl->mBodyElements.push_back(pSpanOpenElement); +void OdpGenerator::openSpan(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openSpan(propList); } void OdpGenerator::closeSpan() { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:span")); + mpImpl->closeSpan(); +} + +void OdpGenerator::openLink(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->openLink(propList); +} + +void OdpGenerator::closeLink() +{ + mpImpl->closeLink(); } -void OdpGenerator::insertText(const WPXString &text) +void OdpGenerator::insertText(const librevenge::RVNGString &text) { - mpImpl->mBodyElements.push_back(new TextElement(text)); + mpImpl->insertText(text); } void OdpGenerator::insertTab() { - mpImpl->mBodyElements.push_back(new TagOpenElement("text:tab")); - mpImpl->mBodyElements.push_back(new TagCloseElement("text:tab")); + mpImpl->insertTab(); } void OdpGenerator::insertSpace() { - mpImpl->mBodyElements.push_back(new TagOpenElement("text:s")); - mpImpl->mBodyElements.push_back(new TagCloseElement("text:s")); + mpImpl->insertSpace(); } void OdpGenerator::insertLineBreak() { - mpImpl->mBodyElements.push_back(new TagOpenElement("text:line-break")); - mpImpl->mBodyElements.push_back(new TagCloseElement("text:line-break")); + mpImpl->insertLineBreak(); } -void OdpGenerator::insertField(const WPXString &/*type*/, const ::WPXPropertyList &/*propList*/) +void OdpGenerator::insertField(const ::librevenge::RVNGPropertyList &propList) { + mpImpl->insertField(propList); } -void OdpGenerator::openOrderedListLevel(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::openOrderedListLevel(const ::librevenge::RVNGPropertyList &propList) { - if (mpImpl->mListStates.top().mbListElementParagraphOpened) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:p")); - mpImpl->mListStates.top().mbListElementParagraphOpened = false; - } - - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list"); - mpImpl->openListLevel(pListLevelOpenElement); - - mpImpl->mBodyElements.push_back(pListLevelOpenElement); + mpImpl->openListLevel(propList, true); } -void OdpGenerator::openUnorderedListLevel(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::openUnorderedListLevel(const ::librevenge::RVNGPropertyList &propList) { - if (mpImpl->mListStates.top().mbListElementParagraphOpened) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:p")); - mpImpl->mListStates.top().mbListElementParagraphOpened = false; - } - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list"); - mpImpl->openListLevel(pListLevelOpenElement); - - mpImpl->mBodyElements.push_back(pListLevelOpenElement); + mpImpl->openListLevel(propList, false); } void OdpGenerator::closeOrderedListLevel() @@ -1911,60 +914,21 @@ mpImpl->closeListLevel(); } -void OdpGenerator::openListElement(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &tabStops) +void OdpGenerator::openListElement(const ::librevenge::RVNGPropertyList &propList) { - if (mpImpl->mListStates.top().mbListElementOpened.top()) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:list-item")); - mpImpl->mListStates.top().mbListElementOpened.top() = false; - } - - WPXPropertyList finalPropList(propList); - finalPropList.insert("style:parent-style-name", "Standard"); - WPXString paragName = mpImpl->mParagraphManager.findOrAdd(finalPropList, tabStops); - - TagOpenElement *pOpenListItem = new TagOpenElement("text:list-item"); - if (propList["text:start-value"] && propList["text:start-value"]->getInt() > 0) - pOpenListItem->addAttribute("text:start-value", propList["text:start-value"]->getStr()); - mpImpl->mBodyElements.push_back(pOpenListItem); - - TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p"); - pOpenListElementParagraph->addAttribute("text:style-name", paragName); - mpImpl->mBodyElements.push_back(pOpenListElementParagraph); - - mpImpl->mListStates.top().mbListElementOpened.top() = true; - mpImpl->mListStates.top().mbListElementParagraphOpened = true; + mpImpl->openListElement(propList); } void OdpGenerator::closeListElement() { - // this code is kind of tricky, because we don't actually close the list element (because this list element - // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel - // code (or when we open another list element) - - if (mpImpl->mListStates.top().mbListElementParagraphOpened) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("text:p")); - mpImpl->mListStates.top().mbListElementParagraphOpened = false; - } + mpImpl->closeListElement(); } -void OdpGenerator::openTable(const ::WPXPropertyList &propList, const ::WPXPropertyListVector &columns) +void OdpGenerator::startTableObject(const ::librevenge::RVNGPropertyList &propList) { if (mpImpl->mState.mInComment) return; - - WPXString sTableName; - sTableName.sprintf("Table%i", mpImpl->mTableStyles.size()); - - // FIXME: we base the table style off of the page's margin left, ignoring (potential) wordperfect margin - // state which is transmitted inside the page. could this lead to unacceptable behaviour? - // WLACH_REFACTORING: characterize this behaviour, probably should nip it at the bud within libwpd - TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr()); - - mpImpl->mTableStyles.push_back(pTableStyle); - - mpImpl->mpCurrentTableStyle = pTableStyle; + mpImpl->pushListState(); // table must be inside a frame TagOpenElement *pFrameOpenElement = new TagOpenElement("draw:frame"); @@ -1979,74 +943,37 @@ if (propList["svg:height"]) pFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - mpImpl->mBodyElements.push_back(pFrameOpenElement); - - TagOpenElement *pTableOpenElement = new TagOpenElement("table:table"); - - pTableOpenElement->addAttribute("table:name", sTableName.cstr()); - pTableOpenElement->addAttribute("table:style-name", sTableName.cstr()); - mpImpl->mBodyElements.push_back(pTableOpenElement); - - for (int i=0; igetNumColumns(); ++i) - { - TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column"); - WPXString sColumnStyleName; - sColumnStyleName.sprintf("%s.Column%i", sTableName.cstr(), (i+1)); - pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr()); - mpImpl->mBodyElements.push_back(pTableColumnOpenElement); - - TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column"); - mpImpl->mBodyElements.push_back(pTableColumnCloseElement); - } + mpImpl->getCurrentStorage()->push_back(pFrameOpenElement); + mpImpl->openTable(propList); } -void OdpGenerator::openTableRow(const ::WPXPropertyList &propList) +void OdpGenerator::endTableObject() { if (mpImpl->mState.mInComment) return; + mpImpl->closeTable(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); + mpImpl->popListState(); +} - if (!mpImpl->mpCurrentTableStyle) - { - ODFGEN_DEBUG_MSG(("OdtGenerator::openTableRow called with no table\n")); +void OdpGenerator::openTableRow(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mState.mInComment) return; - } - - if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt())) - { - mpImpl->mBodyElements.push_back(new TagOpenElement("table:table-header-rows")); - mpImpl->mState.mHeaderRow = true; - } - - WPXString sTableRowStyleName; - sTableRowStyleName.sprintf("%s.Row%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableRowStyles()); - TableRowStyle *pTableRowStyle = new TableRowStyle(propList, sTableRowStyleName.cstr()); - mpImpl->mpCurrentTableStyle->addTableRowStyle(pTableRowStyle); - - TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row"); - pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName); - mpImpl->mBodyElements.push_back(pTableRowOpenElement); + mpImpl->openTableRow(propList); } void OdpGenerator::closeTableRow() { - if (mpImpl->mState.mInComment || !mpImpl->mpCurrentTableStyle) + if (mpImpl->mState.mInComment) return; - - mpImpl->mBodyElements.push_back(new TagCloseElement("table:table-row")); - if (mpImpl->mState.mHeaderRow) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("table:table-header-rows")); - mpImpl->mState.mHeaderRow = false; - } + mpImpl->closeTableRow(); } -void OdpGenerator::openTableCell(const ::WPXPropertyList &propList) +void OdpGenerator::openTableCell(const ::librevenge::RVNGPropertyList &propList) { - if (!mpImpl->mpCurrentTableStyle) - { - ODFGEN_DEBUG_MSG(("OdtGenerator::openTableCell called with no table\n")); + if (mpImpl->mState.mInComment) return; - } if (mpImpl->mState.mTableCellOpened) { @@ -2054,27 +981,24 @@ return; } - WPXString sTableCellStyleName; - sTableCellStyleName.sprintf( "%s.Cell%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableCellStyles()); - TableCellStyle *pTableCellStyle = new GraphicTableCellStyle(propList, sTableCellStyleName.cstr()); - mpImpl->mpCurrentTableStyle->addTableCellStyle(pTableCellStyle); - - TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell"); - pTableCellOpenElement->addAttribute("table:style-name", sTableCellStyleName); - if (propList["table:number-columns-spanned"]) - pTableCellOpenElement->addAttribute("table:number-columns-spanned", - propList["table:number-columns-spanned"]->getStr().cstr()); - if (propList["table:number-rows-spanned"]) - pTableCellOpenElement->addAttribute("table:number-rows-spanned", - propList["table:number-rows-spanned"]->getStr().cstr()); - mpImpl->mBodyElements.push_back(pTableCellOpenElement); - - mpImpl->mState.mTableCellOpened = true; + librevenge::RVNGPropertyList pList(propList); + pList.insert("fo:padding", "0.0382in"); + pList.insert("draw:fill", "none"); + pList.insert("draw:textarea-horizontal-align", "center"); + + if (pList["fo:background-color"]) + { + pList.insert("draw:fill", "solid"); + pList.insert("draw:fill-color", pList["fo:background-color"]->getStr()); + } + if (!propList["fo:border"]) + pList.insert("fo:border", "0.03pt solid #000000"); + mpImpl->mState.mTableCellOpened = mpImpl->openTableCell(pList); } void OdpGenerator::closeTableCell() { - if (mpImpl->mState.mInComment || !mpImpl->mpCurrentTableStyle) + if (mpImpl->mState.mInComment) return; if (!mpImpl->mState.mTableCellOpened) @@ -2083,36 +1007,26 @@ return; } - mpImpl->mBodyElements.push_back(new TagCloseElement("table:table-cell")); + mpImpl->closeTableCell(); mpImpl->mState.mTableCellOpened = false; } -void OdpGenerator::insertCoveredTableCell(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::insertCoveredTableCell(const ::librevenge::RVNGPropertyList &propList) { - if (mpImpl->mState.mInComment || !mpImpl->mpCurrentTableStyle) + if (mpImpl->mState.mInComment) return; - mpImpl->mBodyElements.push_back(new TagOpenElement("table:covered-table-cell")); - mpImpl->mBodyElements.push_back(new TagCloseElement("table:covered-table-cell")); -} - -void OdpGenerator::closeTable() -{ - if (!mpImpl->mState.mInComment) - { - mpImpl->mBodyElements.push_back(new TagCloseElement("table:table")); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); - } + mpImpl->insertCoveredTableCell(propList); } -void OdpGenerator::startComment(const ::WPXPropertyList &propList) +void OdpGenerator::startComment(const ::librevenge::RVNGPropertyList &propList) { if (mpImpl->mState.mInComment) { ODFGEN_DEBUG_MSG(("a comment within a comment?!\n")); return; } - + mpImpl->pushListState(); mpImpl->mState.mInComment = true; TagOpenElement *const commentElement = new TagOpenElement("officeooo:annotation"); @@ -2127,7 +1041,7 @@ if (propList["svg:height"]) commentElement->addAttribute("svg:height", doubleToString(72 * propList["svg:height"]->getDouble())); - mpImpl->mBodyElements.push_back(commentElement); + mpImpl->getCurrentStorage()->push_back(commentElement); } void OdpGenerator::endComment() @@ -2137,12 +1051,12 @@ ODFGEN_DEBUG_MSG(("there is no comment to close\n")); return; } - + mpImpl->popListState(); mpImpl->mState.mInComment = false; - mpImpl->mBodyElements.push_back(new TagCloseElement("officeooo:annotation")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("officeooo:annotation")); } -void OdpGenerator::startNotes(const ::WPXPropertyList &/*propList*/) +void OdpGenerator::startNotes(const ::librevenge::RVNGPropertyList &/*propList*/) { if (mpImpl->mState.mInNotes) { @@ -2150,10 +1064,11 @@ return; } + mpImpl->pushListState(); TagOpenElement *const notesElement = new TagOpenElement("presentation:notes"); notesElement->addAttribute("draw:style-name", "PresentationNotesPage"); - mpImpl->mBodyElements.push_back(notesElement); + mpImpl->getCurrentStorage()->push_back(notesElement); TagOpenElement *const thumbnailElement = new TagOpenElement("draw:page-thumbnail"); thumbnailElement->addAttribute("draw:layer", "layout"); @@ -2164,12 +1079,12 @@ thumbnailElement->addAttribute("svg:height", "4.12in"); thumbnailElement->addAttribute("svg:x", "1.5in"); thumbnailElement->addAttribute("svg:y", "0.84in"); - WPXString pageNumber; + librevenge::RVNGString pageNumber; pageNumber.sprintf("%i", mpImpl->miPageIndex); thumbnailElement->addAttribute("draw:page-number", pageNumber); - mpImpl->mBodyElements.push_back(thumbnailElement); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:page-thumbnail")); + mpImpl->getCurrentStorage()->push_back(thumbnailElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:page-thumbnail")); TagOpenElement *const frameElement = new TagOpenElement("draw:frame"); frameElement->addAttribute("presentation:style-name", "PresentationNotesFrame"); @@ -2180,9 +1095,9 @@ frameElement->addAttribute("svg:x", "0.85in"); frameElement->addAttribute("svg:y", "5.22in"); - mpImpl->mBodyElements.push_back(frameElement); + mpImpl->getCurrentStorage()->push_back(frameElement); - mpImpl->mBodyElements.push_back(new TagOpenElement("draw:text-box")); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("draw:text-box")); mpImpl->mState.mInNotes = true; } @@ -2194,12 +1109,127 @@ ODFGEN_DEBUG_MSG(("no notes opened\n")); return; } - + mpImpl->popListState(); mpImpl->mState.mInNotes = false; - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:text-box")); - mpImpl->mBodyElements.push_back(new TagCloseElement("draw:frame")); - mpImpl->mBodyElements.push_back(new TagCloseElement("presentation:notes")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:text-box")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:frame")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("presentation:notes")); +} + +void OdpGenerator::defineChartStyle(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::openChart(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::closeChart() +{ + // TODO: implement me +} + +void OdpGenerator::openChartTextObject(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::closeChartTextObject() +{ + // TODO: implement me +} + +void OdpGenerator::openChartPlotArea(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::closeChartPlotArea() +{ + // TODO: implement me +} + +void OdpGenerator::insertChartAxis(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::openChartSeries(const ::librevenge::RVNGPropertyList &) +{ + // TODO: implement me +} + +void OdpGenerator::closeChartSeries() +{ + // TODO: implement me +} + +void OdpGenerator::openAnimationSequence(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::closeAnimationSequence() +{ + // TODO: implement me +} + +void OdpGenerator::openAnimationGroup(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::closeAnimationGroup() +{ + // TODO: implement me +} + +void OdpGenerator::openAnimationIteration(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::closeAnimationIteration() +{ + // TODO: implement me +} + +void OdpGenerator::insertMotionAnimation(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::insertColorAnimation(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::insertAnimation(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdpGenerator::insertEffect(const ::librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + + +void OdpGenerator::initStateWith(OdfGenerator const &orig) +{ + mpImpl->initStateWith(orig); } +void OdpGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler) +{ + mpImpl->registerEmbeddedObjectHandler(mimeType, objectHandler); +} + +void OdpGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler) +{ + mpImpl->registerEmbeddedImageHandler(mimeType, imageHandler); +} /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdsGenerator.cxx libodfgen-0.1.1/src/OdsGenerator.cxx --- libodfgen-0.0.4/src/OdsGenerator.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/OdsGenerator.cxx 2014-06-02 17:08:51.000000000 +0000 @@ -0,0 +1,1858 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "DocumentElement.hxx" +#include "FilterInternal.hxx" +#include "InternalHandler.hxx" +#include "ListStyle.hxx" +#include "OdcGenerator.hxx" +#include "OdfGenerator.hxx" +#include "PageSpan.hxx" +#include "SheetStyle.hxx" + +class OdsGeneratorPrivate : public OdfGenerator +{ +public: + enum Command { C_Document=0, C_PageSpan, C_Header, C_Footer, C_Sheet, C_SheetRow, C_SheetCell, + C_Chart, C_ChartDataLabel, C_ChartPlotArea, C_ChartSerie, C_ChartTextObject, + C_Span, C_Paragraph, C_Section, C_OrderedList, C_UnorderedList, C_ListElement, + C_Footnote, C_Comment, C_TextBox, C_Frame, C_Table, C_TableRow, C_TableCell, + C_Group + }; + // the state we use for writing the final document + struct State + { + State() : mbStarted(false), + mbInSheet(false), mbInSheetShapes(false), mbInSheetRow(false), mbFirstInSheetRow(false), mbInSheetCell(false), miLastSheetRow(0), miLastSheetColumn(0), + mbInFootnote(false), mbInComment(false), mbInHeaderFooter(false), mbInFrame(false), mbFirstInFrame(false), mbInChart(false), + mbInGroup(false), mbInTable(false), mbInTextBox(false), + mbNewOdcGenerator(false), mbNewOdtGenerator(false) + { + } + bool canOpenFrame() const + { + return mbStarted && mbInSheet && !mbInSheetCell && !mbInFootnote && !mbInComment + && !mbInHeaderFooter && !mbInFrame && !mbInChart; + } + bool mbStarted; + + bool mbInSheet; + bool mbInSheetShapes; + bool mbInSheetRow; + bool mbFirstInSheetRow; + bool mbInSheetCell; + int miLastSheetRow; + int miLastSheetColumn; + bool mbInFootnote; + bool mbInComment; + bool mbInHeaderFooter; + bool mbInFrame; + bool mbFirstInFrame; + bool mbInChart; + bool mbInGroup; + bool mbInTable; + bool mbInTextBox; + + bool mbNewOdcGenerator; + bool mbNewOdtGenerator; + }; + // the odc state + struct OdcGeneratorState + { + OdcGeneratorState(librevenge::RVNGString const &dir) : mDir(dir), mContentElements(), mInternalHandler(&mContentElements), mGenerator() + { + if (!mDir.empty()) return; + mGenerator.addDocumentHandler(&mInternalHandler,ODF_FLAT_XML); + } + ~OdcGeneratorState() + { + for (size_t i=0; i < mContentElements.size(); ++i) + { + if (mContentElements[i]) delete mContentElements[i]; + } + } + OdcGenerator &get() + { + return mGenerator; + } + librevenge::RVNGString mDir; + std::vector mContentElements; + InternalHandler mInternalHandler; + OdcGenerator mGenerator; + }; + + // the odt state + struct OdtGeneratorState + { + OdtGeneratorState() : mContentElements(), mInternalHandler(&mContentElements), mGenerator() + { + mGenerator.addDocumentHandler(&mInternalHandler,ODF_FLAT_XML); + } + ~OdtGeneratorState() + { + for (size_t i=0; i < mContentElements.size(); ++i) + { + if (mContentElements[i]) delete mContentElements[i]; + } + } + OdtGenerator &get() + { + return mGenerator; + } + std::vector mContentElements; + InternalHandler mInternalHandler; + OdtGenerator mGenerator; + }; + + OdsGeneratorPrivate(); + ~OdsGeneratorPrivate(); + void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) + { + if (!pHandler) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::addDocumentHandler: called without handler\n")); + return; + } + mDocumentStreamHandlers[streamType] = pHandler; + } + // + // command gestion + // + + void open(Command const command) + { + mCommandStack.push(command); + } + bool close(Command command); + + // + // state gestion + // + + // returns the actual state + State &getState() + { + if (mStateStack.empty()) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::getState: no state\n")); + mStateStack.push(State()); + } + return mStateStack.top(); + } + // push a state + void pushState(State const &state) + { + mStateStack.push(state); + } + // pop a state + void popState() + { + if (!mStateStack.empty()) + mStateStack.pop(); + else + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::popState: no state\n")); + } + } + // check if we are in a sheetcell or in a comment + bool canWriteText() const + { + if (mStateStack.empty() || mStateStack.top().mbInFootnote) return false; + return mStateStack.top().mbInComment || mStateStack.top().mbInSheetCell || + mStateStack.top().mbInHeaderFooter || mStateStack.top().mbInTextBox; + } + bool canAddNewShape(bool add=true) + { + if (mStateStack.empty()) + { + if (add) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::canAddNewShape: can not find the state!!!\n")); + } + return false; + } + State &state=mStateStack.top(); + if (!state.mbStarted || !state.mbInSheet || state.mbInChart || state.mbInComment || state.mbInSheetRow) + { + if (add) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::canAddNewShape: call outside a sheet shapes zone!!!\n")); + } + return false; + } + if (add && !state.mbInSheetShapes) + { + getCurrentStorage()->push_back(new TagOpenElement("table:shapes")); + state.mbInSheetShapes=true; + } + return true; + } + + // + // auxilliar generator + // + bool createAuxiliarOdcGenerator() + { + if (mAuxiliarOdcState) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::createAuxiliarOdcGenerator: already created\n")); + return false; + } + bool isFlat = mDocumentStreamHandlers.find(ODF_FLAT_XML)!=mDocumentStreamHandlers.end(); + librevenge::RVNGString dir(""); + if (!isFlat) + dir.sprintf("Object %i/", miObjectNumber++); + mAuxiliarOdcState.reset(new OdcGeneratorState(dir)); + if (!isFlat) + { + createObjectFile(dir, "application/vnd.oasis.opendocument.chart", true); + librevenge::RVNGString file(dir); + file.append("content.xml"); + mAuxiliarOdcState->mGenerator.addDocumentHandler + (&createObjectFile(file, "text/xml").mInternalHandler, ODF_CONTENT_XML); + file=dir; + file.append("meta.xml"); + mAuxiliarOdcState->mGenerator.addDocumentHandler + (&createObjectFile(file, "text/xml").mInternalHandler, ODF_META_XML); + file=dir; + file.append("styles.xml"); + mAuxiliarOdcState->mGenerator.addDocumentHandler + (&createObjectFile(file, "text/xml").mInternalHandler, ODF_STYLES_XML); + } + mAuxiliarOdcState->mGenerator.initStateWith(*this); + mAuxiliarOdcState->mGenerator.startDocument(librevenge::RVNGPropertyList()); + + return true; + } + bool sendAuxiliarOdcGenerator() + { + if (!mAuxiliarOdcState) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::sendAuxiliarOdcGenerator: data seems bad\n")); + return false; + } + mAuxiliarOdcState->mGenerator.endDocument(); + if (mAuxiliarOdcState->mDir.empty() && mAuxiliarOdcState->mContentElements.empty()) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::sendAuxiliarOdcGenerator: data seems bad\n")); + return false; + } + TagOpenElement *object=new TagOpenElement("draw:object"); + if (!mAuxiliarOdcState->mDir.empty()) + { + object->addAttribute("xlink:href",mAuxiliarOdcState->mDir.cstr()); + object->addAttribute("xlink:type","simple"); + object->addAttribute("xlink:show","embed"); + object->addAttribute("xlink:actuate","onLoad"); + } + getCurrentStorage()->push_back(object); + for (std::vector::const_iterator iter = mAuxiliarOdcState->mContentElements.begin(); iter != mAuxiliarOdcState->mContentElements.end(); ++iter) + getCurrentStorage()->push_back(*iter); + mAuxiliarOdcState->mContentElements.resize(0); + getCurrentStorage()->push_back(new TagCloseElement("draw:object")); + return true; + } + void resetAuxiliarOdcGenerator() + { + mAuxiliarOdcState.reset(); + } + bool checkOutsideOdc(char const *function) const + { + if (!mAuxiliarOdcState) return true; + if (!function) return false; + ODFGEN_DEBUG_MSG(("OdsGenerator::%s: call in chart\n", function)); + return false; + } + bool createAuxiliarOdtGenerator() + { + if (mAuxiliarOdtState) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::createAuxiliarOdtGenerator: already created\n")); + return false; + } + mAuxiliarOdtState.reset(new OdtGeneratorState); + mAuxiliarOdtState->mGenerator.initStateWith(*this); + mAuxiliarOdtState->mGenerator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:margin-left", 0.0, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.0, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.0, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.0, librevenge::RVNG_INCH); + mAuxiliarOdtState->mGenerator.openPageSpan(page); + + return true; + } + bool sendAuxiliarOdtGenerator() + { + if (!mAuxiliarOdtState) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::sendAuxiliarOdtGenerator: data seems bad\n")); + return false; + } + mAuxiliarOdtState->mGenerator.closePageSpan(); + mAuxiliarOdtState->mGenerator.endDocument(); + if (mAuxiliarOdtState->mContentElements.empty()) + { + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::sendAuxiliarOdtGenerator: data seems bad\n")); + return false; + } + getCurrentStorage()->push_back(new TagOpenElement("draw:object")); + for (std::vector::const_iterator iter = mAuxiliarOdtState->mContentElements.begin(); iter != mAuxiliarOdtState->mContentElements.end(); ++iter) + getCurrentStorage()->push_back(*iter); + mAuxiliarOdtState->mContentElements.resize(0); + getCurrentStorage()->push_back(new TagCloseElement("draw:object")); + return true; + } + void resetAuxiliarOdtGenerator() + { + mAuxiliarOdtState.reset(); + } + bool checkOutsideOdt(char const *function) const + { + if (!mAuxiliarOdtState) return true; + if (!function) return false; + ODFGEN_DEBUG_MSG(("OdsGenerator::%s: call in text auxilliar\n", function)); + return false; + } + + bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeMasterPages(OdfDocumentHandler *pHandler); + void _writePageLayouts(OdfDocumentHandler *pHandler); + void _writeStyles(OdfDocumentHandler *pHandler); + void _writeAutomaticStyles(OdfDocumentHandler *pHandler); + + std::stack mCommandStack; + std::stack mStateStack; + + // auxiliar odc handler to create data + shared_ptr mAuxiliarOdcState; + // auxiliar odt handler to create data + shared_ptr mAuxiliarOdtState; + + // table styles + SheetManager mSheetManager; + + // page state + std::vector mPageSpans; + PageSpan *mpCurrentPageSpan; + int miNumPageStyles; + + // +private: + OdsGeneratorPrivate(const OdsGeneratorPrivate &); + OdsGeneratorPrivate &operator=(const OdsGeneratorPrivate &); + +}; + +OdsGeneratorPrivate::OdsGeneratorPrivate() : OdfGenerator(), + mCommandStack(), + mStateStack(), + mAuxiliarOdcState(), mAuxiliarOdtState(), + mSheetManager(), + mPageSpans(), mpCurrentPageSpan(0), miNumPageStyles(0) +{ + mStateStack.push(State()); +} + +OdsGeneratorPrivate::~OdsGeneratorPrivate() +{ + // clean up the mess we made + ODFGEN_DEBUG_MSG(("OdsGenerator: Cleaning up our mess..\n")); + + ODFGEN_DEBUG_MSG(("OdsGenerator: Destroying the body elements\n")); + mSheetManager.clean(); + + for (std::vector::iterator iterPageSpans = mPageSpans.begin(); + iterPageSpans != mPageSpans.end(); ++iterPageSpans) + delete(*iterPageSpans); +} + +bool OdsGeneratorPrivate::close(Command command) +{ + if (mCommandStack.empty() || mCommandStack.top()!=command) + { +#ifdef DEBUG + static char const *(wh[]) = + { + "Document", "PageSpan", "Header", "Footer", "Sheet", "SheetRow", "SheetCell", + "Chart", "ChartDataLabel", "ChartPlotArea", "ChartSerie", "ChartTextObject", + "Span", "Paragraph", "Section", "OrderedListLevel", "UnorderedListLevel", "ListElement", + "Footnote", "Comment", "TextBox", "Frame", "Table", "TableRow", "TableCell", + "Group" + }; + ODFGEN_DEBUG_MSG(("OdsGeneratorPrivate::close: unexpected %s\n", wh[command])); +#endif + return false; + } + mCommandStack.pop(); + return true; +} + +void OdsGeneratorPrivate::_writeMasterPages(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:master-styles").write(pHandler); + + static char const *(s_default[2*2]) = { "Standard", "PM0", "Endnote", "PM1" }; + for (int i=0; i < 2; ++i) + { + TagOpenElement pageOpenElement("style:master-page"); + pageOpenElement.addAttribute("style:name", s_default[2*i]); + pageOpenElement.addAttribute("style:page-layout-name", s_default[2*i+1]); + pageOpenElement.write(pHandler); + pHandler->endElement("style:master-page"); + } + + int pageNumber = 1; + for (unsigned int i=0; iwriteMasterPages(pageNumber, (int)i, bLastPage, pHandler); + pageNumber += mPageSpans[i]->getSpan(); + } + pHandler->endElement("office:master-styles"); +} + +void OdsGeneratorPrivate::_writePageLayouts(OdfDocumentHandler *pHandler) +{ + for (int i=0; i < 2; ++i) + { + TagOpenElement layout("style:page-layout"); + layout.addAttribute("style:name", i==0 ? "PM0" : "PM1"); + layout.write(pHandler); + + TagOpenElement layoutProperties("style:page-layout-properties"); + layoutProperties.addAttribute("fo:margin-bottom", "1in"); + layoutProperties.addAttribute("fo:margin-left", "1in"); + layoutProperties.addAttribute("fo:margin-right", "1in"); + layoutProperties.addAttribute("fo:margin-top", "1in"); + layoutProperties.addAttribute("fo:page-height", "11in"); + layoutProperties.addAttribute("fo:page-width", "8.5in"); + layoutProperties.addAttribute("style:print-orientation", "portrait"); + layoutProperties.write(pHandler); + + TagOpenElement footnoteSep("style:footnote-sep"); + footnoteSep.addAttribute("style:adjustment","left"); + footnoteSep.addAttribute("style:color","#000000"); + footnoteSep.addAttribute("style:rel-width","25%"); + if (i==0) + { + footnoteSep.addAttribute("style:distance-after-sep","0.0398in"); + footnoteSep.addAttribute("style:distance-before-sep","0.0398in"); + footnoteSep.addAttribute("style:width","0.0071in"); + } + footnoteSep.write(pHandler); + TagCloseElement("style:footnote-sep").write(pHandler); + TagCloseElement("style:page-layout-properties").write(pHandler); + + TagCloseElement("style:page-layout").write(pHandler); + } + + for (unsigned int i=0; iwritePageLayout((int)i, pHandler); +} + +OdsGenerator::OdsGenerator() : mpImpl(new OdsGeneratorPrivate()) +{ +} + +OdsGenerator::~OdsGenerator() +{ + if (mpImpl) + delete mpImpl; +} + +void OdsGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (mpImpl) + mpImpl->addDocumentHandler(pHandler, streamType); +} + +librevenge::RVNGStringVector OdsGenerator::getObjectNames() const +{ + if (mpImpl) + return mpImpl->getObjectNames(); + return librevenge::RVNGStringVector(); +} + +bool OdsGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!mpImpl) + return false; + return mpImpl->getObjectContent(objectName, pHandler); +} + +void OdsGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:automatic-styles").write(pHandler); + + mFontManager.write(pHandler); // do nothing + mSpanManager.write(pHandler); + mParagraphManager.write(pHandler); + mGraphicManager.writeAutomaticStyles(pHandler); + + _writePageLayouts(pHandler); + // writing out the lists styles + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + (*iterListStyles)->write(pHandler); + mSheetManager.write(pHandler); + + pHandler->endElement("office:automatic-styles"); +} + +void OdsGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler) +{ + TagOpenElement("office:styles").write(pHandler); + + // style:default-style + + // paragraph + TagOpenElement defaultParagraphStyleOpenElement("style:default-style"); + defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph"); + defaultParagraphStyleOpenElement.write(pHandler); + TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:text-autospace", "ideograph-alpha"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:punctuation-wrap", "hanging"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:writing-mode", "page"); + defaultParagraphStylePropertiesOpenElement.write(pHandler); + pHandler->endElement("style:paragraph-properties"); + pHandler->endElement("style:default-style"); + + // graphic + TagOpenElement defaultGraphicStyleOpenElement("style:default-style"); + defaultGraphicStyleOpenElement.addAttribute("style:family", "graphic"); + defaultGraphicStyleOpenElement.write(pHandler); + TagOpenElement defaultGraphicStylePropertiesOpenElement("style:graphic-properties"); + defaultGraphicStylePropertiesOpenElement.addAttribute("draw:fill","solid"); + defaultGraphicStylePropertiesOpenElement.addAttribute("draw:fill-color","#ffffff"); + defaultGraphicStylePropertiesOpenElement.addAttribute("draw:stroke","none"); + defaultGraphicStylePropertiesOpenElement.addAttribute("draw:shadow","hidden"); + defaultGraphicStylePropertiesOpenElement.write(pHandler); + pHandler->endElement("style:graphic-properties"); + pHandler->endElement("style:default-style"); + + // table + TagOpenElement defaultTableStyleOpenElement("style:default-style"); + defaultTableStyleOpenElement.addAttribute("style:family", "table"); + defaultTableStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // table-row + TagOpenElement defaultTableRowStyleOpenElement("style:default-style"); + defaultTableRowStyleOpenElement.addAttribute("style:family", "table-row"); + defaultTableRowStyleOpenElement.write(pHandler); + TagOpenElement defaultTableRowPropertiesOpenElement("style:table-row-properties"); + defaultTableRowPropertiesOpenElement.addAttribute("fo:keep-together", "auto"); + defaultTableRowPropertiesOpenElement.write(pHandler); + pHandler->endElement("style:table-row-properties"); + pHandler->endElement("style:default-style"); + + // table-column + TagOpenElement defaultTableColumnStyleOpenElement("style:default-style"); + defaultTableColumnStyleOpenElement.addAttribute("style:family", "table-column"); + defaultTableColumnStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // table-cell + TagOpenElement defaultTableCellStyleOpenElement("style:default-style"); + defaultTableCellStyleOpenElement.addAttribute("style:family", "table-cell"); + defaultTableCellStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // basic style + + // paragraph Standard + TagOpenElement standardStyleOpenElement("style:style"); + standardStyleOpenElement.addAttribute("style:name", "Standard"); + standardStyleOpenElement.addAttribute("style:family", "paragraph"); + standardStyleOpenElement.addAttribute("style:class", "text"); + standardStyleOpenElement.write(pHandler); + pHandler->endElement("style:style"); + + static char const *(s_paraStyle[4*10]) = + { + "Text_Body", "Text Body", "Standard", "text", + "Table_Contents", "Table Contents", "Text_Body", "extra", + "Table_Heading", "Table Heading", "Table_Contents", "extra", + "List", "List", "Text_Body", "list", + "Header", "Header", "Standard", "extra", + "Footer", "Footer", "Standard", "extra", + "Caption", "Caption", "Standard", "extra", + "Footnote", "Footnote", "Standard", "extra", + "Endnote", "Endnote", "Standard", "extra", + "Index", "Index", "Standard", "extra" + }; + for (int i=0; i<10; ++i) + { + TagOpenElement paraOpenElement("style:style"); + paraOpenElement.addAttribute("style:name", s_paraStyle[4*i]); + paraOpenElement.addAttribute("style:display-name", s_paraStyle[4*i+1]); + paraOpenElement.addAttribute("style:family", "paragraph"); + paraOpenElement.addAttribute("style:parent-style-name", s_paraStyle[4*i+2]); + paraOpenElement.addAttribute("style:class", s_paraStyle[4*i+3]); + paraOpenElement.write(pHandler); + pHandler->endElement("style:style"); + } + + static char const *(s_textStyle[2*4])= + { + "Footnote_Symbol", "Footnote Symbol", "Endnote_Symbol", "Endnote Symbol", + "Footnote_anchor", "Footnote anchor", "Endnote_anchor", "Endnote anchor" + }; + for (int i=0; i<4; ++i) + { + TagOpenElement textOpenElement("style:style"); + textOpenElement.addAttribute("style:name", s_textStyle[2*i]); + textOpenElement.addAttribute("style:display-name", s_textStyle[2*i]); + textOpenElement.addAttribute("style:family", "text"); + textOpenElement.write(pHandler); + TagOpenElement textPropertiesOpenElement("style:text-properties"); + textPropertiesOpenElement.addAttribute("style:text-position", "super 58%"); + textPropertiesOpenElement.write(pHandler); + pHandler->endElement("style:text-properties"); + pHandler->endElement("style:style"); + } + + mGraphicManager.writeStyles(pHandler); + pHandler->endElement("office:styles"); +} + +bool OdsGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) +{ + if (streamType == ODF_MANIFEST_XML) + { + pHandler->startDocument(); + TagOpenElement manifestElement("manifest:manifest"); + manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"); + manifestElement.addAttribute("manifest:version", "1.2", true); + manifestElement.write(pHandler); + + TagOpenElement mainFile("manifest:file-entry"); + mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.spreadsheet"); + mainFile.addAttribute("manifest:full-path", "/"); + mainFile.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + appendFilesInManifest(pHandler); + + TagCloseElement("manifest:manifest").write(pHandler); + pHandler->endDocument(); + return true; + } + + pHandler->startDocument(); + + if (streamType == ODF_FLAT_XML || streamType == ODF_CONTENT_XML) + { + ODFGEN_DEBUG_MSG(("OdsGenerator: Document Body: preamble\n")); + } + + std::string const documentType=OdfGenerator::getDocumentType(streamType); + librevenge::RVNGPropertyList docContentPropList; + docContentPropList.insert("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); + docContentPropList.insert("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0"); + docContentPropList.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/"); + docContentPropList.insert("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0"); + docContentPropList.insert("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0"); + docContentPropList.insert("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0"); + docContentPropList.insert("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"); + docContentPropList.insert("xmlns:of", "urn:oasis:names:tc:opendocument:xmlns:of:1.2"); + + docContentPropList.insert("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"); + docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink"); + docContentPropList.insert("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"); + docContentPropList.insert("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"); + docContentPropList.insert("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0"); + docContentPropList.insert("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"); + docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML"); + docContentPropList.insert("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0"); + docContentPropList.insert("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0"); + docContentPropList.insert("xmlns:tableooo", "http://openoffice.org/2009/table"); + docContentPropList.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); + docContentPropList.insert("xmlns:calcext","urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"); + docContentPropList.insert("office:version", librevenge::RVNGPropertyFactory::newStringProp("1.2")); + if (streamType == ODF_FLAT_XML) + docContentPropList.insert("office:mimetype", "application/vnd.oasis.opendocument.spreadsheet"); + pHandler->startElement(documentType.c_str(), docContentPropList); + + if (streamType == ODF_FLAT_XML || streamType == ODF_META_XML) + writeDocumentMetaData(pHandler); + + // write out the font styles + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + mFontManager.writeFontsDeclaration(pHandler); + + // write default styles + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML) + { + ODFGEN_DEBUG_MSG(("OdsGenerator: Document Body: Writing out the styles..\n")); + _writeStyles(pHandler); + } + // writing automatic style + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + _writeAutomaticStyles(pHandler); + + // writing out the page masters + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML) + _writeMasterPages(pHandler); + + if (streamType == ODF_FLAT_XML || streamType == ODF_CONTENT_XML) + { + ODFGEN_DEBUG_MSG(("OdsGenerator: Document Body: Writing out the document..\n")); + // writing out the document + TagOpenElement("office:body").write(pHandler); + TagOpenElement("office:spreadsheet").write(pHandler); + sendStorage(&mBodyStorage, pHandler); + pHandler->endElement("office:spreadsheet"); + pHandler->endElement("office:body"); + ODFGEN_DEBUG_MSG(("OdsGenerator: Document Body: Finished writing all doc els..\n")); + } + pHandler->endElement(documentType.c_str()); + + pHandler->endDocument(); + + return true; +} + + +void OdsGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->setDocumentMetaData(propList); +} + +void OdsGenerator::defineEmbeddedFont(const librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me +} + +void OdsGenerator::openPageSpan(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_PageSpan); + if (!mpImpl->checkOutsideOdc("openPageSpan") || !mpImpl->checkOutsideOdt("openPageSpan")) + return; + PageSpan *pPageSpan = new PageSpan(propList); + mpImpl->mPageSpans.push_back(pPageSpan); + mpImpl->mpCurrentPageSpan = pPageSpan; + mpImpl->miNumPageStyles++; +} + +void OdsGenerator::closePageSpan() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_PageSpan)) return; +} + +void OdsGenerator::defineSheetNumberingStyle(const librevenge::RVNGPropertyList &propList) +{ + if (!mpImpl->getState().mbInSheet || !mpImpl->mSheetManager.actualSheet()) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::defineSheetNumberingStyle can not be called outside a sheet!!!\n")); + return; + } + mpImpl->mSheetManager.actualSheet()->addNumberingStyle(propList); +} + +void OdsGenerator::openSheet(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Sheet); + OdsGeneratorPrivate::State state=mpImpl->getState(); + state.mbInSheet=false; + mpImpl->pushState(state); + if (!mpImpl->checkOutsideOdc("openSheet") || !mpImpl->checkOutsideOdt("openSheet")) + return; + if (state.mbInSheet || state.mbInFrame || state.mbInFootnote || state.mbInComment || state.mbInHeaderFooter || + mpImpl->mSheetManager.isSheetOpened()) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openSheet can not be called!!!\n")); + return; + } + + librevenge::RVNGPropertyList finalPropList(propList); + librevenge::RVNGString sPageStyleName; + sPageStyleName.sprintf("Page_Style_%i", mpImpl->miNumPageStyles); + finalPropList.insert("style:master-page-name", sPageStyleName); + if (!mpImpl->mSheetManager.openSheet(finalPropList)) return; + mpImpl->getState().mbInSheet=true; + + SheetStyle *style=mpImpl->mSheetManager.actualSheet(); + if (!style) return; + librevenge::RVNGString sTableName(style->getName()); + TagOpenElement *pTableOpenElement = new TagOpenElement("table:table"); + if (propList["librevenge:sheet-name"]) + pTableOpenElement->addAttribute("table:name", propList["librevenge:sheet-name"]->getStr()); + else + pTableOpenElement->addAttribute("table:name", sTableName.cstr()); + pTableOpenElement->addAttribute("table:style-name", sTableName.cstr()); + mpImpl->getCurrentStorage()->push_back(pTableOpenElement); + + /* TODO: open a table:shapes element + a environment to store the table content which must be merged in closeSheet + */ + for (int i=0; i< style->getNumColumns(); ++i) + { + TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column"); + librevenge::RVNGString sColumnStyleName; + sColumnStyleName.sprintf("%s_col%i", sTableName.cstr(), (i+1)); + pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr()); + mpImpl->getCurrentStorage()->push_back(pTableColumnOpenElement); + + TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column"); + mpImpl->getCurrentStorage()->push_back(pTableColumnCloseElement); + } +} + +void OdsGenerator::closeSheet() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Sheet)) + return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState || !state.mbInSheet) return; + if (state.mbInSheetShapes) + { + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:shapes")); + mpImpl->getState().mbInSheetShapes=false; + } + mpImpl->mSheetManager.closeSheet(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table")); +} + +void OdsGenerator::openSheetRow(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_SheetRow); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + SheetStyle *style=mpImpl->mSheetManager.actualSheet(); + + if (!state.mbInSheet || state.mbInComment || !style) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openSheetRow can not be called!!!\n")); + return; + } + if (state.mbInSheetShapes) + { + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:shapes")); + mpImpl->getState().mbInSheetShapes=false; + } + + // check if we need to add some empty row + int row = propList["librevenge:row"] ? propList["librevenge:row"]->getInt() : -1; + if (row > state.miLastSheetRow) + { + librevenge::RVNGString sEmptyRowStyleName=style->addRow(librevenge::RVNGPropertyList()); + + TagOpenElement *pEmptyRowOpenElement = new TagOpenElement("table:table-row"); + pEmptyRowOpenElement->addAttribute("table:style-name", sEmptyRowStyleName); + librevenge::RVNGString numEmpty; + numEmpty.sprintf("%d", row-state.miLastSheetRow); + pEmptyRowOpenElement->addAttribute("table:number-rows-repeated", numEmpty); + + mpImpl->getCurrentStorage()->push_back(pEmptyRowOpenElement); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("table:table-cell")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-cell")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-row")); + } + else + row=state.miLastSheetRow; + mpImpl->getState().miLastSheetRow=row+1; + + state.miLastSheetColumn=0; + state.mbInSheetRow=state.mbFirstInSheetRow=true; + mpImpl->pushState(state); + + librevenge::RVNGString sSheetRowStyleName=style->addRow(propList); + TagOpenElement *pSheetRowOpenElement = new TagOpenElement("table:table-row"); + pSheetRowOpenElement->addAttribute("table:style-name", sSheetRowStyleName); + mpImpl->getCurrentStorage()->push_back(pSheetRowOpenElement); +} + +void OdsGenerator::closeSheetRow() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_SheetRow) || mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + if (!state.mbInSheetRow) return; + if (state.mbFirstInSheetRow) + { + TagOpenElement *pSheetCellOpenElement = new TagOpenElement("table:table-cell"); + pSheetCellOpenElement->addAttribute("table:number-columns-repeated","1"); + mpImpl->getCurrentStorage()->push_back(pSheetCellOpenElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-cell")); + } + mpImpl->popState(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-row")); +} + +void OdsGenerator::openSheetCell(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_SheetCell); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + SheetStyle *style=mpImpl->mSheetManager.actualSheet(); + + if (!state.mbInSheetRow || state.mbInComment || !style) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openSheetCell can not be called!!!\n")); + return; + } + mpImpl->getState().mbFirstInSheetRow=false; + // check if we need to add empty column + int col = propList["librevenge:column"] ? propList["librevenge:column"]->getInt() : -1; + if (col > state.miLastSheetColumn) + { + TagOpenElement *pEmptyElement = new TagOpenElement("table:table-cell"); + librevenge::RVNGString numEmpty; + numEmpty.sprintf("%d", col-state.miLastSheetColumn); + pEmptyElement->addAttribute("table:number-columns-repeated", numEmpty); + mpImpl->getCurrentStorage()->push_back(pEmptyElement); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-cell")); + } + else + col=state.miLastSheetColumn; + mpImpl->getState().miLastSheetColumn=col+1; + + state.mbInSheetCell=true; + mpImpl->pushState(state); + + if (propList["style:font-name"]) + mpImpl->getFontManager().findOrAdd(propList["style:font-name"]->getStr().cstr()); + librevenge::RVNGString sSheetCellStyleName=style->addCell(propList); + + TagOpenElement *pSheetCellOpenElement = new TagOpenElement("table:table-cell"); + pSheetCellOpenElement->addAttribute("table:style-name", sSheetCellStyleName); + + if (propList["librevenge:value-type"]) + { + std::string valueType(propList["librevenge:value-type"]->getStr().cstr()); + if (valueType=="double" || valueType=="scientific") valueType="float"; + else if (valueType=="percent") valueType="percentage"; + if (valueType=="float" || valueType=="percentage" || valueType=="currency") + { + pSheetCellOpenElement->addAttribute("calcext:value-type", valueType.c_str()); + pSheetCellOpenElement->addAttribute("office:value-type", valueType.c_str()); + if (propList["librevenge:value"]) + { + if (!strncmp(propList["librevenge:value"]->getStr().cstr(),"nan",3) || + !strncmp(propList["librevenge:value"]->getStr().cstr(),"NAN",3)) + { + pSheetCellOpenElement->addAttribute("office:string-value", ""); + pSheetCellOpenElement->addAttribute("office:value-type", "string"); + pSheetCellOpenElement->addAttribute("calcext:value-type", "error"); + } + else + { + pSheetCellOpenElement->addAttribute("office:value-type", valueType.c_str()); + pSheetCellOpenElement->addAttribute("office:value", propList["librevenge:value"]->getStr().cstr()); + } + } + } + else if (valueType=="string" || valueType=="text") + { + pSheetCellOpenElement->addAttribute("office:value-type", "string"); + pSheetCellOpenElement->addAttribute("calcext:value-type", "string"); + } + else if (valueType=="bool" || valueType=="boolean") + { + pSheetCellOpenElement->addAttribute("office:value-type", "boolean"); + pSheetCellOpenElement->addAttribute("calcext:value-type", "boolean"); + if (propList["librevenge:value"]) + pSheetCellOpenElement->addAttribute("office:boolean-value", propList["librevenge:value"]->getStr().cstr()); + } + else if (valueType=="date") + { + pSheetCellOpenElement->addAttribute("office:value-type", "date"); + pSheetCellOpenElement->addAttribute("calcext:value-type", "date"); + if (propList["librevenge:day"] && propList["librevenge:month"] && propList["librevenge:year"]) + { + librevenge::RVNGString date; + if (propList["librevenge:hours"]) + { + int minute=propList["librevenge:minutes"] ? propList["librevenge:minutes"]->getInt() : 0; + int second=propList["librevenge:seconds"] ? propList["librevenge:seconds"]->getInt() : 0; + date.sprintf("%04d-%02d-%02dT%02d:%02d:%02d", propList["librevenge:year"]->getInt(), + propList["librevenge:month"]->getInt(), propList["librevenge:day"]->getInt(), + propList["librevenge:hours"]->getInt(), minute, second); + } + else + date.sprintf("%04d-%02d-%02d", propList["librevenge:year"]->getInt(), + propList["librevenge:month"]->getInt(), propList["librevenge:day"]->getInt()); + pSheetCellOpenElement->addAttribute("office:date-value", date); + } + } + else if (valueType=="time") + { + pSheetCellOpenElement->addAttribute("office:value-type", "time"); + pSheetCellOpenElement->addAttribute("calcext:value-type", "time"); + if (propList["librevenge:hours"]) + { + int minute=propList["librevenge:minutes"] ? propList["librevenge:minutes"]->getInt() : 0; + int second=propList["librevenge:seconds"] ? propList["librevenge:seconds"]->getInt() : 0; + librevenge::RVNGString time; + time.sprintf("PT%02dH%02dM%02dS", propList["librevenge:hours"]->getInt(), minute, second); + pSheetCellOpenElement->addAttribute("office:time-value", time); + } + } + else + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openSheetCell: unexpected value type: %s\n", valueType.c_str())); + } + } + librevenge::RVNGPropertyListVector const *formula=propList.child("librevenge:formula"); + if (formula) + { + librevenge::RVNGString finalFormula=SheetManager::convertFormula(*formula); + if (!finalFormula.empty()) + pSheetCellOpenElement->addAttribute("table:formula", finalFormula); + } + mpImpl->getCurrentStorage()->push_back(pSheetCellOpenElement); +} + +void OdsGenerator::closeSheetCell() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_SheetCell) || mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + if (!mpImpl->getState().mbInSheetCell) return; + + mpImpl->popState(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("table:table-cell")); +} + +void OdsGenerator::defineChartStyle(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->defineChartStyle(propList); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().defineChartStyle(propList); +} + +void OdsGenerator::openChart(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Chart); + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->pushState(state); + if (!mpImpl->checkOutsideOdc("openChart") || !mpImpl->checkOutsideOdt("openChart")) + return; + if (!state.mbFirstInFrame) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openChart must be called in a frame!!!\n")); + return; + } + if (mpImpl->createAuxiliarOdcGenerator()) + { + mpImpl->getState().mbInChart=true; + mpImpl->getState().mbNewOdcGenerator=true; + return mpImpl->mAuxiliarOdcState->get().openChart(propList); + } +} + +void OdsGenerator::closeChart() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Chart)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) return; + if (state.mbNewOdcGenerator) + { + mpImpl->mAuxiliarOdcState->get().closeChart(); + mpImpl->sendAuxiliarOdcGenerator(); + mpImpl->resetAuxiliarOdcGenerator(); + } +} + +void OdsGenerator::openChartPlotArea(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_ChartPlotArea); + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->pushState(state); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openChartPlotArea called outside chart!!!\n")); + return; + } + mpImpl->mAuxiliarOdcState->get().openChartPlotArea(propList); +} + +void OdsGenerator::closeChartPlotArea() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_ChartPlotArea)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) return; + mpImpl->mAuxiliarOdcState->get().closeChartPlotArea(); +} + +void OdsGenerator::openChartTextObject(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_ChartTextObject); + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->pushState(state); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openChartTextObject called outside chart!!!\n")); + return; + } + mpImpl->mAuxiliarOdcState->get().openChartTextObject(propList); +} + +void OdsGenerator::closeChartTextObject() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_ChartTextObject)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) return; + mpImpl->mAuxiliarOdcState->get().closeChartTextObject(); +} + +void OdsGenerator::insertChartAxis(const librevenge::RVNGPropertyList &axis) +{ + if (mpImpl->mAuxiliarOdtState) return; + if (!mpImpl->mAuxiliarOdcState || !mpImpl->getState().mbInChart) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::insertChartAxis call outside chart\n")); + return; + } + mpImpl->mAuxiliarOdcState->get().insertChartAxis(axis); +} + +void OdsGenerator::openChartSerie(const librevenge::RVNGPropertyList &serie) +{ + mpImpl->open(OdsGeneratorPrivate::C_ChartSerie); + if (!mpImpl->mAuxiliarOdcState || !mpImpl->getState().mbInChart) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openChartSerie call outside chart\n")); + return; + } + mpImpl->mAuxiliarOdcState->get().openChartSerie(serie); +} + +void OdsGenerator::closeChartSerie() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_ChartSerie)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + if (!mpImpl->mAuxiliarOdcState || !state.mbInChart) return; + mpImpl->mAuxiliarOdcState->get().closeChartSerie(); +} + +void OdsGenerator::openHeader(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Header); + OdsGeneratorPrivate::State state=mpImpl->getState(); + state.mbInHeaderFooter=true; + mpImpl->pushState(state); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + + if (!mpImpl->mpCurrentPageSpan) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openHeader oops can not find the page span\n")); + return; + } + std::vector *pHeaderFooterContentElements = new std::vector; + if (propList["librevenge:occurrence"] && (propList["librevenge:occurrence"]->getStr() == "even" || + propList["librevenge:occurrence"]->getStr() == "left")) + mpImpl->mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "first") + mpImpl->mpCurrentPageSpan->setHeaderFirstContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "last") + mpImpl->mpCurrentPageSpan->setHeaderLastContent(pHeaderFooterContentElements); + else + mpImpl->mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements); + mpImpl->pushStorage(pHeaderFooterContentElements); +} + +void OdsGenerator::closeHeader() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Header)) return; + mpImpl->popState(); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + + if (!mpImpl->mpCurrentPageSpan) return; + mpImpl->popStorage(); +} + +void OdsGenerator::openFooter(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Footer); + OdsGeneratorPrivate::State state=mpImpl->getState(); + state.mbInHeaderFooter=true; + mpImpl->pushState(state); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + + if (!mpImpl->mpCurrentPageSpan) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openFooter oops can not find the page span\n")); + return; + } + std::vector *pHeaderFooterContentElements = new std::vector; + if (propList["librevenge:occurrence"] && (propList["librevenge:occurrence"]->getStr() == "even" || + propList["librevenge:occurrence"]->getStr() == "left")) + mpImpl->mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "first") + mpImpl->mpCurrentPageSpan->setFooterFirstContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "last") + mpImpl->mpCurrentPageSpan->setFooterLastContent(pHeaderFooterContentElements); + else + mpImpl->mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements); + mpImpl->pushStorage(pHeaderFooterContentElements); +} + +void OdsGenerator::closeFooter() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Footer)) return; + mpImpl->popState(); + if (mpImpl->mAuxiliarOdcState || mpImpl->mAuxiliarOdtState) return; + + if (!mpImpl->mpCurrentPageSpan) return; + mpImpl->popStorage(); +} + +void OdsGenerator::openSection(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Section); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openSection(propList); + ODFGEN_DEBUG_MSG(("OdsGenerator::openSection ignored\n")); +} + +void OdsGenerator::closeSection() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Section)) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeSection(); +} + +void OdsGenerator::defineParagraphStyle(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->defineParagraphStyle(propList); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().defineParagraphStyle(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().defineParagraphStyle(propList); +} + +void OdsGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Paragraph); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openParagraph(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openParagraph(propList); + + if (!mpImpl->canWriteText()) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openParagraph: calls outside a text zone\n")); + return; + } + + librevenge::RVNGPropertyList finalPropList(propList); + if (mpImpl->getState().mbInSheetCell) + finalPropList.insert("style:parent-style-name", "Table_Contents"); + else + finalPropList.insert("style:parent-style-name", "Standard"); + mpImpl->openParagraph(finalPropList); +} + +void OdsGenerator::closeParagraph() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Paragraph)) return; + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().closeParagraph(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeParagraph(); + if (!mpImpl->canWriteText()) + return; + mpImpl->closeParagraph(); +} + +void OdsGenerator::defineCharacterStyle(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->defineCharacterStyle(propList); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().defineCharacterStyle(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().defineCharacterStyle(propList); +} + +void OdsGenerator::openSpan(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Span); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openSpan(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openSpan(propList); + + if (!mpImpl->canWriteText()) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openSpan: not in text part\n")); + return; + } + mpImpl->openSpan(propList); +} + +void OdsGenerator::closeSpan() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Span)) return; + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().closeSpan(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeSpan(); + if (!mpImpl->canWriteText()) return; + mpImpl->closeSpan(); +} + +void OdsGenerator::openLink(const librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openLink(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openLink(propList); + mpImpl->openLink(propList); +} + +void OdsGenerator::closeLink() +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().closeLink(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeLink(); + mpImpl->closeLink(); +} + + +void OdsGenerator::openOrderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_OrderedList); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openOrderedListLevel(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openOrderedListLevel(propList); + if (mpImpl->canWriteText() && !mpImpl->getState().mbInSheetCell) + return mpImpl->openListLevel(propList,true); + ODFGEN_DEBUG_MSG(("OdsGenerator::openOrderedListLevel: call outside a text zone\n")); +} + +void OdsGenerator::openUnorderedListLevel(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_UnorderedList); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openUnorderedListLevel(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openUnorderedListLevel(propList); + if (mpImpl->canWriteText() && !mpImpl->getState().mbInSheetCell) + return mpImpl->openListLevel(propList,false); + ODFGEN_DEBUG_MSG(("OdsGenerator::openUnorderedListLevel: call outside a text zone\n")); +} + +void OdsGenerator::closeOrderedListLevel() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_OrderedList)) return; + if (mpImpl->mAuxiliarOdcState) + mpImpl->mAuxiliarOdcState->get().closeOrderedListLevel(); + if (mpImpl->mAuxiliarOdtState) + mpImpl->mAuxiliarOdtState->get().closeOrderedListLevel(); + if (mpImpl->canWriteText() && !mpImpl->getState().mbInSheetCell) + return mpImpl->closeListLevel(); +} + +void OdsGenerator::closeUnorderedListLevel() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_UnorderedList)) return; + if (mpImpl->mAuxiliarOdcState) + mpImpl->mAuxiliarOdcState->get().closeUnorderedListLevel(); + if (mpImpl->mAuxiliarOdtState) + mpImpl->mAuxiliarOdtState->get().closeUnorderedListLevel(); + if (mpImpl->canWriteText() && !mpImpl->getState().mbInSheetCell) + return mpImpl->closeListLevel(); +} + +void OdsGenerator::openListElement(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_ListElement); + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().openListElement(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openListElement(propList); + if (mpImpl->canWriteText()) + { + if (mpImpl->getState().mbInSheetCell) + return mpImpl->openParagraph(propList); + return mpImpl->openListElement(propList); + } + + ODFGEN_DEBUG_MSG(("OdsGenerator::openListElement call outside a text zone\n")); + return; +} + +void OdsGenerator::closeListElement() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_ListElement)) return; + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().closeListElement(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeListElement(); + if (mpImpl->canWriteText()) + { + if (mpImpl->getState().mbInSheetCell) + return mpImpl->closeParagraph(); + return mpImpl->closeListElement(); + } +} + +void OdsGenerator::openFootnote(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Footnote); + OdsGeneratorPrivate::State state=mpImpl->getState(); + state.mbInFootnote=true; + mpImpl->pushState(state); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openFootnote(propList); + ODFGEN_DEBUG_MSG(("OdsGenerator::openFootnote ignored\n")); +} + +void OdsGenerator::closeFootnote() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Footnote)) return; + mpImpl->popState(); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeFootnote(); +} + +void OdsGenerator::openComment(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Comment); + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->getState().mbInComment=false; + mpImpl->pushState(state); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openComment(propList); + if (!mpImpl->checkOutsideOdc("openComment")) + return; + if (!state.mbInSheetCell) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openComment call outside a sheet cell!!!\n")); + return; + } + + mpImpl->getState().mbInComment=true; + mpImpl->pushListState(); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("office:annotation")); +} + +void OdsGenerator::closeComment() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Comment)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeComment(); + + if (mpImpl->mAuxiliarOdcState || !state.mbInComment) return; + mpImpl->popListState(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("office:annotation")); +} + +void OdsGenerator::openTable(const librevenge::RVNGPropertyList &propList) +{ + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->open(OdsGeneratorPrivate::C_Table); + state.mbInTable=true; + mpImpl->pushState(state); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openTable(propList); + if (!mpImpl->checkOutsideOdc("openTable")) + return; + if (!state.mbInFrame) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openTable a table must be in a frame!!!\n")); + return; + } + if (mpImpl->createAuxiliarOdtGenerator()) + { + mpImpl->getState().mbNewOdtGenerator=true; + return mpImpl->mAuxiliarOdtState->get().openTable(propList); + } +} + +void OdsGenerator::closeTable() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Table)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popState(); + if (mpImpl->mAuxiliarOdcState || !state.mbInTable || !mpImpl->mAuxiliarOdtState) return; + mpImpl->mAuxiliarOdtState->get().closeTable(); + if (state.mbNewOdtGenerator) + { + mpImpl->sendAuxiliarOdtGenerator(); + mpImpl->resetAuxiliarOdtGenerator(); + } +} + +void OdsGenerator::openTableRow(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_TableRow); + if (mpImpl->mAuxiliarOdcState) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openTableRow(propList); +} + +void OdsGenerator::closeTableRow() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_TableRow)) return; + if (mpImpl->mAuxiliarOdcState) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeTableRow(); +} + +void OdsGenerator::openTableCell(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_TableCell); + if (mpImpl->mAuxiliarOdcState) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openTableCell(propList); +} + +void OdsGenerator::closeTableCell() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_TableCell)) return; + if (mpImpl->mAuxiliarOdcState) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeTableCell(); +} + +void OdsGenerator::insertCoveredTableCell(const librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdcState) return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertCoveredTableCell(propList); +} + + +void OdsGenerator::insertTab() +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().insertTab(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertTab(); + if (!mpImpl->canWriteText()) + return; + mpImpl->insertTab(); +} + +void OdsGenerator::insertSpace() +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().insertSpace(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertSpace(); + if (!mpImpl->canWriteText()) + return; + mpImpl->insertSpace(); +} + +void OdsGenerator::insertLineBreak() +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().insertLineBreak(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertLineBreak(); + if (!mpImpl->canWriteText()) + return; + mpImpl->insertLineBreak(mpImpl->getState().mbInSheetCell); +} + +void OdsGenerator::insertField(const librevenge::RVNGPropertyList &propList) +{ + if (!propList["librevenge:field-type"] || propList["librevenge:field-type"]->getStr().empty()) + return; + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().insertField(propList); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertField(propList); + mpImpl->insertField(propList); +} + +void OdsGenerator::insertText(const librevenge::RVNGString &text) +{ + if (mpImpl->mAuxiliarOdcState) + return mpImpl->mAuxiliarOdcState->get().insertText(text); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertText(text); + if (mpImpl->canWriteText()) + return mpImpl->insertText(text); + ODFGEN_DEBUG_MSG(("OdsGenerator::insertText ignored\n")); +} + +void OdsGenerator::openFrame(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Frame); + OdsGeneratorPrivate::State &prevState=mpImpl->getState(); + OdsGeneratorPrivate::State state=prevState; + state.mbInFrame=state.mbFirstInFrame=true; + mpImpl->pushState(state); + mpImpl->pushListState(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openFrame(propList); + if (!mpImpl->checkOutsideOdc("openFrame")) + return; + if (!state.mbInSheet || state.mbInComment) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openFrame call outside a sheet!!!\n")); + return; + } + + if (!state.mbInSheetRow && !state.mbInSheetShapes) + { + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("table:shapes")); + mpImpl->getState().mbInSheetShapes=prevState.mbInSheetShapes=true; + } + + librevenge::RVNGPropertyList pList(propList); + if (!propList["text:anchor-type"]) + pList.insert("text:anchor-type","paragraph"); + mpImpl->openFrame(pList); +} + +void OdsGenerator::closeFrame() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Frame)) return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popListState(); + mpImpl->popState(); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeFrame(); + if (mpImpl->mAuxiliarOdcState || !state.mbInFrame) return; + mpImpl->closeFrame(); +} + +void OdsGenerator::insertBinaryObject(const librevenge::RVNGPropertyList &propList) +{ + // Embedded objects without a frame simply don't make sense for us + if (!mpImpl->getState().mbFirstInFrame) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::insertBinaryObject: called outsided a frame\n")); + return; + } + mpImpl->getState().mbFirstInFrame=false; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().insertBinaryObject(propList); + if (!mpImpl->checkOutsideOdc("insertBinaryObject")) + return; + mpImpl->insertBinaryObject(propList); +} + +void OdsGenerator::openTextBox(const librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_TextBox); + + OdsGeneratorPrivate::State state=mpImpl->getState(); + // Text box without a frame simply doesn't make sense for us + if (!state.mbInFrame || !state.mbFirstInFrame) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::openTextBox: called without frame\n")); + return; + } + mpImpl->getState().mbFirstInFrame=false; + mpImpl->pushState(state); + mpImpl->pushListState(); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openTextBox(propList); + if (!mpImpl->checkOutsideOdc("openTextBox")) + return; + + TagOpenElement *textBoxOpenElement = new TagOpenElement("draw:text-box"); + if (propList["librevenge:next-frame-name"]) + { + librevenge::RVNGString frameName; + unsigned id=mpImpl->getFrameId(propList["librevenge:next-frame-name"]->getStr()); + frameName.sprintf("Object%i", id); + textBoxOpenElement->addAttribute("draw:chain-next-name", frameName); + } + mpImpl->getCurrentStorage()->push_back(textBoxOpenElement); + mpImpl->getState().mbInTextBox = true; +} + +void OdsGenerator::closeTextBox() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_TextBox)) + return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + mpImpl->popListState(); + mpImpl->popState(); + + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeTextBox(); + if (mpImpl->mAuxiliarOdcState || !state.mbInTextBox) + return; + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:text-box")); +} + +void OdsGenerator::startDocument(const librevenge::RVNGPropertyList &) +{ + if (mpImpl->getState().mbStarted) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::startDocument: document already started\n")); + return; + } + mpImpl->getState().mbStarted=true; + mpImpl->open(OdsGeneratorPrivate::C_Document); +} + +void OdsGenerator::endDocument() +{ + if (!mpImpl->getState().mbStarted) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::endDocument: document not started\n")); + return; + } + if (mpImpl->mAuxiliarOdcState) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::endDocument: auxiliar odc generator is open\n")); + return; + } + if (mpImpl->mAuxiliarOdtState) + { + ODFGEN_DEBUG_MSG(("OdsGenerator::endDocument: auxiliar odt generator is open\n")); + return; + } + mpImpl->getState().mbStarted=false; + + if (!mpImpl->close(OdsGeneratorPrivate::C_Document)) return; + // Write out the collected document + mpImpl->writeTargetDocuments(); +} + + +void OdsGenerator::openGroup(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->open(OdsGeneratorPrivate::C_Group); + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().openGroup(propList); + if (!mpImpl->checkOutsideOdc("openGroup") || !mpImpl->canAddNewShape()) + return; + OdsGeneratorPrivate::State state=mpImpl->getState(); + state.mbInGroup=true; + mpImpl->pushState(state); + mpImpl->openGroup(propList); +} + +void OdsGenerator::closeGroup() +{ + if (!mpImpl->close(OdsGeneratorPrivate::C_Group)) + return; + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().closeGroup(); + if (mpImpl->mAuxiliarOdcState || !mpImpl->getState().mbInGroup) + return; + mpImpl->popState(); + mpImpl->closeGroup(); +} + +void OdsGenerator::defineGraphicStyle(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().defineGraphicStyle(propList); + mpImpl->defineGraphicStyle(propList); +} + +void OdsGenerator::drawRectangle(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().drawRectangle(propList); + if (!mpImpl->checkOutsideOdc("drawRectangle") || !mpImpl->canAddNewShape()) + return; + mpImpl->drawRectangle(propList); +} + +void OdsGenerator::drawEllipse(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().drawEllipse(propList); + if (!mpImpl->checkOutsideOdc("drawEllipse") || !mpImpl->canAddNewShape()) + return; + mpImpl->drawEllipse(propList); +} + + +void OdsGenerator::drawPolygon(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().drawPolygon(propList); + if (!mpImpl->checkOutsideOdc("drawPolygon") || !mpImpl->canAddNewShape()) + return; + mpImpl->drawPolySomething(propList, true); +} + + +void OdsGenerator::drawPolyline(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().drawPolyline(propList); + if (!mpImpl->checkOutsideOdc("drawPolyline") || !mpImpl->canAddNewShape()) + return; + mpImpl->drawPolySomething(propList, false); +} + + +void OdsGenerator::drawPath(const ::librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->mAuxiliarOdtState) + return mpImpl->mAuxiliarOdtState->get().drawPath(propList); + if (!mpImpl->checkOutsideOdc("drawPath") || !mpImpl->canAddNewShape()) + return; + mpImpl->drawPath(propList); +} + +void OdsGenerator::drawConnector(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawConnector(propList); +} + +void OdsGenerator::initStateWith(OdfGenerator const &orig) +{ + mpImpl->initStateWith(orig); +} + +void OdsGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler) +{ + mpImpl->registerEmbeddedImageHandler(mimeType, imageHandler); +} + +void OdsGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler) +{ + mpImpl->registerEmbeddedObjectHandler(mimeType, objectHandler); +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/OdtGenerator.cxx libodfgen-0.1.1/src/OdtGenerator.cxx --- libodfgen-0.0.4/src/OdtGenerator.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/OdtGenerator.cxx 2014-05-22 18:28:12.000000000 +0000 @@ -24,7 +24,7 @@ * Corel Corporation or Corel Corporation Limited." */ -#include +#include #include #include #include @@ -36,206 +36,100 @@ #include "TextRunStyle.hxx" #include "FontStyle.hxx" #include "ListStyle.hxx" +#include "OdfGenerator.hxx" #include "PageSpan.hxx" #include "SectionStyle.hxx" #include "TableStyle.hxx" #include "FilterInternal.hxx" #include "InternalHandler.hxx" -// the state we use for writing the final document -struct WriterDocumentState -{ - WriterDocumentState(); - - bool mbFirstElement; - bool mbFirstParagraphInPageSpan; - bool mbInFakeSection; - bool mbListElementOpenedAtCurrentLevel; - bool mbTableCellOpened; - bool mbHeaderRow; - bool mbInNote; - bool mbInTextBox; - bool mbInFrame; -}; - -// list state -struct WriterListState -{ - WriterListState(); - WriterListState(const WriterListState &state); - - ListStyle *mpCurrentListStyle; - unsigned int miCurrentListLevel; - unsigned int miLastListLevel; - unsigned int miLastListNumber; - bool mbListContinueNumbering; - bool mbListElementParagraphOpened; - std::stack mbListElementOpened; - // a map id -> last list style defined with such id - std::map mIdListStyleMap; -private: - WriterListState &operator=(const WriterListState &state); -}; - -enum WriterListType { unordered, ordered }; -WriterDocumentState::WriterDocumentState() : - mbFirstElement(true), - mbFirstParagraphInPageSpan(true), - mbInFakeSection(false), - mbListElementOpenedAtCurrentLevel(false), - mbTableCellOpened(false), - mbHeaderRow(false), - mbInNote(false), - mbInTextBox(false), - mbInFrame(false) -{ -} - -WriterListState::WriterListState() : - mpCurrentListStyle(0), - miCurrentListLevel(0), - miLastListLevel(0), - miLastListNumber(0), - mbListContinueNumbering(false), - mbListElementParagraphOpened(false), - mbListElementOpened(), - mIdListStyleMap() -{ -} - -WriterListState::WriterListState(const WriterListState &state) : - mpCurrentListStyle(state.mpCurrentListStyle), - miCurrentListLevel(state.miCurrentListLevel), - miLastListLevel(state.miCurrentListLevel), - miLastListNumber(state.miLastListNumber), - mbListContinueNumbering(state.mbListContinueNumbering), - mbListElementParagraphOpened(state.mbListElementParagraphOpened), - mbListElementOpened(state.mbListElementOpened), - mIdListStyleMap(state.mIdListStyleMap) -{ -} - -class OdtGeneratorPrivate +class OdtGeneratorPrivate : public OdfGenerator { public: - OdtGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType); + OdtGeneratorPrivate(); ~OdtGeneratorPrivate(); - bool _writeTargetDocument(OdfDocumentHandler *pHandler); - void _writeDefaultStyles(OdfDocumentHandler *pHandler); + + bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType); + void _writeStyles(OdfDocumentHandler *pHandler); + void _writeAutomaticStyles(OdfDocumentHandler *pHandler); void _writeMasterPages(OdfDocumentHandler *pHandler); void _writePageLayouts(OdfDocumentHandler *pHandler); - void _openListLevel(TagOpenElement *pListLevelOpenElement); - void _closeListLevel(); - - /** stores a list style: update mListStyles, - mWriterListStates.top().mpCurrentListStyle and the different - maps - */ - void _storeListStyle(ListStyle *listStyle); - /** retrieves the list style corresponding to a given id. */ - void _retrieveListStyle(int id); - - OdfEmbeddedObject _findEmbeddedObjectHandler(const WPXString &mimeType); - OdfEmbeddedImage _findEmbeddedImageHandler(const WPXString &mimeType); - unsigned _getObjectId(WPXString val=""); - - OdfDocumentHandler *mpHandler; - bool mbUsed; // whether or not it has been before (you can only use me once!) - - std::stack mWriterDocumentStates; - - std::stack mWriterListStates; - - // paragraph styles - ParagraphStyleManager mParagraphManager; + // + // state gestion + // + + // the state we use for writing the final document + struct State + { + State() : mbFirstElement(true), mbFirstParagraphInPageSpan(true), + mbInFakeSection(false), mbListElementOpenedAtCurrentLevel(false), + mbTableCellOpened(false), mbInNote(false), + mbInTextBox(false), mbInFrame(false) + { + } - // span styles - SpanStyleManager mSpanManager; + bool mbFirstElement; + bool mbFirstParagraphInPageSpan; + bool mbInFakeSection; + bool mbListElementOpenedAtCurrentLevel; + bool mbTableCellOpened; + bool mbInNote; + bool mbInTextBox; + bool mbInFrame; + }; - // font styles - FontStyleManager mFontManager; + // returns the actual state + State &getState() + { + if (mStateStack.empty()) + { + ODFGEN_DEBUG_MSG(("OdtGeneratorPrivate::getState: no state\n")); + mStateStack.push(State()); + } + return mStateStack.top(); + } + // push a state + void pushState() + { + mStateStack.push(State()); + } + // pop a state + void popState() + { + if (!mStateStack.empty()) + mStateStack.pop(); + else + { + ODFGEN_DEBUG_MSG(("OdtGeneratorPrivate::popState: no state\n")); + } + } + std::stack mStateStack; // section styles std::vector mSectionStyles; - // table styles - std::vector mTableStyles; - - // frame styles - std::vector mFrameStyles; - - std::vector mFrameAutomaticStyles; - - std::map mFrameIdMap; - - // embedded object handlers - std::map mObjectHandlers; - std::map mImageHandlers; - - // metadata - std::vector mMetaData; - - // list styles - unsigned int miNumListStyles; - - // content elements - std::vector mBodyElements; - // the current set of elements that we're writing to - std::vector *mpCurrentContentElements; - // page state std::vector mPageSpans; PageSpan *mpCurrentPageSpan; int miNumPageStyles; - // list styles - std::vector mListStyles; - // a map id -> last list style defined with id - std::map mIdListStyleMap; - - // object state - unsigned miObjectNumber; - - // table state - TableStyle *mpCurrentTableStyle; - - const OdfStreamType mxStreamType; - - const char *mpPassword; - private: OdtGeneratorPrivate(const OdtGeneratorPrivate &); OdtGeneratorPrivate &operator=(const OdtGeneratorPrivate &); }; -OdtGeneratorPrivate::OdtGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType) : - mpHandler(pHandler), - mbUsed(false), - mWriterDocumentStates(), - mWriterListStates(), - mParagraphManager(), mSpanManager(), mFontManager(), - mSectionStyles(), mTableStyles(), - mFrameStyles(), mFrameAutomaticStyles(), mFrameIdMap(), - mObjectHandlers(), mImageHandlers(), mMetaData(), - miNumListStyles(0), - mBodyElements(), - mpCurrentContentElements(&mBodyElements), +OdtGeneratorPrivate::OdtGeneratorPrivate() : + mStateStack(), + mSectionStyles(), mPageSpans(), mpCurrentPageSpan(0), - miNumPageStyles(0), - mListStyles(), - mIdListStyleMap(), - miObjectNumber(0), - mpCurrentTableStyle(0), - mxStreamType(streamType), - mpPassword(0) + miNumPageStyles(0) { - mWriterDocumentStates.push(WriterDocumentState()); - mWriterListStates.push(WriterListState()); + pushState(); } OdtGeneratorPrivate::~OdtGeneratorPrivate() @@ -244,169 +138,202 @@ ODFGEN_DEBUG_MSG(("OdtGenerator: Cleaning up our mess..\n")); ODFGEN_DEBUG_MSG(("OdtGenerator: Destroying the body elements\n")); - for (std::vector::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); ++iterBody) - { - delete (*iterBody); - (*iterBody) = 0; - } - - mParagraphManager.clean(); - mSpanManager.clean(); - mFontManager.clean(); - - for (std::vector::iterator iterListStyles = mListStyles.begin(); - iterListStyles != mListStyles.end(); ++iterListStyles) - { - delete(*iterListStyles); - } for (std::vector::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles) - { delete(*iterSectionStyles); - } - for (std::vector::iterator iterTableStyles = mTableStyles.begin(); - iterTableStyles != mTableStyles.end(); ++iterTableStyles) - { - delete((*iterTableStyles)); - } for (std::vector::iterator iterPageSpans = mPageSpans.begin(); iterPageSpans != mPageSpans.end(); ++iterPageSpans) - { delete(*iterPageSpans); - } - for (std::vector::iterator iterFrameStyles = mFrameStyles.begin(); - iterFrameStyles != mFrameStyles.end(); ++iterFrameStyles) - { - delete(*iterFrameStyles); - } - for (std::vector::iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin(); - iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles) - { - delete(*iterFrameAutomaticStyles); - } - for (std::vector::iterator iterMetaData = mMetaData.begin(); - iterMetaData != mMetaData.end(); ++iterMetaData) - { - delete(*iterMetaData); - } } -OdfEmbeddedObject OdtGeneratorPrivate::_findEmbeddedObjectHandler(const WPXString &mimeType) +void OdtGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler) { - std::map::iterator i = mObjectHandlers.find(mimeType); - if (i != mObjectHandlers.end()) - return i->second; - - return 0; -} - -OdfEmbeddedImage OdtGeneratorPrivate::_findEmbeddedImageHandler(const WPXString &mimeType) -{ - std::map::iterator i = mImageHandlers.find(mimeType); - if (i != mImageHandlers.end()) - return i->second; - - return 0; -} + TagOpenElement("office:automatic-styles").write(pHandler); + mFontManager.write(pHandler); // do nothing + mSpanManager.writeAutomaticStyles(pHandler); + mParagraphManager.writeAutomaticStyles(pHandler); + mGraphicManager.writeAutomaticStyles(pHandler); -unsigned OdtGeneratorPrivate::_getObjectId(WPXString val) -{ - bool hasLabel = val.cstr() && val.len(); - if (hasLabel && mFrameIdMap.find(val) != mFrameIdMap.end()) - return mFrameIdMap.find(val)->second; - unsigned id=miObjectNumber++; - if (hasLabel) - mFrameIdMap[val]=id; - return id; + _writePageLayouts(pHandler); + // writing out the sections styles + for (std::vector::const_iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles) + (*iterSectionStyles)->write(pHandler); + // writing out the lists styles + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + { + if (!(*iterListStyles)->hasDisplayName()) + (*iterListStyles)->write(pHandler); + } + mTableManager.write(pHandler); + pHandler->endElement("office:automatic-styles"); } -OdtGenerator::OdtGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType) : - mpImpl(new OdtGeneratorPrivate(pHandler, streamType)) +void OdtGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler) { -} + TagOpenElement("office:styles").write(pHandler); -OdtGenerator::~OdtGenerator() -{ - if (mpImpl) - delete mpImpl; -} + // style:default-style -void OdtGeneratorPrivate::_writeDefaultStyles(OdfDocumentHandler *pHandler) -{ - TagOpenElement("office:styles").write(pHandler); + // graphic + TagOpenElement defaultGraphicStyleOpenElement("style:default-style"); + defaultGraphicStyleOpenElement.addAttribute("style:family", "graphic"); + defaultGraphicStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + // paragraph TagOpenElement defaultParagraphStyleOpenElement("style:default-style"); defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph"); defaultParagraphStyleOpenElement.write(pHandler); - TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:use-window-font-color", "true"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:line-break", "strict"); defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:text-autospace", "ideograph-alpha"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:punctuation-wrap", "hanging"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:writing-mode", "page"); defaultParagraphStylePropertiesOpenElement.write(pHandler); - TagCloseElement defaultParagraphStylePropertiesCloseElement("style:paragraph-properties"); - defaultParagraphStylePropertiesCloseElement.write(pHandler); + pHandler->endElement("style:paragraph-properties"); + pHandler->endElement("style:default-style"); + // table + TagOpenElement defaultTableStyleOpenElement("style:default-style"); + defaultTableStyleOpenElement.addAttribute("style:family", "table"); + defaultTableStyleOpenElement.write(pHandler); pHandler->endElement("style:default-style"); + // table-row TagOpenElement defaultTableRowStyleOpenElement("style:default-style"); defaultTableRowStyleOpenElement.addAttribute("style:family", "table-row"); defaultTableRowStyleOpenElement.write(pHandler); - TagOpenElement defaultTableRowPropertiesOpenElement("style:table-row-properties"); defaultTableRowPropertiesOpenElement.addAttribute("fo:keep-together", "auto"); defaultTableRowPropertiesOpenElement.write(pHandler); - pHandler->endElement("style:table-row-properties"); pHandler->endElement("style:default-style"); + // table-column + TagOpenElement defaultTableColumnStyleOpenElement("style:default-style"); + defaultTableColumnStyleOpenElement.addAttribute("style:family", "table-column"); + defaultTableColumnStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // table-cell + TagOpenElement defaultTableCellStyleOpenElement("style:default-style"); + defaultTableCellStyleOpenElement.addAttribute("style:family", "table-cell"); + defaultTableCellStyleOpenElement.write(pHandler); + pHandler->endElement("style:default-style"); + + // basic style + TagOpenElement standardStyleOpenElement("style:style"); standardStyleOpenElement.addAttribute("style:name", "Standard"); standardStyleOpenElement.addAttribute("style:family", "paragraph"); standardStyleOpenElement.addAttribute("style:class", "text"); standardStyleOpenElement.write(pHandler); - - pHandler->endElement("style:style"); - - TagOpenElement textBodyStyleOpenElement("style:style"); - textBodyStyleOpenElement.addAttribute("style:name", "Text_Body"); - textBodyStyleOpenElement.addAttribute("style:display-name", "Text Body"); - textBodyStyleOpenElement.addAttribute("style:family", "paragraph"); - textBodyStyleOpenElement.addAttribute("style:parent-style-name", "Standard"); - textBodyStyleOpenElement.addAttribute("style:class", "text"); - textBodyStyleOpenElement.write(pHandler); - - pHandler->endElement("style:style"); - - TagOpenElement tableContentsStyleOpenElement("style:style"); - tableContentsStyleOpenElement.addAttribute("style:name", "Table_Contents"); - tableContentsStyleOpenElement.addAttribute("style:display-name", "Table Contents"); - tableContentsStyleOpenElement.addAttribute("style:family", "paragraph"); - tableContentsStyleOpenElement.addAttribute("style:parent-style-name", "Text_Body"); - tableContentsStyleOpenElement.addAttribute("style:class", "extra"); - tableContentsStyleOpenElement.write(pHandler); - pHandler->endElement("style:style"); - TagOpenElement tableHeadingStyleOpenElement("style:style"); - tableHeadingStyleOpenElement.addAttribute("style:name", "Table_Heading"); - tableHeadingStyleOpenElement.addAttribute("style:display-name", "Table Heading"); - tableHeadingStyleOpenElement.addAttribute("style:family", "paragraph"); - tableHeadingStyleOpenElement.addAttribute("style:parent-style-name", "Table_Contents"); - tableHeadingStyleOpenElement.addAttribute("style:class", "extra"); - tableHeadingStyleOpenElement.write(pHandler); + static char const *(s_paraStyle[4*10]) = + { + "Text_Body", "Text Body", "Standard", "text", + "Table_Contents", "Table Contents", "Text_Body", "extra", + "Table_Heading", "Table Heading", "Table_Contents", "extra", + "List", "List", "Text_Body", "list", + "Header", "Header", "Standard", "extra", + "Footer", "Footer", "Standard", "extra", + "Caption", "Caption", "Standard", "extra", + "Footnote", "Footnote", "Standard", "extra", + "Endnote", "Endnote", "Standard", "extra", + "Index", "Index", "Standard", "extra" + }; + for (int i=0; i<10; ++i) + { + TagOpenElement paraOpenElement("style:style"); + paraOpenElement.addAttribute("style:name", s_paraStyle[4*i]); + paraOpenElement.addAttribute("style:display-name", s_paraStyle[4*i+1]); + paraOpenElement.addAttribute("style:family", "paragraph"); + paraOpenElement.addAttribute("style:parent-style-name", s_paraStyle[4*i+2]); + paraOpenElement.addAttribute("style:class", s_paraStyle[4*i+3]); + paraOpenElement.write(pHandler); + pHandler->endElement("style:style"); + } - pHandler->endElement("style:style"); + static char const *(s_textStyle[2*4])= + { + "Footnote_Symbol", "Footnote Symbol", "Endnote_Symbol", "Endnote Symbol", + "Footnote_anchor", "Footnote anchor", "Endnote_anchor", "Endnote anchor" + }; + for (int i=0; i<4; ++i) + { + TagOpenElement textOpenElement("style:style"); + textOpenElement.addAttribute("style:name", s_textStyle[2*i]); + textOpenElement.addAttribute("style:display-name", s_textStyle[2*i]); + textOpenElement.addAttribute("style:family", "text"); + textOpenElement.write(pHandler); + TagOpenElement textPropertiesOpenElement("style:text-properties"); + textPropertiesOpenElement.addAttribute("style:text-position", "super 58%"); + textPropertiesOpenElement.write(pHandler); + pHandler->endElement("style:text-properties"); + pHandler->endElement("style:style"); + } + mSpanManager.writeNamedStyles(pHandler); + mParagraphManager.writeNamedStyles(pHandler); + for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) + { + if ((*iterListStyles)->hasDisplayName()) + (*iterListStyles)->write(pHandler); + } - for (std::vector::const_iterator iter = mFrameStyles.begin(); - iter != mFrameStyles.end(); ++iter) - (*iter)->write(pHandler); + TagOpenElement lineOpenElement("text:linenumbering-configuration"); + lineOpenElement.addAttribute("text:number-lines", "false"); + lineOpenElement.addAttribute("text:number-position", "left"); + lineOpenElement.addAttribute("text:increment", "5"); + lineOpenElement.addAttribute("text:offset", "0.1965in"); + lineOpenElement.addAttribute("style:num-format", "1"); + lineOpenElement.write(pHandler); + pHandler->endElement("text:linenumbering-configuration"); + static char const *(s_noteConfig[4*2])= + { + "footnote", "Footnote_Symbol", "Footnote_anchor", "1", + "endnote", "Endnote_Symbol", "Endnote_anchor", "i" + }; + for (int i=0; i<2; ++i) + { + TagOpenElement noteOpenElement("text:notes-configuration"); + noteOpenElement.addAttribute("text:note-class", s_noteConfig[4*i]); + noteOpenElement.addAttribute("text:citation-style-name", s_noteConfig[4*i+1]); + noteOpenElement.addAttribute("text:citation-body-style-name", s_noteConfig[4*i+2]); + noteOpenElement.addAttribute("style:num-format", s_noteConfig[4*i+3]); + noteOpenElement.addAttribute("text:start-value", "0"); + if (i==0) + { + noteOpenElement.addAttribute("text:footnotes-position", "page"); + noteOpenElement.addAttribute("text:start-numbering-at", "document"); + } + else + noteOpenElement.addAttribute("text:master-page-name", "Endnote"); + noteOpenElement.write(pHandler); + pHandler->endElement("text:notes-configuration"); + } + mGraphicManager.writeStyles(pHandler); pHandler->endElement("office:styles"); } void OdtGeneratorPrivate::_writeMasterPages(OdfDocumentHandler *pHandler) { - TagOpenElement("office:master-styles").write(mpHandler); + TagOpenElement("office:master-styles").write(pHandler); + + static char const *(s_default[2*2]) = { "Standard", "PM0", "Endnote", "PM1" }; + for (int i=0; i < 2; ++i) + { + TagOpenElement pageOpenElement("style:master-page"); + pageOpenElement.addAttribute("style:name", s_default[2*i]); + pageOpenElement.addAttribute("style:page-layout-name", s_default[2*i+1]); + pageOpenElement.write(pHandler); + pHandler->endElement("style:master-page"); + } + int pageNumber = 1; for (unsigned int i=0; iwritePageLayout((int)i, pHandler); + TagOpenElement layout("style:page-layout"); + layout.addAttribute("style:name", i==0 ? "PM0" : "PM1"); + layout.write(pHandler); + + TagOpenElement layoutProperties("style:page-layout-properties"); + layoutProperties.addAttribute("fo:margin-bottom", "1in"); + layoutProperties.addAttribute("fo:margin-left", "1in"); + layoutProperties.addAttribute("fo:margin-right", "1in"); + layoutProperties.addAttribute("fo:margin-top", "1in"); + layoutProperties.addAttribute("fo:page-height", "11in"); + layoutProperties.addAttribute("fo:page-width", "8.5in"); + layoutProperties.addAttribute("style:print-orientation", "portrait"); + layoutProperties.write(pHandler); + + TagOpenElement footnoteSep("style:footnote-sep"); + footnoteSep.addAttribute("style:adjustment","left"); + footnoteSep.addAttribute("style:color","#000000"); + footnoteSep.addAttribute("style:rel-width","25%"); + if (i==0) + { + footnoteSep.addAttribute("style:distance-after-sep","0.0398in"); + footnoteSep.addAttribute("style:distance-before-sep","0.0398in"); + footnoteSep.addAttribute("style:width","0.0071in"); + } + footnoteSep.write(pHandler); + TagCloseElement("style:footnote-sep").write(pHandler); + TagCloseElement("style:page-layout-properties").write(pHandler); + + TagCloseElement("style:page-layout").write(pHandler); } + for (unsigned int i=0; iwritePageLayout((int)i, pHandler); } -bool OdtGeneratorPrivate::_writeTargetDocument(OdfDocumentHandler *pHandler) +bool OdtGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) { + if (streamType == ODF_MANIFEST_XML) + { + pHandler->startDocument(); + TagOpenElement manifestElement("manifest:manifest"); + manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"); + manifestElement.write(pHandler); + + TagOpenElement mainFile("manifest:file-entry"); + mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.text"); + mainFile.addAttribute("manifest:full-path", "/"); + mainFile.write(pHandler); + TagCloseElement("manifest:file-entry").write(pHandler); + appendFilesInManifest(pHandler); + + TagCloseElement("manifest:manifest").write(pHandler); + pHandler->endDocument(); + return true; + } + ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Printing out the header stuff..\n")); ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Start Document\n")); - mpHandler->startDocument(); + pHandler->startDocument(); ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: preamble\n")); - WPXPropertyList docContentPropList; + std::string const documentType=getDocumentType(streamType); + librevenge::RVNGPropertyList docContentPropList; docContentPropList.insert("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0"); docContentPropList.insert("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0"); docContentPropList.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/"); @@ -452,157 +429,147 @@ docContentPropList.insert("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0"); docContentPropList.insert("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0"); docContentPropList.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0"); - docContentPropList.insert("office:version", "1.0"); - if (mxStreamType == ODF_FLAT_XML) - { + docContentPropList.insert("office:version", librevenge::RVNGPropertyFactory::newStringProp("1.1")); + if (streamType == ODF_FLAT_XML) docContentPropList.insert("office:mimetype", "application/vnd.oasis.opendocument.text"); - mpHandler->startElement("office:document", docContentPropList); - } - else - mpHandler->startElement("office:document-content", docContentPropList); + pHandler->startElement(documentType.c_str(), docContentPropList); // write out the metadata - TagOpenElement("office:meta").write(mpHandler); - for (std::vector::const_iterator iterMetaData = mMetaData.begin(); iterMetaData != mMetaData.end(); ++iterMetaData) - { - (*iterMetaData)->write(mpHandler); - } - mpHandler->endElement("office:meta"); + if (streamType == ODF_FLAT_XML || streamType == ODF_META_XML) + writeDocumentMetaData(pHandler); // write out the font styles - mFontManager.writeFontsDeclaration(mpHandler); + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + mFontManager.writeFontsDeclaration(pHandler); ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Writing out the styles..\n")); // write default styles - _writeDefaultStyles(mpHandler); + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML) + _writeStyles(pHandler); - TagOpenElement("office:automatic-styles").write(mpHandler); + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML || streamType == ODF_CONTENT_XML) + _writeAutomaticStyles(pHandler); - for (std::vector::const_iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin(); - iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles) - { - (*iterFrameAutomaticStyles)->write(pHandler); - } - - mFontManager.write(pHandler); // do nothing - mParagraphManager.write(pHandler); - mSpanManager.write(pHandler); + if (streamType == ODF_FLAT_XML || streamType == ODF_STYLES_XML) + _writeMasterPages(pHandler); - // writing out the sections styles - for (std::vector::const_iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles) + if (streamType == ODF_FLAT_XML || streamType == ODF_CONTENT_XML) { - (*iterSectionStyles)->write(pHandler); - } + ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Writing out the document..\n")); + // writing out the document + TagOpenElement("office:body").write(pHandler); + TagOpenElement("office:text").write(pHandler); + sendStorage(&mBodyStorage, pHandler); + ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Finished writing all doc els..\n")); - // writing out the lists styles - for (std::vector::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) - { - (*iterListStyles)->write(pHandler); + pHandler->endElement("office:text"); + pHandler->endElement("office:body"); } - // writing out the table styles - for (std::vector::const_iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); ++iterTableStyles) - { - (*iterTableStyles)->write(pHandler); - } + pHandler->endElement(documentType.c_str()); - // writing out the page masters - _writePageLayouts(pHandler); - - - pHandler->endElement("office:automatic-styles"); - - _writeMasterPages(pHandler); + pHandler->endDocument(); - ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Writing out the document..\n")); - // writing out the document - TagOpenElement("office:body").write(mpHandler); - TagOpenElement("office:text").write(mpHandler); + return true; +} - for (std::vector::const_iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); ++iterBodyElements) - { - (*iterBodyElements)->write(pHandler); - } - ODFGEN_DEBUG_MSG(("OdtGenerator: Document Body: Finished writing all doc els..\n")); +OdtGenerator::OdtGenerator() : mpImpl(new OdtGeneratorPrivate) +{ +} - pHandler->endElement("office:text"); - pHandler->endElement("office:body"); - if (mxStreamType == ODF_FLAT_XML) - pHandler->endElement("office:document"); - else - pHandler->endElement("office:document-content"); +OdtGenerator::~OdtGenerator() +{ + if (mpImpl) + delete mpImpl; +} - pHandler->endDocument(); +void OdtGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType) +{ + if (mpImpl) + mpImpl->addDocumentHandler(pHandler, streamType); +} - return true; +librevenge::RVNGStringVector OdtGenerator::getObjectNames() const +{ + if (mpImpl) + return mpImpl->getObjectNames(); + return librevenge::RVNGStringVector(); } +bool OdtGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler) +{ + if (!mpImpl) + return false; + return mpImpl->getObjectContent(objectName, pHandler); +} -void OdtGenerator::setDocumentMetaData(const WPXPropertyList &propList) +void OdtGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList) { - WPXPropertyList::Iter i(propList); - for (i.rewind(); i.next(); ) - { - // filter out libwpd elements - if (strncmp(i.key(), "libwpd", 6) != 0 && strncmp(i.key(), "dcterms", 7) != 0) - { - mpImpl->mMetaData.push_back(new TagOpenElement(i.key())); - WPXString sStringValue(i()->getStr(), true); - mpImpl->mMetaData.push_back(new CharDataElement(sStringValue.cstr())); - mpImpl->mMetaData.push_back(new TagCloseElement(i.key())); - } - } + mpImpl->setDocumentMetaData(propList); +} +void OdtGenerator::defineEmbeddedFont(const librevenge::RVNGPropertyList &/*propList*/) +{ + // TODO: implement me } -void OdtGenerator::openPageSpan(const WPXPropertyList &propList) +void OdtGenerator::openPageSpan(const librevenge::RVNGPropertyList &propList) { PageSpan *pPageSpan = new PageSpan(propList); mpImpl->mPageSpans.push_back(pPageSpan); mpImpl->mpCurrentPageSpan = pPageSpan; mpImpl->miNumPageStyles++; - mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = true; + mpImpl->getState().mbFirstParagraphInPageSpan = true; } -void OdtGenerator::openHeader(const WPXPropertyList &propList) +void OdtGenerator::openHeader(const librevenge::RVNGPropertyList &propList) { std::vector *pHeaderFooterContentElements = new std::vector; - if (propList["libwpd:occurence"]->getStr() == "even") + if (propList["librevenge:occurrence"] && (propList["librevenge:occurrence"]->getStr() == "even" || + propList["librevenge:occurrence"]->getStr() == "left")) mpImpl->mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "first") + mpImpl->mpCurrentPageSpan->setHeaderFirstContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "last") + mpImpl->mpCurrentPageSpan->setHeaderLastContent(pHeaderFooterContentElements); else mpImpl->mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements); - mpImpl->mpCurrentContentElements = pHeaderFooterContentElements; + mpImpl->pushStorage(pHeaderFooterContentElements); } void OdtGenerator::closeHeader() { - mpImpl->mpCurrentContentElements = &(mpImpl->mBodyElements); + mpImpl->popStorage(); } -void OdtGenerator::openFooter(const WPXPropertyList &propList) +void OdtGenerator::openFooter(const librevenge::RVNGPropertyList &propList) { std::vector *pHeaderFooterContentElements = new std::vector; - if (propList["libwpd:occurence"]->getStr() == "even") + if (propList["librevenge:occurrence"] && (propList["librevenge:occurrence"]->getStr() == "even" || + propList["librevenge:occurrence"]->getStr() == "left")) mpImpl->mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "first") + mpImpl->mpCurrentPageSpan->setFooterFirstContent(pHeaderFooterContentElements); + else if (propList["librevenge:occurrence"] && propList["librevenge:occurrence"]->getStr() == "last") + mpImpl->mpCurrentPageSpan->setFooterLastContent(pHeaderFooterContentElements); else mpImpl->mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements); - mpImpl->mpCurrentContentElements = pHeaderFooterContentElements; + mpImpl->pushStorage(pHeaderFooterContentElements); } void OdtGenerator::closeFooter() { - mpImpl->mpCurrentContentElements = &(mpImpl->mBodyElements); + mpImpl->popStorage(); } -void OdtGenerator::openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns) +void OdtGenerator::openSection(const librevenge::RVNGPropertyList &propList) { - size_t iNumColumns = columns.count(); double fSectionMarginLeft = 0.0; double fSectionMarginRight = 0.0; if (propList["fo:margin-left"]) @@ -610,920 +577,424 @@ if (propList["fo:margin-right"]) fSectionMarginRight = propList["fo:margin-right"]->getDouble(); - if (iNumColumns > 1 || fSectionMarginLeft != 0 || fSectionMarginRight != 0) + const librevenge::RVNGPropertyListVector *columns = propList.child("style:columns"); + double const eps=1e-4; + if ((columns && columns->count() > 1) || + (fSectionMarginLeft<-eps || fSectionMarginLeft>eps) || + (fSectionMarginRight<-eps || fSectionMarginRight>eps)) { - WPXString sSectionName; + librevenge::RVNGString sSectionName; sSectionName.sprintf("Section%i", mpImpl->mSectionStyles.size()); - SectionStyle *pSectionStyle = new SectionStyle(propList, columns, sSectionName.cstr()); + SectionStyle *pSectionStyle = new SectionStyle(propList, sSectionName.cstr()); mpImpl->mSectionStyles.push_back(pSectionStyle); TagOpenElement *pSectionOpenElement = new TagOpenElement("text:section"); pSectionOpenElement->addAttribute("text:style-name", pSectionStyle->getName()); pSectionOpenElement->addAttribute("text:name", pSectionStyle->getName()); - mpImpl->mpCurrentContentElements->push_back(pSectionOpenElement); + mpImpl->getCurrentStorage()->push_back(pSectionOpenElement); } else - mpImpl->mWriterDocumentStates.top().mbInFakeSection = true; + mpImpl->getState().mbInFakeSection = true; } void OdtGenerator::closeSection() { - if (!mpImpl->mWriterDocumentStates.top().mbInFakeSection) - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:section")); + if (!mpImpl->getState().mbInFakeSection) + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:section")); else - mpImpl->mWriterDocumentStates.top().mbInFakeSection = false; + mpImpl->getState().mbInFakeSection = false; } -void OdtGenerator::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops) +void OdtGenerator::openParagraph(const librevenge::RVNGPropertyList &propList) { // FIXMENOW: What happens if we open a footnote inside a table? do we then inherit the footnote's style // from "Table Contents" - WPXPropertyList finalPropList(propList); - if (mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan && mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements)) + librevenge::RVNGPropertyList finalPropList(propList); + if (mpImpl->getState().mbFirstParagraphInPageSpan && mpImpl->getCurrentStorage() == &mpImpl->getBodyStorage()) { - WPXString sPageStyleName; + librevenge::RVNGString sPageStyleName; sPageStyleName.sprintf("Page_Style_%i", mpImpl->miNumPageStyles); finalPropList.insert("style:master-page-name", sPageStyleName); - mpImpl->mWriterDocumentStates.top().mbFirstElement = false; - mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false; + mpImpl->getState().mbFirstElement = false; + mpImpl->getState().mbFirstParagraphInPageSpan = false; } - if (mpImpl->mWriterDocumentStates.top().mbTableCellOpened) + if (mpImpl->getState().mbTableCellOpened) { - if (mpImpl->mWriterDocumentStates.top().mbHeaderRow) + bool inHeader=false; + if (mpImpl->isInTableRow(inHeader) && inHeader) finalPropList.insert("style:parent-style-name", "Table_Heading"); else finalPropList.insert("style:parent-style-name", "Table_Contents"); } else finalPropList.insert("style:parent-style-name", "Standard"); - - WPXString sName = mpImpl->mParagraphManager.findOrAdd(finalPropList, tabStops); - - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); - pParagraphOpenElement->addAttribute("text:style-name", sName); - mpImpl->mpCurrentContentElements->push_back(pParagraphOpenElement); + mpImpl->openParagraph(finalPropList); } void OdtGenerator::closeParagraph() { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p")); + mpImpl->closeParagraph(); } -void OdtGenerator::openSpan(const WPXPropertyList &propList) +void OdtGenerator::openSpan(const librevenge::RVNGPropertyList &propList) { - if (propList["style:font-name"]) - mpImpl->mFontManager.findOrAdd(propList["style:font-name"]->getStr().cstr()); - - // Get the style - WPXString sName = mpImpl->mSpanManager.findOrAdd(propList); - - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); - pSpanOpenElement->addAttribute("text:style-name", sName.cstr()); - mpImpl->mpCurrentContentElements->push_back(pSpanOpenElement); + mpImpl->openSpan(propList); } void OdtGenerator::closeSpan() { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:span")); -} - -void OdtGeneratorPrivate::_storeListStyle(ListStyle *listStyle) -{ - if (!listStyle || listStyle == mWriterListStates.top().mpCurrentListStyle) - { - return; - } - mListStyles.push_back(listStyle); - mWriterListStates.top().mpCurrentListStyle = listStyle; - mWriterListStates.top().mIdListStyleMap[listStyle->getListID()]=listStyle; - mIdListStyleMap[listStyle->getListID()]=listStyle; -} - -void OdtGeneratorPrivate::_retrieveListStyle(int id) -{ - // first look if the current style is ok - if (mWriterListStates.top().mpCurrentListStyle && - id == mWriterListStates.top().mpCurrentListStyle->getListID()) - { - return; - } - - // use the current map - if (mWriterListStates.top().mIdListStyleMap.find(id) != - mWriterListStates.top().mIdListStyleMap.end()) - { - mWriterListStates.top().mpCurrentListStyle = - mWriterListStates.top().mIdListStyleMap.find(id)->second; - return; - } - - // use the global map - if (mIdListStyleMap.find(id) != mIdListStyleMap.end()) - { - mWriterListStates.top().mpCurrentListStyle = - mIdListStyleMap.find(id)->second; - return; - } - - ODFGEN_DEBUG_MSG(("OdtGenerator: impossible to find a list with id=%d\n",id)); + mpImpl->closeSpan(); } -void OdtGenerator::defineOrderedListLevel(const WPXPropertyList &propList) +void OdtGenerator::openLink(const librevenge::RVNGPropertyList &propList) { - int id = 0; - if (propList["libwpd:id"]) - id = propList["libwpd:id"]->getInt(); - - ListStyle *pListStyle = 0; - if (mpImpl->mWriterListStates.top().mpCurrentListStyle && mpImpl->mWriterListStates.top().mpCurrentListStyle->getListID() == id) - pListStyle = mpImpl->mWriterListStates.top().mpCurrentListStyle; - - // this rather appalling conditional makes sure we only start a - // new list (rather than continue an old one) if: (1) we have no - // prior list or the prior list has another listId OR (2) we can - // tell that the user actually is starting a new list at level 1 - // (and only level 1) - if (pListStyle == 0 || - (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 && - (propList["text:start-value"] && propList["text:start-value"]->getInt() != int(mpImpl->mWriterListStates.top().miLastListNumber+1)))) - { - ODFGEN_DEBUG_MSG(("OdtGenerator: Attempting to create a new ordered list style (listid: %i)\n", id)); - WPXString sName; - sName.sprintf("OL%i", mpImpl->miNumListStyles); - mpImpl->miNumListStyles++; - pListStyle = new ListStyle(sName.cstr(), id); - mpImpl->_storeListStyle(pListStyle); - mpImpl->mWriterListStates.top().mbListContinueNumbering = false; - mpImpl->mWriterListStates.top().miLastListNumber = 0; - } - else - mpImpl->mWriterListStates.top().mbListContinueNumbering = true; - - // Iterate through ALL list styles with the same WordPerfect list id and define a level if it is not already defined - // This solves certain problems with lists that start and finish without reaching certain levels and then begin again - // and reach those levels. See gradguide0405_PC.wpd in the regression suite - for (std::vector::iterator iterListStyles = mpImpl->mListStyles.begin(); iterListStyles != mpImpl->mListStyles.end(); ++iterListStyles) - { - if ((* iterListStyles) && (* iterListStyles)->getListID() == id && propList["libwpd:level"]) - (* iterListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList, true); - } + mpImpl->openLink(propList); } -void OdtGenerator::defineUnorderedListLevel(const WPXPropertyList &propList) +void OdtGenerator::closeLink() { - int id = 0; - if (propList["libwpd:id"]) - id = propList["libwpd:id"]->getInt(); - - ListStyle *pListStyle = 0; - if (mpImpl->mWriterListStates.top().mpCurrentListStyle && mpImpl->mWriterListStates.top().mpCurrentListStyle->getListID() == id) - pListStyle = mpImpl->mWriterListStates.top().mpCurrentListStyle; - - if (pListStyle == 0) - { - ODFGEN_DEBUG_MSG(("OdtGenerator: Attempting to create a new unordered list style (listid: %i)\n", id)); - WPXString sName; - sName.sprintf("UL%i", mpImpl->miNumListStyles); - mpImpl->miNumListStyles++; - pListStyle = new ListStyle(sName.cstr(), id); - mpImpl->_storeListStyle(pListStyle); - } - - // See comment in OdtGenerator::defineOrderedListLevel - for (std::vector::iterator iterListStyles = mpImpl->mListStyles.begin(); iterListStyles != mpImpl->mListStyles.end(); ++iterListStyles) - { - if ((* iterListStyles) && (* iterListStyles)->getListID() == id && propList["libwpd:level"]) - (* iterListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList, false); - } + mpImpl->closeLink(); } -void OdtGenerator::openOrderedListLevel(const WPXPropertyList &propList) +// ------------------------------- +// list +// ------------------------------- +void OdtGenerator::openOrderedListLevel(const librevenge::RVNGPropertyList &propList) { - if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p")); - mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false; - } - if (mpImpl->mWriterListStates.top().mbListElementOpened.empty() && propList["libwpd:id"]) - { - // first item of a list, be sure to use the list with given id - mpImpl->_retrieveListStyle(propList["libwpd:id"]->getInt()); - } - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list"); - mpImpl->_openListLevel(pListLevelOpenElement); - - if (mpImpl->mWriterListStates.top().mbListContinueNumbering) - { - pListLevelOpenElement->addAttribute("text:continue-numbering", "true"); - } - - mpImpl->mpCurrentContentElements->push_back(pListLevelOpenElement); -} - -void OdtGenerator::openUnorderedListLevel(const WPXPropertyList &propList) -{ - if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p")); - mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false; - } - if (mpImpl->mWriterListStates.top().mbListElementOpened.empty() && propList["libwpd:id"]) - { - // first item of a list, be sure to use the list with given id - mpImpl->_retrieveListStyle(propList["libwpd:id"]->getInt()); - } - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list"); - mpImpl->_openListLevel(pListLevelOpenElement); - - mpImpl->mpCurrentContentElements->push_back(pListLevelOpenElement); + mpImpl->openListLevel(propList, true); } -void OdtGeneratorPrivate::_openListLevel(TagOpenElement *pListLevelOpenElement) +void OdtGenerator::openUnorderedListLevel(const librevenge::RVNGPropertyList &propList) { - if (!mWriterListStates.top().mbListElementOpened.empty() && - !mWriterListStates.top().mbListElementOpened.top()) - { - mpCurrentContentElements->push_back(new TagOpenElement("text:list-item")); - mWriterListStates.top().mbListElementOpened.top() = true; - } - - mWriterListStates.top().mbListElementOpened.push(false); - if (mWriterListStates.top().mbListElementOpened.size() == 1) - { - // add a sanity check ( to avoid a crash if mpCurrentListStyle is NULL) - if (mWriterListStates.top().mpCurrentListStyle) - { - pListLevelOpenElement->addAttribute("text:style-name", mWriterListStates.top().mpCurrentListStyle->getName()); - } - } + mpImpl->openListLevel(propList, false); } void OdtGenerator::closeOrderedListLevel() { - mpImpl->_closeListLevel(); + mpImpl->closeListLevel(); } void OdtGenerator::closeUnorderedListLevel() { - mpImpl->_closeListLevel(); + mpImpl->closeListLevel(); } -void OdtGeneratorPrivate::_closeListLevel() +void OdtGenerator::openListElement(const librevenge::RVNGPropertyList &propList) { - if (mWriterListStates.top().mbListElementOpened.empty()) - { - // this implies that openListLevel was not called, so it is better to stop here - ODFGEN_DEBUG_MSG(("OdtGenerator: Attempting to close an unexisting level\n")); - return; - } - if (mWriterListStates.top().mbListElementOpened.top()) - { - mpCurrentContentElements->push_back(new TagCloseElement("text:list-item")); - mWriterListStates.top().mbListElementOpened.top() = false; - } + mpImpl->openListElement(propList); - mpCurrentContentElements->push_back(new TagCloseElement("text:list")); - mWriterListStates.top().mbListElementOpened.pop(); -} - -void OdtGenerator::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops) -{ - mpImpl->mWriterListStates.top().miLastListLevel = mpImpl->mWriterListStates.top().miCurrentListLevel; - if (mpImpl->mWriterListStates.top().miCurrentListLevel == 1) - mpImpl->mWriterListStates.top().miLastListNumber++; - - if (mpImpl->mWriterListStates.top().mbListElementOpened.top()) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:list-item")); - mpImpl->mWriterListStates.top().mbListElementOpened.top() = false; - } - - WPXPropertyList finalPropList(propList); -#if 0 - // this property is ignored in TextRunStyle.c++ - if (mpImpl->mWriterListStates.top().mpCurrentListStyle) - finalPropList.insert("style:list-style-name", mpImpl->mWriterListStates.top().mpCurrentListStyle->getName()); -#endif - finalPropList.insert("style:parent-style-name", "Standard"); - WPXString paragName = mpImpl->mParagraphManager.findOrAdd(finalPropList, tabStops); - - TagOpenElement *pOpenListItem = new TagOpenElement("text:list-item"); - if (propList["text:start-value"] && propList["text:start-value"]->getInt() > 0) - pOpenListItem->addAttribute("text:start-value", propList["text:start-value"]->getStr()); - mpImpl->mpCurrentContentElements->push_back(pOpenListItem); - - TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p"); - pOpenListElementParagraph->addAttribute("text:style-name", paragName); - mpImpl->mpCurrentContentElements->push_back(pOpenListElementParagraph); - - if (mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements)) - mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false; - - mpImpl->mWriterListStates.top().mbListElementOpened.top() = true; - mpImpl->mWriterListStates.top().mbListElementParagraphOpened = true; - mpImpl->mWriterListStates.top().mbListContinueNumbering = false; + if (mpImpl->getCurrentStorage() == &mpImpl->getBodyStorage()) + mpImpl->getState().mbFirstParagraphInPageSpan = false; } void OdtGenerator::closeListElement() { - // this code is kind of tricky, because we don't actually close the list element (because this list element - // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel - // code (or when we open another list element) - - if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p")); - mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false; - } + mpImpl->closeListElement(); } -void OdtGenerator::openFootnote(const WPXPropertyList &propList) +void OdtGenerator::openFootnote(const librevenge::RVNGPropertyList &propList) { - mpImpl->mWriterListStates.push(WriterListState()); + mpImpl->pushListState(); TagOpenElement *pOpenFootNote = new TagOpenElement("text:note"); pOpenFootNote->addAttribute("text:note-class", "footnote"); - if (propList["libwpd:number"]) + if (propList["librevenge:number"]) { - WPXString tmpString("ftn"); - tmpString.append(propList["libwpd:number"]->getStr()); + librevenge::RVNGString tmpString("ftn"); + tmpString.append(propList["librevenge:number"]->getStr()); pOpenFootNote->addAttribute("text:id", tmpString); } - mpImpl->mpCurrentContentElements->push_back(pOpenFootNote); + mpImpl->getCurrentStorage()->push_back(pOpenFootNote); TagOpenElement *pOpenFootCitation = new TagOpenElement("text:note-citation"); if (propList["text:label"]) { - WPXString tmpString(propList["text:label"]->getStr(),true); + librevenge::RVNGString tmpString; + tmpString.appendEscapedXML(propList["text:label"]->getStr()); pOpenFootCitation->addAttribute("text:label", tmpString); } - mpImpl->mpCurrentContentElements->push_back(pOpenFootCitation); + mpImpl->getCurrentStorage()->push_back(pOpenFootCitation); if (propList["text:label"]) - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["text:label"]->getStr().cstr())); - else if (propList["libwpd:number"]) - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr())); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation")); + mpImpl->getCurrentStorage()->push_back(new CharDataElement(propList["text:label"]->getStr().cstr())); + else if (propList["librevenge:number"]) + mpImpl->getCurrentStorage()->push_back(new CharDataElement(propList["librevenge:number"]->getStr().cstr())); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note-citation")); - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:note-body")); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("text:note-body")); - mpImpl->mWriterDocumentStates.top().mbInNote = true; + mpImpl->getState().mbInNote = true; } void OdtGenerator::closeFootnote() { - mpImpl->mWriterDocumentStates.top().mbInNote = false; - if (mpImpl->mWriterListStates.size() > 1) - mpImpl->mWriterListStates.pop(); + mpImpl->getState().mbInNote = false; + mpImpl->popListState(); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-body")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note-body")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note")); } -void OdtGenerator::openEndnote(const WPXPropertyList &propList) +void OdtGenerator::openEndnote(const librevenge::RVNGPropertyList &propList) { - mpImpl->mWriterListStates.push(WriterListState()); + mpImpl->pushListState(); TagOpenElement *pOpenEndNote = new TagOpenElement("text:note"); pOpenEndNote->addAttribute("text:note-class", "endnote"); - if (propList["libwpd:number"]) + if (propList["librevenge:number"]) { - WPXString tmpString("edn"); - tmpString.append(propList["libwpd:number"]->getStr()); + librevenge::RVNGString tmpString("edn"); + tmpString.append(propList["librevenge:number"]->getStr()); pOpenEndNote->addAttribute("text:id", tmpString); } - mpImpl->mpCurrentContentElements->push_back(pOpenEndNote); + mpImpl->getCurrentStorage()->push_back(pOpenEndNote); TagOpenElement *pOpenEndCitation = new TagOpenElement("text:note-citation"); if (propList["text:label"]) { - WPXString tmpString(propList["text:label"]->getStr(),true); + librevenge::RVNGString tmpString; + tmpString.appendEscapedXML(propList["text:label"]->getStr()); pOpenEndCitation->addAttribute("text:label", tmpString); } - mpImpl->mpCurrentContentElements->push_back(pOpenEndCitation); + mpImpl->getCurrentStorage()->push_back(pOpenEndCitation); if (propList["text:label"]) - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["text:label"]->getStr().cstr())); - else if (propList["libwpd:number"]) - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr())); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation")); + mpImpl->getCurrentStorage()->push_back(new CharDataElement(propList["text:label"]->getStr().cstr())); + else if (propList["librevenge:number"]) + mpImpl->getCurrentStorage()->push_back(new CharDataElement(propList["librevenge:number"]->getStr().cstr())); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note-citation")); - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:note-body")); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("text:note-body")); - mpImpl->mWriterDocumentStates.top().mbInNote = true; + mpImpl->getState().mbInNote = true; } void OdtGenerator::closeEndnote() { - mpImpl->mWriterDocumentStates.top().mbInNote = false; - if (mpImpl->mWriterListStates.size() > 1) - mpImpl->mWriterListStates.pop(); - - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-body")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note")); + mpImpl->getState().mbInNote = false; + mpImpl->popListState(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note-body")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("text:note")); } -void OdtGenerator::openComment(const WPXPropertyList &) +void OdtGenerator::openComment(const librevenge::RVNGPropertyList &) { - mpImpl->mWriterListStates.push(WriterListState()); - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:annotation")); + mpImpl->pushListState(); + mpImpl->getCurrentStorage()->push_back(new TagOpenElement("office:annotation")); - mpImpl->mWriterDocumentStates.top().mbInNote = true; + mpImpl->getState().mbInNote = true; } void OdtGenerator::closeComment() { - mpImpl->mWriterDocumentStates.top().mbInNote = false; - if (mpImpl->mWriterListStates.size() > 1) - mpImpl->mWriterListStates.pop(); - - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:annotation")); + mpImpl->getState().mbInNote = false; + mpImpl->popListState(); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("office:annotation")); } -void OdtGenerator::openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns) +void OdtGenerator::openTable(const librevenge::RVNGPropertyList &propList) { - if (!mpImpl->mWriterDocumentStates.top().mbInNote) - { - WPXString sTableName; - sTableName.sprintf("Table%i", mpImpl->mTableStyles.size()); - - // FIXME: we base the table style off of the page's margin left, ignoring (potential) wordperfect margin - // state which is transmitted inside the page. could this lead to unacceptable behaviour? - // WLACH_REFACTORING: characterize this behaviour, probably should nip it at the bud within libwpd - TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr()); - - if (mpImpl->mWriterDocumentStates.top().mbFirstElement && mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements)) - { - WPXString sMasterPageName("Page_Style_1"); - pTableStyle->setMasterPageName(sMasterPageName); - mpImpl->mWriterDocumentStates.top().mbFirstElement = false; - } - - mpImpl->mTableStyles.push_back(pTableStyle); - - mpImpl->mpCurrentTableStyle = pTableStyle; - - TagOpenElement *pTableOpenElement = new TagOpenElement("table:table"); - - pTableOpenElement->addAttribute("table:name", sTableName.cstr()); - pTableOpenElement->addAttribute("table:style-name", sTableName.cstr()); - mpImpl->mpCurrentContentElements->push_back(pTableOpenElement); - - for (int i=0; igetNumColumns(); ++i) - { - TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column"); - WPXString sColumnStyleName; - sColumnStyleName.sprintf("%s.Column%i", sTableName.cstr(), (i+1)); - pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr()); - mpImpl->mpCurrentContentElements->push_back(pTableColumnOpenElement); + if (mpImpl->getState().mbInNote) + return; - TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column"); - mpImpl->mpCurrentContentElements->push_back(pTableColumnCloseElement); - } + librevenge::RVNGPropertyList pList(propList); + if (mpImpl->getState().mbFirstElement && mpImpl->getCurrentStorage() == &mpImpl->getBodyStorage()) + { + pList.insert("style:master-page-name", "Page_Style_1"); + mpImpl->getState().mbFirstElement = false; } + mpImpl->openTable(pList); } -void OdtGenerator::openTableRow(const WPXPropertyList &propList) +void OdtGenerator::closeTable() { - if (mpImpl->mWriterDocumentStates.top().mbInNote) + if (mpImpl->getState().mbInNote) return; - if (!mpImpl->mpCurrentTableStyle) - { - ODFGEN_DEBUG_MSG(("OdtGenerator::openTableRow called with no table\n")); - return; - } - if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt())) - { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("table:table-header-rows")); - mpImpl->mWriterDocumentStates.top().mbHeaderRow = true; - } - - WPXString sTableRowStyleName; - sTableRowStyleName.sprintf("%s.Row%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableRowStyles()); - TableRowStyle *pTableRowStyle = new TableRowStyle(propList, sTableRowStyleName.cstr()); - mpImpl->mpCurrentTableStyle->addTableRowStyle(pTableRowStyle); + mpImpl->closeTable(); +} - TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row"); - pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName); - mpImpl->mpCurrentContentElements->push_back(pTableRowOpenElement); +void OdtGenerator::openTableRow(const librevenge::RVNGPropertyList &propList) +{ + if (mpImpl->getState().mbInNote) + return; + mpImpl->openTableRow(propList); } void OdtGenerator::closeTableRow() { - if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-row")); - if (mpImpl->mWriterDocumentStates.top().mbHeaderRow) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-header-rows")); - mpImpl->mWriterDocumentStates.top().mbHeaderRow = false; - } - } + if (mpImpl->getState().mbInNote) + return; + mpImpl->closeTableRow(); } -void OdtGenerator::openTableCell(const WPXPropertyList &propList) +void OdtGenerator::openTableCell(const librevenge::RVNGPropertyList &propList) { - if (mpImpl->mWriterDocumentStates.top().mbInNote) - return; - if (!mpImpl->mpCurrentTableStyle) - { - ODFGEN_DEBUG_MSG(("OdtGenerator::openTableCell called with no table\n")); + if (mpImpl->getState().mbInNote) return; - } - - WPXString sTableCellStyleName; - sTableCellStyleName.sprintf( "%s.Cell%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableCellStyles()); - TableCellStyle *pTableCellStyle = new TableCellStyle(propList, sTableCellStyleName.cstr()); - mpImpl->mpCurrentTableStyle->addTableCellStyle(pTableCellStyle); - - TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell"); - pTableCellOpenElement->addAttribute("table:style-name", sTableCellStyleName); - if (propList["table:number-columns-spanned"]) - pTableCellOpenElement->addAttribute("table:number-columns-spanned", - propList["table:number-columns-spanned"]->getStr().cstr()); - if (propList["table:number-rows-spanned"]) - pTableCellOpenElement->addAttribute("table:number-rows-spanned", - propList["table:number-rows-spanned"]->getStr().cstr()); - // pTableCellOpenElement->addAttribute("table:value-type", "string"); - mpImpl->mpCurrentContentElements->push_back(pTableCellOpenElement); - mpImpl->mWriterDocumentStates.top().mbTableCellOpened = true; + mpImpl->getState().mbTableCellOpened = mpImpl->openTableCell(propList); } void OdtGenerator::closeTableCell() { - if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-cell")); - mpImpl->mWriterDocumentStates.top().mbTableCellOpened = false; - } -} - -void OdtGenerator::insertCoveredTableCell(const WPXPropertyList &) -{ - if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle) - { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("table:covered-table-cell")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:covered-table-cell")); - } + if (mpImpl->getState().mbInNote) + return; + mpImpl->closeTableCell(); + mpImpl->getState().mbTableCellOpened = false; } -void OdtGenerator::closeTable() +void OdtGenerator::insertCoveredTableCell(const librevenge::RVNGPropertyList &propList) { - if (!mpImpl->mWriterDocumentStates.top().mbInNote) - { - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table")); - } + if (mpImpl->getState().mbInNote) + return; + mpImpl->insertCoveredTableCell(propList); } - void OdtGenerator::insertTab() { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:tab")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:tab")); + mpImpl->insertTab(); } void OdtGenerator::insertSpace() { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:s")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:s")); + mpImpl->insertSpace(); } void OdtGenerator::insertLineBreak() { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:line-break")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:line-break")); + mpImpl->insertLineBreak(); } -void OdtGenerator::insertField(const WPXString &type, const WPXPropertyList &propList) +void OdtGenerator::insertField(const librevenge::RVNGPropertyList &propList) { - if (!type.len()) - return; - - TagOpenElement *openElement = new TagOpenElement(type); - if (type == "text:page-number") - openElement->addAttribute("text:select-page", "current"); - - if (propList["style:num-format"]) - openElement->addAttribute("style:num-format", propList["style:num-format"]->getStr()); - - mpImpl->mpCurrentContentElements->push_back(openElement); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement(type)); + mpImpl->insertField(propList); } -void OdtGenerator::insertText(const WPXString &text) +void OdtGenerator::insertText(const librevenge::RVNGString &text) { - DocumentElement *pText = new TextElement(text); - mpImpl->mpCurrentContentElements->push_back(pText); + mpImpl->insertText(text); } -void OdtGenerator::openFrame(const WPXPropertyList &propList) +void OdtGenerator::openFrame(const librevenge::RVNGPropertyList &propList) { - mpImpl->mWriterListStates.push(WriterListState()); - - // First, let's create a Frame Style for this box - TagOpenElement *frameStyleOpenElement = new TagOpenElement("style:style"); - WPXString frameStyleName; - unsigned objectId = 0; - if (propList["libwpd:frame-name"]) - objectId= mpImpl->_getObjectId(propList["libwpd:frame-name"]->getStr()); - else - objectId= mpImpl->_getObjectId(""); - frameStyleName.sprintf("GraphicFrame_%i", objectId); - frameStyleOpenElement->addAttribute("style:name", frameStyleName); - frameStyleOpenElement->addAttribute("style:family", "graphic"); - - mpImpl->mFrameStyles.push_back(frameStyleOpenElement); - - TagOpenElement *frameStylePropertiesOpenElement = new TagOpenElement("style:graphic-properties"); - - if (propList["text:anchor-type"]) - frameStylePropertiesOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr()); - else - frameStylePropertiesOpenElement->addAttribute("text:anchor-type","paragraph"); - - if (propList["text:anchor-page-number"]) - frameStylePropertiesOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr()); - - if (propList["svg:x"]) - frameStylePropertiesOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr()); - - if (propList["svg:y"]) - frameStylePropertiesOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr()); - - if (propList["svg:width"]) - frameStylePropertiesOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - else if (propList["fo:min-width"]) - frameStylePropertiesOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - - if (propList["svg:height"]) - frameStylePropertiesOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - else if (propList["fo:min-height"]) - frameStylePropertiesOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - - if (propList["style:rel-width"]) - frameStylePropertiesOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr()); - - if (propList["style:rel-height"]) - frameStylePropertiesOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr()); - - if (propList["fo:max-width"]) - frameStylePropertiesOpenElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr()); - - if (propList["fo:max-height"]) - frameStylePropertiesOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - - if (propList["style:wrap"]) - frameStylePropertiesOpenElement->addAttribute("style:wrap", propList["style:wrap"]->getStr()); - - if (propList["style:run-through"]) - frameStylePropertiesOpenElement->addAttribute("style:run-through", propList["style:run-through"]->getStr()); - - mpImpl->mFrameStyles.push_back(frameStylePropertiesOpenElement); - - mpImpl->mFrameStyles.push_back(new TagCloseElement("style:graphic-properties")); - - mpImpl->mFrameStyles.push_back(new TagCloseElement("style:style")); - - // Now, let's create an automatic style for this frame - TagOpenElement *frameAutomaticStyleElement = new TagOpenElement("style:style"); - WPXString frameAutomaticStyleName; - frameAutomaticStyleName.sprintf("fr%i", objectId); - frameAutomaticStyleElement->addAttribute("style:name", frameAutomaticStyleName); - frameAutomaticStyleElement->addAttribute("style:family", "graphic"); - frameAutomaticStyleElement->addAttribute("style:parent-style-name", frameStyleName); - - mpImpl->mFrameAutomaticStyles.push_back(frameAutomaticStyleElement); - - TagOpenElement *frameAutomaticStylePropertiesElement = new TagOpenElement("style:graphic-properties"); - if (propList["style:horizontal-pos"]) - frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", propList["style:horizontal-pos"]->getStr()); - else - frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", "left"); - - if (propList["style:horizontal-rel"]) - frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", propList["style:horizontal-rel"]->getStr()); - else - frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", "paragraph"); - - if (propList["style:vertical-pos"]) - frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", propList["style:vertical-pos"]->getStr()); - else - frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", "top"); - - if (propList["style:vertical-rel"]) - frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", propList["style:vertical-rel"]->getStr()); - else - frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", "page-content"); - - if (propList["fo:max-width"]) - frameAutomaticStylePropertiesElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr()); - - if (propList["fo:max-height"]) - frameAutomaticStylePropertiesElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr()); - - // check if the frame has border, shadow, background attributes - static char const *(bordersString[])= - { - "fo:border","fo:border-top","fo:border-left","fo:border-bottom","fo:border-right", - "style:border-line-width","style:border-line-width-top","style:border-line-width-left", - "style:border-line-width-bottom","style:border-line-width-right", - "style:shadow" - }; - for (int b = 0; b < 11; b++) - { - if (propList[bordersString[b]]) - frameAutomaticStylePropertiesElement->addAttribute(bordersString[b], propList[bordersString[b]]->getStr()); - } - if (propList["fo:background-color"]) - frameAutomaticStylePropertiesElement->addAttribute("fo:background-color", propList["fo:background-color"]->getStr()); - if (propList["style:background-transparency"]) - frameAutomaticStylePropertiesElement->addAttribute("style:background-transparency", propList["style:background-transparency"]->getStr()); - - if (propList["fo:clip"]) - frameAutomaticStylePropertiesElement->addAttribute("fo:clip", propList["fo:clip"]->getStr()); - - frameAutomaticStylePropertiesElement->addAttribute("draw:ole-draw-aspect", "1"); - - mpImpl->mFrameAutomaticStyles.push_back(frameAutomaticStylePropertiesElement); - - mpImpl->mFrameAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties")); - - mpImpl->mFrameAutomaticStyles.push_back(new TagCloseElement("style:style")); - - // And write the frame itself - TagOpenElement *drawFrameOpenElement = new TagOpenElement("draw:frame"); - - drawFrameOpenElement->addAttribute("draw:style-name", frameAutomaticStyleName); - WPXString objectName; - objectName.sprintf("Object%i", objectId); - drawFrameOpenElement->addAttribute("draw:name", objectName); - if (propList["text:anchor-type"]) - drawFrameOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr()); - else - drawFrameOpenElement->addAttribute("text:anchor-type","paragraph"); - - if (propList["text:anchor-page-number"]) - drawFrameOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr()); - - if (propList["svg:x"]) - drawFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr()); - - if (propList["svg:y"]) - drawFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr()); - - if (propList["svg:width"]) - drawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr()); - else if (propList["fo:min-width"]) - drawFrameOpenElement->addAttribute("fo:min-width", propList["fo:min-width"]->getStr()); - - if (propList["svg:height"]) - drawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr()); - else if (propList["fo:min-height"]) - drawFrameOpenElement->addAttribute("fo:min-height", propList["fo:min-height"]->getStr()); - - if (propList["style:rel-width"]) - drawFrameOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr()); - - if (propList["style:rel-height"]) - drawFrameOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr()); - - if (propList["draw:z-index"]) - drawFrameOpenElement->addAttribute("draw:z-index", propList["draw:z-index"]->getStr()); - - mpImpl->mpCurrentContentElements->push_back(drawFrameOpenElement); - - mpImpl->mWriterDocumentStates.top().mbInFrame = true; + mpImpl->pushListState(); + librevenge::RVNGPropertyList pList(propList); + if (!propList["text:anchor-type"]) + pList.insert("text:anchor-type","paragraph"); + mpImpl->openFrame(pList); + mpImpl->getState().mbInFrame = true; } void OdtGenerator::closeFrame() { - if (mpImpl->mWriterListStates.size() > 1) - mpImpl->mWriterListStates.pop(); - - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:frame")); - - mpImpl->mWriterDocumentStates.top().mbInFrame = false; + mpImpl->popListState(); + mpImpl->closeFrame(); + mpImpl->getState().mbInFrame = false; } -void OdtGenerator::insertBinaryObject(const WPXPropertyList &propList, const WPXBinaryData &data) +void OdtGenerator::insertBinaryObject(const librevenge::RVNGPropertyList &propList) { - if (!data.size()) + if (!mpImpl->getState().mbInFrame) // Embedded objects without a frame simply don't make sense for us return; - if (!mpImpl->mWriterDocumentStates.top().mbInFrame) // Embedded objects without a frame simply don't make sense for us - return; - if (!propList["libwpd:mimetype"]) - return; - - OdfEmbeddedObject tmpObjectHandler = mpImpl->_findEmbeddedObjectHandler(propList["libwpd:mimetype"]->getStr()); - OdfEmbeddedImage tmpImageHandler = mpImpl->_findEmbeddedImageHandler(propList["libwpd:mimetype"]->getStr()); + mpImpl->insertBinaryObject(propList); +} - if (tmpObjectHandler || tmpImageHandler) - { - if (tmpObjectHandler) - { - std::vector tmpContentElements; - InternalHandler tmpHandler(&tmpContentElements); +void OdtGenerator::openGroup(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->openGroup(propList); +} - if (tmpObjectHandler(data, &tmpHandler, ODF_FLAT_XML) && !tmpContentElements.empty()) - { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:object")); - for (std::vector::const_iterator iter = tmpContentElements.begin(); iter != tmpContentElements.end(); ++iter) - mpImpl->mpCurrentContentElements->push_back(*iter); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:object")); - } - } - if (tmpImageHandler) - { - WPXBinaryData output; - if (tmpImageHandler(data, output)) - { - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:image")); +void OdtGenerator::closeGroup() +{ + mpImpl->closeGroup(); +} - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:binary-data")); +void OdtGenerator::defineGraphicStyle(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->defineGraphicStyle(propList); +} - WPXString binaryBase64Data = output.getBase64Data(); +void OdtGenerator::drawRectangle(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawRectangle(propList); +} - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(binaryBase64Data.cstr())); +void OdtGenerator::drawEllipse(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawEllipse(propList); +} - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:binary-data")); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:image")); - } - } - } - else - // assuming we have a binary image or a object_ole that we can just insert as it is - { - if (propList["libwpd:mimetype"]->getStr() == "object/ole") - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:object-ole")); - else - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:image")); +void OdtGenerator::drawPolygon(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawPolySomething(propList, true); +} - mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:binary-data")); - WPXString binaryBase64Data = data.getBase64Data(); +void OdtGenerator::drawPolyline(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawPolySomething(propList, false); +} - mpImpl->mpCurrentContentElements->push_back(new CharDataElement(binaryBase64Data.cstr())); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:binary-data")); +void OdtGenerator::drawPath(const ::librevenge::RVNGPropertyList &propList) +{ + /** CHECKME: actually, the drawing is often bad, ie. some + unexpected scaling be applied, can we automatically replace the + shape by an embedded objet ? */ + mpImpl->drawPath(propList); +} - if (propList["libwpd:mimetype"]->getStr() == "object/ole") - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:object-ole")); - else - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:image")); - } +void OdtGenerator::drawConnector(const ::librevenge::RVNGPropertyList &propList) +{ + mpImpl->drawConnector(propList); } -void OdtGenerator::openTextBox(const WPXPropertyList &propList) +void OdtGenerator::openTextBox(const librevenge::RVNGPropertyList &propList) { - if (!mpImpl->mWriterDocumentStates.top().mbInFrame) // Text box without a frame simply doesn't make sense for us + if (!mpImpl->getState().mbInFrame) // Text box without a frame simply doesn't make sense for us return; - mpImpl->mWriterListStates.push(WriterListState()); - mpImpl->mWriterDocumentStates.push(WriterDocumentState()); + mpImpl->pushListState(); + mpImpl->pushState(); TagOpenElement *textBoxOpenElement = new TagOpenElement("draw:text-box"); - if (propList["libwpd:next-frame-name"]) + if (propList["librevenge:next-frame-name"]) { - WPXString frameName; - unsigned id=mpImpl->_getObjectId(propList["libwpd:next-frame-name"]->getStr()); + librevenge::RVNGString frameName; + unsigned id=mpImpl->getFrameId(propList["librevenge:next-frame-name"]->getStr()); frameName.sprintf("Object%i", id); textBoxOpenElement->addAttribute("draw:chain-next-name", frameName); } - mpImpl->mpCurrentContentElements->push_back(textBoxOpenElement); - mpImpl->mWriterDocumentStates.top().mbInTextBox = true; - mpImpl->mWriterDocumentStates.top().mbFirstElement = false; + mpImpl->getCurrentStorage()->push_back(textBoxOpenElement); + mpImpl->getState().mbInTextBox = true; + mpImpl->getState().mbFirstElement = false; } void OdtGenerator::closeTextBox() { - if (!mpImpl->mWriterDocumentStates.top().mbInTextBox) + if (!mpImpl->getState().mbInTextBox) return; - if (mpImpl->mWriterListStates.size() > 1) - mpImpl->mWriterListStates.pop(); - if (mpImpl->mWriterDocumentStates.size() > 1) - mpImpl->mWriterDocumentStates.pop(); + mpImpl->popListState(); + mpImpl->popState(); - mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:text-box")); + mpImpl->getCurrentStorage()->push_back(new TagCloseElement("draw:text-box")); } -void OdtGenerator::defineSectionStyle(WPXPropertyList const &, WPXPropertyListVector const &) +void OdtGenerator::defineSectionStyle(librevenge::RVNGPropertyList const &) { } -void OdtGenerator::insertEquation(WPXPropertyList const &, WPXString const &) +void OdtGenerator::insertEquation(librevenge::RVNGPropertyList const &) { } void OdtGenerator::endDocument() { // Write out the collected document - mpImpl->_writeTargetDocument(mpImpl->mpHandler); + mpImpl->writeTargetDocuments(); } -void OdtGenerator::startDocument() +void OdtGenerator::startDocument(const librevenge::RVNGPropertyList &) { } @@ -1531,26 +1002,33 @@ { } -void OdtGenerator::definePageStyle(WPXPropertyList const &) +void OdtGenerator::definePageStyle(librevenge::RVNGPropertyList const &) +{ +} + +void OdtGenerator::defineParagraphStyle(librevenge::RVNGPropertyList const &propList) { + mpImpl->defineParagraphStyle(propList); } -void OdtGenerator::defineParagraphStyle(WPXPropertyList const &, WPXPropertyListVector const &) +void OdtGenerator::defineCharacterStyle(librevenge::RVNGPropertyList const &propList) { + mpImpl->defineCharacterStyle(propList); } -void OdtGenerator::defineCharacterStyle(WPXPropertyList const &) +void OdtGenerator::initStateWith(OdfGenerator const &orig) { + mpImpl->initStateWith(orig); } -void OdtGenerator::registerEmbeddedObjectHandler(const WPXString &mimeType, OdfEmbeddedObject objectHandler) +void OdtGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler) { - mpImpl->mObjectHandlers[mimeType] = objectHandler; + mpImpl->registerEmbeddedObjectHandler(mimeType, objectHandler); } -void OdtGenerator::registerEmbeddedImageHandler(const WPXString &mimeType, OdfEmbeddedImage imageHandler) +void OdtGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler) { - mpImpl->mImageHandlers[mimeType] = imageHandler; + mpImpl->registerEmbeddedImageHandler(mimeType, imageHandler); } /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/PageSpan.cxx libodfgen-0.1.1/src/PageSpan.cxx --- libodfgen-0.0.4/src/PageSpan.cxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/PageSpan.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -26,12 +26,16 @@ #include "PageSpan.hxx" #include "DocumentElement.hxx" -PageSpan::PageSpan(const WPXPropertyList &xPropList) : +PageSpan::PageSpan(const librevenge::RVNGPropertyList &xPropList) : mxPropList(xPropList), mpHeaderContent(0), mpFooterContent(0), mpHeaderLeftContent(0), - mpFooterLeftContent(0) + mpFooterLeftContent(0), + mpHeaderFirstContent(0), + mpFooterFirstContent(0), + mpHeaderLastContent(0), + mpFooterLastContent(0) { } @@ -60,6 +64,24 @@ delete mpHeaderLeftContent; } + if (mpHeaderFirstContent) + { + for (DEVIter iterHeaderFirstContent = mpHeaderFirstContent->begin(); + iterHeaderFirstContent != mpHeaderFirstContent->end(); + ++iterHeaderFirstContent) + delete(*iterHeaderFirstContent); + delete mpHeaderFirstContent; + } + + if (mpHeaderLastContent) + { + for (DEVIter iterHeaderLastContent = mpHeaderLastContent->begin(); + iterHeaderLastContent != mpHeaderLastContent->end(); + ++iterHeaderLastContent) + delete(*iterHeaderLastContent); + delete mpHeaderLastContent; + } + if (mpFooterContent) { for (DEVIter iterFooterContent = mpFooterContent->begin(); @@ -77,12 +99,30 @@ delete(*iterFooterLeftContent); delete mpFooterLeftContent; } + + if (mpFooterFirstContent) + { + for (DEVIter iterFooterFirstContent = mpFooterFirstContent->begin(); + iterFooterFirstContent != mpFooterFirstContent->end(); + ++iterFooterFirstContent) + delete(*iterFooterFirstContent); + delete mpFooterFirstContent; + } + + if (mpFooterLastContent) + { + for (DEVIter iterFooterLastContent = mpFooterLastContent->begin(); + iterFooterLastContent != mpFooterLastContent->end(); + ++iterFooterLastContent) + delete(*iterFooterLastContent); + delete mpFooterLastContent; + } } int PageSpan::getSpan() const { - if (mxPropList["libwpd:num-pages"]) - return mxPropList["libwpd:num-pages"]->getInt(); + if (mxPropList["librevenge:num-pages"]) + return mxPropList["librevenge:num-pages"]->getInt(); return 0; // should never happen } @@ -143,29 +183,85 @@ mpFooterLeftContent = pFooterContent; } +void PageSpan::setHeaderFirstContent(std::vector *pHeaderContent) +{ + if (mpHeaderFirstContent) + { + for (DEVIter iterHeaderFirstContent = mpHeaderFirstContent->begin(); + iterHeaderFirstContent != mpHeaderFirstContent->end(); + ++iterHeaderFirstContent) + delete(*iterHeaderFirstContent); + delete mpHeaderFirstContent; + } + + mpHeaderFirstContent = pHeaderContent; +} + +void PageSpan::setFooterFirstContent(std::vector *pFooterContent) +{ + if (mpFooterFirstContent) + { + for (DEVIter iterFooterFirstContent = mpFooterFirstContent->begin(); + iterFooterFirstContent != mpFooterFirstContent->end(); + ++iterFooterFirstContent) + delete(*iterFooterFirstContent); + delete mpFooterFirstContent; + } + + mpFooterFirstContent = pFooterContent; +} + +void PageSpan::setHeaderLastContent(std::vector *pHeaderContent) +{ + if (mpHeaderLastContent) + { + for (DEVIter iterHeaderLastContent = mpHeaderLastContent->begin(); + iterHeaderLastContent != mpHeaderLastContent->end(); + ++iterHeaderLastContent) + delete(*iterHeaderLastContent); + delete mpHeaderLastContent; + } + + mpHeaderLastContent = pHeaderContent; +} + +void PageSpan::setFooterLastContent(std::vector *pFooterContent) +{ + if (mpFooterLastContent) + { + for (DEVIter iterFooterLastContent = mpFooterLastContent->begin(); + iterFooterLastContent != mpFooterLastContent->end(); + ++iterFooterLastContent) + delete(*iterFooterLastContent); + delete mpFooterLastContent; + } + + mpFooterLastContent = pFooterContent; +} + void PageSpan::writePageLayout(const int iNum, OdfDocumentHandler *pHandler) const { - WPXPropertyList propList; + librevenge::RVNGPropertyList propList; - WPXString sPageLayoutName; + librevenge::RVNGString sPageLayoutName; sPageLayoutName.sprintf("PM%i", iNum+2); propList.insert("style:name", sPageLayoutName); pHandler->startElement("style:page-layout", propList); - WPXPropertyList tempPropList = mxPropList; + librevenge::RVNGPropertyList tempPropList = mxPropList; if (!tempPropList["style:writing-mode"]) - tempPropList.insert("style:writing-mode", WPXString("lr-tb")); + tempPropList.insert("style:writing-mode", librevenge::RVNGString("lr-tb")); if (!tempPropList["style:footnote-max-height"]) - tempPropList.insert("style:footnote-max-height", WPXString("0in")); + tempPropList.insert("style:footnote-max-height", librevenge::RVNGString("0in")); pHandler->startElement("style:page-layout-properties", tempPropList); - WPXPropertyList footnoteSepPropList; - footnoteSepPropList.insert("style:width", WPXString("0.0071in")); - footnoteSepPropList.insert("style:distance-before-sep", WPXString("0.0398in")); - footnoteSepPropList.insert("style:distance-after-sep", WPXString("0.0398in")); - footnoteSepPropList.insert("style:adjustment", WPXString("left")); - footnoteSepPropList.insert("style:rel-width", WPXString("25%")); - footnoteSepPropList.insert("style:color", WPXString("#000000")); + librevenge::RVNGPropertyList footnoteSepPropList; + footnoteSepPropList.insert("style:width", librevenge::RVNGString("0.0071in")); + footnoteSepPropList.insert("style:distance-before-sep", librevenge::RVNGString("0.0398in")); + footnoteSepPropList.insert("style:distance-after-sep", librevenge::RVNGString("0.0398in")); + footnoteSepPropList.insert("style:adjustment", librevenge::RVNGString("left")); + footnoteSepPropList.insert("style:rel-width", librevenge::RVNGString("25%")); + footnoteSepPropList.insert("style:color", librevenge::RVNGString("#000000")); pHandler->startElement("style:footnote-sep", footnoteSepPropList); pHandler->endElement("style:footnote-sep"); @@ -182,18 +278,18 @@ for (int i=iStartingNum; i<(iStartingNum+iSpan); ++i) { TagOpenElement masterPageOpen("style:master-page"); - WPXString sMasterPageName, sMasterPageDisplayName; + librevenge::RVNGString sMasterPageName, sMasterPageDisplayName; sMasterPageName.sprintf("Page_Style_%i", i); sMasterPageDisplayName.sprintf("Page Style %i", i); - WPXString sPageLayoutName; - WPXPropertyList propList; + librevenge::RVNGString sPageLayoutName; + librevenge::RVNGPropertyList propList; sPageLayoutName.sprintf("PM%i", iPageLayoutNum+2); propList.insert("style:name", sMasterPageName); propList.insert("style:display-name", sMasterPageDisplayName); propList.insert("style:page-layout-name", sPageLayoutName); if (!bLastPageSpan) { - WPXString sNextMasterPageName; + librevenge::RVNGString sNextMasterPageName; sNextMasterPageName.sprintf("Page_Style_%i", (i+1)); propList.insert("style:next-style-name", sNextMasterPageName); } @@ -203,37 +299,57 @@ { _writeHeaderFooter("style:header", *mpHeaderContent, pHandler); pHandler->endElement("style:header"); - if (mpHeaderLeftContent) - { - _writeHeaderFooter("style:header-left", *mpHeaderLeftContent, pHandler); - pHandler->endElement("style:header-left"); - } } - else if (mpHeaderLeftContent) + else if (mpHeaderLeftContent || mpHeaderFirstContent /* || mpHeaderLastContent */) { TagOpenElement("style:header").write(pHandler); pHandler->endElement("style:header"); + } + if (mpHeaderLeftContent) + { _writeHeaderFooter("style:header-left", *mpHeaderLeftContent, pHandler); pHandler->endElement("style:header-left"); } + if (mpHeaderFirstContent) + { + _writeHeaderFooter("style:header-first", *mpHeaderFirstContent, pHandler); + pHandler->endElement("style:header-first"); + } + /* + if (mpHeaderLastContent) + { + _writeHeaderFooter("style:header-last", *mpHeaderLastContent, pHandler); + pHandler->endElement("style:header-last"); + } + */ if (mpFooterContent) { _writeHeaderFooter("style:footer", *mpFooterContent, pHandler); pHandler->endElement("style:footer"); - if (mpFooterLeftContent) - { - _writeHeaderFooter("style:footer-left", *mpFooterLeftContent, pHandler); - pHandler->endElement("style:footer-left"); - } } - else if (mpFooterLeftContent) + else if (mpFooterLeftContent || mpFooterFirstContent /* || mpFooterLastContent */) { TagOpenElement("style:footer").write(pHandler); pHandler->endElement("style:footer"); + } + if (mpFooterLeftContent) + { _writeHeaderFooter("style:footer-left", *mpFooterLeftContent, pHandler); pHandler->endElement("style:footer-left"); } + if (mpFooterFirstContent) + { + _writeHeaderFooter("style:footer-first", *mpFooterFirstContent, pHandler); + pHandler->endElement("style:footer-first"); + } + /* + if (mpFooterLastContent) + { + _writeHeaderFooter("style:footer-last", *mpFooterLastContent, pHandler); + pHandler->endElement("style:footer-last"); + } + */ pHandler->endElement("style:master-page"); } diff -Nru libodfgen-0.0.4/src/PageSpan.hxx libodfgen-0.1.1/src/PageSpan.hxx --- libodfgen-0.0.4/src/PageSpan.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/PageSpan.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -25,7 +25,7 @@ #ifndef _PAGESPAN_HXX_ #define _PAGESPAN_HXX_ -#include +#include #include class DocumentElement; @@ -34,7 +34,7 @@ class PageSpan { public: - PageSpan(const WPXPropertyList &xPropList); + PageSpan(const librevenge::RVNGPropertyList &xPropList); virtual ~PageSpan(); void writePageLayout(const int iNum, OdfDocumentHandler *pHandler) const; void writeMasterPages(const int iStartingNum, const int iPageLayoutNum, const bool bLastPageSpan, OdfDocumentHandler *pHandler) const; @@ -44,17 +44,25 @@ void setFooterContent(std::vector *pFooterContent); void setHeaderLeftContent(std::vector *pHeaderContent); void setFooterLeftContent(std::vector *pFooterContent); + void setHeaderFirstContent(std::vector *pHeaderContent); + void setFooterFirstContent(std::vector *pFooterContent); + void setHeaderLastContent(std::vector *pHeaderContent); + void setFooterLastContent(std::vector *pFooterContent); protected: void _writeHeaderFooter(const char *headerFooterTagName, const std::vector &headerFooterContent, OdfDocumentHandler *pHandler) const; private: PageSpan(const PageSpan &); PageSpan &operator=(const PageSpan &); - WPXPropertyList mxPropList; + librevenge::RVNGPropertyList mxPropList; std::vector *mpHeaderContent; std::vector *mpFooterContent; std::vector *mpHeaderLeftContent; std::vector *mpFooterLeftContent; + std::vector *mpHeaderFirstContent; + std::vector *mpFooterFirstContent; + std::vector *mpHeaderLastContent; + std::vector *mpFooterLastContent; }; #endif diff -Nru libodfgen-0.0.4/src/SectionStyle.cxx libodfgen-0.1.1/src/SectionStyle.cxx --- libodfgen-0.0.4/src/SectionStyle.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/SectionStyle.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -32,12 +32,10 @@ double rint(double x); #endif /* _WIN32 */ -SectionStyle::SectionStyle(const WPXPropertyList &xPropList, - const WPXPropertyListVector &xColumns, +SectionStyle::SectionStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName) : Style(psName), - mPropList(xPropList), - mColumns(xColumns) + mPropList(xPropList) { } @@ -48,42 +46,43 @@ styleOpen.addAttribute("style:family", "section"); styleOpen.write(pHandler); - WPXPropertyList propList; - WPXPropertyList::Iter p(mPropList); - for (p.rewind(); p.next(); ) + librevenge::RVNGPropertyList propList; + librevenge::RVNGPropertyList::Iter p(mPropList); + for (p.rewind(); p.next();) { - if (strncmp(p.key(), "libwpd:", 7) != 0) + if (strncmp(p.key(), "librevenge:", 11) && !p.child()) propList.insert(p.key(), p()->getStr()); } pHandler->startElement("style:section-properties", propList); // column properties - WPXPropertyList columnProps; + librevenge::RVNGPropertyList columnProps; // if the number of columns is <= 1, we will never come here. This is only an additional check // style properties - if (mColumns.count() > 1) + const librevenge::RVNGPropertyListVector *columns = mPropList.child("style:columns"); + if (columns && columns->count() > 1) { - columnProps.insert("fo:column-count", (int)mColumns.count()); + columnProps.insert("fo:column-count", (int)columns->count()); pHandler->startElement("style:columns", columnProps); - if (mPropList["libwpd:colsep-width"] && mPropList["libwpd:colsep-color"]) + if (mPropList["librevenge:colsep-width"] && mPropList["librevenge:colsep-color"]) { - WPXPropertyList columnSeparator; - columnSeparator.insert("style:width", mPropList["libwpd:colsep-width"]->getStr()); - columnSeparator.insert("style:color", mPropList["libwpd:colsep-color"]->getStr()); - if (mPropList["libwpd:colsep-height"]) - columnSeparator.insert("style:height", mPropList["libwpd:colsep-height"]->getStr()); + librevenge::RVNGPropertyList columnSeparator; + columnSeparator.insert("style:width", mPropList["librevenge:colsep-width"]->getStr()); + columnSeparator.insert("style:color", mPropList["librevenge:colsep-color"]->getStr()); + if (mPropList["librevenge:colsep-height"]) + columnSeparator.insert("style:height", mPropList["librevenge:colsep-height"]->getStr()); else columnSeparator.insert("style:height", "100%"); - if (mPropList["libwpd:colsep-vertical-align"]) - columnSeparator.insert("style:vertical-align", mPropList["libwpd:colsep-vertical-align"]->getStr()); + if (mPropList["librevenge:colsep-vertical-align"]) + columnSeparator.insert("style:vertical-align", mPropList["librevenge:colsep-vertical-align"]->getStr()); else columnSeparator.insert("style:vertical-align", "middle"); pHandler->startElement("style:column-sep", columnSeparator); pHandler->endElement("style:column-sep"); } - WPXPropertyListVector::Iter i(mColumns); + librevenge::RVNGPropertyListVector::Iter i(*columns); for (i.rewind(); i.next();) { pHandler->startElement("style:column", i()); diff -Nru libodfgen-0.0.4/src/SectionStyle.hxx libodfgen-0.1.1/src/SectionStyle.hxx --- libodfgen-0.0.4/src/SectionStyle.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/SectionStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -25,8 +25,7 @@ #ifndef _SECTIONSTYLE_HXX_ #define _SECTIONSTYLE_HXX_ -#include -#include +#include #include "Style.hxx" @@ -34,12 +33,11 @@ class SectionStyle : public Style { public: - SectionStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &xColumns, const char *psName); + SectionStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName); virtual void write(OdfDocumentHandler *pHandler) const; private: - WPXPropertyList mPropList; - WPXPropertyListVector mColumns; + librevenge::RVNGPropertyList mPropList; }; #endif diff -Nru libodfgen-0.0.4/src/SheetStyle.cxx libodfgen-0.1.1/src/SheetStyle.cxx --- libodfgen-0.0.4/src/SheetStyle.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/SheetStyle.cxx 2014-06-02 17:08:51.000000000 +0000 @@ -0,0 +1,708 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#include +#ifdef _MSC_VER +# include +#endif +#include + +#include +#include + +#include "DocumentElement.hxx" +#include "FilterInternal.hxx" +#include "TextRunStyle.hxx" + +#include "SheetStyle.hxx" + +SheetNumberingStyle::SheetNumberingStyle(const librevenge::RVNGPropertyList &xPropList, const librevenge::RVNGString &psName) + : Style(psName), mPropList(xPropList) +{ +} + +void SheetNumberingStyle::writeCondition(librevenge::RVNGPropertyList const &propList, OdfDocumentHandler *pHandler, SheetStyle const &sheet) const +{ + librevenge::RVNGString applyName(""); + librevenge::RVNGPropertyListVector const *formula=propList.child("librevenge:formula"); + librevenge::RVNGString formulaString(""); + if (!formula||!propList["librevenge:name"]|| + (applyName=sheet.getNumberingStyleName(propList["librevenge:name"]->getStr())).empty() || + (formulaString=SheetManager::convertFormula(*formula)).empty()) + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeCondition: can not find condition data\n")); + return; + } + TagOpenElement mapOpen("style:map"); + mapOpen.addAttribute("style:condition",formulaString); + mapOpen.addAttribute("style:apply-style-name",applyName); + mapOpen.write(pHandler); + TagCloseElement("style:map").write(pHandler); +} + +void SheetNumberingStyle::writeStyle(OdfDocumentHandler *pHandler, SheetStyle const &sheet) const +{ + if (!mPropList["librevenge:value-type"]) + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: can not find value type\n")); + return; + } + std::string type(mPropList["librevenge:value-type"]->getStr().cstr()); + librevenge::RVNGString what(""); + if (type.substr(0,7)=="number:") type=type.substr(7); + size_t len=type.length(); + if (len>5 && type.substr(len-5)=="-type") type=type.substr(0,len-5); + if (type=="float" || type=="double") type="number"; + else if (type=="percent") type="percentage"; + else if (type=="bool") type="boolean"; + if (type=="number" || type=="fraction" || type=="percentage" || type=="scientific") + { + what.sprintf("number:%s-style", type=="percentage" ? "percentage" : "number"); + TagOpenElement styleOpen(what); + styleOpen.addAttribute("style:name", getName()); + styleOpen.write(pHandler); + librevenge::RVNGString subWhat; + subWhat.sprintf("number:%s", type=="percentage" ? "number" : type=="scientific" ? "scientific-number" : type.c_str()); + TagOpenElement number(subWhat); + if (mPropList["number:decimal-places"]) + number.addAttribute("number:decimal-places", mPropList["number:decimal-places"]->getStr()); + if (mPropList["number:min-integer-digits"]) + number.addAttribute("number:min-integer-digits", mPropList["number:min-integer-digits"]->getStr()); + else + number.addAttribute("number:min-integer-digits", "1"); + if (mPropList["number:grouping"]) + number.addAttribute("number:grouping", mPropList["number:grouping"]->getStr()); + if (type=="scientific") + { + if (mPropList["number:min-exponent-digits"]) + number.addAttribute("number:min-exponent-digits", mPropList["number:min-exponent-digits"]->getStr()); + else + number.addAttribute("number:min-exponent-digits", "2"); + } + else if (type=="fraction") + { + if (mPropList["number:min-numerator-digits"]) + number.addAttribute("number:min-numerator-digits", mPropList["number:min-numerator-digits"]->getStr()); + if (mPropList["number:min-denominator-digits"]) + number.addAttribute("number:min-denominator-digits", mPropList["number:min-denominator-digits"]->getStr()); + } + number.write(pHandler); + TagCloseElement(subWhat).write(pHandler); + if (type=="percentage") + { + TagOpenElement("number:text").write(pHandler); + pHandler->characters("%"); + TagCloseElement("number:text").write(pHandler); + } + } + else if (type=="boolean") + { + what="number:boolean-style"; + TagOpenElement styleOpen(what); + styleOpen.addAttribute("style:name", getName()); + styleOpen.write(pHandler); + TagOpenElement("number:boolean").write(pHandler); + TagCloseElement("number:boolean").write(pHandler); + } + else if (type=="time" || type=="date") + { + what.sprintf("number:%s-style", type.c_str()); + TagOpenElement styleOpen(what); + styleOpen.addAttribute("style:name", getName()); + if (mPropList["number:language"]) + styleOpen.addAttribute("number:language", mPropList["number:language"]->getStr()); + if (mPropList["number:country"]) + styleOpen.addAttribute("number:country", mPropList["number:country"]->getStr()); + if (type=="date" && mPropList["number:automatic-order"]) + styleOpen.addAttribute("number:automatic-order", mPropList["number:automatic-order"]->getStr()); + styleOpen.write(pHandler); + } + else if (type=="currency") + { + what.sprintf("number:currency-style", type.c_str()); + TagOpenElement styleOpen(what); + styleOpen.addAttribute("style:name", getName()); + styleOpen.write(pHandler); + } + else + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: unexpected value type %s\n", type.c_str())); + return; + } + librevenge::RVNGPropertyListVector const *format=mPropList.child("librevenge:format"); + // now read the potential formats sub list + for (unsigned long f=0; format && f < format->count(); ++f) + { + librevenge::RVNGPropertyList const &prop=(*format)[f]; + if (!prop["librevenge:value-type"]) + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: can not find format type[%d]\n", int(f))); + continue; + } + std::string wh=prop["librevenge:value-type"]->getStr().cstr(); + if (wh.substr(0,7)=="number:") wh=wh.substr(7); + + if (wh=="number") + { + TagOpenElement formatOpen("number:number"); + if (prop["number:decimal-places"]) + formatOpen.addAttribute("number:decimal-places", prop["number:decimal-places"]->getStr()); + if (prop["number:min-integer-digits"]) + formatOpen.addAttribute("number:min-integer-digits", prop["number:min-integer-digits"]->getStr()); + else + formatOpen.addAttribute("number:min-integer-digits", "1"); + if (prop["number:grouping"]) + formatOpen.addAttribute("number:grouping", prop["number:grouping"]->getStr()); + formatOpen.write(pHandler); + TagCloseElement("number:number").write(pHandler); + } + else if (wh=="year" || wh=="month" || wh=="day" || wh=="day-of-week" || wh=="quarter" || wh=="week-of-year" || + wh=="hours" || wh=="minutes" || wh=="seconds" || wh=="am-pm") + { + librevenge::RVNGString subWhat; + subWhat.sprintf("number:%s", wh.c_str()); + TagOpenElement formatOpen(subWhat); + if (prop["number:style"]) + formatOpen.addAttribute("number:style", prop["number:style"]->getStr()); + if (prop["number:textual"]) + formatOpen.addAttribute("number:textual", prop["number:textual"]->getStr()); + formatOpen.write(pHandler); + TagCloseElement(subWhat).write(pHandler); + } + else if (wh=="text") + { + if (prop["librevenge:text"]) + { + TagOpenElement("number:text").write(pHandler); + pHandler->characters(prop["librevenge:text"]->getStr()); + TagCloseElement("number:text").write(pHandler); + } + else + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: can not find text data\n")); + } + } + else if (wh=="currency-symbol") + { + if (prop["librevenge:currency"]) + { + TagOpenElement currency("number:currency-symbol"); + if (prop["number:language"]) + currency.addAttribute("number:language", prop["number:language"]->getStr()); + if (prop["number:country"]) + currency.addAttribute("number:country", prop["number:country"]->getStr()); + currency.write(pHandler); + pHandler->characters(prop["librevenge:currency"]->getStr()); + TagCloseElement("number:currency-symbol").write(pHandler); + } + else + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: can not find currency data\n")); + } + } + else + { + ODFGEN_DEBUG_MSG(("SheetNumberingStyle::writeStyle: find unexpected format type:%s\n", wh.c_str())); + } + } + + librevenge::RVNGPropertyListVector const *conditions=mPropList.child("librevenge::conditions"); + for (unsigned long c=0; c < (conditions ? conditions->count() : 0); ++c) + writeCondition((*conditions)[c], pHandler, sheet); + TagCloseElement(what).write(pHandler); +} + +SheetCellStyle::SheetCellStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName) : + Style(psName), + mPropList(xPropList) +{ +} + +void SheetCellStyle::writeStyle(OdfDocumentHandler *pHandler, SheetStyle const &sheet) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + if (mPropList["style:parent-style-name"]) + styleOpen.addAttribute("style:parent-style-name", mPropList["style:parent-style-name"]->getStr()); + styleOpen.addAttribute("style:family", "table-cell"); + if (mPropList["librevenge:numbering-name"]) + { + librevenge::RVNGString numberingName= + sheet.getNumberingStyleName(mPropList["librevenge:numbering-name"]->getStr()); + if (numberingName.empty()) + { + ODFGEN_DEBUG_MSG(("SheetCellStyle::writeStyle can not find numbering style %s\n", mPropList["librevenge:numbering-name"]->getStr().cstr())); + } + else + styleOpen.addAttribute("style:data-style-name", numberingName.cstr()); + } + styleOpen.write(pHandler); + + librevenge::RVNGPropertyList textProp; + SpanStyleManager::addSpanProperties(mPropList, textProp); + if (!textProp.empty()) + { + pHandler->startElement("style:text-properties", textProp); + pHandler->endElement("style:text-properties"); + } + // WLACH_REFACTORING: Only temporary.. a much better solution is to + // generalize this sort of thing into the "Style" superclass + librevenge::RVNGPropertyList stylePropList; + librevenge::RVNGPropertyList::Iter i(mPropList); + /* first set padding, so that mPropList can redefine, if + mPropList["fo:padding"] is defined */ + stylePropList.insert("fo:padding", "0.0382in"); + bool hasTextAlign=false; + for (i.rewind(); i.next();) + { + int len = (int) strlen(i.key()); + if (len > 2 && !strncmp(i.key(), "fo", 2)) + { + if (len==13 && !strcmp(i.key(), "fo:text-align")) + hasTextAlign=true; + else + stylePropList.insert(i.key(), i()->clone()); + } + else if (len > 22 && !strncmp(i.key(), "style:border-line-width", 23)) + { + if (!strcmp(i.key(), "style:border-line-width") || + !strcmp(i.key(), "style:border-line-width-left") || + !strcmp(i.key(), "style:border-line-width-right") || + !strcmp(i.key(), "style:border-line-width-top")|| + !strcmp(i.key(), "style:border-line-width-bottom")) + stylePropList.insert(i.key(), i()->clone()); + } + else if (len == 23 && !strcmp(i.key(), "style:text-align-source")) + stylePropList.insert(i.key(), i()->clone()); + else if (len == 18 && !strcmp(i.key(), "style:cell-protect")) + stylePropList.insert(i.key(), i()->clone()); + else if (!strcmp(i.key(), "style:vertical-align")) + stylePropList.insert(i.key(), i()->clone()); + } + pHandler->startElement("style:table-cell-properties", stylePropList); + pHandler->endElement("style:table-cell-properties"); + + if (hasTextAlign) + { + librevenge::RVNGPropertyList paragPropList; + paragPropList.insert("fo:margin-left", "0cm"); + paragPropList.insert("fo:text-align", mPropList["fo:text-align"]->clone()); + pHandler->startElement("style:paragraph-properties", paragPropList); + pHandler->endElement("style:paragraph-properties"); + } + pHandler->endElement("style:style"); +} + +SheetRowStyle::SheetRowStyle(const librevenge::RVNGPropertyList &propList, const char *psName) : + Style(psName), + mPropList(propList) +{ +} + +void SheetRowStyle::write(OdfDocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "table-row"); + styleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:table-row-properties"); + if (mPropList["style:min-row-height"]) + stylePropertiesOpen.addAttribute("style:min-row-height", mPropList["style:min-row-height"]->getStr()); + else if (mPropList["style:row-height"]) + stylePropertiesOpen.addAttribute("style:row-height", mPropList["style:row-height"]->getStr()); + stylePropertiesOpen.addAttribute("fo:keep-together", "auto"); + stylePropertiesOpen.write(pHandler); + pHandler->endElement("style:table-row-properties"); + + pHandler->endElement("style:style"); +} + + +SheetStyle::SheetStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName) : + Style(psName), mPropList(xPropList), mColumns(0), + mRowNameHash(), mRowStyleHash(), mCellNameHash(), mCellStyleHash(), mNumberingHash() +{ + mColumns = mPropList.child("librevenge:columns"); +} + +SheetStyle::~SheetStyle() +{ +} + +void SheetStyle::write(OdfDocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "table"); + if (mPropList["style:master-page-name"]) + styleOpen.addAttribute("style:master-page-name", mPropList["style:master-page-name"]->getStr()); + styleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:table-properties"); + stylePropertiesOpen.addAttribute("table:display", "true"); + if (mPropList["table:align"]) + stylePropertiesOpen.addAttribute("table:align", mPropList["table:align"]->getStr()); + if (mPropList["fo:margin-left"]) + stylePropertiesOpen.addAttribute("fo:margin-left", mPropList["fo:margin-left"]->getStr()); + if (mPropList["fo:margin-right"]) + stylePropertiesOpen.addAttribute("fo:margin-right", mPropList["fo:margin-right"]->getStr()); + if (mPropList["style:width"]) + stylePropertiesOpen.addAttribute("style:width", mPropList["style:width"]->getStr()); + if (mPropList["fo:break-before"]) + stylePropertiesOpen.addAttribute("fo:break-before", mPropList["fo:break-before"]->getStr()); + if (mPropList["table:border-model"]) + stylePropertiesOpen.addAttribute("table:border-model", mPropList["table:border-model"]->getStr()); + stylePropertiesOpen.write(pHandler); + + pHandler->endElement("style:table-properties"); + + pHandler->endElement("style:style"); + + int col=1; + if (mColumns) + { + librevenge::RVNGPropertyListVector::Iter j(*mColumns); + for (j.rewind(); j.next(); ++col) + { + TagOpenElement columnStyleOpen("style:style"); + librevenge::RVNGString sColumnName; + sColumnName.sprintf("%s_col%i", getName().cstr(), col); + columnStyleOpen.addAttribute("style:name", sColumnName); + columnStyleOpen.addAttribute("style:family", "table-column"); + columnStyleOpen.write(pHandler); + + pHandler->startElement("style:table-column-properties", j()); + pHandler->endElement("style:table-column-properties"); + + pHandler->endElement("style:style"); + } + } + + std::map >::const_iterator rIt; + for (rIt=mRowStyleHash.begin(); rIt!=mRowStyleHash.end(); ++rIt) + { + if (!rIt->second) continue; + rIt->second->write(pHandler); + } + + std::map >::const_iterator nIt; + for (nIt=mNumberingHash.begin(); nIt!=mNumberingHash.end(); ++nIt) + { + if (!nIt->second) continue; + nIt->second->writeStyle(pHandler, *this); + } + + std::map >::const_iterator cIt; + for (cIt=mCellStyleHash.begin(); cIt!=mCellStyleHash.end(); ++cIt) + { + if (!cIt->second) continue; + cIt->second->writeStyle(pHandler, *this); + } +} + +librevenge::RVNGString SheetStyle::getNumberingStyleName(librevenge::RVNGString const &localName) const +{ + std::map >::const_iterator it= + mNumberingHash.find(localName); + if (it==mNumberingHash.end() || !it->second) + { + ODFGEN_DEBUG_MSG(("SheetStyle::getNumberingStyleName: can not find %s\n", localName.cstr())); + return librevenge::RVNGString(""); + } + return it->second->getName(); +} + +void SheetStyle::addNumberingStyle(const librevenge::RVNGPropertyList &xPropList) +{ + if (!xPropList["librevenge:name"] || xPropList["librevenge:name"]->getStr().len()==0) + { + ODFGEN_DEBUG_MSG(("SheetStyle::addNumberingStyle: can not find the style name\n")); + return; + } + librevenge::RVNGString name(xPropList["librevenge:name"]->getStr()); + librevenge::RVNGString finalName; + if (mNumberingHash.find(name)!=mNumberingHash.end() && mNumberingHash.find(name)->second) + finalName=mNumberingHash.find(name)->second->getName(); + else + finalName.sprintf("%s_num%i", getName().cstr(), (int) mNumberingHash.size()); + + shared_ptr style(new SheetNumberingStyle(xPropList, finalName)); + mNumberingHash[name]=style; +} + +librevenge::RVNGString SheetStyle::addRow(const librevenge::RVNGPropertyList &propList) +{ + // first remove unused data + librevenge::RVNGPropertyList pList; + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (!strncmp(i.key(), "librevenge:", 11)) + continue; + if (i.child()) + continue; + pList.insert(i.key(),i()->clone()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + std::map::const_iterator iter = + mRowNameHash.find(hashKey); + if (iter!=mRowNameHash.end()) return iter->second; + + librevenge::RVNGString name; + name.sprintf("%s_row%i", getName().cstr(), (int) mRowStyleHash.size()); + mRowNameHash[hashKey]=name; + mRowStyleHash[name]=shared_ptr(new SheetRowStyle(propList, name.cstr())); + return name; +} + +librevenge::RVNGString SheetStyle::addCell(const librevenge::RVNGPropertyList &propList) +{ + // first remove unused data + librevenge::RVNGPropertyList pList; + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (!strncmp(i.key(), "librevenge:", 11) && + strncmp(i.key(), "librevenge:numbering-name", 24)) + continue; + if (i.child()) + continue; + pList.insert(i.key(),i()->clone()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + std::map::const_iterator iter = + mCellNameHash.find(hashKey); + if (iter!=mCellNameHash.end()) return iter->second; + + librevenge::RVNGString name; + name.sprintf("%s_cell%i", getName().cstr(), (int) mCellStyleHash.size()); + mCellNameHash[hashKey]=name; + mCellStyleHash[name]=shared_ptr(new SheetCellStyle(propList, name.cstr())); + return name; +} + +SheetManager::SheetManager() : mbSheetOpened(false), mSheetStyles() +{ +} + +SheetManager::~SheetManager() +{ +} + +void SheetManager::clean() +{ + mSheetStyles.clear(); +} + +bool SheetManager::openSheet(const librevenge::RVNGPropertyList &xPropList) +{ + if (mbSheetOpened) + { + ODFGEN_DEBUG_MSG(("SheetManager::oops: a sheet is already open\n")); + return false; + } + mbSheetOpened=true; + librevenge::RVNGString sTableName; + sTableName.sprintf("Sheet%i", (int) mSheetStyles.size()); + shared_ptr sheet(new SheetStyle(xPropList, sTableName.cstr())); + mSheetStyles.push_back(sheet); + return true; +} + +bool SheetManager::closeSheet() +{ + if (!mbSheetOpened) + { + ODFGEN_DEBUG_MSG(("SheetManager::oops: no sheet are opened\n")); + return false; + } + mbSheetOpened=false; + return true; +} + +librevenge::RVNGString SheetManager::convertFormula(const librevenge::RVNGPropertyListVector &formula) +{ + librevenge::RVNGString res(""); + std::stringstream s; + s << "of:="; + for (unsigned long i=0; igetStr().cstr()); + if (type=="librevenge-operator") + { + if (!list["librevenge:operator"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula can not find operator for formula[%s]!!!\n", s.str().c_str())); + return res; + } + std::string oper(list["librevenge:operator"]->getStr().cstr()); + bool find=false; + for (int w=0; w<14; ++w) + { + static char const *(s_operators[14])= + { + "(", ")", "+", "-", "*", "/", "=", "<>", ";", "<", ">", "<=", ">=", "^" + }; + if (oper!=s_operators[w]) continue; + s << oper; + find=true; + break; + } + if (!find) + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula find unknown operator for formula[%s]!!!\n", s.str().c_str())); + return res; + } + } + else if (type=="librevenge-function") + { + if (!list["librevenge:function"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula can not find value for formula[%s]!!!\n", s.str().c_str())); + return res; + } + s << list["librevenge:function"]->getStr().cstr(); + } + else if (type=="librevenge-number") + { + if (!list["librevenge:number"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula can not find value for formula[%s]!!!\n", s.str().c_str())); + return res; + } + s << list["librevenge:number"]->getStr().cstr(); + } + else if (type=="librevenge-text") + { + if (!list["librevenge:text"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula can not find text for formula[%s]!!!\n", s.str().c_str())); + return res; + } + librevenge::RVNGString escaped; + escaped.appendEscapedXML(list["librevenge:text"]->getStr()); + s << "\"" << escaped.cstr() << "\""; + } + else if (type=="librevenge-cell") + { + librevenge::RVNGString range=convertCellRange(list); + if (range.empty()) return res; + s << "[" << range.cstr() << "]"; + } + else if (type=="librevenge-cells") + { + librevenge::RVNGString ranges=convertCellsRange(list); + if (ranges.empty()) return res; + s << "[" << ranges.cstr() << "]"; + } + else + { + ODFGEN_DEBUG_MSG(("SheetManager::addFormula find unknown type %s!!!\n", type.c_str())); + return res; + } + } + return librevenge::RVNGString::escapeXML(s.str().c_str()); +} + +librevenge::RVNGString SheetManager::convertCellRange(const librevenge::RVNGPropertyList &list) +{ + std::stringstream s; + librevenge::RVNGString res(""); + if (!list["librevenge:row"]||!list["librevenge:column"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::convertCellRange can not find cordinate!!!\n")); + return res; + } + int column=list["librevenge:column"]->getInt(); + int row=list["librevenge:row"]->getInt(); + if (column<0 || row<0) + { + ODFGEN_DEBUG_MSG(("SheetManager::convertCellRange: find bad coordinate!!!\n")); + return res; + } + if (list["librevenge:sheet"]) s << list["librevenge:sheet"]->getStr().cstr(); + s << "."; + if (list["librevenge:column-absolute"] && list["librevenge:column-absolute"]->getInt()) s << "$"; + if (column>=26) s << char('A'+(column/26-1)); + s << char('A'+(column%26)); + if (list["librevenge:row-absolute"] && list["librevenge:row-absolute"]->getInt()) s << "$"; + s << row+1; + return s.str().c_str(); +} + +librevenge::RVNGString SheetManager::convertCellsRange(const librevenge::RVNGPropertyList &list) +{ + std::stringstream s; + librevenge::RVNGString res(""); + if (!list["librevenge:start-row"]||!list["librevenge:start-column"]) + { + ODFGEN_DEBUG_MSG(("SheetManager::convertCellsRange can not find cordinate!!!\n")); + return res; + } + int column=list["librevenge:start-column"]->getInt(); + int row=list["librevenge:start-row"]->getInt(); + if (column<0 || row<0) + { + ODFGEN_DEBUG_MSG(("SheetManager::convertCellsRange: find bad coordinate1!!!\n")); + return res; + } + if (list["librevenge:sheet-name"]) s << list["librevenge:sheet-name"]->getStr().cstr(); + s << "."; + if (list["librevenge:start-column-absolute"] && list["librevenge:start-column-absolute"]->getInt()) s << "$"; + if (column>=26) s << char('A'+(column/26-1)); + s << char('A'+(column%26)); + if (list["librevenge:start-row-absolute"] && list["librevenge:start-row-absolute"]->getInt()) s << "$"; + s << row+1 << ":"; + if (list["librevenge:end-column"]) + column=list["librevenge:end-column"]->getInt(); + if (list["librevenge:end-row"]) + row=list["librevenge:end-row"]->getInt(); + if (column<0 || row<0) + { + ODFGEN_DEBUG_MSG(("SheetManager::convertCellsRange: find bad coordinate2!!!\n")); + return res; + } + if (list["librevenge:end-column-absolute"] && list["librevenge:end-column-absolute"]->getInt()) s << "$"; + if (column>=26) s << char('A'+(column/26-1)); + s << char('A'+(column%26)); + if (list["librevenge:end-row-absolute"] && list["librevenge:end-row-absolute"]->getInt()) s << "$"; + s << row+1; + return s.str().c_str(); +} + +void SheetManager::write(OdfDocumentHandler *pHandler) const +{ + for (size_t i=0; i < mSheetStyles.size(); ++i) + { + if (mSheetStyles[i]) + mSheetStyles[i]->write(pHandler); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/SheetStyle.hxx libodfgen-0.1.1/src/SheetStyle.hxx --- libodfgen-0.0.4/src/SheetStyle.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/src/SheetStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2003 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _SHEETSTYLE_HXX_ +#define _SHEETSTYLE_HXX_ +#include +#include +#include +#include + +#include "FilterInternal.hxx" + +#include "Style.hxx" + +class OdfDocumentHandler; +class SheetManager; +class SheetStyle; + +class SheetNumberingStyle : public Style +{ +public: + SheetNumberingStyle(const librevenge::RVNGPropertyList &xPropList, const librevenge::RVNGString &psName); + virtual ~SheetNumberingStyle() {}; + void writeStyle(OdfDocumentHandler *pHandler, SheetStyle const &sheet) const; + +private: + void writeCondition(librevenge::RVNGPropertyList const &propList, OdfDocumentHandler *pHandler, SheetStyle const &sheet) const; + + librevenge::RVNGPropertyList mPropList; +}; + +class SheetCellStyle : public Style +{ +public: + virtual ~SheetCellStyle() {}; + SheetCellStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName); + virtual void writeStyle(OdfDocumentHandler *pHandler, SheetStyle const &manager) const; +private: + librevenge::RVNGPropertyList mPropList; +}; + +class SheetRowStyle : public Style +{ +public: + virtual ~SheetRowStyle() {}; + SheetRowStyle(const librevenge::RVNGPropertyList &propList, const char *psName); + virtual void write(OdfDocumentHandler *pHandler) const; +private: + librevenge::RVNGPropertyList mPropList; +}; + +class SheetStyle : public Style, public TopLevelElementStyle +{ +public: + SheetStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName); + virtual ~SheetStyle(); + virtual void write(OdfDocumentHandler *pHandler) const; + int getNumColumns() const + { + return mColumns ? (int)mColumns->count() : 0; + } + + librevenge::RVNGString addCell(const librevenge::RVNGPropertyList &propList); + librevenge::RVNGString addRow(const librevenge::RVNGPropertyList &propList); + + void addNumberingStyle(const librevenge::RVNGPropertyList &xPropList); + librevenge::RVNGString getNumberingStyleName(librevenge::RVNGString const &localName) const; + +private: + librevenge::RVNGPropertyList mPropList; + librevenge::RVNGPropertyListVector const *mColumns; + + // hash key -> row style name + std::map mRowNameHash; + // style name -> SheetRowStyle + std::map > mRowStyleHash; + // hash key -> cell style name + std::map mCellNameHash; + // style name -> SheetCellStyle + std::map > mCellStyleHash; + // style name -> NumberingStyle + std::map > mNumberingHash; + + // Disable copying + SheetStyle(const SheetStyle &); + SheetStyle &operator=(const SheetStyle &); +}; + +class SheetManager +{ +public: + SheetManager(); + virtual ~SheetManager(); + //! clean all data + void clean(); + void write(OdfDocumentHandler *pHandler) const; + + bool isSheetOpened() const + { + return mbSheetOpened; + } + SheetStyle *actualSheet() + { + if (!mbSheetOpened || !mSheetStyles.back()) return 0; + return mSheetStyles.back().get(); + } + //! open a sheet and update the list of elements + bool openSheet(const librevenge::RVNGPropertyList &xPropList); + bool closeSheet(); + + static librevenge::RVNGString convertFormula(const librevenge::RVNGPropertyListVector &formatsList); + static librevenge::RVNGString convertCellRange(const librevenge::RVNGPropertyList &cell); + static librevenge::RVNGString convertCellsRange(const librevenge::RVNGPropertyList &cells); + +private: + bool mbSheetOpened; + std::vector > mSheetStyles; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/Style.hxx libodfgen-0.1.1/src/Style.hxx --- libodfgen-0.0.4/src/Style.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/Style.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -25,48 +25,35 @@ #ifndef _STYLE_HXX_ #define _STYLE_HXX_ -#include +#include #include "DocumentElement.hxx" class TopLevelElementStyle { public: - TopLevelElementStyle() : mpsMasterPageName(0) {} - virtual ~TopLevelElementStyle() - { - if (mpsMasterPageName) delete mpsMasterPageName; - } - void setMasterPageName(WPXString &sMasterPageName) - { - if (mpsMasterPageName) delete mpsMasterPageName; - mpsMasterPageName = new WPXString(sMasterPageName); - } - const WPXString *getMasterPageName() const - { - return mpsMasterPageName; - } + TopLevelElementStyle() {} + virtual ~TopLevelElementStyle() {} private: TopLevelElementStyle(const TopLevelElementStyle &); TopLevelElementStyle &operator=(const TopLevelElementStyle &); - WPXString *mpsMasterPageName; }; class Style { public: - Style(const WPXString &psName) : msName(psName) {} + Style(const librevenge::RVNGString &psName) : msName(psName) {} virtual ~Style() {} virtual void write(OdfDocumentHandler *) const {}; - const WPXString &getName() const + const librevenge::RVNGString &getName() const { return msName; } private: - WPXString msName; + librevenge::RVNGString msName; }; class StyleManager diff -Nru libodfgen-0.0.4/src/TableStyle.cxx libodfgen-0.1.1/src/TableStyle.cxx --- libodfgen-0.0.4/src/TableStyle.cxx 2013-12-02 16:52:11.000000000 +0000 +++ libodfgen-0.1.1/src/TableStyle.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -35,13 +35,13 @@ #include -TableCellStyle::TableCellStyle(const WPXPropertyList &xPropList, const char *psName) : +TableCellStyle::TableCellStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName) : Style(psName), mPropList(xPropList) { } -void TableCellStyle::write(OdfDocumentHandler *pHandler) const +void TableCellStyle::writeStyles(OdfDocumentHandler *pHandler, bool compatibleOdp) const { TagOpenElement styleOpen("style:style"); styleOpen.addAttribute("style:name", getName()); @@ -50,40 +50,58 @@ // WLACH_REFACTORING: Only temporary.. a much better solution is to // generalize this sort of thing into the "Style" superclass - WPXPropertyList stylePropList; - WPXPropertyList::Iter i(mPropList); + librevenge::RVNGPropertyList stylePropList; + librevenge::RVNGPropertyList::Iter i(mPropList); /* first set padding, so that mPropList can redefine, if mPropList["fo:padding"] is defined */ - stylePropList.insert("fo:padding", "0.0382in"); + stylePropList.insert("fo:padding", 0.0382); for (i.rewind(); i.next();) { - if (strlen(i.key()) > 2 && strncmp(i.key(), "fo", 2) == 0) + if (!strncmp(i.key(), "fo", 2)) stylePropList.insert(i.key(), i()->clone()); - else if (strlen(i.key()) > 22 && strncmp(i.key(), "style:border-line-width", 23) == 0) + else if (!strncmp(i.key(), "style:border-line-width", 23)) { - if (strcmp(i.key(), "style:border-line-width") == 0 || - strcmp(i.key(), "style:border-line-width-left") == 0 || - strcmp(i.key(), "style:border-line-width-right") == 0 || - strcmp(i.key(), "style:border-line-width-top") == 0 || - strcmp(i.key(), "style:border-line-width-bottom") == 0) + if (!strcmp(i.key(), "style:border-line-width") || + !strcmp(i.key(), "style:border-line-width-left") || + !strcmp(i.key(), "style:border-line-width-right") || + !strcmp(i.key(), "style:border-line-width-top") || + !strcmp(i.key(), "style:border-line-width-bottom")) stylePropList.insert(i.key(), i()->clone()); } - else if (strcmp(i.key(), "style:vertical-align")==0) + else if (!strcmp(i.key(), "style:vertical-align")) stylePropList.insert(i.key(), i()->clone()); } pHandler->startElement("style:table-cell-properties", stylePropList); pHandler->endElement("style:table-cell-properties"); - writeCompat(pHandler, mPropList); + if (compatibleOdp) + { + librevenge::RVNGPropertyList pList; + pList.insert("fo:padding", "0.0382in"); + if (mPropList["draw:fill"]) + pList.insert("draw:fill", mPropList["draw:fill"]->getStr()); + if (mPropList["draw:fill-color"]) + pList.insert("draw:fill-color", mPropList["draw:fill-color"]->getStr()); + if (mPropList["fo:padding"]) + pList.insert("fo:padding", mPropList["fo:padding"]->getStr()); + if (mPropList["draw:textarea-horizontal-align"]) + pList.insert("draw:textarea-horizontal-align", mPropList["draw:textarea-horizontal-align"]->getStr()); + pHandler->startElement("style:graphic-properties", pList); + pHandler->endElement("style:graphic-properties"); + // HACK to get visible borders + if (mPropList["fo:border"]) + { + pList.clear(); + pList.insert("fo:border", mPropList["fo:border"]->getStr()); + pHandler->startElement("style:paragraph-properties", pList); + pHandler->endElement("style:paragraph-properties"); + } + } pHandler->endElement("style:style"); } -void TableCellStyle::writeCompat(OdfDocumentHandler *, const WPXPropertyList &) const -{ -} - -TableRowStyle::TableRowStyle(const WPXPropertyList &propList, const char *psName) : +TableRowStyle::TableRowStyle(const librevenge::RVNGPropertyList &propList, const char *psName) : Style(psName), mPropList(propList) { @@ -109,32 +127,129 @@ } -TableStyle::TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName) : - Style(psName), - mPropList(xPropList), - mColumns(columns), - mTableCellStyles(), - mTableRowStyles() +Table::Table(const librevenge::RVNGPropertyList &xPropList, const char *psName) : + Style(psName), mPropList(xPropList), + mbRowOpened(false), mbRowHeaderOpened(false), mbCellOpened(false), + mRowNameHash(), mRowStyleHash(), mCellNameHash(), mCellStyleHash() +{ +} + +Table::~Table() +{ +} + +int Table::getNumColumns() const +{ + const librevenge::RVNGPropertyListVector *columns = mPropList.child("librevenge:table-columns"); + if (columns) + return (int)(columns->count()); + return 0; +} + +librevenge::RVNGString Table::openRow(const librevenge::RVNGPropertyList &propList) +{ + if (mbRowOpened) + { + ODFGEN_DEBUG_MSG(("Table::openRow: a row is already open\n")); + return ""; + } + mbRowOpened=true; + mbRowHeaderOpened=propList["librevenge:is-header-row"] && + propList["librevenge:is-header-row"]->getInt(); + // first remove unused data + librevenge::RVNGPropertyList pList; + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (strncmp(i.key(), "librevenge:", 11)==0) + continue; + if (i.child()) + continue; + pList.insert(i.key(),i()->clone()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + std::map::const_iterator iter = + mRowNameHash.find(hashKey); + if (iter!=mRowNameHash.end()) return iter->second; + + librevenge::RVNGString name; + name.sprintf("%s_row%i", getName().cstr(), (int) mRowStyleHash.size()); + mRowNameHash[hashKey]=name; + mRowStyleHash[name]=shared_ptr(new TableRowStyle(propList, name.cstr())); + return name; +} + +bool Table::closeRow() +{ + if (!mbRowOpened) + { + ODFGEN_DEBUG_MSG(("Table::closeRow: no row is open\n")); + return false; + } + mbRowOpened=mbRowHeaderOpened=false; + return true; +} + +librevenge::RVNGString Table::openCell(const librevenge::RVNGPropertyList &propList) +{ + if (!mbRowOpened || mbCellOpened) + { + ODFGEN_DEBUG_MSG(("Table::openCell: can not open a cell\n")); + return ""; + } + mbCellOpened=true; + // first remove unused data + librevenge::RVNGPropertyList pList; + librevenge::RVNGPropertyList::Iter i(propList); + for (i.rewind(); i.next();) + { + if (!strncmp(i.key(), "librevenge:", 11) && + strncmp(i.key(), "librevenge:numbering-name", 24)) + continue; + if (i.child()) + continue; + pList.insert(i.key(),i()->clone()); + } + librevenge::RVNGString hashKey = pList.getPropString(); + std::map::const_iterator iter = + mCellNameHash.find(hashKey); + if (iter!=mCellNameHash.end()) return iter->second; + + librevenge::RVNGString name; + name.sprintf("%s_cell%i", getName().cstr(), (int) mCellStyleHash.size()); + mCellNameHash[hashKey]=name; + mCellStyleHash[name]=shared_ptr(new TableCellStyle(propList, name.cstr())); + return name; +} + +bool Table::closeCell() { + if (!mbCellOpened) + { + ODFGEN_DEBUG_MSG(("Table::closeCell: no cell are opened\n")); + return false; + } + mbCellOpened=false; + return true; } -TableStyle::~TableStyle() +bool Table::insertCoveredCell(const librevenge::RVNGPropertyList &) { - typedef std::vector::iterator TCSVIter; - typedef std::vector::iterator TRSVIter; - for (TCSVIter iterTableCellStyles = mTableCellStyles.begin() ; iterTableCellStyles != mTableCellStyles.end(); ++iterTableCellStyles) - delete(*iterTableCellStyles); - for (TRSVIter iterTableRowStyles = mTableRowStyles.begin() ; iterTableRowStyles != mTableRowStyles.end(); ++iterTableRowStyles) - delete(*iterTableRowStyles); + if (!mbRowOpened || mbCellOpened) + { + ODFGEN_DEBUG_MSG(("Table::insertCoveredCell: can not open a cell\n")); + return false; + } + return true; } -void TableStyle::write(OdfDocumentHandler *pHandler) const +void Table::writeStyles(OdfDocumentHandler *pHandler, bool compatibleOdp) const { TagOpenElement styleOpen("style:style"); styleOpen.addAttribute("style:name", getName()); styleOpen.addAttribute("style:family", "table"); - if (getMasterPageName()) - styleOpen.addAttribute("style:master-page-name", getMasterPageName()->cstr()); + if (mPropList["style:master-page-name"]) + styleOpen.addAttribute("style:master-page-name", mPropList["style:master-page-name"]->getStr()); styleOpen.write(pHandler); TagOpenElement stylePropertiesOpen("style:table-properties"); @@ -156,32 +271,85 @@ pHandler->endElement("style:style"); - int i=1; - WPXPropertyListVector::Iter j(mColumns); - for (j.rewind(); j.next();) + const librevenge::RVNGPropertyListVector *columns = mPropList.child("librevenge:table-columns"); + if (columns && columns->count()) { - TagOpenElement columnStyleOpen("style:style"); - WPXString sColumnName; - sColumnName.sprintf("%s.Column%i", getName().cstr(), i); - columnStyleOpen.addAttribute("style:name", sColumnName); - columnStyleOpen.addAttribute("style:family", "table-column"); - columnStyleOpen.write(pHandler); + librevenge::RVNGPropertyListVector::Iter j(*columns); + + int i=1; + for (j.rewind(); j.next(); ++i) + { + TagOpenElement columnStyleOpen("style:style"); + librevenge::RVNGString sColumnName; + sColumnName.sprintf("%s.Column%i", getName().cstr(), i); + columnStyleOpen.addAttribute("style:name", sColumnName); + columnStyleOpen.addAttribute("style:family", "table-column"); + columnStyleOpen.write(pHandler); - pHandler->startElement("style:table-column-properties", j()); - pHandler->endElement("style:table-column-properties"); + pHandler->startElement("style:table-column-properties", j()); + pHandler->endElement("style:table-column-properties"); - pHandler->endElement("style:style"); + pHandler->endElement("style:style"); + } + } - i++; + std::map >::const_iterator rIt; + for (rIt=mRowStyleHash.begin(); rIt!=mRowStyleHash.end(); ++rIt) + { + if (!rIt->second) continue; + rIt->second->write(pHandler); } - typedef std::vector::const_iterator TRSVIter; - for (TRSVIter iterTableRow = mTableRowStyles.begin() ; iterTableRow != mTableRowStyles.end(); ++iterTableRow) - (*iterTableRow)->write(pHandler); + std::map >::const_iterator cIt; + for (cIt=mCellStyleHash.begin(); cIt!=mCellStyleHash.end(); ++cIt) + { + if (!cIt->second) continue; + cIt->second->writeStyles(pHandler, compatibleOdp); + } +} + +TableManager::TableManager() : mTableOpened(), mTableStyles() +{ +} - typedef std::vector::const_iterator TCSVIter; - for (TCSVIter iterTableCell = mTableCellStyles.begin() ; iterTableCell != mTableCellStyles.end(); ++iterTableCell) - (*iterTableCell)->write(pHandler); +TableManager::~TableManager() +{ +} + +void TableManager::clean() +{ + mTableOpened.clear(); + mTableStyles.clear(); +} + +bool TableManager::openTable(const librevenge::RVNGPropertyList &xPropList) +{ + librevenge::RVNGString sTableName; + sTableName.sprintf("Table%i", (int) mTableStyles.size()); + shared_ptr table(new Table(xPropList, sTableName.cstr())); + mTableOpened.push_back(table); + mTableStyles.push_back(table); + return true; +} + +bool TableManager::closeTable() +{ + if (mTableOpened.empty()) + { + ODFGEN_DEBUG_MSG(("TableManager::oops: no table are opened\n")); + return false; + } + mTableOpened.pop_back(); + return true; +} + +void TableManager::write(OdfDocumentHandler *pHandler, bool compatibleOdp) const +{ + for (size_t i=0; i < mTableStyles.size(); ++i) + { + if (mTableStyles[i]) + mTableStyles[i]->writeStyles(pHandler, compatibleOdp); + } } /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/TableStyle.hxx libodfgen-0.1.1/src/TableStyle.hxx --- libodfgen-0.0.4/src/TableStyle.hxx 2013-12-02 16:51:28.000000000 +0000 +++ libodfgen-0.1.1/src/TableStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -26,9 +26,14 @@ #ifndef _TABLESTYLE_HXX_ #define _TABLESTYLE_HXX_ -#include +#include + +#include #include +// for shared_ptr +#include "FilterInternal.hxx" + #include "Style.hxx" class OdfDocumentHandler; @@ -37,56 +42,99 @@ { public: virtual ~TableCellStyle() {}; - TableCellStyle(const WPXPropertyList &xPropList, const char *psName); - virtual void write(OdfDocumentHandler *pHandler) const; -private: - virtual void writeCompat(OdfDocumentHandler *pHandler, const WPXPropertyList &propList) const; + TableCellStyle(const librevenge::RVNGPropertyList &xPropList, const char *psName); + virtual void writeStyles(OdfDocumentHandler *pHandler, bool odpCompat=false) const; private: - WPXPropertyList mPropList; + librevenge::RVNGPropertyList mPropList; }; class TableRowStyle : public Style { public: virtual ~TableRowStyle() {}; - TableRowStyle(const WPXPropertyList &propList, const char *psName); + TableRowStyle(const librevenge::RVNGPropertyList &propList, const char *psName); virtual void write(OdfDocumentHandler *pHandler) const; private: - WPXPropertyList mPropList; + librevenge::RVNGPropertyList mPropList; }; -class TableStyle : public Style, public TopLevelElementStyle +class Table : public Style, public TopLevelElementStyle { public: - TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName); - virtual ~TableStyle(); - virtual void write(OdfDocumentHandler *pHandler) const; - int getNumColumns() const + Table(const librevenge::RVNGPropertyList &xPropList, const char *psName); + virtual ~Table(); + virtual void writeStyles(OdfDocumentHandler *pHandler, bool compatibleOdp=false) const; + int getNumColumns() const; + + librevenge::RVNGString openRow(const librevenge::RVNGPropertyList &propList); + bool closeRow(); + bool isRowOpened(bool &inHeaderRow) const { - return (int)mColumns.count(); + inHeaderRow=mbRowHeaderOpened; + return mbRowOpened; } - void addTableCellStyle(TableCellStyle *pTableCellStyle) + librevenge::RVNGString openCell(const librevenge::RVNGPropertyList &propList); + bool closeCell(); + bool insertCoveredCell(const librevenge::RVNGPropertyList &propList); + bool isCellOpened() const { - mTableCellStyles.push_back(pTableCellStyle); + return mbCellOpened; } - int getNumTableCellStyles() + +private: + librevenge::RVNGPropertyList mPropList; + bool mbRowOpened, mbRowHeaderOpened, mbCellOpened; + + // hash key -> row style name + std::map mRowNameHash; + // style name -> TableRowStyle + std::map > mRowStyleHash; + // hash key -> cell style name + std::map mCellNameHash; + // style name -> TableCellStyle + std::map > mCellStyleHash; + + // disable copying + Table(const Table &); + Table &operator=(const Table &); +}; + +class TableManager +{ +public: + TableManager(); + virtual ~TableManager(); + //! clean all data + void clean(); + void write(OdfDocumentHandler *pHandler, bool compatibleOdp=false) const; + + bool isTableOpened() const { - return (int)mTableCellStyles.size(); + return !mTableOpened.empty(); } - void addTableRowStyle(TableRowStyle *pTableRowStyle) + Table *getActualTable() { - mTableRowStyles.push_back(pTableRowStyle); + if (mTableOpened.empty()) return 0; + return mTableOpened.back().get(); } - int getNumTableRowStyles() + Table const *getActualTable() const { - return (int)mTableRowStyles.size(); + if (mTableOpened.empty()) return 0; + return mTableOpened.back().get(); } + //! open a table and update the list of elements + bool openTable(const librevenge::RVNGPropertyList &xPropList); + bool closeTable(); + private: - WPXPropertyList mPropList; - WPXPropertyListVector mColumns; - std::vector mTableCellStyles; - std::vector mTableRowStyles; + std::vector > mTableOpened; + std::vector > mTableStyles; + + // disable copying + TableManager(const TableManager &); + TableManager &operator=(const TableManager &); }; + #endif /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/src/TextRunStyle.cxx libodfgen-0.1.1/src/TextRunStyle.cxx --- libodfgen-0.0.4/src/TextRunStyle.cxx 2013-12-02 20:20:34.000000000 +0000 +++ libodfgen-0.1.1/src/TextRunStyle.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -33,28 +33,8 @@ #include -namespace -{ - -WPXString propListToStyleKey(const WPXPropertyList &xPropList) -{ - WPXString sKey; - WPXPropertyList::Iter i(xPropList); - for (i.rewind(); i.next(); ) - { - WPXString sProp; - sProp.sprintf("[%s:%s]", i.key(), i()->getStr().cstr()); - sKey.append(sProp); - } - - return sKey; -} - -} // anonymous namespace - -ParagraphStyle::ParagraphStyle(const WPXPropertyList &pPropList, const WPXPropertyListVector &xTabStops, const WPXString &sName) : +ParagraphStyle::ParagraphStyle(const librevenge::RVNGPropertyList &pPropList, const librevenge::RVNGString &sName) : mpPropList(pPropList), - mxTabStops(xTabStops), msName(sName) { } @@ -63,93 +43,89 @@ { } +bool ParagraphStyle::hasDisplayName() const +{ + return mpPropList["style:display-name"] && !mpPropList["style:display-name"]->getStr().empty(); +} + void ParagraphStyle::write(OdfDocumentHandler *pHandler) const { ODFGEN_DEBUG_MSG(("ParagraphStyle: Writing a paragraph style..\n")); - WPXPropertyList propList; + librevenge::RVNGPropertyList propList; propList.insert("style:name", msName.cstr()); propList.insert("style:family", "paragraph"); + if (mpPropList["style:display-name"]) + propList.insert("style:display-name", mpPropList["style:display-name"]->clone()); if (mpPropList["style:parent-style-name"]) - propList.insert("style:parent-style-name", mpPropList["style:parent-style-name"]->getStr()); + propList.insert("style:parent-style-name", mpPropList["style:parent-style-name"]->clone()); if (mpPropList["style:master-page-name"]) - propList.insert("style:master-page-name", mpPropList["style:master-page-name"]->getStr()); + propList.insert("style:master-page-name", mpPropList["style:master-page-name"]->clone()); pHandler->startElement("style:style", propList); propList.clear(); - WPXPropertyList::Iter i(mpPropList); - for (i.rewind(); i.next(); ) + librevenge::RVNGPropertyList::Iter i(mpPropList); + for (i.rewind(); i.next();) { - if (strncmp(i.key(), "fo:margin-",10) == 0) + if (i.child() || + !strcmp(i.key(), "style:display-name") || + !strcmp(i.key(), "style:parent-style-name") || + !strcmp(i.key(), "style:master-page-name") || + !strncmp(i.key(), "librevenge:",11)) + continue; + else if (!strncmp(i.key(), "fo:margin-",10)) { - if (strcmp(i.key(), "fo:margin-left") == 0 || - strcmp(i.key(), "fo:margin-right") == 0 || - strcmp(i.key(), "fo:margin-top") == 0) - propList.insert(i.key(), i()->getStr()); - else if (strcmp(i.key(), "fo:margin-bottom") == 0) + if (!strcmp(i.key(), "fo:margin-left") || + !strcmp(i.key(), "fo:margin-right") || + !strcmp(i.key(), "fo:margin-top")) + propList.insert(i.key(), i()->clone()); + else if (!strcmp(i.key(), "fo:margin-bottom")) { if (i()->getDouble() > 0.0) - propList.insert("fo:margin-bottom", i()->getStr()); + propList.insert("fo:margin-bottom", i()->clone()); else propList.insert("fo:margin-bottom", 0.0); } } - else if (strcmp(i.key(), "fo:text-indent") == 0) - propList.insert("fo:text-indent", i()->getStr()); - else if (strcmp(i.key(), "fo:line-height") == 0) - propList.insert("fo:line-height", i()->getStr()); - else if (strcmp(i.key(), "style:line-height-at-least") == 0) - propList.insert("style:line-height-at-least", i()->getStr()); - else if (strcmp(i.key(), "fo:break-before") == 0) - propList.insert("fo:break-before", i()->getStr()); - else if (strcmp(i.key(), "fo:text-align") == 0) - propList.insert("fo:text-align", i()->getStr()); - else if (strcmp(i.key(), "fo:text-align-last") == 0) - propList.insert("fo:text-align-last", i()->getStr()); - else if (strcmp(i.key(), "style:page-number") == 0) - propList.insert("style:page-number", i()->getStr()); - else if (strcmp(i.key(), "fo:background-color") == 0) - propList.insert("fo:background-color", i()->getStr()); - else if (strncmp(i.key(), "style:border-line-width", 23) == 0) + else if (!strncmp(i.key(), "style:border-line-width", 23)) { - if (strcmp(i.key(), "style:border-line-width") == 0 || - strcmp(i.key(), "style:border-line-width-left") == 0 || - strcmp(i.key(), "style:border-line-width-right") == 0 || - strcmp(i.key(), "style:border-line-width-top") == 0 || - strcmp(i.key(), "style:border-line-width-bottom") == 0) - propList.insert(i.key(), i()->getStr()); + if (!strcmp(i.key(), "style:border-line-width") || + !strcmp(i.key(), "style:border-line-width-left") || + !strcmp(i.key(), "style:border-line-width-right") || + !strcmp(i.key(), "style:border-line-width-top") || + !strcmp(i.key(), "style:border-line-width-bottom")) + propList.insert(i.key(), i()->clone()); } - else if (strncmp(i.key(), "fo:border", 9) == 0) + else if (!strncmp(i.key(), "fo:border", 9)) { - if (strcmp(i.key(), "fo:border") == 0 || - strcmp(i.key(), "fo:border-left") == 0 || - strcmp(i.key(), "fo:border-right") == 0 || - strcmp(i.key(), "fo:border-top") == 0 || - strcmp(i.key(), "fo:border-bottom") == 0) - propList.insert(i.key(), i()->getStr()); + if (!strcmp(i.key(), "fo:border") || + !strcmp(i.key(), "fo:border-left") || + !strcmp(i.key(), "fo:border-right") || + !strcmp(i.key(), "fo:border-top") || + !strcmp(i.key(), "fo:border-bottom")) + propList.insert(i.key(), i()->clone()); } - else if (strcmp(i.key(), "fo:keep-together") == 0) - propList.insert("fo:keep-together", i()->getStr()); - else if (strcmp(i.key(), "fo:keep-with-next") == 0) - propList.insert("fo:keep-with-next", i()->getStr()); + else + propList.insert(i.key(), i()->clone()); } propList.insert("style:justify-single-word", "false"); pHandler->startElement("style:paragraph-properties", propList); - if (mxTabStops.count() > 0) + const librevenge::RVNGPropertyListVector *pTabStops = mpPropList.child("style:tab-stops"); + if (pTabStops && pTabStops->count()) { TagOpenElement tabListOpen("style:tab-stops"); tabListOpen.write(pHandler); - WPXPropertyListVector::Iter k(mxTabStops); + librevenge::RVNGPropertyListVector::Iter k(*pTabStops); for (k.rewind(); k.next();) { if (k()["style:position"] && k()["style:position"]->getDouble() < 0.0) continue; TagOpenElement tabStopOpen("style:tab-stop"); - WPXPropertyList::Iter j(k()); - for (j.rewind(); j.next(); ) + librevenge::RVNGPropertyList::Iter j(k()); + for (j.rewind(); j.next();) { tabStopOpen.addAttribute(j.key(), j()->getStr().cstr()); } @@ -163,152 +139,208 @@ pHandler->endElement("style:style"); } -SpanStyle::SpanStyle(const char *psName, const WPXPropertyList &xPropList) : +SpanStyle::SpanStyle(const char *psName, const librevenge::RVNGPropertyList &xPropList) : Style(psName), mPropList(xPropList) { } +bool SpanStyle::hasDisplayName() const +{ + return mPropList["style:display-name"] && !mPropList["style:display-name"]->getStr().empty(); +} + void SpanStyle::write(OdfDocumentHandler *pHandler) const { ODFGEN_DEBUG_MSG(("SpanStyle: Writing a span style..\n")); - WPXPropertyList styleOpenList; + librevenge::RVNGPropertyList styleOpenList; styleOpenList.insert("style:name", getName()); + if (mPropList["style:display-name"]) + styleOpenList.insert("style:display-name", mPropList["style:display-name"]->clone()); styleOpenList.insert("style:family", "text"); pHandler->startElement("style:style", styleOpenList); - WPXPropertyList propList(mPropList); - - if (mPropList["style:font-name"]) - { - propList.insert("style:font-name-asian", mPropList["style:font-name"]->getStr()); - propList.insert("style:font-name-complex", mPropList["style:font-name"]->getStr()); - } - - if (mPropList["fo:font-size"]) - { - if (mPropList["fo:font-size"]->getDouble() > 0.0) - { - propList.insert("style:font-size-asian", mPropList["fo:font-size"]->getStr()); - propList.insert("style:font-size-complex", mPropList["fo:font-size"]->getStr()); - } - else - propList.remove("fo:font-size"); - } - - if (mPropList["fo:font-weight"]) - { - propList.insert("style:font-weight-asian", mPropList["fo:font-weight"]->getStr()); - propList.insert("style:font-weight-complex", mPropList["fo:font-weight"]->getStr()); - } - - if (mPropList["fo:font-style"]) - { - propList.insert("style:font-style-asian", mPropList["fo:font-style"]->getStr()); - propList.insert("style:font-style-complex", mPropList["fo:font-style"]->getStr()); - } - - pHandler->startElement("style:text-properties", propList); - + librevenge::RVNGPropertyList style; + SpanStyleManager::addSpanProperties(mPropList, style); + pHandler->startElement("style:text-properties", style); pHandler->endElement("style:text-properties"); pHandler->endElement("style:style"); } void ParagraphStyleManager::clean() { - mNameHash.clear(); + mHashNameMap.clear(); mStyleHash.clear(); + mDisplayNameMap.clear(); } -void ParagraphStyleManager::write(OdfDocumentHandler *pHandler) const +void ParagraphStyleManager::write(OdfDocumentHandler *pHandler, bool automatic) const { - for (std::map, ltstr>::const_iterator iter = mStyleHash.begin(); + for (std::map >::const_iterator iter = mStyleHash.begin(); iter != mStyleHash.end(); ++iter) { - if (strcmp(iter->second->getName().cstr(), "Standard") == 0) - continue; - (iter->second)->write(pHandler); + if (iter->second && iter->second->hasDisplayName()!=automatic) + (iter->second)->write(pHandler); } } -WPXString ParagraphStyleManager::getKey(const WPXPropertyList &xPropList, const WPXPropertyListVector &tabStops) const -{ - WPXString sKey = propListToStyleKey(xPropList); - - WPXString sTabStops; - sTabStops.sprintf("[num-tab-stops:%i]", tabStops.count()); - WPXPropertyListVector::Iter i(tabStops); - for (i.rewind(); i.next();) - { - sTabStops.append(propListToStyleKey(i())); - } - sKey.append(sTabStops); - - return sKey; -} - -WPXString ParagraphStyleManager::findOrAdd(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops) +librevenge::RVNGString ParagraphStyleManager::findOrAdd(const librevenge::RVNGPropertyList &propList) { - WPXString hashKey = getKey(propList, tabStops); - std::map::const_iterator iter = - mNameHash.find(hashKey); - if (iter!=mNameHash.end()) return iter->second; + librevenge::RVNGString hashKey = propList.getPropString(); + std::map::const_iterator iter = + mHashNameMap.find(hashKey); + if (iter!=mHashNameMap.end()) return iter->second; // ok create a new list + librevenge::RVNGString sName(""); ODFGEN_DEBUG_MSG(("ParagraphStyleManager::findOrAdd: Paragraph Hash Key: %s\n", hashKey.cstr())); - WPXString sName; + librevenge::RVNGPropertyList pList(propList); + if (propList["style:display-name"]) + { + librevenge::RVNGString name(propList["style:display-name"]->getStr()); + if (propList["style:master-page-name"]) + pList.remove("style:display-name"); + else if (mDisplayNameMap.find(name) != mDisplayNameMap.end()) + { + ODFGEN_DEBUG_MSG(("ParagraphStyleManager::findOrAdd: a paragraph with name %s already exists\n", name.cstr())); + pList.remove("style:display-name"); + } + else + mDisplayNameMap[name]=sName; + } + sName.sprintf("S%i", mStyleHash.size()); - shared_ptr parag(new ParagraphStyle(propList, tabStops, sName)); + shared_ptr parag(new ParagraphStyle(pList, sName)); mStyleHash[sName] =parag; - mNameHash[hashKey] = sName; + mHashNameMap[hashKey] = sName; + return sName; } -shared_ptr const ParagraphStyleManager::get(const WPXString &name) const +shared_ptr const ParagraphStyleManager::get(const librevenge::RVNGString &name) const { - std::map, ltstr>::const_iterator iter + std::map >::const_iterator iter = mStyleHash.find(name); if (iter == mStyleHash.end()) return shared_ptr(); return iter->second; } +//////////////////////////////////////////////////////////// +// span manager +//////////////////////////////////////////////////////////// void SpanStyleManager::clean() { - mNameHash.clear(); + mHashNameMap.clear(); mStyleHash.clear(); + mDisplayNameMap.clear(); } -void SpanStyleManager::write(OdfDocumentHandler *pHandler) const +void SpanStyleManager::addSpanProperties(librevenge::RVNGPropertyList const &style, librevenge::RVNGPropertyList &element) { - for (std::map, ltstr>::const_iterator iter = mStyleHash.begin(); + librevenge::RVNGPropertyList::Iter i(style); + for (i.rewind(); i.next();) + { + if (i.child()) continue; + switch (i.key()[0]) + { + case 'f': + if (!strcmp(i.key(), "fo:font-size")) + { + if (style["fo:font-size"]->getDouble() > 0.0) + { + element.insert("fo:font-size", style["fo:font-size"]->clone()); + element.insert("style:font-size-asian", style["fo:font-size"]->clone()); + element.insert("style:font-size-complex", style["fo:font-size"]->clone()); + } + break; + } + if (!strcmp(i.key(), "fo:font-weight")) + { + element.insert("fo:font-weight", style["fo:font-weight"]->clone()); + element.insert("style:font-weight-asian", style["fo:font-weight"]->clone()); + element.insert("style:font-weight-complex", style["fo:font-weight"]->clone()); + break; + } + if (!strcmp(i.key(), "fo:font-style")) + { + element.insert("fo:font-style", style["fo:font-style"]->clone()); + element.insert("style:font-style-asian", style["fo:font-style"]->clone()); + element.insert("style:font-style-complex", style["fo:font-style"]->clone()); + break; + } + if (!strcmp(i.key(), "fo:background-color") || !strcmp(i.key(), "fo:color") || + !strcmp(i.key(), "fo:country") || !strncmp(i.key(), "fo:font", 7) || + !strncmp(i.key(), "fo:hyphen", 9) || !strncmp(i.key(), "fo:text", 7) || + !strcmp(i.key(), "fo:language") || !strcmp(i.key(), "fo:letter-spacing") || + !strcmp(i.key(), "fo:script")) + element.insert(i.key(),i()->clone()); + break; + case 's': + if (!strcmp(i.key(), "style:font-name")) + { + element.insert("style:font-name", style["style:font-name"]->clone()); + element.insert("style:font-name-asian", style["style:font-name"]->clone()); + element.insert("style:font-name-complex", style["style:font-name"]->clone()); + break; + } + if (!strncmp(i.key(), "style:country", 13) || !strncmp(i.key(), "style:font", 10) || + !strncmp(i.key(), "style:language", 14) || !strncmp(i.key(), "style:letter", 12) || + !strncmp(i.key(), "style:rfc-", 10) || !strncmp(i.key(), "style:script", 12) || + !strncmp(i.key(), "style:text", 10)) + element.insert(i.key(),i()->clone()); + break; + case 't': + if (!strcmp(i.key(), "text:display")) + element.insert(i.key(),i()->clone()); + break; + default: + break; + } + } +} + +void SpanStyleManager::write(OdfDocumentHandler *pHandler, bool automatic) const +{ + for (std::map >::const_iterator iter = mStyleHash.begin(); iter != mStyleHash.end(); ++iter) { - (iter->second)->write(pHandler); + if (iter->second && iter->second->hasDisplayName()!=automatic) + (iter->second)->write(pHandler); } } -WPXString SpanStyleManager::findOrAdd(const WPXPropertyList &propList) +librevenge::RVNGString SpanStyleManager::findOrAdd(const librevenge::RVNGPropertyList &propList) { - WPXString hashKey = propListToStyleKey(propList); - std::map::const_iterator iter = - mNameHash.find(hashKey); - if (iter!=mNameHash.end()) return iter->second; + librevenge::RVNGString hashKey = propList.getPropString(); + std::map::const_iterator iter = + mHashNameMap.find(hashKey); + if (iter!=mHashNameMap.end()) return iter->second; // ok create a new list ODFGEN_DEBUG_MSG(("SpanStyleManager::findOrAdd: Span Hash Key: %s\n", hashKey.cstr())); - WPXString sName; + librevenge::RVNGString sName(""); sName.sprintf("Span%i", mStyleHash.size()); shared_ptr span(new SpanStyle(sName.cstr(), propList)); mStyleHash[sName] = span; - mNameHash[hashKey] = sName; + mHashNameMap[hashKey] = sName; + if (span->hasDisplayName()) + mDisplayNameMap[propList["style:display-name"]->getStr()]=sName; return sName; } -shared_ptr const SpanStyleManager::get(const WPXString &name) const +librevenge::RVNGString SpanStyleManager::getFinalDisplayName(const librevenge::RVNGString &displayName) +{ + if (mDisplayNameMap.find(displayName) != mDisplayNameMap.end()) + return mDisplayNameMap.find(displayName)->second; + ODFGEN_DEBUG_MSG(("SpanStyleManager::getName: can not find style with display name: %s\n", displayName.cstr())); + return librevenge::RVNGString(""); +} + +shared_ptr const SpanStyleManager::get(const librevenge::RVNGString &name) const { - std::map, ltstr>::const_iterator iter + std::map >::const_iterator iter = mStyleHash.find(name); if (iter == mStyleHash.end()) return shared_ptr(); return iter->second; diff -Nru libodfgen-0.0.4/src/TextRunStyle.hxx libodfgen-0.1.1/src/TextRunStyle.hxx --- libodfgen-0.0.4/src/TextRunStyle.hxx 2013-12-01 20:54:24.000000000 +0000 +++ libodfgen-0.1.1/src/TextRunStyle.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -29,7 +29,7 @@ #include -#include +#include #include "FilterInternal.hxx" @@ -40,34 +40,35 @@ class ParagraphStyle { public: - ParagraphStyle(WPXPropertyList const &propList, const WPXPropertyListVector &tabStops, const WPXString &sName); + ParagraphStyle(librevenge::RVNGPropertyList const &propList, const librevenge::RVNGString &sName); virtual ~ParagraphStyle(); virtual void write(OdfDocumentHandler *pHandler) const; - WPXString getName() const + librevenge::RVNGString getName() const { return msName; } + bool hasDisplayName() const; + private: - WPXPropertyList mpPropList; - WPXPropertyListVector mxTabStops; - WPXString msName; + librevenge::RVNGPropertyList mpPropList; + librevenge::RVNGString msName; }; class SpanStyle : public Style { public: - SpanStyle(const char *psName, const WPXPropertyList &xPropList); + SpanStyle(const char *psName, const librevenge::RVNGPropertyList &xPropList); virtual void write(OdfDocumentHandler *pHandler) const; - + bool hasDisplayName() const; private: - WPXPropertyList mPropList; + librevenge::RVNGPropertyList mPropList; }; class ParagraphStyleManager : public StyleManager { public: - ParagraphStyleManager() : mNameHash(), mStyleHash() {} + ParagraphStyleManager() : mHashNameMap(), mStyleHash(), mDisplayNameMap() {} virtual ~ParagraphStyleManager() { clean(); @@ -76,29 +77,46 @@ /* create a new style if it does not exists. In all case, returns the name of the style Note: using S%i as new name*/ - WPXString findOrAdd(const WPXPropertyList &xPropList, const WPXPropertyListVector &tabStops); + librevenge::RVNGString findOrAdd(const librevenge::RVNGPropertyList &xPropList); /* returns the style corresponding to a given name ( if it exists ) */ - shared_ptr const get(const WPXString &name) const; + shared_ptr const get(const librevenge::RVNGString &name) const; + //! return the file name corresponding to a display name + librevenge::RVNGString getFinalDisplayName(const librevenge::RVNGString &displayName); virtual void clean(); - virtual void write(OdfDocumentHandler *) const; - + // write all + virtual void write(OdfDocumentHandler *pHandler) const + { + write(pHandler, false); + write(pHandler, true); + } + // write named style + void writeNamedStyles(OdfDocumentHandler *pHandler) const + { + write(pHandler, false); + } + // write basic style + void writeAutomaticStyles(OdfDocumentHandler *pHandler) const + { + write(pHandler, true); + } protected: - // return a unique key - WPXString getKey(const WPXPropertyList &xPropList, const WPXPropertyListVector &tabStops) const; - + // write automatic/named style + void write(OdfDocumentHandler *, bool automaticStyle) const; // hash key -> name - std::map mNameHash; + std::map mHashNameMap; // style name -> paragraph style - std::map, ltstr> mStyleHash; + std::map > mStyleHash; + // display name -> style name + std::map mDisplayNameMap; }; class SpanStyleManager : public StyleManager { public: - SpanStyleManager() : mNameHash(), mStyleHash() {} + SpanStyleManager() : mHashNameMap(), mStyleHash(), mDisplayNameMap() {} virtual ~SpanStyleManager() { clean(); @@ -107,19 +125,41 @@ /* create a new style if it does not exists. In all case, returns the name of the style Note: using Span%i as new name*/ - WPXString findOrAdd(const WPXPropertyList &xPropList); - + librevenge::RVNGString findOrAdd(const librevenge::RVNGPropertyList &xPropList); /* returns the style corresponding to a given name ( if it exists ) */ - shared_ptr const get(const WPXString &name) const; + shared_ptr const get(const librevenge::RVNGString &name) const; + /** append the span in the element, ie. the stroke, pattern, bitmap, marker properties */ + static void addSpanProperties(librevenge::RVNGPropertyList const &style, librevenge::RVNGPropertyList &element); + //! return the file name corresponding to a display name + librevenge::RVNGString getFinalDisplayName(const librevenge::RVNGString &displayName); virtual void clean(); - virtual void write(OdfDocumentHandler *) const; + // write all + virtual void write(OdfDocumentHandler *pHandler) const + { + write(pHandler, false); + write(pHandler, true); + } + // write named style + void writeNamedStyles(OdfDocumentHandler *pHandler) const + { + write(pHandler, false); + } + // write basic style + void writeAutomaticStyles(OdfDocumentHandler *pHandler) const + { + write(pHandler, true); + } protected: + // write automatic/named style + void write(OdfDocumentHandler *, bool automaticStyle) const; // hash key -> style name - std::map mNameHash; + std::map mHashNameMap; // style name -> SpanStyle - std::map, ltstr> mStyleHash; + std::map > mStyleHash; + // display name -> style name + std::map mDisplayNameMap; }; #endif diff -Nru libodfgen-0.0.4/test/Makefile.am libodfgen-0.1.1/test/Makefile.am --- libodfgen-0.0.4/test/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/Makefile.am 2014-06-02 17:08:51.000000000 +0000 @@ -0,0 +1,49 @@ +if COMPILE_TEST + +AM_CXXFLAGS = $(REVENGE_CFLAGS) -I../inc/ + +targets=testChart1 testGraphic1 testLink1 testList1 testPara1 testSpan1 testTable1 testTextbox1 +noinst_PROGRAMS= $(targets) + +EXTRA_SRC=StringDocumentHandler.cxx StringDocumentHandler.hxx +EXTRA_LDD=../src/libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@.la \ + $(REVENGE_LIBS) $(REVENGE_STREAM_LIBS) + +testChart1_DEPENDENCIES = +testChart1_LDADD = $(EXTRA_LDD) +testChart1_SOURCES = $(EXTRA_SRC) testChart1.cxx + +testGraphic1_DEPENDENCIES = +testGraphic1_LDADD = $(EXTRA_LDD) +testGraphic1_SOURCES = $(EXTRA_SRC) testGraphic1.cxx + +testLink1_DEPENDENCIES = +testLink1_LDADD = $(EXTRA_LDD) +testLink1_SOURCES = $(EXTRA_SRC) testLink1.cxx + +testList1_DEPENDENCIES = +testList1_LDADD = $(EXTRA_LDD) +testList1_SOURCES = $(EXTRA_SRC) testList1.cxx + +testPara1_DEPENDENCIES = +testPara1_LDADD = $(EXTRA_LDD) +testPara1_SOURCES = $(EXTRA_SRC) testParagraph1.cxx + +testSpan1_DEPENDENCIES = +testSpan1_LDADD = $(EXTRA_LDD) +testSpan1_SOURCES = $(EXTRA_SRC) testSpan1.cxx + +testTable1_DEPENDENCIES = +testTable1_LDADD = $(EXTRA_LDD) +testTable1_SOURCES = $(EXTRA_SRC) testTable1.cxx + +testTextbox1_DEPENDENCIES = +testTextbox1_LDADD = $(EXTRA_LDD) +testTextbox1_SOURCES = $(EXTRA_SRC) testTextbox1.cxx + +clean:: + @rm -f test*.odg test*.odp test*.ods test*.odt $(targets) + +launch_all:: $(targets) + ./testGraphic1 && ./testLink1 && ./testList1 && ./testPara1 && ./testSpan1 && ./testTable1 && ./testTextbox1 +endif diff -Nru libodfgen-0.0.4/test/Makefile.in libodfgen-0.1.1/test/Makefile.in --- libodfgen-0.0.4/test/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/Makefile.in 2014-06-02 17:11:59.000000000 +0000 @@ -0,0 +1,733 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@COMPILE_TEST_TRUE@noinst_PROGRAMS = $(am__EXEEXT_1) +subdir = test +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@COMPILE_TEST_TRUE@am__EXEEXT_1 = testChart1$(EXEEXT) \ +@COMPILE_TEST_TRUE@ testGraphic1$(EXEEXT) testLink1$(EXEEXT) \ +@COMPILE_TEST_TRUE@ testList1$(EXEEXT) testPara1$(EXEEXT) \ +@COMPILE_TEST_TRUE@ testSpan1$(EXEEXT) testTable1$(EXEEXT) \ +@COMPILE_TEST_TRUE@ testTextbox1$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am__testChart1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testChart1.cxx +@COMPILE_TEST_TRUE@am__objects_1 = StringDocumentHandler.$(OBJEXT) +@COMPILE_TEST_TRUE@am_testChart1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testChart1.$(OBJEXT) +testChart1_OBJECTS = $(am_testChart1_OBJECTS) +am__DEPENDENCIES_1 = +@COMPILE_TEST_TRUE@am__DEPENDENCIES_2 = ../src/libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@.la \ +@COMPILE_TEST_TRUE@ $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am__testGraphic1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testGraphic1.cxx +@COMPILE_TEST_TRUE@am_testGraphic1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testGraphic1.$(OBJEXT) +testGraphic1_OBJECTS = $(am_testGraphic1_OBJECTS) +am__testLink1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testLink1.cxx +@COMPILE_TEST_TRUE@am_testLink1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testLink1.$(OBJEXT) +testLink1_OBJECTS = $(am_testLink1_OBJECTS) +am__testList1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testList1.cxx +@COMPILE_TEST_TRUE@am_testList1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testList1.$(OBJEXT) +testList1_OBJECTS = $(am_testList1_OBJECTS) +am__testPara1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testParagraph1.cxx +@COMPILE_TEST_TRUE@am_testPara1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testParagraph1.$(OBJEXT) +testPara1_OBJECTS = $(am_testPara1_OBJECTS) +am__testSpan1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testSpan1.cxx +@COMPILE_TEST_TRUE@am_testSpan1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testSpan1.$(OBJEXT) +testSpan1_OBJECTS = $(am_testSpan1_OBJECTS) +am__testTable1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testTable1.cxx +@COMPILE_TEST_TRUE@am_testTable1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testTable1.$(OBJEXT) +testTable1_OBJECTS = $(am_testTable1_OBJECTS) +am__testTextbox1_SOURCES_DIST = StringDocumentHandler.cxx \ + StringDocumentHandler.hxx testTextbox1.cxx +@COMPILE_TEST_TRUE@am_testTextbox1_OBJECTS = $(am__objects_1) \ +@COMPILE_TEST_TRUE@ testTextbox1.$(OBJEXT) +testTextbox1_OBJECTS = $(am_testTextbox1_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(testChart1_SOURCES) $(testGraphic1_SOURCES) \ + $(testLink1_SOURCES) $(testList1_SOURCES) $(testPara1_SOURCES) \ + $(testSpan1_SOURCES) $(testTable1_SOURCES) \ + $(testTextbox1_SOURCES) +DIST_SOURCES = $(am__testChart1_SOURCES_DIST) \ + $(am__testGraphic1_SOURCES_DIST) $(am__testLink1_SOURCES_DIST) \ + $(am__testList1_SOURCES_DIST) $(am__testPara1_SOURCES_DIST) \ + $(am__testSpan1_SOURCES_DIST) $(am__testTable1_SOURCES_DIST) \ + $(am__testTextbox1_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_CXXFLAGS = @DEBUG_CXXFLAGS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBODFGEN_MAJOR_VERSION = @LIBODFGEN_MAJOR_VERSION@ +LIBODFGEN_MICRO_VERSION = @LIBODFGEN_MICRO_VERSION@ +LIBODFGEN_MINOR_VERSION = @LIBODFGEN_MINOR_VERSION@ +LIBODFGEN_WIN32_RESOURCE = @LIBODFGEN_WIN32_RESOURCE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_CURRENT = @LT_CURRENT@ +LT_REVISION = @LT_REVISION@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +REVENGE_CFLAGS = @REVENGE_CFLAGS@ +REVENGE_LIBS = @REVENGE_LIBS@ +REVENGE_LIGS = @REVENGE_LIGS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@COMPILE_TEST_TRUE@AM_CXXFLAGS = $(REVENGE_CFLAGS) -I../inc/ +@COMPILE_TEST_TRUE@targets = testChart1 testGraphic1 testLink1 testList1 testPara1 testSpan1 testTable1 testTextbox1 +@COMPILE_TEST_TRUE@EXTRA_SRC = StringDocumentHandler.cxx StringDocumentHandler.hxx +@COMPILE_TEST_TRUE@EXTRA_LDD = ../src/libodfgen-@LIBODFGEN_MAJOR_VERSION@.@LIBODFGEN_MINOR_VERSION@.la \ +@COMPILE_TEST_TRUE@ $(REVENGE_LIBS) $(REVENGE_STREAM_LIBS) + +@COMPILE_TEST_TRUE@testChart1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testChart1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testChart1_SOURCES = $(EXTRA_SRC) testChart1.cxx +@COMPILE_TEST_TRUE@testGraphic1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testGraphic1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testGraphic1_SOURCES = $(EXTRA_SRC) testGraphic1.cxx +@COMPILE_TEST_TRUE@testLink1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testLink1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testLink1_SOURCES = $(EXTRA_SRC) testLink1.cxx +@COMPILE_TEST_TRUE@testList1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testList1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testList1_SOURCES = $(EXTRA_SRC) testList1.cxx +@COMPILE_TEST_TRUE@testPara1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testPara1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testPara1_SOURCES = $(EXTRA_SRC) testParagraph1.cxx +@COMPILE_TEST_TRUE@testSpan1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testSpan1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testSpan1_SOURCES = $(EXTRA_SRC) testSpan1.cxx +@COMPILE_TEST_TRUE@testTable1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testTable1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testTable1_SOURCES = $(EXTRA_SRC) testTable1.cxx +@COMPILE_TEST_TRUE@testTextbox1_DEPENDENCIES = +@COMPILE_TEST_TRUE@testTextbox1_LDADD = $(EXTRA_LDD) +@COMPILE_TEST_TRUE@testTextbox1_SOURCES = $(EXTRA_SRC) testTextbox1.cxx +all: all-am + +.SUFFIXES: +.SUFFIXES: .cxx .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +testChart1$(EXEEXT): $(testChart1_OBJECTS) $(testChart1_DEPENDENCIES) $(EXTRA_testChart1_DEPENDENCIES) + @rm -f testChart1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testChart1_OBJECTS) $(testChart1_LDADD) $(LIBS) + +testGraphic1$(EXEEXT): $(testGraphic1_OBJECTS) $(testGraphic1_DEPENDENCIES) $(EXTRA_testGraphic1_DEPENDENCIES) + @rm -f testGraphic1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testGraphic1_OBJECTS) $(testGraphic1_LDADD) $(LIBS) + +testLink1$(EXEEXT): $(testLink1_OBJECTS) $(testLink1_DEPENDENCIES) $(EXTRA_testLink1_DEPENDENCIES) + @rm -f testLink1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testLink1_OBJECTS) $(testLink1_LDADD) $(LIBS) + +testList1$(EXEEXT): $(testList1_OBJECTS) $(testList1_DEPENDENCIES) $(EXTRA_testList1_DEPENDENCIES) + @rm -f testList1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testList1_OBJECTS) $(testList1_LDADD) $(LIBS) + +testPara1$(EXEEXT): $(testPara1_OBJECTS) $(testPara1_DEPENDENCIES) $(EXTRA_testPara1_DEPENDENCIES) + @rm -f testPara1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testPara1_OBJECTS) $(testPara1_LDADD) $(LIBS) + +testSpan1$(EXEEXT): $(testSpan1_OBJECTS) $(testSpan1_DEPENDENCIES) $(EXTRA_testSpan1_DEPENDENCIES) + @rm -f testSpan1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testSpan1_OBJECTS) $(testSpan1_LDADD) $(LIBS) + +testTable1$(EXEEXT): $(testTable1_OBJECTS) $(testTable1_DEPENDENCIES) $(EXTRA_testTable1_DEPENDENCIES) + @rm -f testTable1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testTable1_OBJECTS) $(testTable1_LDADD) $(LIBS) + +testTextbox1$(EXEEXT): $(testTextbox1_OBJECTS) $(testTextbox1_DEPENDENCIES) $(EXTRA_testTextbox1_DEPENDENCIES) + @rm -f testTextbox1$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(testTextbox1_OBJECTS) $(testTextbox1_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringDocumentHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testChart1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testGraphic1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testLink1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testList1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testParagraph1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testSpan1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testTable1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testTextbox1.Po@am__quote@ + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@COMPILE_TEST_FALSE@clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +@COMPILE_TEST_TRUE@clean:: +@COMPILE_TEST_TRUE@ @rm -f test*.odg test*.odp test*.ods test*.odt $(targets) + +@COMPILE_TEST_TRUE@launch_all:: $(targets) +@COMPILE_TEST_TRUE@ ./testGraphic1 && ./testLink1 && ./testList1 && ./testPara1 && ./testSpan1 && ./testTable1 && ./testTextbox1 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru libodfgen-0.0.4/test/StringDocumentHandler.cxx libodfgen-0.1.1/test/StringDocumentHandler.cxx --- libodfgen-0.0.4/test/StringDocumentHandler.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/StringDocumentHandler.cxx 2014-05-23 13:57:43.000000000 +0000 @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* writerperfect + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#include + +#include "StringDocumentHandler.hxx" + +StringDocumentHandler::StringDocumentHandler() : m_data(""), m_isTagOpened(false), m_openedTagName("") +{ + m_data.append("\n"); +} + +void StringDocumentHandler::endDocument() +{ + if (!m_isTagOpened) return; + m_data.append(">"); + m_isTagOpened = false; +} + +void StringDocumentHandler::startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList) +{ + if (m_isTagOpened) + { + m_data.append(">"); + m_isTagOpened = false; + } + m_data.append("<"); + m_data.append(psName); + librevenge::RVNGPropertyList::Iter i(xPropList); + for (i.rewind(); i.next();) + { + // filter out librevenge elements + if (!strncmp(i.key(), "librevenge:", 11)) continue; + + m_data.append(" "); + m_data.append(i.key()); + m_data.append("=\""); + if (i()->getStr().len()>0) + m_data.append(i()->getStr().cstr()); + m_data.append("\""); + } + m_isTagOpened = true; + m_openedTagName.sprintf("%s", psName); +} +void StringDocumentHandler::endElement(const char *psName) +{ + if (m_isTagOpened) + { + if (m_openedTagName == psName) + { + m_data.append("/>"); + m_isTagOpened = false; + } + else // should not happen, but handle it + { + m_data.append(">"); + m_data.append(""); + m_isTagOpened = false; + } + } + else + { + m_data.append(""); + m_isTagOpened = false; + } +} + +void StringDocumentHandler::characters(const librevenge::RVNGString &sCharacters) +{ + if (m_isTagOpened) + { + m_data.append(">"); + m_isTagOpened = false; + } + librevenge::RVNGString sEscapedCharacters; + sEscapedCharacters.appendEscapedXML(sCharacters); + if (sEscapedCharacters.len() > 0) + m_data.append(sEscapedCharacters.cstr()); +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/test/StringDocumentHandler.hxx libodfgen-0.1.1/test/StringDocumentHandler.hxx --- libodfgen-0.0.4/test/StringDocumentHandler.hxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/StringDocumentHandler.hxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* writerperfect + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com) + * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +#ifndef _STRING_DOCUMENT_HANDLER_H +#define _STRING_DOCUMENT_HANDLER_H + +#include + +class StringDocumentHandler : public OdfDocumentHandler +{ +public: + StringDocumentHandler(); + + char const *cstr() const + { + return m_data.cstr(); + } + + virtual void startDocument() {} + virtual void endDocument(); + virtual void startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList); + virtual void endElement(const char *psName); + virtual void characters(const librevenge::RVNGString &sCharacters); +private: +private: + librevenge::RVNGString m_data; + bool m_isTagOpened; + librevenge::RVNGString m_openedTagName; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff -Nru libodfgen-0.0.4/test/testChart1.cxx libodfgen-0.1.1/test/testChart1.cxx --- libodfgen-0.0.4/test/testChart1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testChart1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,302 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendChart(Generator &generator) +{ + librevenge::RVNGPropertyList style1; + style1.insert("librevenge:chart-id", "1"); + style1.insert("draw:stroke", "none"); + style1.insert("draw:fill", "none"); + generator.defineChartStyle(style1); + + librevenge::RVNGPropertyList chart; + chart.insert("svg:width", 400, librevenge::RVNG_POINT); + chart.insert("svg:height", 300, librevenge::RVNG_POINT); + chart.insert("chart:class", "bar"); + chart.insert("librevenge:chart-id", 1); + generator.openChart(chart); + + librevenge::RVNGPropertyList style(style1); + style.insert("librevenge:chart-id", "2"); + style.insert("chart:auto-position", "true"); + style.insert("draw:stroke", "none"); + style.insert("draw:fill", "none"); + style.insert("fo:font-size", "10pt"); + generator.defineChartStyle(style); + style.remove("chart:auto-position"); + + librevenge::RVNGPropertyList legend; + legend.insert("librevenge:zone-type", "legend"); + legend.insert("svg:x", 40, librevenge::RVNG_POINT); + legend.insert("svg:y", 50, librevenge::RVNG_POINT); + legend.insert("chart:legend-position", "end"); + legend.insert("style:legend-expansion", "high"); + legend.insert("librevenge:chart-id", 2); + generator.openChartTextObject(legend); + generator.closeChartTextObject(); + + + librevenge::RVNGPropertyList plotStyle, plotArea, floor, floorStyle, wall, wallStyle; + plotStyle.insert("librevenge:chart-id", 3); + plotStyle.insert("chart:include-hidden-cells","false"); + plotStyle.insert("chart:auto-position","true"); + plotStyle.insert("chart:auto-size","true"); + plotStyle.insert("chart:treat-empty-cells","leave-gap"); + plotStyle.insert("chart:right-angled-axes","true"); + generator.defineChartStyle(plotStyle); + floorStyle.insert("librevenge:chart-id", 9); + floorStyle.insert("draw:stroke","solid"); + floorStyle.insert("svg:stroke-color","#b3b3b3"); + floorStyle.insert("draw:fill","none"); + generator.defineChartStyle(floorStyle); + wallStyle.insert("librevenge:chart-id", 10); + wallStyle.insert("draw:stroke","solid"); + wallStyle.insert("svg:stroke-color","#b3b3b3"); + wallStyle.insert("draw:fill","solid"); + wallStyle.insert("draw:fill-color","#ffffff"); + generator.defineChartStyle(wallStyle); + + librevenge::RVNGPropertyListVector vect; + plotArea.insert("svg:x", 20, librevenge::RVNG_POINT); + plotArea.insert("svg:y", 20, librevenge::RVNG_POINT); + plotArea.insert("svg:width", 350, librevenge::RVNG_POINT); + plotArea.insert("svg:height", 250, librevenge::RVNG_POINT); + plotArea.insert("librevenge:chart-id", 3); + floor.insert("librevenge:type", "floor"); + floor.insert("librevenge:chart-id", "9"); + vect.append(floor); + wall.insert("librevenge:type", "wall"); + wall.insert("librevenge:chart-id", "10"); + vect.append(wall); + plotArea.insert("librevenge:childs", vect); + generator.openChartPlotArea(plotArea); + + librevenge::RVNGPropertyList axisStyle(style); + axisStyle.insert("librevenge:chart-id", "4"); + axisStyle.insert("draw:stroke", "solid"); + axisStyle.insert("svg:stroke-color", "#b3b3b3"); + axisStyle.insert("chart:display-label","true"); + axisStyle.insert("chart:logarithmic","false"); + axisStyle.insert("chart:reverse-direction","false"); + axisStyle.insert("text:line-break","false"); + axisStyle.insert("chart:axis-position","0"); + generator.defineChartStyle(axisStyle); + style.insert("librevenge:chart-id", "5"); + style.insert("draw:stroke", "solid"); + style.insert("draw:stroke-color", "#b3b3b3"); + generator.defineChartStyle(style); + + librevenge::RVNGPropertyList axis, grid; + axis.insert("chart:dimension","x"); + axis.insert("chart:name","primary-x"); + axis.insert("librevenge:chart-id", 4); + generator.insertChartAxis(axis); + + axis.insert("chart:dimension","y"); + axis.insert("chart:name","primary-y"); + grid.insert("librevenge:type","grid"); + grid.insert("chart:class","major"); + grid.insert("librevenge:chart-id", 5); + vect.clear(); + vect.append(grid); + axis.insert("librevenge:childs", vect); + generator.insertChartAxis(axis); + + style.insert("librevenge:chart-id", "7"); + style.insert("draw:stroke", "none"); + style.insert("draw:fill", "solid"); + style.insert("draw:fill-color", "#004586"); + style.insert("dr3d:edge-rounding", 0.05, librevenge::RVNG_PERCENT); + generator.defineChartStyle(style); + + librevenge::RVNGPropertyList serie, range, datapoint; + range.insert("librevenge:sheet-name", "MySheet"); + range.insert("librevenge:start-row", 1); + range.insert("librevenge:start-column", 0); + range.insert("librevenge:end-row", 1); + range.insert("librevenge:end-column", 2); + vect.clear(); + vect.append(range); + serie.insert("chart:class","chart:bar"); + serie.insert("chart:values-cell-range-address", vect); + vect.clear(); + datapoint.insert("librevenge:type", "data-point"); + datapoint.insert("chart:repeated", 2); + vect.append(datapoint); + serie.insert("librevenge:childs", vect); + serie.insert("librevenge:chart-id", "7"); + generator.openChartSerie(serie); + generator.closeChartSerie(); + + style.insert("librevenge:chart-id", "8"); + style.insert("draw:fill-color", "#ff420e"); + generator.defineChartStyle(style); + + range.insert("librevenge:sheet-name", "MySheet"); + range.insert("librevenge:start-row", 2); + range.insert("librevenge:start-column", 0); + range.insert("librevenge:end-row", 2); + range.insert("librevenge:end-column", 2); + vect.clear(); + vect.append(range); + serie.insert("chart:values-cell-range-address", vect); + serie.insert("librevenge:chart-id", "8"); + generator.openChartSerie(serie); + generator.closeChartSerie(); + + generator.closeChartPlotArea(); + + generator.closeChart(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 3; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + list.insert("librevenge:sheet-name", "MySheet"); + generator.openSheet(list); + + librevenge::RVNGPropertyList frame; + frame.insert("svg:x",0.2, librevenge::RVNG_INCH); + frame.insert("svg:y",1.4, librevenge::RVNG_INCH); + frame.insert("svg:width",400, librevenge::RVNG_POINT); + frame.insert("svg:height",400, librevenge::RVNG_POINT); + frame.insert("text:anchor-type", "page"); + frame.insert("text:anchor-page-number", 1); + frame.insert("style:vertical-rel", "page"); + frame.insert("style:horizontal-rel", "page"); + frame.insert("style:horizontal-pos", "from-left"); + frame.insert("style:vertical-pos", "from-top"); + + frame.insert("draw:stroke", "none"); + frame.insert("draw:fill", "none"); + generator.openFrame(frame); + sendChart(generator); + generator.closeFrame(); + + librevenge::RVNGPropertyList numbering, span, row, cell; + span.insert("style:font-name","Courier"); + span.insert("fo:font-size", 12, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + numbering.insert("librevenge:value-type","number"); + numbering.insert("librevenge:name", "Numbering0"); + generator.defineSheetNumberingStyle(numbering); + + row.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(row); + cell.insert("librevenge:row", 0); + for (int c=0; c<3; ++c) + { + cell.insert("librevenge:column", c); + generator.openSheetCell(cell); + static char const *(wh[3])= {"a","b","c"}; + generator.openParagraph(librevenge::RVNGPropertyList()); + generator.openSpan(span); + generator.insertText(wh[c]); + generator.closeSpan(); + generator.closeParagraph(); + generator.closeSheetCell(); + } + generator.closeSheetRow(); + + generator.openSheetRow(row); + cell.insert("librevenge:row", 1); + cell.insert("librevenge:numbering-name", "Numbering0"); + cell.insert("librevenge:value-type", "float"); + for (int c=0; c<3; ++c) + { + static double wh[3]= {0.1, 0.2, 0.3}; + cell.insert("librevenge:column", c); + cell.insert("librevenge:value", wh[c], librevenge::RVNG_GENERIC); + generator.openSheetCell(cell); + generator.closeSheetCell(); + } + generator.closeSheetRow(); + + generator.openSheetRow(row); + cell.insert("librevenge:row", 2); + for (int c=0; c<3; ++c) + { + static double wh[3]= {2, 3, 10.3}; + cell.insert("librevenge:column", c); + cell.insert("librevenge:value", wh[c], librevenge::RVNG_GENERIC); + generator.openSheetCell(cell); + generator.closeSheetCell(); + } + generator.closeSheetRow(); + + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testChart1.ods"); + file << content.cstr(); +} + +int main() +{ + createOds(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testGraphic1.cxx libodfgen-0.1.1/test/testGraphic1.cxx --- libodfgen-0.0.4/test/testGraphic1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testGraphic1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendGraphic(Generator &generator, void (Generator::*SetStyle)(const librevenge::RVNGPropertyList &), double xDiff=0, double yDiff=0) +{ + librevenge::RVNGPropertyList style1; + style1.insert("draw:stroke", "solid"); + style1.insert("svg:stroke-color", "#FF0000"); + style1.insert("svg:stroke-width", 3, librevenge::RVNG_POINT); + style1.insert("draw:fill", "none"); + (generator.*SetStyle)(style1); + + librevenge::RVNGPropertyList shape, point; + librevenge::RVNGPropertyListVector vertices; + point.insert("svg:x", 20+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 40+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + point.insert("svg:x", 200+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 40+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + shape.insert("svg:points", vertices); + generator.drawPolyline(shape); + + librevenge::RVNGPropertyList style2; + style2.clear(); + style2.insert("draw:stroke", "dash"); + style2.insert("draw:dots1", 1); + style2.insert("draw:dots1-length", librevenge::RVNG_POINT); + style2.insert("svg:stroke-color", "#00FF00"); + style2.insert("svg:stroke-width", 3, librevenge::RVNG_POINT); + style2.insert("draw:fill", "solid"); + style2.insert("draw:fill-color", "#0000FF"); + (generator.*SetStyle)(style2); + + shape.clear(); + shape.insert("svg:x", 70+xDiff, librevenge::RVNG_POINT); + shape.insert("svg:y", 80+yDiff, librevenge::RVNG_POINT); + shape.insert("svg:width", 100, librevenge::RVNG_POINT); + shape.insert("svg:height", 30, librevenge::RVNG_POINT); + generator.drawRectangle(shape); + + (generator.*SetStyle)(style1); + shape.clear(); + vertices.clear(); + point.insert("svg:x", 20+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 100+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + point.insert("svg:x", 200+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 100+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + shape.insert("svg:points", vertices); + generator.drawPolyline(shape); + + librevenge::RVNGPropertyList style(style1); + style.insert("draw:marker-start-path", "m10 0-10 30h20z"); + style.insert("draw:marker-start-viewbox", "0 0 20 30"); + style.insert("draw:marker-start-center", "false"); + style.insert("draw:marker-start-width", "5pt"); + (generator.*SetStyle)(style); + + shape.clear(); + vertices.clear(); + point.insert("svg:x", 20+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 200+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + point.insert("svg:x", 200+xDiff, librevenge::RVNG_POINT); + point.insert("svg:y", 200+yDiff, librevenge::RVNG_POINT); + vertices.append(point); + shape.insert("svg:points", vertices); + generator.drawPolyline(shape); + + style=style2; + style.insert("draw:fill", "gradient"); + style.insert("draw:style", "axial"); + style.insert("draw:start-color", "#FF00FF"); + style.insert("draw:start-opacity", 1., librevenge::RVNG_PERCENT); + style.insert("draw:end-color", "#700070"); + style.insert("draw:end-opacity", 1., librevenge::RVNG_PERCENT); + (generator.*SetStyle)(style); + + // point does not works for ellipse so inch + shape.clear(); + shape.insert("svg:cx", 3+xDiff/72., librevenge::RVNG_INCH); + shape.insert("svg:cy", 1.2+yDiff/72., librevenge::RVNG_INCH); + shape.insert("svg:rx", 0.8, librevenge::RVNG_INCH); + shape.insert("svg:ry", 0.4, librevenge::RVNG_INCH); + generator.drawEllipse(shape); + + style.insert("draw:stroke", "solid"); + style.insert("draw:shadow", "visible"); + style.insert("draw:shadow-color", "#000020"); + style.insert("draw:shadow-opacity", 1, librevenge::RVNG_PERCENT); + style.insert("draw:shadow-offset-x", "30"); + style.insert("draw:shadow-offset-y", "30"); + style.insert("draw:angle", 30); + (generator.*SetStyle)(style); + shape.insert("svg:cy", 1.8+yDiff/72., librevenge::RVNG_INCH); + shape.insert("librevenge:rotate", 30); + generator.drawEllipse(shape); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + sendGraphic(generator, &OdgGenerator::setStyle); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testGraphic1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + sendGraphic(generator, &OdpGenerator::setStyle); + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testGraphic1.odp"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + + generator.openGroup(librevenge::RVNGPropertyList()); + sendGraphic(generator, &OdsGenerator::defineGraphicStyle); + generator.closeGroup(); + + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testGraphic1.ods"); + file << content.cstr(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + { + // anchor on page + librevenge::RVNGPropertyList group; + group.insert("text:anchor-type", "page"); + group.insert("text:anchor-page-number", "1"); + group.insert("style:vertical-rel", "page"); + group.insert("style:horizontal-rel", "page"); + group.insert("style:horizontal-pos", "from-left"); + group.insert("style:vertical-pos", "from-top"); + group.insert("style:wrap", "run-through"); + group.insert("style:run-through", "background"); + generator.openGroup(group); + sendGraphic(generator, &OdtGenerator::defineGraphicStyle, 100, 200); + generator.closeGroup(); + } + librevenge::RVNGPropertyList para, span; + generator.openParagraph(para); + generator.openSpan(span); + { + // a basic char + librevenge::RVNGPropertyList group; + group.insert("svg:width",400, librevenge::RVNG_POINT); + group.insert("fo:min-height",300, librevenge::RVNG_POINT); + group.insert("text:anchor-type", "char"); + group.insert("style:vertical-rel", "char"); + group.insert("style:horizontal-rel", "char"); + generator.openGroup(group); + sendGraphic(generator, &OdtGenerator::defineGraphicStyle); + generator.closeGroup(); + } + generator.closeSpan(); + generator.closeParagraph(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testGraphic1.odt"); + file << content.cstr(); +} + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testLink1.cxx libodfgen-0.1.1/test/testLink1.cxx --- libodfgen-0.0.4/test/testLink1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testLink1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,224 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendText(Generator &generator) +{ + librevenge::RVNGPropertyList paragraph; + generator.openParagraph(paragraph); + + librevenge::RVNGPropertyList span; + span.insert("style:font-name","Courier"); + span.insert("fo:font-size", 13, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + generator.openSpan(span); + generator.insertText("test of links, a http link: "); + librevenge::RVNGPropertyList link; + link.insert("librevenge:type","link"); + link.insert("xlink:type","simple"); + link.insert("xlink:href","http://www.google.com"); + generator.openLink(link); + generator.insertText("search a word"); + generator.closeLink(); + + generator.insertText(", a ftp link: "); + link.insert("xlink:href","ftp://localhost"); + generator.openLink(link); + generator.insertText("ftp"); + generator.closeLink(); + + generator.insertText(", a mail link: "); + link.insert("xlink:href","mail:toto@server.com"); + generator.openLink(link); + generator.insertText("mail"); + generator.closeLink(); + generator.insertText("."); + generator.closeSpan(); + + generator.closeParagraph(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + sendText(generator); + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testLink1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + list.clear(); + list.insert("librevenge:column", 1); + list.insert("librevenge:row", 1); + list.insert("table:number-columns-spanned", 1); + list.insert("table:number-rows-spanned", 1); + generator.openSheetCell(list); + sendText(generator); + generator.closeSheetCell(); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testLink1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testLink1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testLink1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testList1.cxx libodfgen-0.1.1/test/testList1.cxx --- libodfgen-0.0.4/test/testList1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testList1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendText(Generator &generator) +{ + librevenge::RVNGPropertyList span; + span.insert("style:font-name","Geneva"); + span.insert("fo:font-size", 12, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + + // begin by a basic paragraph + librevenge::RVNGPropertyList para; + para.insert("librevenge:paragraph-id",1); + generator.defineParagraphStyle(span); + + para.clear(); + para.insert("librevenge:paragraph-id",1); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("basic "); // basic + generator.closeSpan(); + generator.closeParagraph(); + + librevenge::RVNGPropertyList level1, list; + // first test list using librevenge:list-id + level1.clear(); + level1.insert("librevenge:list-id",1); + level1.insert("style:display-name","MyList"); + level1.insert("librevenge:level",1); + level1.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + level1.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + level1.insert("style:num-format", "1"); + generator.openOrderedListLevel(level1); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1"); // 1 level 1 + generator.closeSpan(); + generator.closeListElement(); + + librevenge::RVNGPropertyList level2(level1); + level2.insert("librevenge:level",2); + level2.insert("style:num-format", "I"); + generator.openOrderedListLevel(level2); + list.insert("fo:margin-left",0.5,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 2"); // I level 2 + generator.closeSpan(); + generator.closeListElement(); + generator.closeOrderedListLevel(); + + generator.closeOrderedListLevel(); + + // now redefine level 2 and try again + librevenge::RVNGPropertyList level; + level.insert("librevenge:list-id",2); + level.insert("librevenge:list-definition",true); + level.insert("librevenge:level",1); + level.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + level.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + level.insert("style:num-format", "1"); + generator.openOrderedListLevel(level); + + level.insert("librevenge:level",2); + level.insert("style:num-format", "A"); + generator.openOrderedListLevel(level); + list.insert("fo:margin-left",0.5,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 2 (redef)"); // A level 2 (redef) + generator.closeSpan(); + generator.closeListElement(); + generator.closeOrderedListLevel(); + generator.closeOrderedListLevel(); + + generator.openOrderedListLevel(level1); + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + list.insert("text:start-value", 2); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1 again"); // 2 level 1 again + generator.closeSpan(); + generator.closeListElement(); + + generator.closeOrderedListLevel(); + + // paragraph + para.insert("librevenge:paragraph-id",1); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("basic again"); // basic again + generator.closeSpan(); + generator.closeParagraph(); + + // now test if the list without id works + list.clear(); + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "i"); + generator.openOrderedListLevel(list); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct)"); // i level 1(direct) + generator.closeSpan(); + generator.closeListElement(); + + list.clear(); + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "1"); + generator.openOrderedListLevel(list); + list.insert("fo:margin-left",0.5,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 2(direct)"); // 1 level 2(direct) + generator.closeSpan(); + generator.closeListElement(); + generator.closeOrderedListLevel(); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct)"); // ii level 1(direct) + generator.closeSpan(); + generator.closeListElement(); + + generator.closeOrderedListLevel(); + + list.clear(); + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "A"); + list.insert("style:display-name", "MyList2"); + generator.openOrderedListLevel(list); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct + automatic reset)"); // A level 1(...) + generator.closeSpan(); + generator.closeListElement(); + + generator.closeOrderedListLevel(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + sendText(generator); + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testList1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + + // first in textbox ( must works) + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",2, librevenge::RVNG_INCH); + textbox.insert("svg:y",3, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("text:anchor-type", "page"); + textbox.insert("text:anchor-page-number", 1); + textbox.insert("style:vertical-rel", "page"); + textbox.insert("style:horizontal-rel", "page"); + textbox.insert("style:horizontal-pos", "from-left"); + textbox.insert("style:vertical-pos", "from-top"); + + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.openFrame(textbox); + generator.openTextBox(librevenge::RVNGPropertyList()); + sendText(generator); + generator.closeTextBox(); + generator.closeFrame(); + + // now in a cell ( must only respect the linebreak ) + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + list.clear(); + list.insert("librevenge:column", 1); + list.insert("librevenge:row", 1); + list.insert("table:number-columns-spanned", 1); + list.insert("table:number-rows-spanned", 1); + generator.openSheetCell(list); + sendText(generator); + generator.closeSheetCell(); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testList1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testList1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testList1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testParagraph1.cxx libodfgen-0.1.1/test/testParagraph1.cxx --- libodfgen-0.0.4/test/testParagraph1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testParagraph1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendText(Generator &generator) +{ + librevenge::RVNGPropertyList span; + span.insert("style:font-name","Geneva"); + span.insert("fo:font-size", 12, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + + librevenge::RVNGPropertyList para; + para.insert("librevenge:paragraph-id",1); + para.insert("style:display-name","Default"); + generator.defineParagraphStyle(para); + + para.clear(); + para.insert("librevenge:paragraph-id",1); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("basic "); + generator.closeSpan(); + generator.closeParagraph(); + + para.clear(); + para.insert("fo:margin-left",1,librevenge::RVNG_INCH); + para.insert("fo:text-align","center"); + para.insert("style:display-name","Center"); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("center(style)"); + generator.closeSpan(); + generator.closeParagraph(); + + para.clear(); + para.insert("fo:margin-left",1,librevenge::RVNG_INCH); + para.insert("fo:text-align","center"); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("center(no style)"); + generator.closeSpan(); + generator.closeParagraph(); + + para.clear(); + para.insert("librevenge:paragraph-id",1); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("basic"); + generator.insertLineBreak(); + generator.insertText("again"); + generator.closeSpan(); + generator.closeParagraph(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + sendText(generator); + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testParagraph1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + list.clear(); + list.insert("librevenge:column", 1); + list.insert("librevenge:row", 1); + list.insert("table:number-columns-spanned", 1); + list.insert("table:number-rows-spanned", 1); + generator.openSheetCell(list); + sendText(generator); + generator.closeSheetCell(); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testParagraph1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testParagraph1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testParagraph1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testSpan1.cxx libodfgen-0.1.1/test/testSpan1.cxx --- libodfgen-0.0.4/test/testSpan1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testSpan1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendText(Generator &generator) +{ + librevenge::RVNGPropertyList paragraph; + generator.openParagraph(paragraph); + + librevenge::RVNGPropertyList span; + span.insert("style:display-name","A Imported Style"); + span.insert("style:font-name","Courier"); + span.insert("fo:font-size", 13, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + generator.openSpan(span); + generator.insertText("basic "); + generator.closeSpan(); + + span.clear(); + span.insert("style:font-name","Geneva"); + span.insert("fo:font-size", 11, librevenge::RVNG_POINT); + span.insert("fo:font-style", "italic"); + generator.openSpan(span); + generator.insertText("italic "); + generator.closeSpan(); + + span.clear(); + span.insert("librevenge:span-id",1); + generator.openSpan(span); + generator.insertText("basic again"); + generator.closeSpan(); + + generator.closeParagraph(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + sendText(generator); + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testSpan1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + list.clear(); + list.insert("librevenge:column", 1); + list.insert("librevenge:row", 1); + list.insert("table:number-columns-spanned", 1); + list.insert("table:number-rows-spanned", 1); + generator.openSheetCell(list); + sendText(generator); + generator.closeSheetCell(); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testSpan1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testSpan1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testSpan1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testTable1.cxx libodfgen-0.1.1/test/testTable1.cxx --- libodfgen-0.0.4/test/testTable1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testTable1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,373 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendTableContent(Generator &generator) +{ + librevenge::RVNGPropertyList span; + span.insert("style:font-name","Courier"); + span.insert("fo:font-size", 13, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + + librevenge::RVNGPropertyList para; + para.insert("librevenge:paragraph-id",1); + para.insert("fo:margin-left",0.1,librevenge::RVNG_INCH); + para.insert("fo:text-align","left"); + generator.defineParagraphStyle(para); + para.clear(); + para.insert("librevenge:paragraph-id",1); + + librevenge::RVNGPropertyList row, cell; + row.insert("librevenge:is-header-row", false); + cell.insert("table:number-rows-spanned", 1); + cell.insert("table:number-columns-spanned", 1); + + row.insert("style:row-height", 1, librevenge::RVNG_INCH); + generator.openTableRow(row); + cell.insert("librevenge:row", 1); + cell.insert("librevenge:column", 1); + cell.insert("fo:border", "1pt dashed #00ff00"); + generator.openTableCell(cell); + generator.closeTableCell(); + cell.remove("fo:border"); + + cell.insert("librevenge:column", 2); + generator.openTableCell(cell); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("B1"); + generator.closeSpan(); + generator.closeParagraph(); + generator.closeTableCell(); + + cell.insert("librevenge:column", 3); + cell.insert("fo:background-color", "#ff0000"); + generator.openTableCell(cell); + generator.closeTableCell(); + cell.remove("fo:background-color"); + generator.closeTableRow(); + + row.insert("style:row-height", 0.3, librevenge::RVNG_INCH); + generator.openTableRow(row); + cell.insert("librevenge:row", 2); + + cell.insert("librevenge:column", 1); + cell.insert("table:number-rows-spanned", 2); + cell.insert("table:number-columns-spanned", 2); + generator.openTableCell(cell); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("2 rows 2 col"); + generator.closeSpan(); + generator.closeParagraph(); + generator.closeTableCell(); + generator.insertCoveredTableCell(librevenge::RVNGPropertyList()); + cell.insert("librevenge:column", 3); + cell.insert("table:number-rows-spanned", 2); + cell.insert("table:number-columns-spanned", 1); + generator.openTableCell(cell); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("2 rows"); + generator.closeSpan(); + generator.closeParagraph(); + generator.closeTableCell(); + generator.closeTableRow(); + + row.insert("style:row-height", 1, librevenge::RVNG_INCH); + generator.openTableRow(row); + generator.insertCoveredTableCell(librevenge::RVNGPropertyList()); + generator.insertCoveredTableCell(librevenge::RVNGPropertyList()); + generator.insertCoveredTableCell(librevenge::RVNGPropertyList()); + generator.closeTableRow(); + + // copy of table 1 + row.insert("style:row-height", 1, librevenge::RVNG_INCH); + generator.openTableRow(row); + cell.insert("librevenge:row", 4); + cell.insert("table:number-rows-spanned", 1); + cell.insert("librevenge:column", 1); + cell.insert("fo:border", "1pt dashed #00ff00"); + generator.openTableCell(cell); + generator.closeTableCell(); + cell.remove("fo:border"); + + cell.insert("librevenge:column", 2); + generator.openTableCell(cell); + generator.openParagraph(para); + generator.openSpan(span); + generator.insertText("B1"); + generator.closeSpan(); + generator.closeParagraph(); + generator.closeTableCell(); + + cell.insert("librevenge:column", 3); + cell.insert("fo:background-color", "#ff0000"); + generator.openTableCell(cell); + generator.closeTableCell(); + cell.remove("fo:background-color"); + generator.closeTableRow(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("fo:min-height",100, librevenge::RVNG_POINT); + textbox.insert("text:anchor-type", "page"); + textbox.insert("text:anchor-page-number", 1); + textbox.insert("style:vertical-rel", "page"); + textbox.insert("style:horizontal-rel", "page"); + textbox.insert("style:horizontal-pos", "from-left"); + textbox.insert("style:vertical-pos", "from-top"); + + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.openFrame(textbox); + generator.openTextBox(librevenge::RVNGPropertyList()); + + librevenge::RVNGPropertyList table; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 3; ++c) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 2, librevenge::RVNG_INCH); + columns.append(column); + } + table.insert("style:width", 6, librevenge::RVNG_INCH); + table.insert("librevenge:table-columns", columns); + generator.openTable(table); + sendTableContent(generator); + generator.closeTable(); + + generator.closeTextBox(); + generator.closeFrame(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testTable1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:width",6, librevenge::RVNG_INCH); + textbox.insert("svg:height",180, librevenge::RVNG_POINT); + textbox.insert("text:anchor-type", "page"); + textbox.insert("text:anchor-page-number", 1); + textbox.insert("style:vertical-rel", "page"); + textbox.insert("style:horizontal-rel", "page"); + textbox.insert("style:horizontal-pos", "from-left"); + textbox.insert("style:vertical-pos", "from-top"); + + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.openFrame(textbox); + librevenge::RVNGPropertyList table; + columns.clear(); + for (size_t c = 0; c < 3; ++c) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 2, librevenge::RVNG_INCH); + columns.append(column); + } + table.insert("style:width", 6, librevenge::RVNG_INCH); + table.insert("librevenge:table-columns", columns); + generator.openTable(table); + sendTableContent(generator); + generator.closeTable(); + generator.closeFrame(); + + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testTable1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList table; + table.insert("svg:x",2, librevenge::RVNG_INCH); + table.insert("svg:y",2, librevenge::RVNG_INCH); + table.insert("svg:width",200, librevenge::RVNG_POINT); + table.insert("fo:min-height",100, librevenge::RVNG_POINT); + table.insert("draw:stroke", "none"); + table.insert("draw:fill", "none"); + + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 3; ++c) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 2, librevenge::RVNG_INCH); + columns.append(column); + } + table.insert("librevenge:table-columns", columns); + + generator.startTableObject(table); + sendTableContent(generator); + generator.endTableObject(); + + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testTable1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList table; + table.insert("svg:x",0.2, librevenge::RVNG_INCH); + table.insert("svg:y",0.02, librevenge::RVNG_INCH); + table.insert("svg:width",200, librevenge::RVNG_POINT); + table.insert("fo:min-height",100, librevenge::RVNG_POINT); + table.insert("draw:stroke", "none"); + table.insert("draw:fill", "none"); + + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 3; ++c) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 2, librevenge::RVNG_INCH); + columns.append(column); + } + table.insert("librevenge:table-columns", columns); + + generator.startTableObject(table); + sendTableContent(generator); + generator.endTableObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testTable1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ + diff -Nru libodfgen-0.0.4/test/testTextbox1.cxx libodfgen-0.1.1/test/testTextbox1.cxx --- libodfgen-0.0.4/test/testTextbox1.cxx 1970-01-01 00:00:00.000000000 +0000 +++ libodfgen-0.1.1/test/testTextbox1.cxx 2014-03-29 10:15:48.000000000 +0000 @@ -0,0 +1,306 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libodfgen + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) + * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include +#include + +#include +#include + +#include "StringDocumentHandler.hxx" + +template +static void sendText(Generator &generator) +{ + librevenge::RVNGPropertyList paragraph; + generator.openParagraph(paragraph); + + librevenge::RVNGPropertyList span; + span.insert("style:font-name","Courier"); + span.insert("fo:font-size", 13, librevenge::RVNG_POINT); + span.insert("librevenge:span-id",1); + generator.defineCharacterStyle(span); + span.clear(); + span.insert("librevenge:span-id",1); + generator.openSpan(span); + generator.insertText("basic "); + generator.closeSpan(); + + span.clear(); + span.insert("style:font-name","Geneva"); + span.insert("fo:font-size", 11, librevenge::RVNG_POINT); + span.insert("fo:font-style", "italic"); + generator.openSpan(span); + generator.insertText("italic "); + generator.closeSpan(); + + span.clear(); + span.insert("librevenge:span-id",1); + generator.openSpan(span); + generator.insertText("basic again"); + generator.closeSpan(); + + generator.closeParagraph(); + + // now test if the list works or not + librevenge::RVNGPropertyList list; + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "i"); + generator.openOrderedListLevel(list); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct)"); // i level 1(direct) + generator.closeSpan(); + generator.closeListElement(); + + list.clear(); + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "1"); + generator.openOrderedListLevel(list); + list.insert("fo:margin-left",0.5,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 2(direct)"); // 1 level 2(direct) + generator.closeSpan(); + generator.closeListElement(); + generator.closeOrderedListLevel(); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct)"); // ii level 1(direct) + generator.closeSpan(); + generator.closeListElement(); + + generator.closeOrderedListLevel(); + + list.clear(); + list.insert("text:min-label-width", 0.2, librevenge::RVNG_INCH); + list.insert("text:space-before", 0.1, librevenge::RVNG_INCH); + list.insert("style:num-format", "A"); + list.insert("style:display-name", "MyList2"); + generator.openOrderedListLevel(list); + + list.clear(); + list.insert("fo:margin-left",0.2,librevenge::RVNG_INCH); + generator.openListElement(list); + generator.openSpan(span); + generator.insertText("level 1(direct + automatic reset)"); // A level 1(...) + generator.closeSpan(); + generator.closeListElement(); + + generator.closeOrderedListLevel(); +} + +static void createOdt() +{ + StringDocumentHandler content; + OdtGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("text:anchor-type", "page"); + textbox.insert("text:anchor-page-number", 1); + textbox.insert("style:vertical-rel", "page"); + textbox.insert("style:horizontal-rel", "page"); + textbox.insert("style:horizontal-pos", "from-left"); + textbox.insert("style:vertical-pos", "from-top"); + + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.openFrame(textbox); + generator.openTextBox(librevenge::RVNGPropertyList()); + sendText(generator); + generator.closeTextBox(); + generator.closeFrame(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testTextbox1.odt"); + file << content.cstr(); +} + +static void createOds() +{ + StringDocumentHandler content; + OdsGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("librevenge:num-pages", 1); + page.insert("fo:page-height", 11.5, librevenge::RVNG_INCH); + page.insert("fo:page-width", 9, librevenge::RVNG_INCH); + page.insert("style:print-orientation", "portrait"); + page.insert("fo:margin-left", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-right", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-top", 0.1, librevenge::RVNG_INCH); + page.insert("fo:margin-bottom", 0.1, librevenge::RVNG_INCH); + generator.openPageSpan(page); + + librevenge::RVNGPropertyList list; + librevenge::RVNGPropertyListVector columns; + for (size_t c = 0; c < 2; c++) + { + librevenge::RVNGPropertyList column; + column.insert("style:column-width", 3, librevenge::RVNG_INCH); + columns.append(column); + } + list.insert("librevenge:columns", columns); + generator.openSheet(list); + + librevenge::RVNGPropertyList frame; + frame.insert("svg:x",0.2, librevenge::RVNG_INCH); + frame.insert("svg:y",0.2, librevenge::RVNG_INCH); + frame.insert("svg:width",200, librevenge::RVNG_POINT); + frame.insert("svg:height",100, librevenge::RVNG_POINT); + frame.insert("text:anchor-type", "page"); + frame.insert("text:anchor-page-number", 1); + frame.insert("style:vertical-rel", "page"); + frame.insert("style:horizontal-rel", "page"); + frame.insert("style:horizontal-pos", "from-left"); + frame.insert("style:vertical-pos", "from-top"); + + frame.insert("draw:stroke", "none"); + frame.insert("draw:fill", "none"); + generator.openFrame(frame); + generator.openTextBox(librevenge::RVNGPropertyList()); + sendText(generator); + generator.closeTextBox(); + generator.closeFrame(); + + list.clear(); + list.insert("style:row-height", 40, librevenge::RVNG_POINT); + generator.openSheetRow(list); + generator.closeSheetRow(); + generator.closeSheet(); + + generator.closePageSpan(); + generator.endDocument(); + + std::ofstream file("testTextbox1.ods"); + file << content.cstr(); +} + +static void createOdg() +{ + StringDocumentHandler content; + OdgGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + page.insert("librevenge:enforce-frame",true); + generator.startPage(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + generator.endPage(); + generator.endDocument(); + + std::ofstream file("testTextbox1.odg"); + file << content.cstr(); +} + +static void createOdp() +{ + StringDocumentHandler content; + OdpGenerator generator; + generator.addDocumentHandler(&content, ODF_FLAT_XML); + + generator.startDocument(librevenge::RVNGPropertyList()); + librevenge::RVNGPropertyList page; + page.insert("svg:x",0, librevenge::RVNG_POINT); + page.insert("svg:y",0, librevenge::RVNG_POINT); + page.insert("svg:width", 9, librevenge::RVNG_INCH); + page.insert("svg:height", 11, librevenge::RVNG_INCH); + generator.startSlide(page); + + librevenge::RVNGPropertyList textbox; + textbox.insert("svg:x",0.2, librevenge::RVNG_INCH); + textbox.insert("svg:y",0.02, librevenge::RVNG_INCH); + textbox.insert("svg:width",200, librevenge::RVNG_POINT); + textbox.insert("svg:height",100, librevenge::RVNG_POINT); + textbox.insert("draw:stroke", "none"); + textbox.insert("draw:fill", "none"); + generator.startTextObject(textbox); + sendText(generator); + generator.endTextObject(); + + generator.endSlide(); + generator.endDocument(); + + std::ofstream file("testTextbox1.odp"); + file << content.cstr(); +} + + +int main() +{ + createOdg(); + createOdp(); + createOds(); + createOdt(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ +