[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [calligra] filters: Merge the improvements to the ODF reader:
From:       Inge Wallin <inge () lysator ! liu ! se>
Date:       2015-03-02 12:13:21
Message-ID: E1YSPDt-000826-CM () scm ! kde ! org
[Download RAW message or body]

Git commit b2ad4ee8655200f18f822296e76d95c918075cf1 by Inge Wallin.
Committed on 02/03/2015 at 12:05.
Pushed by ingwa into branch 'master'.

Merge the improvements to the ODF reader:
 - Basic reader for ODS
 - Reader for frames
 - Reader for most graphics items
 - Reader for charts
 - Support for tables in the text reader
 - Better support for tables in the text reader
 - Smarter implementation

REVIEW: 122035

Squashed commit of the following:

commit d0255df44214f471d1b560dab5e63cfd6b24a440
Merge: 70d29fc 0f6dd09
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Mar 2 00:27:23 2015 +0100

    Merge branch 'master' into filters-libodfreader-ingwa

commit 70d29fcf7175adf6d4cb9e6e1b8639726f1b2831
Merge: 4136306 c9e4f87
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Wed Feb 25 19:32:48 2015 +0100

    Merge branch 'master' into filters-libodfreader-ingwa

commit 41363060c53f84836611b2149d4e82f044683830
Merge: e20537d 189c859
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Tue Jan 13 15:10:33 2015 +0100

    Merge branch 'master' into filters-libodfreader-ingwa

commit e20537df4f4085c4f80bdd2e0e5a43181b496984
Merge: 0f989c5 ccbd9e3
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 26 02:59:36 2014 +0100

    Merge branch 'master' into filters-libodfreader-ingwa

commit ccbd9e3f2d2ef17db204c3833de9a3ba6dc47e1d
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 20:28:06 2014 +0200

    Fix build

commit 0f989c54990da8c0681aefaeebeee411b8b8c678
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 19 16:52:37 2014 +0200

    Implement graphics objects and 3D objects

commit 8356af68fee60c222ba9bbf3617e32008dc98409
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 19 06:25:53 2014 +0200

    Support for <chart:series> and all its children

    This completes the chart reader.

    There is also a new macro: IMPLEMENT_READER_FUNCTION_ONE_CHILD

commit e13387a7dd506361956e4278b1fba2617f212020
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 19 05:21:36 2014 +0200

    Support for chart:axis and children

commit b6b049eb3eec9c4839aab61ea944739e4181463f
Merge: 3e3c5bd 367991a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 19 04:30:37 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 367991ab885b318930d82ddf7eaa13986d1d3cbc
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 20:28:06 2014 +0200

    Fix build

commit 3e3c5bd1e9f018c02cba78e5857b5283a005b46f
Merge: 41ef6e4 c30c93a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Fri Oct 17 01:02:30 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

    Conflicts:
    	plugins/semanticitems/event/KoRdfCalendarEvent.h

commit c30c93a5263e3df9970ad97f3b6d64b11a25d6e2
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 20:28:06 2014 +0200

    Fix build

commit 41ef6e4f49b7240be0becbfb24b015ee435a6c22
Merge: e7b3ed3 edfcd93
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 21:07:38 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

    Conflicts:
    	plugins/semanticitems/event/KoRdfCalendarEvent.h

commit edfcd938a6ed4ba90b0d01f0740855fb4a6fbf9a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 20:28:06 2014 +0200

    Fix build

commit e7b3ed300dcd976b1263301bbbcb349b45087a26
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Oct 6 20:19:33 2014 +0200

    Improve some comments

commit cd1541f3025abaad71a5e2743beaeccfd4fac7ba
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 5 02:02:52 2014 +0200

    More macros.

commit c4503f51de72958bc978b95ccb23dbb11fb655a3
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 5 01:15:50 2014 +0200

    Use macros everywhere for repetitive functions.

commit 286025c7873e8238c4d90a85a25bcadf1b4ce24a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 5 00:33:59 2014 +0200

    Use the new macros to declare all reader functions

commit 1d3a79ce1375535866eaf0898647f028b5caf113
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Oct 5 00:19:00 2014 +0200

    ChartReader: More support for children of chart:chart

    Also: some implementation and declaration macros

commit 41a2221cb8a94c9b008267afe632ed9521bdc257
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 22:10:52 2014 +0200

    Make it build again

commit 07c19ff71e02b01b539bec2d1435c6f0dc5a9930
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 21:08:09 2014 +0200

    Mark as done

commit c494850d3d8a2f4479b1c77b343ff1829291943c
Merge: 396165b ecaf659
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 20:12:37 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 396165b871ed4d3183791b4d08a69c65941d6e71
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 02:03:01 2014 +0200

    ChartReader: Implement support for legend.

commit e5b4005dfa5abf012979a8e327b509923ee69cf2
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 01:38:47 2014 +0200

    Forgot to call the new functions

commit 06af78488c8e09d8a1be7ee68ef105c3c28febdf
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Oct 4 01:31:20 2014 +0200

    Chart reader: Implement the simple parts.

     - chart:footer
     - chart:title
     - chart:subtitle
     - table:table

commit 33fc0801d2a2439209caba5b6a6420c76af646b0
Merge: cb2b386 72a8017
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Fri Oct 3 23:51:55 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

    Conflicts:
    	filters/libodfreader/OdfTextReader.cpp
    	filters/libodfreader/OdfTextReader.h

commit cb2b38608b1fcfc7b44ee4b02a542224f727249f
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Oct 2 02:16:22 2014 +0200

    First embryo of a chart reader

commit abf8c690e9929e94e60da2d91ca45e5c5d2fb58c
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Oct 2 02:15:11 2014 +0200

    Fix minor issues in OdfDrawReader.h

     - a typo
     - unnecessary class declarations

commit bbc3e12f9a15ffb2315d1d96cd05c7aef544732f
Merge: a2ed867 beea244
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Tue Sep 30 21:16:43 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit a2ed867a4cbb1bda7bfafbf6b3384ce057d91e0c
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Tue Sep 30 21:15:16 2014 +0200

    Add support for OLE objects in frames

commit 5e655eb21cf93f9936c4201c9e9cd4d0a6625a7d
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Sep 28 01:01:56 2014 +0200

    Finish the support for <office:annotation>

commit b5b575e82ed2cca50d6d2561a9658355ad74f422
Merge: 1213ce6 ee0ae28
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Sep 27 20:13:56 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 1213ce6fa8e454c41e1265f6516b8ff25495af1b
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Sep 27 20:11:56 2014 +0200

    Finish table support in the OdfTextReader.

    Also add a new XML utility which can be used in many other places.

commit 7747c76f152c9913a2aa4d81a662ebdbf47ca156
Merge: 7199351 0e51913
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Fri Sep 26 00:05:31 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 7199351bb89689127bb41d0ec3b5023132aa5801
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Sep 25 04:30:24 2014 +0200

    Add support for <table:column-group> and <table:row-group> to the text reader

commit 63f76c41cadc839e5a08ea82a02fe7a26761d90d
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Sep 25 04:04:16 2014 +0200

    Add support for <draw:object> and <table:table> in frames.

commit fb3b47febeac5e76ac4d41f96f05aa6ac52011d4
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Wed Sep 24 22:41:42 2014 +0200

    Add support for <draw:frame>

commit f1f82a672cd3cb1a2cc18784d051f1c3f33776a0
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Sep 22 17:55:49 2014 +0200

    More support for tables

    <table:table-header-columns>
    <table:table-columns>

commit 5e8530d8a51cad280e9642fbf84a063b8837afde
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Sep 22 17:25:47 2014 +0200

    Call the draw reader from more places

commit 964a3adcce3128537c6b0b1c8f46b42a29694237
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Sep 22 14:13:53 2014 +0200

    Create a foundation for the draw reader.

    From here on it's just filling in all the graphics objects.

commit 00bdcd9eb72b93099f41d7d542aa18cb440aa983
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Sep 22 05:52:14 2014 +0200

    Add support for reading graphics elements.

    This is done by introducing the OdfDrawReader which is similar to the
    OdfTextReader except it handles graphics elements mainly in the dr3d and draw
    namespaces.

commit 9c248e6bf7d60b628559a1ad43d412a91151ae20
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Mon Sep 22 04:15:31 2014 +0200

    Implement a spreadsheet reader.

commit b0f62e518b25c650a7dfffaa101a25e22ce17a2a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Sep 21 04:04:42 2014 +0200

    Prepare for more readers of ODF files than just ODT.

    This patch creates a baseclass OdfReader, which is inherited by
    OdtReader. Most of the common functionality is kept in OdfReader. There is
    also a new accompanying class OdfReaderBackend which is inherited by
    OdtReaderBackend.

    The same pattern will be followed by OdsReader, OdpReader and so on.

commit 350d9a8ad09885354f15da3077fb2a70406b6d35
Merge: b8b2d51 f436f6b
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Sep 21 02:49:12 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit b8b2d517ac8e24f870217cdfebea7feca436197a
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Sep 20 23:05:31 2014 +0200

    README: Fixed some typos

commit 5334c0ee94191fd39dcb9336873ec48f6e298fe9
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Sep 20 03:24:11 2014 +0200

    Small fixes in the odf reader.

commit 6ae66d0202360b70ed65cac326cbb2a4054eaa46
Merge: 79016d9 e15f4cc
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Fri Sep 19 21:34:41 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 79016d9731c3286ac0728580b0c9b284391f9d65
Merge: c3656f7 089dff6
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Apr 13 12:54:49 2014 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit c3656f7df06f10af3d7abdb7725d334eb92469a5
Merge: b780dd3 f1c4432
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 19:23:06 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit b780dd3c0adb9874f7fc72d7bfd579f7ff5f60f1
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 11:10:56 2013 +0200

    Define LIBODFREADER_INCLUDES in the main CMakeLists.txt

commit 6d01c07c0fd4086301794f22709c24918932e980
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 09:26:54 2013 +0200

    Implement support for <text:soft-page-break>.

commit f8071086e346bee93ba6be4101e080dacce0f90c
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 08:59:58 2013 +0200

    Implement table:covered-table-cell

commit 003298177a95af1eb456c343fcbf8bedcfd6afa3
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 08:49:02 2013 +0200

    Better comments

commit 33e182f456bff86d2bf6c9d7986d9bc5ff849091
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Aug 25 08:20:29 2013 +0200

    Enable reading of table contents.

commit 35a7e163725412fc972a4df52e11917fdd417542
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Aug 24 18:56:41 2013 +0200

    Add support for table header rows.

    Also do some nicer formatting of some comments

commit 83111e63651ede0f22835d8e7ce23254d83cfaea
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Aug 24 11:24:14 2013 +0200

    Implement very basic support for tables

commit 5de9e69685bdaf3e1620d07b7ca13117520bb381
Merge: 43d6494 9c43651
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Fri Aug 23 02:34:08 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

    Conflicts:
    	filters/libodfreader/OdtReaderBackend.cpp
    	filters/libodfreader/OdtReaderBackend.h

commit 43d649485099d61cedbc91c5aafcd5ecd8a9bfaf
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Jul 18 23:02:13 2013 +0200

    Make the API of the OdtReaderBackend slightly saner.

    Previously there was a completely unused pointer given to the constructor.

commit 251716c604e68e5525f6b9c6bfd0ea01a943a407
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Jul 18 22:32:16 2013 +0200

    Split out a reader for ODF text contents.

    This prepares for readers of e.g. ODS and ODP since it means that we
    can share the text reading part between them.

    Also adapt the ascii filter to the new API.

commit eb5e0f50e3b2a461837f14daeaa725dfa8933dae
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Jul 18 15:04:47 2013 +0200

    Prepare for merge into master

     * Remove some things to come in later installments
     * Fix a build issue.

commit 83017f4258513c5bfeaa7e877ce27c2db5fcc538
Merge: 73570b5 35ca4ac
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Thu Jul 18 14:41:40 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 73570b5a3f7b3478d772610c794aa7476c23d4d3
Merge: a46ecd9 cc6f5ab
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun Jul 14 14:29:51 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit a46ecd992995474a85af245395e38d80c9a74b21
Merge: 80a6a66 7e03514
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Jul 6 07:51:48 2013 +0700

    Merge branch 'master' into filters-libodfreader-ingwa

    Conflicts:
    	filters/libodfreader/CMakeLists.txt

commit 80a6a66e1240bcc581e62276a2b9cd06cee3cd32
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Jun 8 22:05:07 2013 +0200

    Add documentation and support for a few new elements.

commit 591bacd9cb3e972528eb79ec489f65a26ff615ff
Merge: bf7ed75 cedf488
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat Jun 1 15:12:31 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit bf7ed7502d85f6455312c8fb3888a21fe481e372
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Wed May 22 02:20:04 2013 +0200

    Implement elementOfficeDocumentcontent() backend call

    This is the last one of the document level callbacks.

commit 22c0ab5311d21491f8eb8249f408da55c1ff0054
Merge: 613c7b4 ac8f70b
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Tue May 21 21:44:59 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

    We need the newly merged changes from libs-odf2-ingwa.

commit 613c7b480b708c5370ce179765376788585da645
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 13:31:45 2013 +0200

    Some cleanup.

commit 592c376fff0d9ab980c8f914cdad336013ad23cc
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 12:30:31 2013 +0200

    Make it easy to turn debug on and off.

commit 2e318ad5e0d2f3f40002b4f1209d5be056f51a22
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 12:11:09 2013 +0200

    Fix last bug with the OdtReader.

    This makes the ascii export filter work!  In fact it's already better
    than the old one because this one also extracts contents inside
    tables.

commit 8d32f10efea822af97b187a9662d369980dedf7b
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 12:01:24 2013 +0200

    More fixes and more debug.

commit cc5c24036bc06147a80a26d4dd1d73b243e777ad
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 03:23:14 2013 +0200

    Improve debugging and fix a couple of bugs.

commit 53017dfbdd5546ec0912fb673410cf6a195f3b85
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 19 00:51:29 2013 +0200

    Add more features to the reader

     - support for all children office:text (most are ignored)
     - debug statements
     - better parsing

commit c3cb4a6065a25351a14342d8e9dee0f5cfb084d5
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat May 18 22:10:36 2013 +0200

    Port the ascii filter to the odfreader.

    Still doesn't work perfectly.

commit 0a4d1ee10c1d0104b24b89de4702d7859a02aa69
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat May 18 19:58:11 2013 +0200

    Handle unknown elements

commit f7500ab149b243afe11bb1806d6bccb4be5653df
Merge: 9c14652 0b8b9c7
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sat May 18 19:02:40 2013 +0200

    Merge branch 'master' into filters-libodfreader-ingwa

commit 9c14652d8f35946b80b9255b4d2113229f082875
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 12 21:33:35 2013 +0200

    Add a simple README to the library.

commit e26e12a9baea6f8492926e12ce0e03ac3115b50f
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 12 17:12:41 2013 +0200

    Use our own version of prepareForOdf() until it's exported from libodf.

commit 884c2e681231fe4a926012b2a9f83510b4b598ec
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 12 17:05:25 2013 +0200

    Add the first embryo to the new reader and the backend class.

commit fb0a654b9577d12d7c42b49e3de6f798acf6f8b1
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 12 14:12:50 2013 +0200

    Forgot the export macros.

commit 5bc522bc16c2fd962c2f8f2d2c80f5a3695d9194
Author: Inge Wallin <inge@lysator.liu.se>
Date:   Sun May 12 14:11:28 2013 +0200

    First commit on the new odfreader library.

    This one contains:
     - create the directory
     - define the LIB_ODFREADER product in cmake
     - include it in all levels of cmake files
     - First two classes: OdfParser and OdfReaderContext

M  +2    -0    filters/libodf2/CMakeLists.txt
M  +1    -1    filters/libodf2/KoXmlStreamReader.h
A  +47   -0    filters/libodf2/KoXmlUtils.cpp     [License: LGPL (v2+)]
A  +46   -0    filters/libodf2/KoXmlUtils.h     [License: LGPL (v2+)]
M  +10   -2    filters/libodfreader/CMakeLists.txt
A  +390  -0    filters/libodfreader/OdfChartReader.cpp     [License: LGPL (v2+)]
A  +108  -0    filters/libodfreader/OdfChartReader.h     [License: LGPL (v2+)]
A  +97   -0    filters/libodfreader/OdfChartReaderBackend.cpp     [License: LGPL \
(v2+)] A  +95   -0    filters/libodfreader/OdfChartReaderBackend.h     [License: LGPL \
(v2+)] A  +518  -0    filters/libodfreader/OdfDrawReader.cpp     [License: LGPL \
(v2+)] A  +125  -0    filters/libodfreader/OdfDrawReader.h     [License: LGPL (v2+)]
A  +108  -0    filters/libodfreader/OdfDrawReaderBackend.cpp     [License: LGPL \
(v2+)] A  +103  -0    filters/libodfreader/OdfDrawReaderBackend.h     [License: LGPL \
(v2+)] C  +77   -104  filters/libodfreader/OdfReader.cpp [from: \
filters/libodfreader/OdtReader.cpp - 074% similarity] C  +38   -21   \
filters/libodfreader/OdfReader.h [from: filters/libodfreader/OdtReader.h - 058% \
similarity] C  +13   -29   filters/libodfreader/OdfReaderBackend.cpp [from: \
filters/libodfreader/OdtReaderBackend.cpp - 059% similarity] C  +13   -14   \
filters/libodfreader/OdfReaderBackend.h [from: \
filters/libodfreader/OdtReaderBackend.h - 077% similarity] A  +79   -0    \
filters/libodfreader/OdfReaderInternals.h     [License: LGPL (v2+)] M  +224  -23   \
filters/libodfreader/OdfTextReader.cpp M  +32   -22   \
filters/libodfreader/OdfTextReader.h M  +35   -124  \
filters/libodfreader/OdfTextReaderBackend.cpp M  +30   -22   \
filters/libodfreader/OdfTextReaderBackend.h A  +207  -0    \
filters/libodfreader/OdsReader.cpp     [License: LGPL (v2+)] C  +21   -33   \
filters/libodfreader/OdsReader.h [from: filters/libodfreader/OdtReader.h - 061% \
similarity] C  +12   -29   filters/libodfreader/OdsReaderBackend.cpp [from: \
filters/libodfreader/OdtReaderBackend.cpp - 059% similarity] C  +14   -14   \
filters/libodfreader/OdsReaderBackend.h [from: \
filters/libodfreader/OdtReaderBackend.h - 077% similarity] M  +6    -218  \
filters/libodfreader/OdtReader.cpp M  +5    -23   filters/libodfreader/OdtReader.h
M  +2    -19   filters/libodfreader/OdtReaderBackend.cpp
M  +5    -5    filters/libodfreader/OdtReaderBackend.h

http://commits.kde.org/calligra/b2ad4ee8655200f18f822296e76d95c918075cf1

diff --git a/filters/libodf2/CMakeLists.txt b/filters/libodf2/CMakeLists.txt
index 3792771..0006016 100644
--- a/filters/libodf2/CMakeLists.txt
+++ b/filters/libodf2/CMakeLists.txt
@@ -6,6 +6,8 @@ include_directories( ${KOODF_INCLUDES} ${KOODF2_INCLUDES} )
 
 set(koodf2_LIB_SRCS
     KoXmlStreamReader.cpp
+    KoXmlUtils.cpp
+
     KoTable.cpp
     KoRow.cpp
     KoColumn.cpp
diff --git a/filters/libodf2/KoXmlStreamReader.h \
b/filters/libodf2/KoXmlStreamReader.h index a06c8ec..21977db 100644
--- a/filters/libodf2/KoXmlStreamReader.h
+++ b/filters/libodf2/KoXmlStreamReader.h
@@ -219,4 +219,4 @@ class KOODF2_EXPORT KoXmlStreamAttributes
 void KOODF2_EXPORT prepareForOdf(KoXmlStreamReader &reader);
 
 
-#endif /* KOGENCHANGES_H */
+#endif /* KOXMLSTREAMREADER_H */
diff --git a/filters/libodf2/KoXmlUtils.cpp b/filters/libodf2/KoXmlUtils.cpp
new file mode 100644
index 0000000..f976cea
--- /dev/null
+++ b/filters/libodf2/KoXmlUtils.cpp
@@ -0,0 +1,47 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2014 Inge Wallin <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+// Own
+#include "KoXmlUtils.h"
+
+// Qt
+#include <QString>
+
+// libodf2
+#include "KoXmlStreamReader.h"
+
+
+void readCharacterData(KoXmlStreamReader &reader, QString &result)
+{
+    while (!reader.atEnd() && !reader.isEndElement()) {
+	reader.readNext();
+
+        if (reader.isCharacters()) {
+            //kDebug(30503) << "Found character data";
+	    result.append(reader.text());
+        }
+	else if (reader.isStartElement()) {
+	    // Collect character data recursively and read past the end element.
+	    readCharacterData(reader, result);
+	    reader.readNext(); 
+	}
+    }
+}
diff --git a/filters/libodf2/KoXmlUtils.h b/filters/libodf2/KoXmlUtils.h
new file mode 100644
index 0000000..26adb2c
--- /dev/null
+++ b/filters/libodf2/KoXmlUtils.h
@@ -0,0 +1,46 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2014 Inge Wallin <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KOXMLUTILS_H
+#define KOXMLUTILS_H
+
+
+#include "koodf2_export.h"
+
+
+class QString;
+class KoXmlStreamReader;
+
+
+/**
+ * @brief Read and collect the text (character data) from an element.
+ *
+ * This function is recursive and disregards everything from child elements
+ * except any text content.
+ *
+ * @param reader The XML stream reader that we will read from. This should point to \
a start element. + * @param result The result will be accumulated into this string.
+ *
+ */
+
+void KOODF2_EXPORT readCharacterData(KoXmlStreamReader &reader, QString &result);
+
+
+#endif /* KOXMLUTILS_H */
diff --git a/filters/libodfreader/CMakeLists.txt \
b/filters/libodfreader/CMakeLists.txt index e4bfdda..9d02be8 100644
--- a/filters/libodfreader/CMakeLists.txt
+++ b/filters/libodfreader/CMakeLists.txt
@@ -7,15 +7,23 @@ include_directories(
 ########### libodfreader ###############
 
 set(odfreader_LIB_SRCS
+    OdfReader.cpp
     OdfReaderContext.cpp
+    OdfReaderBackend.cpp
     OdfParser.cpp
     OdtReader.cpp
     OdtReaderBackend.cpp
-    #OdsReader.cpp
-    #OdsReaderBackend.cpp
+    OdsReader.cpp
+    OdsReaderBackend.cpp
+    #OdpReader.cpp
+    #OdpReaderBackend.cpp
 
     OdfTextReader.cpp
     OdfTextReaderBackend.cpp
+    OdfDrawReader.cpp
+    OdfDrawReaderBackend.cpp
+    OdfChartReader.cpp
+    OdfChartReaderBackend.cpp
 )
 
 kde4_add_library(koodfreader SHARED ${odfreader_LIB_SRCS})
diff --git a/filters/libodfreader/OdfChartReader.cpp \
b/filters/libodfreader/OdfChartReader.cpp new file mode 100644
index 0000000..49d36f0
--- /dev/null
+++ b/filters/libodfreader/OdfChartReader.cpp
@@ -0,0 +1,390 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+
+// Own
+#include "OdfTextReader.h"
+
+// Qt
+#include <QStringList>
+#include <QBuffer>
+
+// KDE
+#include <kdebug.h>
+#include <klocalizedstring.h>
+
+// Calligra
+#include <KoStore.h>
+#include <KoXmlStreamReader.h>
+#include <KoXmlNS.h>
+#include <KoXmlWriter.h>  // For copyXmlElement
+#include <KoOdfReadStore.h>
+
+// Reader library
+#include "OdfReader.h"
+#include "OdfChartReaderBackend.h"
+#include "OdfReaderContext.h"
+
+
+#if 1
+static int debugIndent = 0;
+#define DEBUGSTART() \
+    ++debugIndent; \
+    DEBUG_READING("entering")
+#define DEBUGEND() \
+    DEBUG_READING("exiting"); \
+    --debugIndent
+#define DEBUG_READING(param) \
+    kDebug(30503) << QString("%1").arg(" ", debugIndent * 2) << param << ": " \
+    << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : \
"other")) \ +    << reader.qualifiedName().toString()
+#else
+#define DEBUGSTART() \
+    // NOTHING
+#define DEBUGEND() \
+    // NOTHING
+#define DEBUG_READING(param) \
+    // NOTHING
+#endif
+
+
+OdfChartReader::OdfChartReader()
+    : m_parent(0)
+    , m_backend(0)
+    , m_context(0)
+{
+}
+
+OdfChartReader::~OdfChartReader()
+{
+}
+
+
+// ----------------------------------------------------------------
+
+
+void OdfChartReader::setParent(OdfReader *parent)
+{
+    m_parent = parent;
+}
+
+void OdfChartReader::setBackend(OdfChartReaderBackend *backend)
+{
+    m_backend = backend;
+}
+
+void OdfChartReader::setContext(OdfReaderContext *context)
+{
+    m_context = context;
+}
+
+
+// ----------------------------------------------------------------
+
+
+void OdfChartReader::readElementOfficeChart(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementOfficeChart(reader, m_context);
+
+    // <office:chart> has the following children in ODF 1.2:
+    //   [done] <chart:chart> 11.1
+    //          <table:calculation-settings> 9.4.1
+    //          <table:consolidation> 9.7
+    //          <table:content-validations> 9.4.4
+    //          <table:database-ranges> 9.4.14
+    //          <table:data-pilot-tables> 9.6.2
+    //          <table:dde-links> 9.8
+    //          <table:label-ranges> 9.4.10
+    //          <table:named-expressions> 9.4.11
+    //          <text:alphabetical-index-auto-mark-file> 8.8.3
+    //          <text:dde-connection-decls> 14.6.2
+    //          <text:sequence-decls> 7.4.11
+    //          <text:user-field-decls> 7.4.7
+    //          <text:variable-decls> 7.4.2
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "chart:chart") {
+	    readElementChartChart(reader);
+        }
+        else if (tagName == "table:calculation-settings") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        //...  MORE else if () HERE
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementOfficeChart(reader, m_context);
+    DEBUGEND();
+}
+
+void OdfChartReader::readElementChartChart(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementChartChart(reader, m_context);
+
+    // <chart:chart> has the following children in ODF 1.2:
+    //   [done] <chart:footer> 11.2.3
+    //   [done] <chart:legend> 11.3
+    //   [done] <chart:plot-area> 11.4
+    //   [done] <chart:subtitle> 11.2.2
+    //   [done] <chart:title> 11.2.1
+    //   [done] <table:table> 9.1.2
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "chart:footer") {
+	    readElementChartFooter(reader);
+        }
+        else if (tagName == "chart:subtitle") {
+	    readElementChartSubtitle(reader);
+        }
+        else if (tagName == "chart:title") {
+	    readElementChartTitle(reader);
+        }
+        else if (tagName == "chart:legend") {
+	    readElementChartLegend(reader);
+        }
+        else if (tagName == "chart:plot-area") {
+	    readElementChartPlotArea(reader);
+        }
+        else if (tagName == "table:table") {
+	    OdfTextReader *textReader = m_parent->textReader();
+	    if (textReader) {
+		textReader->readElementTableTable(reader);
+	    }
+	    else {
+		reader.skipCurrentElement();
+	    }
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementChartChart(reader, m_context);
+    DEBUGEND();
+}
+
+#define IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(readername, name)      \
+IMPLEMENT_READER_FUNCTION_START(readername, name)                   \
+    while (reader.readNextStartElement()) {                         \
+        QString tagName = reader.qualifiedName().toString();        \
+                                                                    \
+        if (tagName == "text:p") {                                  \
+	    OdfTextReader *textReader = m_parent->textReader();     \
+	    if (textReader) {                                       \
+		textReader->readElementTextP(reader);               \
+	    }                                                       \
+	    else {                                                  \
+		reader.skipCurrentElement();                        \
+	    }                                                       \
+        }                                                           \
+        else {                                                      \
+            reader.skipCurrentElement();                            \
+        }                                                           \
+    }                                                               \
+IMPLEMENT_READER_FUNCTION_END(name)
+
+
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartFooter)
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartSubtitle)
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartTitle)
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartLegend)
+
+
+void OdfChartReader::readElementChartPlotArea(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementChartPlotArea(reader, m_context);
+
+    // <chart:plot-area> has the following children in ODF 1.2:
+    //   [done] <chart:wall> 11.6
+    //   [done] <chart:floor> 11.7
+    //   [done] <chart:axis> 11.8
+    //   [done] <chart:series> 11.11
+    //   [done] <chart:stock-gain-marker> 11.19
+    //   [done] <chart:stock-loss-marker> 11.20
+    //   [done] <chart:stock-range-line> 11.21
+    //          <dr3d:light> 10.5.3
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+	if (tagName == "chart:wall") {
+	    readElementChartWall(reader);
+        }
+        else if (tagName == "chart:floor") {
+	    readElementChartFloor(reader);
+        }
+        else if (tagName == "chart:axis") {
+	    readElementChartAxis(reader);
+        }
+        else if (tagName == "chart:series") {
+	    readElementChartSeries(reader);
+        }
+        else if (tagName == "chart:stock-gain-marker") {
+	    readElementChartStockGainMarker(reader);
+        }
+        else if (tagName == "chart:stock-loss-marker") {
+	    readElementChartStockLossMarker(reader);
+        }
+        else if (tagName == "chart:stock-range-line") {
+	    readElementChartStockRangeLine(reader);
+        }
+        else if (tagName == "dr3d:light") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementChartPlotArea(reader, m_context);
+    DEBUGEND();
+}
+
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartWall)
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartFloor)
+
+void OdfChartReader::readElementChartAxis(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementChartAxis(reader, m_context);
+
+    // <chart:axis> has the following children in ODF 1.2:
+    //   [done] <chart:categories> 11.9
+    //   [done] <chart:grid> 11.10
+    //   [done] <chart:title> 11.2.1
+
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "chart:categories") {
+	    readElementChartCategories(reader);
+        }
+        else if (tagName == "chart:grid") {
+	    readElementChartGrid(reader);
+        }
+        else if (tagName == "chart:title") {
+	    readElementChartTitle(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementChartAxis(reader, m_context);
+    DEBUGEND();
+}
+
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartCategories)
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartGrid)
+
+// ODF 1.2  11.11: <chart:series>
+void OdfChartReader::readElementChartSeries(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementChartSeries(reader, m_context);
+
+    // <chart:series> has the following children in ODF 1.2:
+    //   [done] <chart:data-label> 11.14
+    //   [done] <chart:data-point> 11.13
+    //   [done] <chart:domain> 11.12
+    //   [done] <chart:error-indicator> 11.16
+    //   [done] <chart:mean-value> 11.15
+    //   [done] <chart:regression-curve> 11.17
+
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "chart:data-label") {
+	    readElementChartDataLabel(reader);
+        }
+        else if (tagName == "chart:data-point") {
+	    readElementChartDataPoint(reader);
+        }
+        else if (tagName == "chart:domain") {
+	    readElementChartDomain(reader);
+        }
+        else if (tagName == "chart:error-indicator") {
+	    readElementChartErrorIndicator(reader);
+        }
+        else if (tagName == "chart:mean-value") {
+	    readElementChartMeanValue(reader);
+        }
+        else if (tagName == "chart:regression-curve") {
+	    readElementChartRegressionCurve(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementChartSeries(reader, m_context);
+    DEBUGEND();
+}
+
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartDomain)          // ODF \
1.2  11.12 +IMPLEMENT_READER_FUNCTION_ONE_CHILD(OdfChartReader, ChartDataPoint,
+				    "chart:data-label", ChartDataLabel)     // ODF 1.2  11.13
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartDataLabel)        // ODF \
1.2  11.14 +IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartMeanValue)     \
// ODF 1.2  11.15 +IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, \
ChartErrorIndicator)  // ODF 1.2  11.16 \
+IMPLEMENT_READER_FUNCTION_ONE_CHILD(OdfChartReader, ChartRegressionCurve, +				    \
"chart:equation", ChartEquation)        // ODF 1.2  11.17 \
+IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartEquation)         // ODF \
1.2  11.18 +IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, \
ChartStockGainMarker) // ODF 1.2  11.19 \
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartStockLossMarker) // ODF \
1.2  11.20 +IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, \
ChartStockRangeLine)  // ODF 1.2  11.21 +
+
+
+// ----------------------------------------------------------------
+//                             Other functions
+
+
+void OdfChartReader::readUnknownElement(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+
+#if 0  // FIXME: Fix this
+    if (m_context->isInsideParagraph()) {
+        // readParagraphContents expect to have the reader point to the
+        // contents of the paragraph so we have to read past the chart:p
+        // start tag here.
+        reader.readNext();
+        readParagraphContents(reader);
+    }
+    else {
+        while (reader.readNextStartElement()) {
+            readTextLevelElement(reader);
+        }
+    }
+#else
+    reader.skipCurrentElement();
+#endif
+
+    DEBUGEND();
+}
diff --git a/filters/libodfreader/OdfChartReader.h \
b/filters/libodfreader/OdfChartReader.h new file mode 100644
index 0000000..972ad9e
--- /dev/null
+++ b/filters/libodfreader/OdfChartReader.h
@@ -0,0 +1,108 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ODFCHARTREADER_H
+#define ODFCHARTREADER_H
+
+// Qt
+#include <QHash>
+#include <QString>
+
+// Calligra
+#include <KoXmlStreamReader.h>
+
+// this library
+#include "koodfreader_export.h"
+#include "OdfReaderInternals.h"
+
+
+class QSizeF;
+
+class OdfReader;
+class OdfChartReaderBackend;
+class OdfReaderContext;
+
+
+/** @brief Read the XML tree of the content of an ODT file.
+ *
+ * The OdfChartReader is used to traverse (read) the chart contents of
+ * an ODF file using an XML stream reader.  For every XML element that
+ * the reading process comes across it will call a specific function
+ * in a backend class: @see OdfChartReaderBackend.  The OdfChartReader
+ * is used as a common way to read chart content and is called from all
+ * readers for different ODF formats.  @see OdtReader, @see OdsReader,
+ * @see OdpReader.
+ */
+class KOODFREADER_EXPORT OdfChartReader
+{
+ public:
+    OdfChartReader();
+    ~OdfChartReader();
+
+    void setParent(OdfReader *parent);
+    void setBackend(OdfChartReaderBackend *backend);
+    void setContext(OdfReaderContext *context);
+
+    // ----------------------------------------------------------------
+    // element reader functions
+
+    DECLARE_READER_FUNCTION(OfficeChart);
+    DECLARE_READER_FUNCTION(ChartChart);           // ODF 1.2  11.1
+
+    DECLARE_READER_FUNCTION(ChartFooter);	   // ODF 1.2  11.2.3
+    DECLARE_READER_FUNCTION(ChartSubtitle);	   // ODF 1.2  11.2.2
+    DECLARE_READER_FUNCTION(ChartTitle);	   // ODF 1.2  11.2.1
+    DECLARE_READER_FUNCTION(ChartLegend);	   // ODF 1.2  11.3
+    DECLARE_READER_FUNCTION(ChartPlotArea);	   // ODF 1.2  11.4
+    DECLARE_READER_FUNCTION(ChartWall);		   // ODF 1.2  11.6
+    DECLARE_READER_FUNCTION(ChartFloor);	   // ODF 1.2  11.7
+    DECLARE_READER_FUNCTION(ChartAxis);            // ODF 1.2  11.8
+    DECLARE_READER_FUNCTION(ChartCategories);      // ODF 1.2  11.9
+    DECLARE_READER_FUNCTION(ChartGrid);		   // ODF 1.2  11.10
+    DECLARE_READER_FUNCTION(ChartSeries);	   // ODF 1.2  11.11
+    DECLARE_READER_FUNCTION(ChartDomain);	   // ODF 1.2  11.12
+    DECLARE_READER_FUNCTION(ChartDataPoint);	   // ODF 1.2  11.13
+    DECLARE_READER_FUNCTION(ChartDataLabel);	   // ODF 1.2  11.14
+    DECLARE_READER_FUNCTION(ChartMeanValue);	   // ODF 1.2  11.15
+    DECLARE_READER_FUNCTION(ChartErrorIndicator);  // ODF 1.2  11.16
+    DECLARE_READER_FUNCTION(ChartRegressionCurve); // ODF 1.2  11.17
+    DECLARE_READER_FUNCTION(ChartEquation);        // ODF 1.2  11.18
+    DECLARE_READER_FUNCTION(ChartStockGainMarker); // ODF 1.2  11.19
+    DECLARE_READER_FUNCTION(ChartStockLossMarker); // ODF 1.2  11.20
+    DECLARE_READER_FUNCTION(ChartStockRangeLine);  // ODF 1.2  11.21
+
+ protected:
+
+
+    // ----------------------------------------------------------------
+    // Other functions
+
+    // FIXME: Move this to a common file (OdfReaderUtils?)
+    void readUnknownElement(KoXmlStreamReader &reader);
+
+
+ private:
+    OdfReader             *m_parent;  // The OdfReader controlling this one.
+
+    OdfChartReaderBackend *m_backend;
+    OdfReaderContext      *m_context;
+};
+
+#endif // ODFCHARTREADER_H
diff --git a/filters/libodfreader/OdfChartReaderBackend.cpp \
b/filters/libodfreader/OdfChartReaderBackend.cpp new file mode 100644
index 0000000..7b33697
--- /dev/null
+++ b/filters/libodfreader/OdfChartReaderBackend.cpp
@@ -0,0 +1,97 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+
+// Own
+#include "OdfChartReaderBackend.h"
+
+// Calligra
+#include <KoXmlReader.h>
+
+// Odftraverse library
+#include "OdfParser.h"
+
+
+// ================================================================
+//             class OdfChartReaderBackend::Private
+
+
+class OdfChartReaderBackend::Private
+{
+ public:
+    Private();
+    ~Private();
+
+    bool dummy;                 // We don't have any actual content in
+                                // this class yet but it's still
+                                // needed for forward binary compatibility.
+};
+
+OdfChartReaderBackend::Private::Private()
+{
+}
+
+OdfChartReaderBackend::Private::~Private()
+{
+}
+
+
+// ================================================================
+//                 class OdfChartReaderBackend
+
+
+OdfChartReaderBackend::OdfChartReaderBackend()
+    : d(new OdfChartReaderBackend::Private)
+{
+}
+
+OdfChartReaderBackend::~OdfChartReaderBackend()
+{
+    delete d;
+}
+
+
+// ----------------------------------------------------------------
+
+
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, OfficeChart)
+
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartChart)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartFooter)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartSubtitle)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartTitle)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartLegend)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartPlotArea)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartWall)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartFloor)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartAxis)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartCategories)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartGrid)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartSeries)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartDomain)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartDataPoint)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartDataLabel)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartMeanValue)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartErrorIndicator)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartRegressionCurve)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartEquation)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartStockGainMarker)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartStockLossMarker)
+IMPLEMENT_BACKEND_FUNCTION(OdfChartReader, ChartStockRangeLine)
diff --git a/filters/libodfreader/OdfChartReaderBackend.h \
b/filters/libodfreader/OdfChartReaderBackend.h new file mode 100644
index 0000000..1fd614c
--- /dev/null
+++ b/filters/libodfreader/OdfChartReaderBackend.h
@@ -0,0 +1,95 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ODFCHARTREADERBACKEND_H
+#define ODFCHARTREADERBACKEND_H
+
+// Calligra
+#include <KoXmlStreamReader.h>
+#include <KoFilter.h>
+
+// this library
+#include "koodfreader_export.h"
+#include "OdfChartReader.h"
+#include "OdfReaderInternals.h"
+
+
+class QByteArray;
+class QSizeF;
+class QStringList;
+class KoStore;
+class OdfReaderContext;
+
+
+/** @brief A default backend for the OdfChartReader class.
+ *
+ * This class defines an interface and the default behaviour for the
+ * backend to the ODF chart reader (@see OdfChartReader). When the
+ * reader is called upon to traverse a certain XML tree, there will
+ * be two parameters to the root traverse function: a pointer to a
+ * backend object and a pointer to a context object.
+ *
+ * The reader will traverse (read) the XML tree and for every element
+ * it comes across it will call a specific function in the backend and
+ * every call will pass the pointer to the context object.
+ *
+ * Each supported XML tag has a corresponding callback function. This
+ * callback function will be called twice: once when the tag is first
+ * encountered anc once when the tag is closed.  This means that an
+ * element with no child elements will be called twice in succession.
+ */
+class KOODFREADER_EXPORT OdfChartReaderBackend
+{
+ public:
+    explicit OdfChartReaderBackend();
+    virtual ~OdfChartReaderBackend();
+
+    DECLARE_BACKEND_FUNCTION(OfficeChart);
+    DECLARE_BACKEND_FUNCTION(ChartChart);           // ODF 1.2  11.1
+
+    DECLARE_BACKEND_FUNCTION(ChartFooter);	    // ODF 1.2  11.2.3
+    DECLARE_BACKEND_FUNCTION(ChartSubtitle);	    // ODF 1.2  11.2.2
+    DECLARE_BACKEND_FUNCTION(ChartTitle); 	    // ODF 1.2  11.2.1
+    DECLARE_BACKEND_FUNCTION(ChartLegend);	    // ODF 1.2  11.3
+    DECLARE_BACKEND_FUNCTION(ChartPlotArea);	    // ODF 1.2  11.4
+    DECLARE_BACKEND_FUNCTION(ChartWall);	    // ODF 1.2  11.6
+    DECLARE_BACKEND_FUNCTION(ChartFloor);           // ODF 1.2  11.7
+    DECLARE_BACKEND_FUNCTION(ChartAxis);            // ODF 1.2  11.8
+    DECLARE_BACKEND_FUNCTION(ChartCategories);      // ODF 1.2  11.9
+    DECLARE_BACKEND_FUNCTION(ChartGrid);	    // ODF 1.2  11.10
+    DECLARE_BACKEND_FUNCTION(ChartSeries);	    // ODF 1.2  11.11
+    DECLARE_BACKEND_FUNCTION(ChartDomain);	    // ODF 1.2  11.12
+    DECLARE_BACKEND_FUNCTION(ChartDataPoint);	    // ODF 1.2  11.13
+    DECLARE_BACKEND_FUNCTION(ChartDataLabel);	    // ODF 1.2  11.14
+    DECLARE_BACKEND_FUNCTION(ChartMeanValue);	    // ODF 1.2  11.15
+    DECLARE_BACKEND_FUNCTION(ChartErrorIndicator);  // ODF 1.2  11.16
+    DECLARE_BACKEND_FUNCTION(ChartRegressionCurve); // ODF 1.2  11.17
+    DECLARE_BACKEND_FUNCTION(ChartEquation);        // ODF 1.2  11.18
+    DECLARE_BACKEND_FUNCTION(ChartStockGainMarker); // ODF 1.2  11.19
+    DECLARE_BACKEND_FUNCTION(ChartStockLossMarker); // ODF 1.2  11.20
+    DECLARE_BACKEND_FUNCTION(ChartStockRangeLine);  // ODF 1.2  11.21
+
+ private:
+    class Private;
+    Private * const d;
+};
+
+
+#endif // ODFCHARTREADERBACKEND_H
diff --git a/filters/libodfreader/OdfDrawReader.cpp \
b/filters/libodfreader/OdfDrawReader.cpp new file mode 100644
index 0000000..1b4bc82
--- /dev/null
+++ b/filters/libodfreader/OdfDrawReader.cpp
@@ -0,0 +1,518 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+
+// Own
+#include "OdfTextReader.h"
+
+// Qt
+#include <QStringList>
+#include <QBuffer>
+
+// KDE
+#include <kdebug.h>
+#include <klocalizedstring.h>
+
+// Calligra
+#include <KoStore.h>
+#include <KoXmlStreamReader.h>
+#include <KoXmlNS.h>
+#include <KoXmlWriter.h>  // For copyXmlElement
+#include <KoOdfReadStore.h>
+
+// Reader library
+#include "OdfReader.h"
+#include "OdfDrawReaderBackend.h"
+#include "OdfReaderContext.h"
+
+
+#if 1
+static int debugIndent = 0;
+#define DEBUGSTART() \
+    ++debugIndent; \
+    DEBUG_READING("entering")
+#define DEBUGEND() \
+    DEBUG_READING("exiting"); \
+    --debugIndent
+#define DEBUG_READING(param) \
+    kDebug(30503) << QString("%1").arg(" ", debugIndent * 2) << param << ": " \
+    << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : \
"other")) \ +    << reader.qualifiedName().toString()
+#else
+#define DEBUGSTART() \
+    // NOTHING
+#define DEBUGEND() \
+    // NOTHING
+#define DEBUG_READING(param) \
+    // NOTHING
+#endif
+
+
+OdfDrawReader::OdfDrawReader()
+    : m_parent(0)
+    , m_backend(0)
+    , m_context(0)
+{
+}
+
+OdfDrawReader::~OdfDrawReader()
+{
+}
+
+
+// ----------------------------------------------------------------
+//                             setters
+
+
+void OdfDrawReader::setParent(OdfReader *parent)
+{
+    m_parent = parent;
+}
+
+void OdfDrawReader::setBackend(OdfDrawReaderBackend *backend)
+{
+    m_backend = backend;
+}
+
+void OdfDrawReader::setContext(OdfReaderContext *context)
+{
+    m_context = context;
+}
+
+
+// ----------------------------------------------------------------
+//                         namespace dr3d
+
+
+void OdfDrawReader::readElementDr3dScene(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementDr3dScene(reader, m_context);
+
+    // <dr3d:scene> has the following children in ODF 1.2:
+    //   [done] <dr3d:cube> 10.5.4
+    //   [done] <dr3d:extrude> 10.5.6
+    //   [done] <dr3d:light> 10.5.3
+    //   [done] <dr3d:rotate> 10.5.7
+    //   [done] <dr3d:scene> 10.5.2
+    //   [done] <dr3d:sphere> 10.5.5
+
+    //          <draw:glue-point> 10.3.16
+    //          <svg:desc> 10.3.18
+    //          <svg:title> 10.3.17.
+    //
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "dr3d:cube") {
+	    readElementDr3dCube(reader);
+        }
+        else if (tagName == "dr3d:extrude") {
+	    readElementDr3dExtrude(reader);
+        }
+        else if (tagName == "dr3d:light") {
+	    readElementDr3dLight(reader);
+        }
+        else if (tagName == "dr3d:rotate") {
+	    readElementDr3dRotate(reader);
+        }
+        else if (tagName == "dr3d:scene") {
+	    readElementDr3dScene(reader);
+        }
+        else if (tagName == "dr3d:sphere") {
+	    readElementDr3dSphere(reader);
+        }
+        //...  MORE else if () HERE
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementDr3dScene(reader, m_context);
+    DEBUGEND();
+}
+
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfDrawReader, Dr3dLight)   // ODF 1.2  10.5.3
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfDrawReader, Dr3dCube)    // ODF 1.2  10.5.4
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfDrawReader, Dr3dSphere)  // ODF 1.2  10.5.5
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfDrawReader, Dr3dExtrude) // ODF 1.2  10.5.6
+IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfDrawReader, Dr3dRotate)  // ODF 1.2  10.5.7
+
+
+// ================================================================
+//                         namespace draw
+
+
+// ----------------------------------------------------------------
+
+
+#if 0
+// This is a template function for the reader library.
+// Copy this one and change the name and fill in the code.
+void OdfDrawReader::readElementNamespaceTagname(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementNamespaceTagname(reader, m_context);
+
+    // <namespace:tagname> has the following children in ODF 1.2:
+    //   FILL IN THE CHILDREN LIKE THIS EXAMPLE (taken from \
office:document-content): +    //          <office:automatic-styles> 3.15.3
+    //          <office:body> 3.3
+    //          <office:font-face-decls> 3.14
+    //          <office:scripts> 3.12.
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "office:automatic-styles") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "office:body") {
+            readElementOfficeBody(reader);
+        }
+        ...  MORE else if () HERE
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementNamespaceTagname(reader, m_context);
+    DEBUGEND();
+}
+#endif
+
+
+void OdfDrawReader::readCommonGraphicsElements(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+
+    // This is a function common to all draw elements so no backend function
+    // should be called here.
+
+    // The common graphics elements are:
+    //   [done] <dr3d:scene> 10.5.2
+    //   [done] <draw:a> 10.4.12
+    //   [done] <draw:caption> 10.3.11
+    //   [done] <draw:circle> 10.3.8
+    //   [done] <draw:connector> 10.3.10
+    //          <draw:control> 10.3.13
+    //          <draw:custom-shape> 10.6.1
+    //   [done] <draw:ellipse> 10.3.9
+    //   [done] <draw:frame> 10.4.2
+    //          <draw:g> 10.3.15
+    //   [done] <draw:line> 10.3.3
+    //   [done] <draw:measure> 10.3.12
+    //          <draw:page-thumbnail> 10.3.14
+    //   [path] <draw:path> 10.3.7
+    //   [done] <draw:polygon> 10.3.5
+    //   [done] <draw:polyline> 10.3.4
+    //   [done] <draw:rect> 10.3.2
+    //   [done] <draw:regular-polygon> 10.3.6
+
+    QString tagName = reader.qualifiedName().toString();
+    //kDebug() << "list child:" << tagName;
+    if (tagName == "dr3d:scene") {
+	readElementDr3dScene(reader);
+    }
+    else if (tagName == "draw:a") {
+	readElementDrawA(reader);
+    }
+    else if (tagName == "draw:caption") {
+	readElementDrawCaption(reader);
+    }
+    else if (tagName == "draw:circle") {
+	readElementDrawCircle(reader);
+    }
+    else if (tagName == "draw:connector") {
+	readElementDrawConnector(reader);
+    }
+    else if (tagName == "draw:ellipse") {
+	readElementDrawEllipse(reader);
+    }
+    else if (tagName == "draw:frame") {
+	readElementDrawFrame(reader);
+    }
+    else if (tagName == "draw:line") {
+	readElementDrawLine(reader);
+    }
+    else if (tagName == "draw:measure") {
+	readElementDrawMeasure(reader);
+    }
+    else if (tagName == "draw:path") {
+	readElementDrawPath(reader);
+    }
+    else if (tagName == "draw:polygon") {
+	readElementDrawPolygon(reader);
+    }
+    else if (tagName == "draw:polyline") {
+	readElementDrawPolyline(reader);
+    }
+    else if (tagName == "draw:rect") {
+	readElementDrawRect(reader);
+    }
+    else if (tagName == "draw:regular-polygon") {
+	readElementDrawRegularPolygon(reader);
+    }
+    else {
+	// FIXME: Should this perhaps be skipCurrentElement()?
+	readUnknownElement(reader);
+    }
+
+    DEBUGEND();
+}
+
+void OdfDrawReader::readElementDrawA(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementDrawA(reader, m_context);
+
+    // <draw:a> has all the normal drawing children.
+    readCommonGraphicsElements(reader);
+
+    m_backend->elementDrawA(reader, m_context);
+    DEBUGEND();
+}
+
+
+#define IMPLEMENT_GRAPHIC_OBJECT(object)                                \
+void OdfDrawReader::readElementDraw##object(KoXmlStreamReader &reader)  \
+{                                                                       \
+    DEBUGSTART();                                                       \
+    m_backend->elementDraw##object(reader, m_context);                  \
+                                                                        \
+    readGraphicsObjectChildren(reader);                                 \
+                                                                        \
+    m_backend->elementDraw##object(reader, m_context);                  \
+    DEBUGEND();                                                         \
+}
+
+IMPLEMENT_GRAPHIC_OBJECT(Rect)            // ODF 1.2  10.3.2
+IMPLEMENT_GRAPHIC_OBJECT(Line)		  // ODF 1.2  10.3.3
+IMPLEMENT_GRAPHIC_OBJECT(Polyline)	  // ODF 1.2  10.3.4
+IMPLEMENT_GRAPHIC_OBJECT(Polygon)	  // ODF 1.2  10.3.5
+IMPLEMENT_GRAPHIC_OBJECT(RegularPolygon)  // ODF 1.2  10.3.6
+IMPLEMENT_GRAPHIC_OBJECT(Path)		  // ODF 1.2  10.3.7
+IMPLEMENT_GRAPHIC_OBJECT(Circle)	  // ODF 1.2  10.3.8
+IMPLEMENT_GRAPHIC_OBJECT(Ellipse)	  // ODF 1.2  10.3.9
+IMPLEMENT_GRAPHIC_OBJECT(Connector)	  // ODF 1.2  10.3.10
+IMPLEMENT_GRAPHIC_OBJECT(Caption)	  // ODF 1.2  10.3.11
+IMPLEMENT_GRAPHIC_OBJECT(Measure)	  // ODF 1.2  10.3.12
+
+
+void OdfDrawReader::readGraphicsObjectChildren(KoXmlStreamReader &reader)
+{
+    // No backend calls in this function
+
+    // <draw:circle>, <draw:rect>, etc have the following children in ODF 1.2:
+    //          <draw:glue-point> 10.3.16
+    //          <office:event-listeners> 10.3.19
+    //          <svg:desc> 10.3.18
+    //          <svg:title> 10.3.17
+    //   [done] <text:list> 5.3.1
+    //   [done] <text:p> 5.1.3.
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "draw:glue-point") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+            //readElementOfficeDrawGluePoint(reader);
+        }
+        else if (tagName == "office:event-listeners") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+            //readElementOfficeEventListeners(reader);
+        }
+        else if (reader.prefix() == "svg") {
+	    if (tagName == "svg:desc") {
+		// FIXME: NYI
+		reader.skipCurrentElement();
+		//readElementSvgDesc(reader);
+	    }
+	    else if (tagName == "svg:title") {
+		// FIXME: NYI
+		reader.skipCurrentElement();
+		//readElementSvgTitle(reader);
+	    }
+	    else {
+		reader.skipCurrentElement();
+	    }
+        } // namespace svg
+        else if (reader.prefix() == "text") {
+	    OdfTextReader *textReader = m_parent->textReader();
+	    if (!textReader) {
+		reader.skipCurrentElement();
+	    }
+	    else if (tagName == "text:list") {
+		textReader->readElementTextList(reader);
+	    }
+	    else if (tagName == "text:p") {
+		textReader->readElementTextP(reader);
+	    }
+	    else {
+		reader.skipCurrentElement();
+	    }
+        } // namespace text
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+}
+
+
+// ----------------------------------------------------------------
+//                                 Frames
+
+
+void OdfDrawReader::readElementDrawFrame(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementDrawFrame(reader, m_context);
+
+    // <draw:frame> has the following children in ODF 1.2:
+    //          <draw:applet> 10.4.7
+    //          <draw:contour-path> 10.4.11.3
+    //          <draw:contour-polygon> 10.4.11.2
+    //          <draw:floating-frame> 10.4.10
+    //          <draw:glue-point> 10.3.16
+    //          <draw:image> 10.4.4
+    //          <draw:image-map> 10.4.13.2
+    //   [done] <draw:object> 10.4.6.2
+    //   [done] <draw:object-ole> 10.4.6.3
+    //          <draw:plugin> 10.4.8
+    //          <draw:text-box> 10.4.3
+    //          <office:event-listeners> 10.3.19
+    //          <svg:desc> 10.3.18
+    //          <svg:title> 10.3.17
+    //   [done] <table:table> 9.1.2
+    //
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "draw:image") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "draw:object") {
+	    readElementDrawObject(reader);
+        }
+        else if (tagName == "draw:object-ole") {
+	    readElementDrawObjectOle(reader);
+        }
+        //...  MORE else if () HERE
+        else if (tagName == "table:table") {
+	    OdfTextReader *textReader = m_parent->textReader();
+	    if (textReader) {
+		textReader->readElementTableTable(reader);
+	    }
+	    else {
+		reader.skipCurrentElement();
+	    }
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementDrawFrame(reader, m_context);
+    DEBUGEND();
+}
+
+void OdfDrawReader::readElementDrawObject(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementDrawObject(reader, m_context);
+
+    // <draw:object> has the following children in ODF 1.2:
+    //          <math:math> 14.5
+    //          <office:document> 3.1.2
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "math:math") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "office:document") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else {
+	    // Shouldn't happen.
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementDrawObject(reader, m_context);
+    DEBUGEND();
+}
+
+void OdfDrawReader::readElementDrawObjectOle(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementDrawObjectOle(reader, m_context);
+
+    // <draw:object-ole> has the following children in ODF 1.2:
+    //          <office:binary-data> 10.4.5
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+	if (tagName == "office:binary-data") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else {
+	    // Shouldn't happen.
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementDrawObjectOle(reader, m_context);
+    DEBUGEND();
+}
+
+
+// ----------------------------------------------------------------
+//                             Other functions
+
+
+void OdfDrawReader::readUnknownElement(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+
+#if 0  // FIXME: Fix this
+    if (m_context->isInsideParagraph()) {
+        // readParagraphContents expect to have the reader point to the
+        // contents of the paragraph so we have to read past the draw:p
+        // start tag here.
+        reader.readNext();
+        readParagraphContents(reader);
+    }
+    else {
+        while (reader.readNextStartElement()) {
+            readTextLevelElement(reader);
+        }
+    }
+#else
+    reader.skipCurrentElement();
+#endif
+
+    DEBUGEND();
+}
diff --git a/filters/libodfreader/OdfDrawReader.h \
b/filters/libodfreader/OdfDrawReader.h new file mode 100644
index 0000000..2ef4916
--- /dev/null
+++ b/filters/libodfreader/OdfDrawReader.h
@@ -0,0 +1,125 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ODFDRAWREADER_H
+#define ODFDRAWREADER_H
+
+// Qt
+#include <QHash>
+#include <QString>
+
+// Calligra
+#include <KoXmlStreamReader.h>
+
+// this library
+#include "koodfreader_export.h"
+#include "OdfReaderInternals.h"
+
+
+class QSizeF;
+
+class OdfReader;
+class OdfDrawReaderBackend;
+class OdfReaderContext;
+
+
+/** @brief Read the XML tree of the content of an ODT file.
+ *
+ * The OdfDrawReader is used to traverse (read) the draw contents of
+ * an ODF file using an XML stream reader.  For every XML element that
+ * the reading process comes across it will call a specific function
+ * in a backend class: @see OdfDrawReaderBackend.  The OdfDrawReader
+ * is used as a common way to read draw content and is called from all
+ * readers for different ODF formats.  @see OdtReader, @see OdsReader,
+ * @see OdpReader.
+ */
+class KOODFREADER_EXPORT OdfDrawReader
+{
+ public:
+    OdfDrawReader();
+    ~OdfDrawReader();
+
+    void setParent(OdfReader *parent);
+    void setBackend(OdfDrawReaderBackend *backend);
+    void setContext(OdfReaderContext *context);
+
+    // ----------------------------------------------------------------
+    // Dr3d elements
+
+    DECLARE_READER_FUNCTION(Dr3dScene);   // ODF 1.2  10.5.2
+    DECLARE_READER_FUNCTION(Dr3dLight);   // ODF 1.2  10.5.3
+    DECLARE_READER_FUNCTION(Dr3dCube);    // ODF 1.2  10.5.4
+    DECLARE_READER_FUNCTION(Dr3dSphere);  // ODF 1.2  10.5.5
+    DECLARE_READER_FUNCTION(Dr3dExtrude); // ODF 1.2  10.5.6
+    DECLARE_READER_FUNCTION(Dr3dRotate);  // ODF 1.2  10.5.7
+
+    // ----------------------------------------------------------------
+    // Draw elements
+
+    // Read all common draw level elements like draw:p, draw:h, draw:frame, etc.
+    // This is the main entry point for draw reading.
+    void readCommonGraphicsElements(KoXmlStreamReader &reader);
+
+ protected:
+    // ----------------------------------------------------------------
+    // Dr3d elements
+
+
+    // ----------------------------------------------------------------
+    // Draw functions: circle, rectangle, etc
+
+    DECLARE_READER_FUNCTION(DrawA);
+
+    DECLARE_READER_FUNCTION(DrawRect);            // ODF 1.2  10.3.2
+    DECLARE_READER_FUNCTION(DrawLine);            // ODF 1.2  10.3.3
+    DECLARE_READER_FUNCTION(DrawPolyline);        // ODF 1.2  10.3.4
+    DECLARE_READER_FUNCTION(DrawPolygon);         // ODF 1.2  10.3.5
+    DECLARE_READER_FUNCTION(DrawRegularPolygon);  // ODF 1.2  10.3.6
+    DECLARE_READER_FUNCTION(DrawPath);            // ODF 1.2  10.3.7
+    DECLARE_READER_FUNCTION(DrawCircle);          // ODF 1.2  10.3.8
+    DECLARE_READER_FUNCTION(DrawEllipse);         // ODF 1.2  10.3.9
+    DECLARE_READER_FUNCTION(DrawConnector);       // ODF 1.2  10.3.10
+    DECLARE_READER_FUNCTION(DrawCaption);         // ODF 1.2  10.3.11
+    DECLARE_READER_FUNCTION(DrawMeasure);         // ODF 1.2  10.3.12
+
+    void readGraphicsObjectChildren(KoXmlStreamReader &reader);
+
+    // ----------------------------------------------------------------
+    // Frames
+
+    DECLARE_READER_FUNCTION(DrawFrame);
+    DECLARE_READER_FUNCTION(DrawObject);
+    DECLARE_READER_FUNCTION(DrawObjectOle);
+
+    // ----------------------------------------------------------------
+    // Other functions
+
+    // FIXME: Move this to a common file (OdfReaderUtils?)
+    void readUnknownElement(KoXmlStreamReader &reader);
+
+
+ private:
+    OdfReader             *m_parent;  // The OdfReader controlling this one.
+
+    OdfDrawReaderBackend  *m_backend;
+    OdfReaderContext      *m_context;
+};
+
+#endif // ODFDRAWREADER_H
diff --git a/filters/libodfreader/OdfDrawReaderBackend.cpp \
b/filters/libodfreader/OdfDrawReaderBackend.cpp new file mode 100644
index 0000000..ba3300c
--- /dev/null
+++ b/filters/libodfreader/OdfDrawReaderBackend.cpp
@@ -0,0 +1,108 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+
+// Own
+#include "OdfDrawReaderBackend.h"
+
+// Calligra
+#include <KoXmlReader.h>
+
+// Odftraverse library
+#include "OdfParser.h"
+
+
+// ================================================================
+//             class OdfDrawReaderBackend::Private
+
+
+class OdfDrawReaderBackend::Private
+{
+ public:
+    Private();
+    ~Private();
+
+    bool dummy;                 // We don't have any actual content in
+                                // this class yet but it's still
+                                // needed for forward binary compatibility.
+};
+
+OdfDrawReaderBackend::Private::Private()
+{
+}
+
+OdfDrawReaderBackend::Private::~Private()
+{
+}
+
+
+// ================================================================
+//                 class OdfDrawReaderBackend
+
+
+OdfDrawReaderBackend::OdfDrawReaderBackend()
+    : d(new OdfDrawReaderBackend::Private)
+{
+}
+
+OdfDrawReaderBackend::~OdfDrawReaderBackend()
+{
+    delete d;
+}
+
+
+// ----------------------------------------------------------------
+//                         Dr3d functions
+
+
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dScene)    // ODF 1.2  10.5.2
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dLight);   // ODF 1.2  10.5.3
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dCube);    // ODF 1.2  10.5.4
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dSphere);  // ODF 1.2  10.5.5
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dExtrude); // ODF 1.2  10.5.6
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, Dr3dRotate);  // ODF 1.2  10.5.7
+
+
+// ----------------------------------------------------------------
+//                         Draw functions
+
+
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawA)
+
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawRect);            // ODF 1.2  10.3.2
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawLine);            // ODF 1.2  10.3.3
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawPolyline);        // ODF 1.2  10.3.4
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawPolygon);         // ODF 1.2  10.3.5
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawRegularPolygon);  // ODF 1.2  10.3.6
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawPath);            // ODF 1.2  10.3.7
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawCircle);          // ODF 1.2  10.3.8
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawEllipse);         // ODF 1.2  10.3.9
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawConnector);       // ODF 1.2  10.3.10
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawCaption);         // ODF 1.2  10.3.11
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawMeasure);         // ODF 1.2  10.3.12
+
+
+// ----------------------------------------------------------------
+//                             Frames
+
+
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawFrame)
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawObject)
+IMPLEMENT_BACKEND_FUNCTION(OdfDrawReader, DrawObjectOle)
diff --git a/filters/libodfreader/OdfDrawReaderBackend.h \
b/filters/libodfreader/OdfDrawReaderBackend.h new file mode 100644
index 0000000..627a9ea
--- /dev/null
+++ b/filters/libodfreader/OdfDrawReaderBackend.h
@@ -0,0 +1,103 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ODFDRAWREADERBACKEND_H
+#define ODFDRAWREADERBACKEND_H
+
+// Calligra
+#include <KoXmlStreamReader.h>
+#include <KoFilter.h>
+
+// this library
+#include "koodfreader_export.h"
+#include "OdfDrawReader.h"
+
+
+class QByteArray;
+class QSizeF;
+class QStringList;
+class KoStore;
+class OdfReaderContext;
+
+
+/** @brief A default backend for the OdfDrawReader class.
+ *
+ * This class defines an interface and the default behaviour for the
+ * backend to the ODF draw reader (@see OdfDrawReader). When the
+ * reader is called upon to traverse a certain XML tree, there will
+ * be two parameters to the root traverse function: a pointer to a
+ * backend object and a pointer to a context object.
+ *
+ * The reader will traverse (read) the XML tree and for every element
+ * it comes across it will call a specific function in the backend and
+ * every call will pass the pointer to the context object.
+ *
+ * Each supported XML tag has a corresponding callback function. This
+ * callback function will be called twice: once when the tag is first
+ * encountered anc once when the tag is closed.  This means that an
+ * element with no child elements will be called twice in succession.
+ */
+class KOODFREADER_EXPORT OdfDrawReaderBackend
+{
+ public:
+    explicit OdfDrawReaderBackend();
+    virtual ~OdfDrawReaderBackend();
+
+    // ----------------------------------------------------------------
+    // Dr3d functions
+
+    DECLARE_BACKEND_FUNCTION(Dr3dScene);   // ODF 1.2  10.5.2
+    DECLARE_BACKEND_FUNCTION(Dr3dLight);   // ODF 1.2  10.5.3
+    DECLARE_BACKEND_FUNCTION(Dr3dCube);    // ODF 1.2  10.5.4
+    DECLARE_BACKEND_FUNCTION(Dr3dSphere);  // ODF 1.2  10.5.5
+    DECLARE_BACKEND_FUNCTION(Dr3dExtrude); // ODF 1.2  10.5.6
+    DECLARE_BACKEND_FUNCTION(Dr3dRotate);  // ODF 1.2  10.5.7
+
+    // ----------------------------------------------------------------
+    // Draw functions
+
+    DECLARE_BACKEND_FUNCTION(DrawA);
+
+    DECLARE_BACKEND_FUNCTION(DrawRect);            // ODF 1.2  10.3.2
+    DECLARE_BACKEND_FUNCTION(DrawLine);            // ODF 1.2  10.3.3
+    DECLARE_BACKEND_FUNCTION(DrawPolyline);        // ODF 1.2  10.3.4
+    DECLARE_BACKEND_FUNCTION(DrawPolygon);         // ODF 1.2  10.3.5
+    DECLARE_BACKEND_FUNCTION(DrawRegularPolygon);  // ODF 1.2  10.3.6
+    DECLARE_BACKEND_FUNCTION(DrawPath);            // ODF 1.2  10.3.7
+    DECLARE_BACKEND_FUNCTION(DrawCircle);          // ODF 1.2  10.3.8
+    DECLARE_BACKEND_FUNCTION(DrawEllipse);         // ODF 1.2  10.3.9
+    DECLARE_BACKEND_FUNCTION(DrawConnector);       // ODF 1.2  10.3.10
+    DECLARE_BACKEND_FUNCTION(DrawCaption);         // ODF 1.2  10.3.11
+    DECLARE_BACKEND_FUNCTION(DrawMeasure);         // ODF 1.2  10.3.12
+
+    // ----------------------------------------------------------------
+    // Frames
+
+    DECLARE_BACKEND_FUNCTION(DrawFrame);
+    DECLARE_BACKEND_FUNCTION(DrawObject);
+    DECLARE_BACKEND_FUNCTION(DrawObjectOle);
+
+ private:
+    class Private;
+    Private * const d;
+};
+
+
+#endif // ODFDRAWREADERBACKEND_H
diff --git a/filters/libodfreader/OdtReader.cpp b/filters/libodfreader/OdfReader.cpp
similarity index 74%
copy from filters/libodfreader/OdtReader.cpp
copy to filters/libodfreader/OdfReader.cpp
index 48e1037..d234142 100644
--- a/filters/libodfreader/OdtReader.cpp
+++ b/filters/libodfreader/OdfReader.cpp
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -20,7 +20,7 @@
 
 
 // Own
-#include "OdtReader.h"
+#include "OdfReader.h"
 
 // Qt
 #include <QStringList>
@@ -34,11 +34,14 @@
 #include <KoStore.h>
 #include <KoXmlStreamReader.h>
 #include <KoXmlNS.h>
+#include <KoXmlWriter.h>  // For copyXmlElement
+#include <KoOdfReadStore.h>
 
 // Reader library
-#include "OdtReaderBackend.h"
+#include "OdfReaderBackend.h"
 #include "OdfReaderContext.h"
 #include "OdfTextReader.h"
+#include "OdfDrawReader.h"
 
 
 static void prepareForOdfInternal(KoXmlStreamReader &reader);
@@ -66,24 +69,46 @@ static int debugIndent = 0;
 #endif
 
 
-OdtReader::OdtReader()
+OdfReader::OdfReader()
     : m_backend(0)
     , m_context(0)
     , m_textReader(0)
+    , m_drawReader(0)
 {
 }
 
-OdtReader::~OdtReader()
+OdfReader::~OdfReader()
 {
 }
 
 
-void OdtReader::setTextReader(OdfTextReader *textReader)
+OdfTextReader *OdfReader::textReader() const
+{
+    return m_textReader;
+}
+
+void OdfReader::setTextReader(OdfTextReader *textReader)
 {
     m_textReader = textReader;
+    if (textReader) {
+        textReader->setParent(this);
+    }
+}
+
+OdfDrawReader *OdfReader::drawReader() const
+{
+    return m_drawReader;
 }
 
-bool OdtReader::analyzeContent(OdfReaderContext *context)
+void OdfReader::setDrawReader(OdfDrawReader *drawReader)
+{
+    m_drawReader = drawReader;
+    if (drawReader) {
+        drawReader->setParent(this);
+    }
+}
+
+bool OdfReader::analyzeContent(OdfReaderContext *context)
 {
     // Extract styles, manifest, settings, etc
     if (context->analyzeOdfFile() != KoFilter::OK) {
@@ -93,7 +118,7 @@ bool OdtReader::analyzeContent(OdfReaderContext *context)
     return true;
 }
 
-bool OdtReader::readContent(OdtReaderBackend *backend, OdfReaderContext *context)
+bool OdfReader::readContent(OdfReaderBackend *backend, OdfReaderContext *context)
 {
     kDebug(30503) << "entering";
 
@@ -173,7 +198,7 @@ bool OdtReader::readContent(OdtReaderBackend *backend, \
OdfReaderContext *context  #if 0
 // This is a template function for the reader library.
 // Copy this one and change the name and fill in the code.
-void OdtReader::readElementNamespaceTagname(KoXmlStreamReader &reader)
+void OdfReader::readElementNamespaceTagname(KoXmlStreamReader &reader)
 { 
    DEBUGSTART();
 
@@ -188,6 +213,7 @@ void OdtReader::readElementNamespaceTagname(KoXmlStreamReader \
&reader)  
         if (tagName == "office:automatic-styles") {
             // FIXME: NYI
+            reader.skipCurrentElement();
         }
         else if (tagName == "office:body") {
             readElementOfficeBody(reader);
@@ -204,7 +230,7 @@ void OdtReader::readElementNamespaceTagname(KoXmlStreamReader \
&reader)  #endif
 
 
-void OdtReader::readElementOfficeBody(KoXmlStreamReader &reader)
+void OdfReader::readElementOfficeBody(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
     m_backend->elementOfficeBody(reader, m_context);
@@ -214,17 +240,23 @@ void OdtReader::readElementOfficeBody(KoXmlStreamReader \
&reader)  //          <office:database> 12.1
     //          <office:drawing> 3.5
     //          <office:image> 3.9
-    //          <office:presentation> 3.6
-    //          <office:spreadsheet> 3.7
+    //   [done] <office:presentation> 3.6
+    //   [done] <office:spreadsheet> 3.7
     //   [done] <office:text> 3.4
     //
-    // Of those only <office:text> is present in a text document (odt).
+    // Of those only <office:text> is present in a text document (odf).
     while (reader.readNextStartElement()) {
         QString tagName = reader.qualifiedName().toString();
         
         if (tagName == "office:text") {
             readElementOfficeText(reader);
         }
+        else if (tagName == "office:spreadsheet") {
+            readElementOfficeSpreadsheet(reader);
+        }
+        else if (tagName == "office:presentation") {
+            readElementOfficePresentation(reader);
+        }
         else {
             reader.skipCurrentElement();
         }
@@ -234,100 +266,41 @@ void OdtReader::readElementOfficeBody(KoXmlStreamReader \
&reader)  DEBUGEND();
 }
 
-void OdtReader::readElementOfficeText(KoXmlStreamReader &reader)
+
+// ----------------------------------------------------------------
+//
+// The following functions are just NULL versions of the actual functions. All
+// of these are virtual and the real functionality should be implemented in a
+// subclass.
+//
+
+void OdfReader::readElementOfficeText(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
-    m_backend->elementOfficeText(reader, m_context);
 
-    // <office:text> has the following children in ODF 1.2:
-    //
-    // In addition to the text level tags like <text:p> etc that can
-    // be found in any textbox, table cell or similar, it has the
-    // following text document children:
-    //
-    //          <office:forms> 13.2
-    //          <table:calculation-settings> 9.4.1
-    //          <table:consolidation> 9.7
-    //          <table:content-validations> 9.4.4
-    //          <table:database-ranges> 9.4.14
-    //          <table:data-pilot-tables> 9.6.2
-    //          <table:dde-links> 9.8
-    //          <table:label-ranges> 9.4.10
-    //          <table:named-expressions> 9.4.11
-    //          <text:alphabetical-index-auto-mark-file> 8.8.3
-    //          <text:dde-connection-decls> 14.6.2
-    //          <text:page-sequence> 5.2
-    //          <text:sequence-decls> 7.4.11
-    //          <text:tracked-changes> 5.5.1
-    //          <text:user-field-decls> 7.4.7
-    //          <text:variable-decls> 7.4.2
-    //
-    // FIXME: For now, none of these are handled
-    while (reader.readNextStartElement()) {
-        DEBUG_READING("loop-start");
-        
-        QString tagName = reader.qualifiedName().toString();
-        if (tagName == "office:forms") {
-            // FIXME: NYI
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:calculation-settings") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:consolidation") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:content-validation") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:database-ranges") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:data-pilot-tables") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:dde-links") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:label-ranges") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "table:named-expressions") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:alphabetical-index-auto-mark-file") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:dde-connection-decls") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:page-sequence") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:sequence-decls") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:tracked-changes") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:user-field-decls") {
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "text:variable-decls") {
-            reader.skipCurrentElement();
-        }
-        else {
-            if (m_textReader) {
-                m_textReader->readTextLevelElement(reader);
-            }
-            else {
-                reader.skipCurrentElement();
-            }
-        }
-        DEBUG_READING("loop-end");
-    }
+    kError() << "Unimplemented function";
+    reader.skipCurrentElement();  
+
+    DEBUGEND();
+}
+
+void OdfReader::readElementOfficeSpreadsheet(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+
+    kError() << "Unimplemented function";
+    reader.skipCurrentElement();  
+
+    DEBUGEND();
+}
+
+void OdfReader::readElementOfficePresentation(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+
+    kError() << "Unimplemented function";
+    reader.skipCurrentElement();  
 
-    m_backend->elementOfficeText(reader, m_context);
     DEBUGEND();
 }
 
@@ -336,7 +309,7 @@ void OdtReader::readElementOfficeText(KoXmlStreamReader &reader)
 //                             Other functions
 
 
-void OdtReader::readUnknownElement(KoXmlStreamReader &reader)
+void OdfReader::readUnknownElement(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
 
diff --git a/filters/libodfreader/OdtReader.h b/filters/libodfreader/OdfReader.h
similarity index 58%
copy from filters/libodfreader/OdtReader.h
copy to filters/libodfreader/OdfReader.h
index 22ae935..f397436 100644
--- a/filters/libodfreader/OdtReader.h
+++ b/filters/libodfreader/OdfReader.h
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -18,8 +18,8 @@
    Boston, MA 02110-1301, USA.
 */
 
-#ifndef ODTREADER_H
-#define ODTREADER_H
+#ifndef ODFREADER_H
+#define ODFREADER_H
 
 // Qt
 #include <QHash>
@@ -30,24 +30,32 @@
 
 // this library
 #include "koodfreader_export.h"
+#include "OdfReaderInternals.h"
 
 
 class QSizeF;
 
-class OdtReaderBackend;
+class KoXmlWriter;
+class KoStore;
+
+class OdfReaderBackend;
 class OdfReaderContext;
 
 class OdfTextReader;
+class OdfDrawReader;
 
 
-/** @brief Read the XML tree of the content of an ODT file.
+/** @brief Read the XML tree of the content of an ODF file.
+ *
+ * The OdfReader is used to traverse (read) the contents of an ODF file using
+ * an XML stream reader.  For reading a specific type of ODF, e.g. a text
+ * document, you should create a new class, OdtReader that inherits this
+ * class.
  *
- * The OdtReader is used to traverse (read) the contents of an ODT
- * file using an XML stream reader.  For every XML element that the
- * reading process comes across it will call a specific function in a
- * backend class: @see OdtReaderBackend.
+ * For every XML element that the reading process comes across it will call a
+ * specific function in a backend class: @see OdfReaderBackend.
  *
- * Before the reading process is started the ODT file will be
+ * Before the reading process is started the ODF file will be
  * analyzed to collect some data that may be needed during the
  * read: metadata, manifest and styles are examples of this. This
  * data is stored in the so called reading context, which is kept in
@@ -56,30 +64,38 @@ class OdfTextReader;
  * The context will be passed around to the backend in every call to a
  * backend callback function.
  *
- * In addition to the pre-analyzed data from the ODT file, the context
+ * In addition to the pre-analyzed data from the ODF file, the context
  * can be used to keep track of data that is used in the backend
  * processing such as internal links, lists of embedded data such as
  * pictures.
  */
-class KOODFREADER_EXPORT OdtReader
+class KOODFREADER_EXPORT OdfReader
 {
  public:
-    OdtReader();
-    ~OdtReader();
+    OdfReader();
+    virtual ~OdfReader();
 
+    OdfTextReader *textReader() const;
     void setTextReader(OdfTextReader *textReader);
 
+    OdfDrawReader *drawReader() const;
+    void setDrawReader(OdfDrawReader *drawReader);
+
     bool analyzeContent(OdfReaderContext *context);
 
-    bool readContent(OdtReaderBackend *backend, OdfReaderContext *context);
+    bool readContent(OdfReaderBackend *backend, OdfReaderContext *context);
 
  protected:
     // All readElement*() are named after the full qualifiedName of
     // the element in ODF that they handle.
 
-    // ODT document level functions
-    void readElementOfficeBody(KoXmlStreamReader &reader);
-    void readElementOfficeText(KoXmlStreamReader &reader);
+    // ODF document level functions
+    DECLARE_READER_FUNCTION(OfficeBody);
+
+    // ONE of these should be reimplemented by each subclass, respectively.
+    DECLARE_READER_FUNCTION(OfficeText);
+    DECLARE_READER_FUNCTION(OfficeSpreadsheet);
+    DECLARE_READER_FUNCTION(OfficePresentation);
 
     // ----------------------------------------------------------------
     // Other functions
@@ -87,12 +103,13 @@ class KOODFREADER_EXPORT OdtReader
     void readUnknownElement(KoXmlStreamReader &reader);
 
 
- private:
-    OdtReaderBackend  *m_backend;
+ protected:
+    OdfReaderBackend  *m_backend;
     OdfReaderContext  *m_context;
 
     // Helper readers
     OdfTextReader     *m_textReader;
+    OdfDrawReader     *m_drawReader;
 };
 
-#endif // ODTREADER_H
+#endif // ODFREADER_H
diff --git a/filters/libodfreader/OdtReaderBackend.cpp \
b/filters/libodfreader/OdfReaderBackend.cpp similarity index 59%
copy from filters/libodfreader/OdtReaderBackend.cpp
copy to filters/libodfreader/OdfReaderBackend.cpp
index cdc59f1..701cc2d 100644
--- a/filters/libodfreader/OdtReaderBackend.cpp
+++ b/filters/libodfreader/OdfReaderBackend.cpp
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -20,7 +20,7 @@
 
 
 // Own
-#include "OdtReaderBackend.h"
+#include "OdfReaderBackend.h"
 
 // Calligra
 #include <KoXmlReader.h>
@@ -30,10 +30,10 @@
 
 
 // ================================================================
-//             class OdtReaderBackend::Private
+//             class OdfReaderBackend::Private
 
 
-class OdtReaderBackend::Private
+class OdfReaderBackend::Private
 {
  public:
     Private();
@@ -44,49 +44,33 @@ class OdtReaderBackend::Private
                                 // needed for forward binary compatibility.
 };
 
-OdtReaderBackend::Private::Private()
+OdfReaderBackend::Private::Private()
 {
 }
 
-OdtReaderBackend::Private::~Private()
+OdfReaderBackend::Private::~Private()
 {
 }
 
 
 // ================================================================
-//                 class OdtReaderBackend
+//                 class OdfReaderBackend
 
 
-OdtReaderBackend::OdtReaderBackend()
-    : d(new OdtReaderBackend::Private)
+OdfReaderBackend::OdfReaderBackend()
+    : d(new OdfReaderBackend::Private)
 {
 }
 
-OdtReaderBackend::~OdtReaderBackend()
+OdfReaderBackend::~OdfReaderBackend()
 {
     delete d;
 }
 
 
 // ----------------------------------------------------------------
-//                 ODT document level functions
+//                 ODF document level functions
 
 
-void OdtReaderBackend::elementOfficeDocumentcontent(KoXmlStreamReader &reader,
-                                                    OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
+IMPLEMENT_BACKEND_FUNCTION(OdfReader, OfficeDocumentcontent);
+IMPLEMENT_BACKEND_FUNCTION(OdfReader, OfficeBody);
diff --git a/filters/libodfreader/OdtReaderBackend.h \
b/filters/libodfreader/OdfReaderBackend.h similarity index 77%
copy from filters/libodfreader/OdtReaderBackend.h
copy to filters/libodfreader/OdfReaderBackend.h
index ae321ab..0f2e283 100644
--- a/filters/libodfreader/OdtReaderBackend.h
+++ b/filters/libodfreader/OdfReaderBackend.h
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -18,8 +18,8 @@
    Boston, MA 02110-1301, USA.
 */
 
-#ifndef ODTREADERBACKEND_H
-#define ODTREADERBACKEND_H
+#ifndef ODFREADERBACKEND_H
+#define ODFREADERBACKEND_H
 
 // Calligra
 #include <KoXmlStreamReader.h>
@@ -27,7 +27,7 @@
 
 // this library
 #include "koodfreader_export.h"
-#include "OdtReader.h"
+#include "OdfReader.h"
 
 
 class QByteArray;
@@ -37,10 +37,10 @@ class KoStore;
 class OdfReaderContext;
 
 
-/** @brief A default backend for the OdtReader class.
+/** @brief A default backend for the OdfReader class.
  *
  * This class defines an interface and the default behaviour for the
- * backend to the ODT reader (@see OdtReader). When the
+ * backend to the ODF reader (@see OdfReader). When the
  * reader is called upon to traverse a certain XML tree, there will
  * be two parameters to the root traverse function: a pointer to a
  * backend object and a pointer to a context object.
@@ -67,18 +67,17 @@ class OdfReaderContext;
  * inherit this class and only reimplement those functions that are
  * actually needed.
  */
-class KOODFREADER_EXPORT OdtReaderBackend
+class KOODFREADER_EXPORT OdfReaderBackend
 {
  public:
-    explicit OdtReaderBackend();
-    virtual ~OdtReaderBackend();
+    explicit OdfReaderBackend();
+    virtual ~OdfReaderBackend();
 
     // ----------------------------------------------------------------
-    // ODT document level functions
+    // ODF document level functions
 
-    virtual void elementOfficeDocumentcontent(KoXmlStreamReader &reader, \
                OdfReaderContext *context);
-    virtual void elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
*context); +    DECLARE_BACKEND_FUNCTION(OfficeDocumentcontent);
+    DECLARE_BACKEND_FUNCTION(OfficeBody);
 
  private:
     class Private;
@@ -86,4 +85,4 @@ class KOODFREADER_EXPORT OdtReaderBackend
 };
 
 
-#endif // ODTREADERBACKEND_H
+#endif // ODFREADERBACKEND_H
diff --git a/filters/libodfreader/OdfReaderInternals.h \
b/filters/libodfreader/OdfReaderInternals.h new file mode 100644
index 0000000..bf5c699
--- /dev/null
+++ b/filters/libodfreader/OdfReaderInternals.h
@@ -0,0 +1,79 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ODFREADERINTERNALS_H
+#define ODFREADERINTERNALS_H
+
+
+// ----------------------------------------------------------------
+//                     Reader functions
+
+
+#define DECLARE_READER_FUNCTION(name) \
+    void readElement##name(KoXmlStreamReader &reader)
+
+#define IMPLEMENT_READER_FUNCTION_START(readername, name)            \
+void readername::readElement##name(KoXmlStreamReader &reader)        \
+{                                                                    \
+    DEBUGSTART();                                                    \
+    m_backend->element##name(reader, m_context);
+
+#define IMPLEMENT_READER_FUNCTION_END(name)                          \
+    m_backend->element##name(reader, m_context);                     \
+    DEBUGEND();                                                      \
+}
+
+#define IMPLEMENT_READER_FUNCTION_NO_CHILDREN(readername, name)      \
+IMPLEMENT_READER_FUNCTION_START(readername, name)                    \
+    reader.skipCurrentElement();                                     \
+IMPLEMENT_READER_FUNCTION_END(name)
+
+#define IMPLEMENT_READER_FUNCTION_ONE_CHILD(readername, name, element, \
childfunction)	\ +IMPLEMENT_READER_FUNCTION_START(readername, name)                   \
\ +    while (reader.readNextStartElement()) {                          \
+        QString tagName = reader.qualifiedName().toString();         \
+                                                                     \
+        if (tagName == element) {                                    \
+	    readElement##childfunction(reader);                      \
+        }                                                            \
+        else {                                                       \
+            reader.skipCurrentElement();                             \
+        }                                                            \
+    }                                                                \
+IMPLEMENT_READER_FUNCTION_END(name)
+
+
+// ----------------------------------------------------------------
+//                     Backend functions
+
+
+#define DECLARE_BACKEND_FUNCTION(name)                               \
+    virtual void element##name(KoXmlStreamReader &reader, OdfReaderContext *context)
+
+#define IMPLEMENT_BACKEND_FUNCTION(readername, name)                 \
+void readername##Backend::element##name(KoXmlStreamReader &reader,   \
+				OdfReaderContext *context)	     \
+{                                                                    \
+    Q_UNUSED(reader);                                                \
+    Q_UNUSED(context);						     \
+}
+
+
+#endif // ODFREADERINTERNALS_H
diff --git a/filters/libodfreader/OdfTextReader.cpp \
b/filters/libodfreader/OdfTextReader.cpp index ab6514d..6b265c5 100644
--- a/filters/libodfreader/OdfTextReader.cpp
+++ b/filters/libodfreader/OdfTextReader.cpp
@@ -30,13 +30,16 @@
 #include <kdebug.h>
 #include <klocalizedstring.h>
 
-// Calligra
-#include <KoXmlStreamReader.h>
+// Calligra, libodf{,2}
 #include <KoXmlNS.h>
+#include <KoXmlStreamReader.h>
+#include <KoXmlUtils.h>
 
 // Reader library
+#include "OdfReader.h"
 #include "OdfTextReaderBackend.h"
 #include "OdfReaderContext.h"
+#include "OdfDrawReader.h"
 
 
 #if 1
@@ -62,7 +65,8 @@ static int debugIndent = 0;
 
 
 OdfTextReader::OdfTextReader()
-    : m_backend(0)
+    : m_parent(0)
+    , m_backend(0)
     , m_context(0)
 {
 }
@@ -75,6 +79,11 @@ OdfTextReader::~OdfTextReader()
 // ----------------------------------------------------------------
 
 
+void OdfTextReader::setParent(OdfReader *parent)
+{
+    m_parent = parent;
+}
+
 void OdfTextReader::setBackend(OdfTextReaderBackend *backend)
 {
     m_backend = backend;
@@ -108,6 +117,7 @@ void OdfTextReader::readElementNamespaceTagname(KoXmlStreamReader \
&reader)  
         if (tagName == "office:automatic-styles") {
             // FIXME: NYI
+            reader.skipCurrentElement();
         }
         else if (tagName == "office:body") {
             readElementOfficeBody(reader);
@@ -168,6 +178,8 @@ void OdfTextReader::readTextLevelElement(KoXmlStreamReader \
&reader)  //          <draw:polyline> 10.3.4
     //          <draw:rect> 10.3.2
     //          <draw:regular-polygon> 10.3.6
+    // All of the above are sent to the draw reader.
+    //
     //   [done] <table:table> 9.1.2
     //          <text:alphabetical-index> 8.8
     //          <text:bibliography> 8.9
@@ -188,7 +200,16 @@ void OdfTextReader::readTextLevelElement(KoXmlStreamReader \
&reader)  
     QString tagName = reader.qualifiedName().toString();
         
-    if (tagName == "text:h") {
+    if (reader.prefix() == "draw" || reader.prefix() == "dr3d") {
+	OdfDrawReader *drawReader = m_parent->drawReader();
+	if (drawReader) {
+	    drawReader->readCommonGraphicsElements(reader);
+	}
+	else {
+	    reader.skipCurrentElement();
+	}
+    } // draw | dr3d namespace
+    else if (tagName == "text:h") {
         readElementTextH(reader);
     }
     else if (tagName == "text:p") {
@@ -289,20 +310,20 @@ void OdfTextReader::readElementTableTable(KoXmlStreamReader \
&reader)  // <table:table> has the following children in ODF 1.2:
     //          <office:dde-source> 14.6.5
     //          <office:forms> 13.2
-    //          <table:desc> 9.1.14
+    //   [done] <table:desc> 9.1.14
     //          <table:named-expressions> 9.4.11
     //          <table:scenario> 9.2.7
     //          <table:shapes> 9.2.8
     //   [done] <table:table-column> 9.1.6
-    //          <table:table-column-group> 9.1.10
-    //          <table:table-columns> 9.1.12
-    //          <table:table-header-columns> 9.1.11
+    //   [done] <table:table-column-group> 9.1.10
+    //   [done] <table:table-columns> 9.1.12
+    //   [done] <table:table-header-columns> 9.1.11
     //   [done] <table:table-header-rows> 9.1.7
     //   [done] <table:table-row> 9.1.3
-    //          <table:table-row-group> 9.1.9
-    //          <table:table-rows> 9.1.8
+    //   [done] <table:table-row-group> 9.1.9
+    //   [done] <table:table-rows> 9.1.8
     //          <table:table-source> 9.2.6
-    //          <table:title> 9.1.13
+    //   [done] <table:title> 9.1.13
     //   [done] <text:soft-page-break> 5.6
     while (reader.readNextStartElement()) {
         QString tagName = reader.qualifiedName().toString();
@@ -310,12 +331,37 @@ void OdfTextReader::readElementTableTable(KoXmlStreamReader \
&reader)  if (tagName == "table:table-column") {
             readElementTableTableColumn(reader);
         }
+        else if (tagName == "table:table-column-group") {
+            readElementTableTableColumnGroup(reader);
+        }
+        else if (tagName == "table:table-columns") {
+            readElementTableTableColumns(reader);
+        }
+        else if (tagName == "table:table-header-columns") {
+            readElementTableTableHeaderColumns(reader);
+        }
         else if (tagName == "table:table-header-rows") {
             readElementTableTableHeaderRows(reader);
         }
         else if (tagName == "table:table-row") {
             readElementTableTableRow(reader);
         }
+        else if (tagName == "table:table-row-group") {
+            readElementTableTableRowGroup(reader);
+        }
+        else if (tagName == "table:table-rows") {
+            readElementTableTableRows(reader);
+        }
+        else if (tagName == "table:title") {
+	    QString value;
+	    readCharacterData(reader, value);
+	    m_backend->textVariable(tagName, value);
+        }
+        else if (tagName == "table:desc") {
+	    QString value;
+	    readCharacterData(reader, value);
+	    m_backend->textVariable(tagName, value);
+        }
         else if (tagName == "text:soft-page-break") {
             readElementTextSoftPageBreak(reader);
         }
@@ -328,6 +374,85 @@ void OdfTextReader::readElementTableTable(KoXmlStreamReader \
&reader)  DEBUGEND();
 }
 
+void OdfTextReader::readElementTableTableColumnGroup(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementTableTableColumnGroup(reader, m_context);
+
+    // <table:table-column-group> has the following children in ODF 1.2:
+    //          <table:table-header-columns> 9.1.11
+    //          <table:table-column> 9.1.6
+    //          <table:table-column-group> 9.1.10
+    //          <table:table-columns> 9.1.12
+    //
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+	if (tagName == "table:table-header-columns") {
+            readElementTableTableHeaderColumns(reader);
+        }
+        else if (tagName == "table:table-column") {
+            readElementTableTableColumn(reader);
+        }
+        else if (tagName == "table:table-column-group") {
+            readElementTableTableColumnGroup(reader);
+        }
+        else if (tagName == "table:table-columns") {
+            readElementTableTableColumns(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementTableTableColumnGroup(reader, m_context);
+    DEBUGEND();
+}
+
+void OdfTextReader::readElementTableTableColumns(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementTableTableColumns(reader, m_context);
+
+    // <table:table-columns> has the following children in ODF 1.2:
+    //   [done] <table:table-column> 9.1.6
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "table:table-column") {
+            readElementTableTableColumn(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementTableTableColumns(reader, m_context);
+    DEBUGEND();
+}
+
+void OdfTextReader::readElementTableTableHeaderColumns(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementTableTableHeaderColumns(reader, m_context);
+
+    // <table:table-header-columns> has the following children in ODF 1.2:
+    //   [done] <table:table-column> 9.1.6
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "table:table-column") {
+            readElementTableTableColumn(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementTableTableHeaderColumns(reader, m_context);
+    DEBUGEND();
+}
+
 void OdfTextReader::readElementTableTableHeaderRows(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
@@ -366,6 +491,45 @@ void \
OdfTextReader::readElementTableTableColumn(KoXmlStreamReader &reader)  DEBUGEND();
 }
 
+void OdfTextReader::readElementTableTableRowGroup(KoXmlStreamReader &reader)
+{
+   DEBUGSTART();
+    m_backend->elementTableTableRowGroup(reader, m_context);
+
+    // <table:table-row-group> has the following children in ODF 1.2:
+    //          <table:table-header-rows> 9.1.7
+    //          <table:table-row> 9.1.3
+    //          <table:table-row-group> 9.1.9
+    //          <table:table-rows> 9.1.8
+    //          <text:soft-page-break> 5.6
+   //
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+	if (tagName == "table:table-header-rows") {
+            readElementTableTableHeaderRows(reader);
+        }
+        else if (tagName == "table:table-row") {
+            readElementTableTableRow(reader);
+        }
+        else if (tagName == "table:table-row-group") {
+            readElementTableTableRowGroup(reader);
+        }
+        else if (tagName == "table:table-rows") {
+            readElementTableTableRows(reader);
+        }
+        else if (tagName == "text:soft-page-break") {
+            readElementTextSoftPageBreak(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementTableTableRowGroup(reader, m_context);
+    DEBUGEND();
+}
+
 void OdfTextReader::readElementTableTableRow(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
@@ -392,6 +556,32 @@ void OdfTextReader::readElementTableTableRow(KoXmlStreamReader \
&reader)  DEBUGEND();
 }
 
+void OdfTextReader::readElementTableTableRows(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    m_backend->elementTableTableRows(reader, m_context);
+
+    // <table:table-header-rows> has the following children in ODF 1.2:
+    //   [done] <table:table-row> 9.1.3
+    //   [done] <text:soft-page-break> 5.6.
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "table:table-row") {
+            readElementTableTableRow(reader);
+        }
+        else if (tagName == "text:soft-page-break") {
+            readElementTextSoftPageBreak(reader);
+        }
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementTableTableRows(reader, m_context);
+    DEBUGEND();
+}
+
 void OdfTextReader::readElementTableTableCell(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
@@ -403,7 +593,7 @@ void OdfTextReader::readElementTableTableCell(KoXmlStreamReader \
&reader)  // be found in any textbox, table cell or similar, it has the
     // following text document children:
     //
-    //          <office:annotation> 14.1
+    //   [done] <office:annotation> 14.1
     //          <table:cell-range-source> 9.3.1
     //          <table:detective> 9.3.2
 
@@ -412,8 +602,7 @@ void OdfTextReader::readElementTableTableCell(KoXmlStreamReader \
&reader)  
         QString tagName = reader.qualifiedName().toString();
         if (tagName == "office:annotation") {
-            // FIXME: NYI
-            reader.skipCurrentElement();
+	    readElementOfficeAnnotation(reader);
         }
         else if (tagName == "table:cell-range-source") {
             // FIXME: NYI
@@ -444,7 +633,7 @@ void \
OdfTextReader::readElementTableCoveredTableCell(KoXmlStreamReader &reader)  // be \
found in any textbox, table cell or similar, it has the  // following text document \
children:  //
-    //          <office:annotation> 14.1
+    //   [done] <office:annotation> 14.1
     //          <table:cell-range-source> 9.3.1
     //          <table:detective> 9.3.2
 
@@ -453,9 +642,8 @@ void \
OdfTextReader::readElementTableCoveredTableCell(KoXmlStreamReader &reader)  
         QString tagName = reader.qualifiedName().toString();
         if (tagName == "office:annotation") {
-            // FIXME: NYI
-            reader.skipCurrentElement();
-        }
+	    readElementOfficeAnnotation(reader);
+	}
         else if (tagName == "table:cell-range-source") {
             // FIXME: NYI
             reader.skipCurrentElement();
@@ -520,7 +708,7 @@ void OdfTextReader::readParagraphContents(KoXmlStreamReader \
&reader)  //          <draw:control> 10.3.13
         //          <draw:custom-shape> 10.6.1
         //          <draw:ellipse> 10.3.9
-        //          <draw:frame> 10.4.2
+        //   [done] <draw:frame> 10.4.2
         //          <draw:g> 10.3.15
         //          <draw:line> 10.3.3
         //          <draw:measure> 10.3.12
@@ -530,6 +718,8 @@ void OdfTextReader::readParagraphContents(KoXmlStreamReader \
&reader)  //          <draw:polyline> 10.3.4
         //          <draw:rect> 10.3.2
         //          <draw:regular-polygon> 10.3.6
+	// All of the above are sent to the draw reader.
+	//
         //   [done] <office:annotation> 14.1
         //   [done] <office:annotation-end> 14.2
         //          <presentation:date-time> 10.9.3.5
@@ -644,7 +834,17 @@ void OdfTextReader::readParagraphContents(KoXmlStreamReader \
&reader)  // FIXME: Only very few tags are handled right now.
 
         QString tagName = reader.qualifiedName().toString();
-        if (reader.prefix() == "office") {
+
+	if (reader.prefix() == "draw" || reader.prefix() == "dr3d") {
+	    OdfDrawReader *drawReader = m_parent->drawReader();
+	    if (drawReader) {
+		drawReader->readCommonGraphicsElements(reader);
+	    }
+	    else {
+		reader.skipCurrentElement();
+	    }
+        } // draw | dr3d namespace
+        else if (reader.prefix() == "office") {
             if (tagName == "office:annotation") {
                 readElementOfficeAnnotation(reader);
             }
@@ -699,7 +899,7 @@ void OdfTextReader::readElementOfficeAnnotation(KoXmlStreamReader \
&reader)  // <office:annotation> has the following children in ODF 1.2:
     //   [done] <dc:creator> 4.3.2.7
     //   [done] <dc:date> 4.3.2.10
-    //          <meta:date-string> 14.3
+    //   [done] <meta:date-string> 14.3
     //   [done] <text:list> 5.3.1
     //   [done] <text:p> 5.1.3
     while (reader.readNextStartElement()) {
@@ -712,8 +912,9 @@ void OdfTextReader::readElementOfficeAnnotation(KoXmlStreamReader \
&reader)  readElementDcDate(reader);
         }
         else if (tagName == "meta:date-string") {
-            // FIXME: NYI
-            reader.skipCurrentElement();
+	    QString value;
+	    readCharacterData(reader, value);
+	    m_backend->textVariable(tagName, value);
         }
         else if (tagName == "text:list") {
             readElementTextList(reader);
diff --git a/filters/libodfreader/OdfTextReader.h \
b/filters/libodfreader/OdfTextReader.h index d6c5bc8..020a2f7 100644
--- a/filters/libodfreader/OdfTextReader.h
+++ b/filters/libodfreader/OdfTextReader.h
@@ -30,12 +30,14 @@
 
 // this library
 #include "koodfreader_export.h"
+#include "OdfReaderInternals.h"
 
 
 class QSizeF;
 
-class OdfTextReaderBackend;
+class OdfReader;
 class OdfReaderContext;
+class OdfTextReaderBackend;
 
 
 /** @brief Read the XML tree of the content of an ODT file.
@@ -57,58 +59,66 @@ class KOODFREADER_EXPORT OdfTextReader
     // Read all common text level elements like text:p, text:h, draw:frame, etc.
     // This is the main entry point for text reading.
     void readTextLevelElement(KoXmlStreamReader &reader);
+    void readElementTableTable(KoXmlStreamReader &reader);
 
+    void setParent(OdfReader *parent);
     void setBackend(OdfTextReaderBackend *backend);
     void setContext(OdfReaderContext *context);
 
- protected:
     // All readElement*() are named after the full qualifiedName of
     // the element in ODF that they handle.
 
     // ----------------------------------------------------------------
     // Text level functions: paragraphs, headings, sections, frames, objects, etc
 
-    void readElementOfficeAnnotation(KoXmlStreamReader &reader);
-    void readElementOfficeAnnotationEnd(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(OfficeAnnotation);
+    DECLARE_READER_FUNCTION(OfficeAnnotationEnd);
 
-    void readElementDcCreator(KoXmlStreamReader &reader);
-    void readElementDcDate(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(DcCreator);
+    DECLARE_READER_FUNCTION(DcDate);
 
-    void readElementTextH(KoXmlStreamReader &reader);
-    void readElementTextP(KoXmlStreamReader &reader);
-    void readElementTextList(KoXmlStreamReader &reader);
-    void readElementTextA(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(TextH);
+    DECLARE_READER_FUNCTION(TextP);
+    DECLARE_READER_FUNCTION(TextList);
+    DECLARE_READER_FUNCTION(TextA);
 
-    void readElementTableTable(KoXmlStreamReader &reader);
-    void readElementTableTableColumn(KoXmlStreamReader &reader);
-    void readElementTableTableHeaderRows(KoXmlStreamReader &reader);
-    void readElementTableTableRow(KoXmlStreamReader &reader);
-    void readElementTableTableCell(KoXmlStreamReader &reader);
-    void readElementTableCoveredTableCell(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(TableTableColumnGroup);
+    DECLARE_READER_FUNCTION(TableTableColumn);
+    DECLARE_READER_FUNCTION(TableTableColumns);
+    DECLARE_READER_FUNCTION(TableTableHeaderColumns);
+    DECLARE_READER_FUNCTION(TableTableHeaderRows);
+    DECLARE_READER_FUNCTION(TableTableRowGroup);
+    DECLARE_READER_FUNCTION(TableTableRow);
+    DECLARE_READER_FUNCTION(TableTableRows);
+    DECLARE_READER_FUNCTION(TableTableCell);
+    DECLARE_READER_FUNCTION(TableCoveredTableCell);
 
     // ----------------------------------------------------------------
     // Paragraph level functions: spans, annotations, notes, text content itself, \
etc.  
     void readParagraphContents(KoXmlStreamReader &reader);
 
-    void readElementTextLineBreak(KoXmlStreamReader &reader);
-    void readElementTextS(KoXmlStreamReader &reader);
-    void readElementTextSpan(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(TextLineBreak);
+    DECLARE_READER_FUNCTION(TextS);
+    DECLARE_READER_FUNCTION(TextSpan);
 
     // ----------------------------------------------------------------
     // List level functions: list-item and list header.
 
-    void readElementTextListItem(KoXmlStreamReader &reader);
-    void readElementTextListHeader(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(TextListItem);
+    DECLARE_READER_FUNCTION(TextListHeader);
 
     // ----------------------------------------------------------------
     // Other functions
 
-    void readElementTextSoftPageBreak(KoXmlStreamReader &reader);
+    DECLARE_READER_FUNCTION(TextSoftPageBreak);
+
     void readUnknownElement(KoXmlStreamReader &reader);
 
 
  private:
+    OdfReader             *m_parent;  // The OdfReader controlling this one.
+
     OdfTextReaderBackend  *m_backend;
     OdfReaderContext      *m_context;
 };
diff --git a/filters/libodfreader/OdfTextReaderBackend.cpp \
b/filters/libodfreader/OdfTextReaderBackend.cpp index 30219ff..8cad16f 100644
--- a/filters/libodfreader/OdfTextReaderBackend.cpp
+++ b/filters/libodfreader/OdfTextReaderBackend.cpp
@@ -72,148 +72,59 @@ OdfTextReaderBackend::~OdfTextReaderBackend()
 // Text level functions: paragraphs, headings, sections, frames, objects, etc
 
 
-void OdfTextReaderBackend::elementOfficeAnnotation(KoXmlStreamReader &reader,
-                                                   OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementOfficeAnnotationEnd(KoXmlStreamReader &reader,
-                                                      OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementDcCreator(KoXmlStreamReader &reader,
-                                            OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementDcDate(KoXmlStreamReader &reader,
-                                         OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTextH(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTextP(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTextList(KoXmlStreamReader &reader, \
                OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableTable(KoXmlStreamReader &reader, \
                OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableTableColumn(KoXmlStreamReader &reader,
-                                                   OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableTableRow(KoXmlStreamReader &reader,
-                                                OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableTableHeaderRows(KoXmlStreamReader &reader,
-                                                       OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableTableCell(KoXmlStreamReader &reader,
-                                                 OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTableCoveredTableCell(KoXmlStreamReader &reader,
-                                                        OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, OfficeAnnotation)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, OfficeAnnotationEnd)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, DcCreator)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, DcDate)
+
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextH)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextP)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextList)
+
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTable)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableColumnGroup)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableColumn)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableRowGroup)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableRow)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableRows)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableColumns)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableHeaderColumns)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableHeaderRows)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableTableCell)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TableCoveredTableCell)
 
 
 // ----------------------------------------------------------------
 // Paragraph level functions: spans, annotations, notes, text content itself, etc.
 
 
-void OdfTextReaderBackend::elementTextA(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextA)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextLineBreak)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextSpan)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextS)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextSoftPageBreak)
 
-void OdfTextReaderBackend::elementTextLineBreak(KoXmlStreamReader &reader, \
                OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTextSpan(KoXmlStreamReader &reader, \
                OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdfTextReaderBackend::elementTextS(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
 
+// ----------------------------------------------------------------
+// List level functions: lit-header and list-item.
 
-void OdfTextReaderBackend::elementTextSoftPageBreak(KoXmlStreamReader &reader,
-                                                    OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
 
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextListHeader)
+IMPLEMENT_BACKEND_FUNCTION(OdfTextReader, TextListItem)
 
-void OdfTextReaderBackend::characterData(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
 
 // ----------------------------------------------------------------
-// List level functions: lit-header and list-item.
+// Some special functions
+
 
-void OdfTextReaderBackend::elementTextListHeader(KoXmlStreamReader &reader, \
OdfReaderContext *context) +void \
OdfTextReaderBackend::characterData(KoXmlStreamReader &reader, OdfReaderContext \
*context)  {
     Q_UNUSED(reader);
     Q_UNUSED(context);
 }
 
-void OdfTextReaderBackend::elementTextListItem(KoXmlStreamReader &reader, \
OdfReaderContext *context) +void OdfTextReaderBackend::textVariable(const QString \
&name, const QString &value)  {
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
+    Q_UNUSED(name);
+    Q_UNUSED(value);
 }
diff --git a/filters/libodfreader/OdfTextReaderBackend.h \
b/filters/libodfreader/OdfTextReaderBackend.h index 49c25ea..3d78193 100644
--- a/filters/libodfreader/OdfTextReaderBackend.h
+++ b/filters/libodfreader/OdfTextReaderBackend.h
@@ -63,39 +63,47 @@ class KOODFREADER_EXPORT OdfTextReaderBackend
     // ----------------------------------------------------------------
     // Text level functions: paragraphs, headings, sections, frames, objects, etc
 
-    virtual void elementOfficeAnnotation(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementOfficeAnnotationEnd(KoXmlStreamReader &reader, \
                OdfReaderContext *context);
-    virtual void elementDcCreator(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementDcDate(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-
-    virtual void elementTextH(KoXmlStreamReader &reader, OdfReaderContext *context);
-    virtual void elementTextP(KoXmlStreamReader &reader, OdfReaderContext *context);
-    virtual void elementTextList(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-
-    virtual void elementTableTable(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTableTableColumn(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTableTableHeaderRows(KoXmlStreamReader &reader, \
                OdfReaderContext *context);
-    virtual void elementTableTableRow(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTableTableCell(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTableCoveredTableCell(KoXmlStreamReader &reader, \
OdfReaderContext *context); +    DECLARE_BACKEND_FUNCTION(OfficeAnnotation);
+    DECLARE_BACKEND_FUNCTION(OfficeAnnotationEnd);
+    DECLARE_BACKEND_FUNCTION(DcCreator);
+    DECLARE_BACKEND_FUNCTION(DcDate);
+
+    DECLARE_BACKEND_FUNCTION(TextH);
+    DECLARE_BACKEND_FUNCTION(TextP);
+    DECLARE_BACKEND_FUNCTION(TextList);
+
+    DECLARE_BACKEND_FUNCTION(TableTable);
+    DECLARE_BACKEND_FUNCTION(TableTableColumnGroup);
+    DECLARE_BACKEND_FUNCTION(TableTableColumn);
+    DECLARE_BACKEND_FUNCTION(TableTableColumns);
+    DECLARE_BACKEND_FUNCTION(TableTableHeaderColumns);
+    DECLARE_BACKEND_FUNCTION(TableTableHeaderRows);
+    DECLARE_BACKEND_FUNCTION(TableTableRowGroup);
+    DECLARE_BACKEND_FUNCTION(TableTableRow);
+    DECLARE_BACKEND_FUNCTION(TableTableRows);
+    DECLARE_BACKEND_FUNCTION(TableTableCell);
+    DECLARE_BACKEND_FUNCTION(TableCoveredTableCell);
 
     // ----------------------------------------------------------------
     // Paragraph level functions: spans, annotations, notes, etc.
     // This includes text content itself.
 
-    virtual void elementTextA(KoXmlStreamReader &reader, OdfReaderContext *context);
-    virtual void elementTextLineBreak(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTextSpan(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTextS(KoXmlStreamReader &reader, OdfReaderContext *context);
+    DECLARE_BACKEND_FUNCTION(TextA);
+    DECLARE_BACKEND_FUNCTION(TextLineBreak);
+    DECLARE_BACKEND_FUNCTION(TextSpan);
+    DECLARE_BACKEND_FUNCTION(TextS);
 
     // ----------------------------------------------------------------
     // List level functions: list-header and list-item.
 
-    virtual void elementTextListHeader(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTextListItem(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementTextSoftPageBreak(KoXmlStreamReader &reader, \
OdfReaderContext *context); +    DECLARE_BACKEND_FUNCTION(TextListHeader);
+    DECLARE_BACKEND_FUNCTION(TextListItem);
+    DECLARE_BACKEND_FUNCTION(TextSoftPageBreak);
 
+    // ----------------------------------------------------------------
+    // Some special functions
     virtual void characterData(KoXmlStreamReader &reader, OdfReaderContext \
*context); +    virtual void textVariable(const QString &name, const QString &value);
 
  private:
     class Private;
diff --git a/filters/libodfreader/OdsReader.cpp b/filters/libodfreader/OdsReader.cpp
new file mode 100644
index 0000000..785ed99
--- /dev/null
+++ b/filters/libodfreader/OdsReader.cpp
@@ -0,0 +1,207 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+
+// Own
+#include "OdsReader.h"
+
+// Qt
+#include <QStringList>
+#include <QBuffer>
+
+// KDE
+#include <kdebug.h>
+#include <klocalizedstring.h>
+
+// Calligra
+#include <KoStore.h>
+#include <KoXmlStreamReader.h>
+#include <KoXmlNS.h>
+#include <KoXmlWriter.h>  // For copyXmlElement
+#include <KoOdfReadStore.h>
+
+// Reader library
+#include "OdsReaderBackend.h"
+#include "OdfReaderContext.h"
+#include "OdfTextReader.h"
+
+
+#if 0
+static int debugIndent = 0;
+#define DEBUGSTART() \
+    ++debugIndent; \
+    DEBUG_READING("entering")
+#define DEBUGEND() \
+    DEBUG_READING("exiting"); \
+    --debugIndent
+#define DEBUG_READING(param) \
+    kDebug(30503) << QString("%1").arg(" ", debugIndent * 2) << param << ": " \
+    << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : \
"other")) \ +    << reader.qualifiedName().toString()
+#else
+#define DEBUGSTART() \
+    // NOTHING
+#define DEBUGEND() \
+    // NOTHING
+#define DEBUG_READING(param) \
+    // NOTHING
+#endif
+
+
+OdsReader::OdsReader()
+    : OdfReader()
+{
+}
+
+OdsReader::~OdsReader()
+{
+}
+
+
+#if 0
+// This is a template function for the reader library.
+// Copy this one and change the name and fill in the code.
+void OdsReader::readElementNamespaceTagname(KoXmlStreamReader &reader)
+{ 
+   DEBUGSTART();
+
+    // <namespace:tagname> has the following children in ODF 1.2:
+    //   FILL IN THE CHILDREN LIKE THIS EXAMPLE (taken from \
office:document-content): +    //          <office:automatic-styles> 3.15.3
+    //          <office:body> 3.3
+    //          <office:font-face-decls> 3.14
+    //          <office:scripts> 3.12.
+    while (reader.readNextStartElement()) {
+        QString tagName = reader.qualifiedName().toString();
+        
+        if (tagName == "office:automatic-styles") {
+            // FIXME: NYI
+        }
+        else if (tagName == "office:body") {
+            readElementOfficeBody(reader);
+        }
+        ...  MORE else if () HERE
+        else {
+            reader.skipCurrentElement();
+        }
+    }
+
+    m_backend->elementNamespaceTagname(reader, m_context);
+    DEBUGEND();
+}
+#endif
+
+
+// Reimplemented from OdfReader
+void OdsReader::readElementOfficeSpreadsheet(KoXmlStreamReader &reader)
+{
+    DEBUGSTART();
+    OdsReaderBackend *backend = dynamic_cast<OdsReaderBackend *>(m_backend);
+    backend->elementOfficeSpreadsheet(reader, m_context);
+
+    // <office:spreadsheet> has the following children in ODF 1.2:
+    //
+    //          <table:calculation-settings> 9.4.1
+    //          <table:consolidation> 9.7
+    //          <table:content-validations> 9.4.4
+    //          <table:database-ranges> 9.4.14
+    //          <table:data-pilot-tables> 9.6.2
+    //          <table:dde-links> 9.8
+    //          <table:label-ranges> 9.4.10
+    //          <table:named-expressions> 9.4.11
+    //   [done] <table:table> 9.1.2
+    //          <table:tracked-changes> 9.9.2
+    //          <text:alphabetical-index-auto-mark-file> 8.8.3
+    //          <text:dde-connection-decls> 14.6.2
+    //          <text:sequence-decls> 7.4.11
+    //          <text:user-field-decls> 7.4.7
+    //          <text:variable-decls> 7.4.2
+
+    //
+    // FIXME: For now, only very few of these are handled.
+    while (reader.readNextStartElement()) {
+        DEBUG_READING("loop-start");
+        
+        QString tagName = reader.qualifiedName().toString();
+        if (tagName == "table:table") {
+            if (m_textReader) {
+		// <table:table> is handled in the text reader even in spreadsheets.
+                m_textReader->readElementTableTable(reader);
+            }
+            else {
+                reader.skipCurrentElement();
+            }
+        }
+        else if (tagName == "table:calculation-settings") {
+            // FIXME: NYI
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:consolidation") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:content-validation") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:database-ranges") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:data-pilot-tables") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:dde-links") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:label-ranges") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:named-expressions") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "table:tracked-changes") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "text:alphabetical-index-auto-mark-file") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "text:dde-connection-decls") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "text:sequence-decls") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "text:user-field-decls") {
+            reader.skipCurrentElement();
+        }
+        else if (tagName == "text:variable-decls") {
+            reader.skipCurrentElement();
+        }
+        else {
+	    reader.skipCurrentElement();
+        }
+        DEBUG_READING("loop-end");
+    }
+
+    backend->elementOfficeSpreadsheet(reader, m_context);
+    DEBUGEND();
+}
+
+
+// ----------------------------------------------------------------
+//                             Other functions
diff --git a/filters/libodfreader/OdtReader.h b/filters/libodfreader/OdsReader.h
similarity index 61%
copy from filters/libodfreader/OdtReader.h
copy to filters/libodfreader/OdsReader.h
index 22ae935..385d647 100644
--- a/filters/libodfreader/OdtReader.h
+++ b/filters/libodfreader/OdsReader.h
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -18,8 +18,8 @@
    Boston, MA 02110-1301, USA.
 */
 
-#ifndef ODTREADER_H
-#define ODTREADER_H
+#ifndef ODSREADER_H
+#define ODSREADER_H
 
 // Qt
 #include <QHash>
@@ -30,24 +30,29 @@
 
 // this library
 #include "koodfreader_export.h"
+#include "OdfReader.h"
+#include "OdfReaderInternals.h"
 
 
 class QSizeF;
 
-class OdtReaderBackend;
+class KoXmlWriter;
+class KoStore;
+
+class OdsReaderBackend;
 class OdfReaderContext;
 
 class OdfTextReader;
 
 
-/** @brief Read the XML tree of the content of an ODT file.
+/** @brief Read the XML tree of the content of an ODS file.
  *
- * The OdtReader is used to traverse (read) the contents of an ODT
+ * The OdsReader is used to traverse (read) the contents of an ODS
  * file using an XML stream reader.  For every XML element that the
  * reading process comes across it will call a specific function in a
- * backend class: @see OdtReaderBackend.
+ * backend class: @see OdsReaderBackend.
  *
- * Before the reading process is started the ODT file will be
+ * Before the reading process is started the ODS file will be
  * analyzed to collect some data that may be needed during the
  * read: metadata, manifest and styles are examples of this. This
  * data is stored in the so called reading context, which is kept in
@@ -56,43 +61,26 @@ class OdfTextReader;
  * The context will be passed around to the backend in every call to a
  * backend callback function.
  *
- * In addition to the pre-analyzed data from the ODT file, the context
+ * In addition to the pre-analyzed data from the ODS file, the context
  * can be used to keep track of data that is used in the backend
  * processing such as internal links, lists of embedded data such as
  * pictures.
  */
-class KOODFREADER_EXPORT OdtReader
+class KOODFREADER_EXPORT OdsReader : public OdfReader
 {
  public:
-    OdtReader();
-    ~OdtReader();
-
-    void setTextReader(OdfTextReader *textReader);
-
-    bool analyzeContent(OdfReaderContext *context);
-
-    bool readContent(OdtReaderBackend *backend, OdfReaderContext *context);
+    OdsReader();
+    ~OdsReader();
 
  protected:
     // All readElement*() are named after the full qualifiedName of
     // the element in ODF that they handle.
 
-    // ODT document level functions
-    void readElementOfficeBody(KoXmlStreamReader &reader);
-    void readElementOfficeText(KoXmlStreamReader &reader);
-
-    // ----------------------------------------------------------------
-    // Other functions
-
-    void readUnknownElement(KoXmlStreamReader &reader);
-
+    // ODS document level functions
+    DECLARE_READER_FUNCTION(OfficeSpreadsheet);
 
  private:
-    OdtReaderBackend  *m_backend;
-    OdfReaderContext  *m_context;
-
-    // Helper readers
-    OdfTextReader     *m_textReader;
+    // Not much here. Most are already in OdfReader.
 };
 
-#endif // ODTREADER_H
+#endif // ODSREADER_H
diff --git a/filters/libodfreader/OdtReaderBackend.cpp \
b/filters/libodfreader/OdsReaderBackend.cpp similarity index 59%
copy from filters/libodfreader/OdtReaderBackend.cpp
copy to filters/libodfreader/OdsReaderBackend.cpp
index cdc59f1..7507b70 100644
--- a/filters/libodfreader/OdtReaderBackend.cpp
+++ b/filters/libodfreader/OdsReaderBackend.cpp
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -20,7 +20,7 @@
 
 
 // Own
-#include "OdtReaderBackend.h"
+#include "OdsReaderBackend.h"
 
 // Calligra
 #include <KoXmlReader.h>
@@ -30,10 +30,10 @@
 
 
 // ================================================================
-//             class OdtReaderBackend::Private
+//             class OdsReaderBackend::Private
 
 
-class OdtReaderBackend::Private
+class OdsReaderBackend::Private
 {
  public:
     Private();
@@ -44,49 +44,32 @@ class OdtReaderBackend::Private
                                 // needed for forward binary compatibility.
 };
 
-OdtReaderBackend::Private::Private()
+OdsReaderBackend::Private::Private()
 {
 }
 
-OdtReaderBackend::Private::~Private()
+OdsReaderBackend::Private::~Private()
 {
 }
 
 
 // ================================================================
-//                 class OdtReaderBackend
+//                 class OdsReaderBackend
 
 
-OdtReaderBackend::OdtReaderBackend()
-    : d(new OdtReaderBackend::Private)
+OdsReaderBackend::OdsReaderBackend()
+    : d(new OdsReaderBackend::Private)
 {
 }
 
-OdtReaderBackend::~OdtReaderBackend()
+OdsReaderBackend::~OdsReaderBackend()
 {
     delete d;
 }
 
 
 // ----------------------------------------------------------------
-//                 ODT document level functions
+//                 ODS document level functions
 
 
-void OdtReaderBackend::elementOfficeDocumentcontent(KoXmlStreamReader &reader,
-                                                    OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
+IMPLEMENT_BACKEND_FUNCTION(OdsReader, OfficeSpreadsheet)
diff --git a/filters/libodfreader/OdtReaderBackend.h \
b/filters/libodfreader/OdsReaderBackend.h similarity index 77%
copy from filters/libodfreader/OdtReaderBackend.h
copy to filters/libodfreader/OdsReaderBackend.h
index ae321ab..bde68ed 100644
--- a/filters/libodfreader/OdtReaderBackend.h
+++ b/filters/libodfreader/OdsReaderBackend.h
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -18,8 +18,8 @@
    Boston, MA 02110-1301, USA.
 */
 
-#ifndef ODTREADERBACKEND_H
-#define ODTREADERBACKEND_H
+#ifndef ODSREADERBACKEND_H
+#define ODSREADERBACKEND_H
 
 // Calligra
 #include <KoXmlStreamReader.h>
@@ -27,7 +27,9 @@
 
 // this library
 #include "koodfreader_export.h"
-#include "OdtReader.h"
+#include "OdsReader.h"
+#include "OdfReaderBackend.h"
+#include "OdfReaderInternals.h"
 
 
 class QByteArray;
@@ -37,10 +39,10 @@ class KoStore;
 class OdfReaderContext;
 
 
-/** @brief A default backend for the OdtReader class.
+/** @brief A default backend for the OdsReader class.
  *
  * This class defines an interface and the default behaviour for the
- * backend to the ODT reader (@see OdtReader). When the
+ * backend to the ODS reader (@see OdsReader). When the
  * reader is called upon to traverse a certain XML tree, there will
  * be two parameters to the root traverse function: a pointer to a
  * backend object and a pointer to a context object.
@@ -67,18 +69,16 @@ class OdfReaderContext;
  * inherit this class and only reimplement those functions that are
  * actually needed.
  */
-class KOODFREADER_EXPORT OdtReaderBackend
+class KOODFREADER_EXPORT OdsReaderBackend : public OdfReaderBackend
 {
  public:
-    explicit OdtReaderBackend();
-    virtual ~OdtReaderBackend();
+    explicit OdsReaderBackend();
+    virtual ~OdsReaderBackend();
 
     // ----------------------------------------------------------------
-    // ODT document level functions
+    // ODS document level functions
 
-    virtual void elementOfficeDocumentcontent(KoXmlStreamReader &reader, \
                OdfReaderContext *context);
-    virtual void elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
*context); +    DECLARE_BACKEND_FUNCTION(OfficeSpreadsheet);
 
  private:
     class Private;
@@ -86,4 +86,4 @@ class KOODFREADER_EXPORT OdtReaderBackend
 };
 
 
-#endif // ODTREADERBACKEND_H
+#endif // ODSREADERBACKEND_H
diff --git a/filters/libodfreader/OdtReader.cpp b/filters/libodfreader/OdtReader.cpp
index 48e1037..4a75b5e 100644
--- a/filters/libodfreader/OdtReader.cpp
+++ b/filters/libodfreader/OdtReader.cpp
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2012-2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2012-2014 Inge Wallin            <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -41,9 +41,6 @@
 #include "OdfTextReader.h"
 
 
-static void prepareForOdfInternal(KoXmlStreamReader &reader);
-
-
 #if 0
 static int debugIndent = 0;
 #define DEBUGSTART() \
@@ -67,9 +64,7 @@ static int debugIndent = 0;
 
 
 OdtReader::OdtReader()
-    : m_backend(0)
-    , m_context(0)
-    , m_textReader(0)
+    : OdfReader()
 {
 }
 
@@ -78,98 +73,6 @@ OdtReader::~OdtReader()
 }
 
 
-void OdtReader::setTextReader(OdfTextReader *textReader)
-{
-    m_textReader = textReader;
-}
-
-bool OdtReader::analyzeContent(OdfReaderContext *context)
-{
-    // Extract styles, manifest, settings, etc
-    if (context->analyzeOdfFile() != KoFilter::OK) {
-        return false;
-    }
-    kDebug(30503) << "analyze ok";
-    return true;
-}
-
-bool OdtReader::readContent(OdtReaderBackend *backend, OdfReaderContext *context)
-{
-    kDebug(30503) << "entering";
-
-    m_backend = backend;
-    m_context = context;
-
-    if (m_textReader) {
-        m_textReader->setContext(context);
-    }
-
-    // ----------------------------------------------------------------
-    // Read the body from content.xml
-
-    KoStore *odfStore = m_context->odfStore();
-
-    if (!odfStore->open("content.xml")) {
-        kError(30503) << "Unable to open input file content.xml" << endl;
-        return false;
-    }
-    kDebug(30503) << "open content.xml ok";
-
-    KoXmlStreamReader reader;
-    prepareForOdfInternal(reader);
-
-    reader.setDevice(odfStore->device());
-    bool  foundContent = false;
-    while (!reader.atEnd()) {
-        reader.readNext();
-
-        if (reader.isStartElement() && reader.qualifiedName() == \
                "office:document-content") {
-            foundContent = true;
-            break;
-        }
-    }
-    if (!foundContent) {
-        kError(30503) << "Couldn't find the content in content.xml" << endl;
-    }
-
-    m_backend->elementOfficeDocumentcontent(reader, m_context);
-
-    // <office:document-content> has the following children in ODF 1.2:
-    //          <office:automatic-styles> 3.15.3
-    //   [done] <office:body> 3.3
-    //          <office:font-face-decls> 3.14
-    //          <office:scripts> 3.12.
-    while (reader.readNextStartElement()) {
-        QString tagName = reader.qualifiedName().toString();
-        
-        if (tagName == "office:automatic-styles") {
-            // We already have the styles in the context.  No need to read them \
                again.
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "office:body") {
-            // This is the big one.
-            readElementOfficeBody(reader);
-        }
-        else if (tagName == "office:font-face-decls") {
-            // FIXME: Not yet implemented
-            reader.skipCurrentElement();
-        }
-        else if (tagName == "office:scripts") {
-            // FIXME: Not yet implemented
-            reader.skipCurrentElement();
-        }
-        else {
-            reader.skipCurrentElement();
-        }
-    }
-
-    m_backend->elementOfficeDocumentcontent(reader, m_context);
-    odfStore->close();
-
-    return true;
-}
-
-
 #if 0
 // This is a template function for the reader library.
 // Copy this one and change the name and fill in the code.
@@ -204,40 +107,12 @@ void OdtReader::readElementNamespaceTagname(KoXmlStreamReader \
&reader)  #endif
 
 
-void OdtReader::readElementOfficeBody(KoXmlStreamReader &reader)
-{
-    DEBUGSTART();
-    m_backend->elementOfficeBody(reader, m_context);
-
-    // <office:body> has the following children in ODF 1.2:
-    //          <office:chart> 3.8,
-    //          <office:database> 12.1
-    //          <office:drawing> 3.5
-    //          <office:image> 3.9
-    //          <office:presentation> 3.6
-    //          <office:spreadsheet> 3.7
-    //   [done] <office:text> 3.4
-    //
-    // Of those only <office:text> is present in a text document (odt).
-    while (reader.readNextStartElement()) {
-        QString tagName = reader.qualifiedName().toString();
-        
-        if (tagName == "office:text") {
-            readElementOfficeText(reader);
-        }
-        else {
-            reader.skipCurrentElement();
-        }
-    }
-
-    m_backend->elementOfficeBody(reader, m_context);
-    DEBUGEND();
-}
-
+// Reimplemented from OdfReader
 void OdtReader::readElementOfficeText(KoXmlStreamReader &reader)
 {
     DEBUGSTART();
-    m_backend->elementOfficeText(reader, m_context);
+    OdtReaderBackend *backend = dynamic_cast<OdtReaderBackend *>(m_backend);
+    backend->elementOfficeText(reader, m_context);
 
     // <office:text> has the following children in ODF 1.2:
     //
@@ -327,97 +202,10 @@ void OdtReader::readElementOfficeText(KoXmlStreamReader \
&reader)  DEBUG_READING("loop-end");
     }
 
-    m_backend->elementOfficeText(reader, m_context);
+    backend->elementOfficeText(reader, m_context);
     DEBUGEND();
 }
 
 
 // ----------------------------------------------------------------
 //                             Other functions
-
-
-void OdtReader::readUnknownElement(KoXmlStreamReader &reader)
-{
-    DEBUGSTART();
-
-#if 1
-    // FIXME: We need to handle this.
-    reader.skipCurrentElement();
-#else
-    if (m_context->isInsideParagraph()) {
-        // readParagraphContents expect to have the reader point to the
-        // contents of the paragraph so we have to read past the text:p
-        // start tag here.
-        reader.readNext();
-        readParagraphContents(reader);
-    }
-    else {
-        while (reader.readNextStartElement()) {
-            readTextLevelElement(reader);
-        }
-    }
-#endif
-
-    DEBUGEND();
-}
-
-
-// FIXME: Remove this function when it is exported from \
                libs/odf/KoXmlStreamReader.cpp
-//
-static void prepareForOdfInternal(KoXmlStreamReader &reader)
-{
-    // This list of namespaces is taken from KoXmlNs.cpp
-    // Maybe not all of them are expected in an ODF document?
-    reader.addExpectedNamespace("office", \
                "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
-    reader.addExpectedNamespace("meta", \
                "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
-    reader.addExpectedNamespace("config", \
                "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
-    reader.addExpectedNamespace("text", \
                "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
-    reader.addExpectedNamespace("table", \
                "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
-    reader.addExpectedNamespace("draw", \
                "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
-    reader.addExpectedNamespace("presentation", \
                "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0");
-    reader.addExpectedNamespace("dr3d", \
                "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0");
-    reader.addExpectedNamespace("chart", \
                "urn:oasis:names:tc:opendocument:xmlns:chart:1.0");
-    reader.addExpectedNamespace("form", \
                "urn:oasis:names:tc:opendocument:xmlns:form:1.0");
-    reader.addExpectedNamespace("script", \
                "urn:oasis:names:tc:opendocument:xmlns:script:1.0");
-    reader.addExpectedNamespace("style", \
                "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
-    reader.addExpectedNamespace("number", \
                "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0");
-    reader.addExpectedNamespace("manifest", \
                "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0");
-    reader.addExpectedNamespace("anim", \
                "urn:oasis:names:tc:opendocument:xmlns:animation:1.0");
-
-    reader.addExpectedNamespace("math", "http://www.w3.org/1998/Math/MathML");
-    reader.addExpectedNamespace("svg", \
                "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
-    reader.addExpectedNamespace("fo", \
                "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
-    reader.addExpectedNamespace("dc", "http://purl.org/dc/elements/1.1/");
-    reader.addExpectedNamespace("xlink", "http://www.w3.org/1999/xlink");
-    reader.addExpectedNamespace("VL", "http://openoffice.org/2001/versions-list");
-    reader.addExpectedNamespace("smil", \
                "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0");
-    reader.addExpectedNamespace("xhtml", "http://www.w3.org/1999/xhtml");
-    reader.addExpectedNamespace("xml", "http://www.w3.org/XML/1998/namespace");
-
-    reader.addExpectedNamespace("calligra", "http://www.calligra.org/2005/");
-    reader.addExpectedNamespace("officeooo", "http://openoffice.org/2009/office");
-    reader.addExpectedNamespace("ooo", "http://openoffice.org/2004/office");
-
-    reader.addExpectedNamespace("delta", \
                "http://www.deltaxml.com/ns/track-changes/delta-namespace");
-    reader.addExpectedNamespace("split", \
                "http://www.deltaxml.com/ns/track-changes/split-namespace");
-    reader.addExpectedNamespace("ac", \
                "http://www.deltaxml.com/ns/track-changes/attribute-change-namespace");
                
-
-    // This list of namespaces is taken from KoXmlReader::fixNamespace()
-    // They were generated by old versions of OpenOffice.org.
-    reader.addExtraNamespace("office",    "http://openoffice.org/2000/office");
-    reader.addExtraNamespace("text",      "http://openoffice.org/2000/text");
-    reader.addExtraNamespace("style",     "http://openoffice.org/2000/style");
-    reader.addExtraNamespace("fo",        "http://www.w3.org/1999/XSL/Format");
-    reader.addExtraNamespace("table",     "http://openoffice.org/2000/table");
-    reader.addExtraNamespace("drawing",   "http://openoffice.org/2000/drawing");
-    reader.addExtraNamespace("datastyle", "http://openoffice.org/2000/datastyle");
-    reader.addExtraNamespace("svg",       "http://www.w3.org/2000/svg");
-    reader.addExtraNamespace("chart",     "http://openoffice.org/2000/chart");
-    reader.addExtraNamespace("dr3d",      "http://openoffice.org/2000/dr3d");
-    reader.addExtraNamespace("form",      "http://openoffice.org/2000/form");
-    reader.addExtraNamespace("script",    "http://openoffice.org/2000/script");
-    reader.addExtraNamespace("meta",      "http://openoffice.org/2000/meta");
-    reader.addExtraNamespace("config",    "http://openoffice.org/2001/config");
-    reader.addExtraNamespace("pres",      \
                "http://openoffice.org/2000/presentation");
-    reader.addExtraNamespace("manifest",  "http://openoffice.org/2001/manifest");
-}
diff --git a/filters/libodfreader/OdtReader.h b/filters/libodfreader/OdtReader.h
index 22ae935..20b8bfa 100644
--- a/filters/libodfreader/OdtReader.h
+++ b/filters/libodfreader/OdtReader.h
@@ -30,6 +30,8 @@
 
 // this library
 #include "koodfreader_export.h"
+#include "OdfReader.h"
+#include "OdfReaderInternals.h"
 
 
 class QSizeF;
@@ -61,38 +63,18 @@ class OdfTextReader;
  * processing such as internal links, lists of embedded data such as
  * pictures.
  */
-class KOODFREADER_EXPORT OdtReader
+class KOODFREADER_EXPORT OdtReader : public OdfReader
 {
  public:
     OdtReader();
     ~OdtReader();
 
-    void setTextReader(OdfTextReader *textReader);
-
-    bool analyzeContent(OdfReaderContext *context);
-
-    bool readContent(OdtReaderBackend *backend, OdfReaderContext *context);
-
  protected:
-    // All readElement*() are named after the full qualifiedName of
-    // the element in ODF that they handle.
-
     // ODT document level functions
-    void readElementOfficeBody(KoXmlStreamReader &reader);
-    void readElementOfficeText(KoXmlStreamReader &reader);
-
-    // ----------------------------------------------------------------
-    // Other functions
-
-    void readUnknownElement(KoXmlStreamReader &reader);
-
+    DECLARE_READER_FUNCTION(OfficeText);
 
  private:
-    OdtReaderBackend  *m_backend;
-    OdfReaderContext  *m_context;
-
-    // Helper readers
-    OdfTextReader     *m_textReader;
+    // Not much here. Most are already in OdfReader.
 };
 
 #endif // ODTREADER_H
diff --git a/filters/libodfreader/OdtReaderBackend.cpp \
b/filters/libodfreader/OdtReaderBackend.cpp index cdc59f1..5ad14e0 100644
--- a/filters/libodfreader/OdtReaderBackend.cpp
+++ b/filters/libodfreader/OdtReaderBackend.cpp
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -72,21 +72,4 @@ OdtReaderBackend::~OdtReaderBackend()
 //                 ODT document level functions
 
 
-void OdtReaderBackend::elementOfficeDocumentcontent(KoXmlStreamReader &reader,
-                                                    OdfReaderContext *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
-
-void OdtReaderBackend::elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
                *context)
-{
-    Q_UNUSED(reader);
-    Q_UNUSED(context);
-}
+IMPLEMENT_BACKEND_FUNCTION(OdtReader, OfficeText)
diff --git a/filters/libodfreader/OdtReaderBackend.h \
b/filters/libodfreader/OdtReaderBackend.h index ae321ab..5652dc5 100644
--- a/filters/libodfreader/OdtReaderBackend.h
+++ b/filters/libodfreader/OdtReaderBackend.h
@@ -1,6 +1,6 @@
 /* This file is part of the KDE project
 
-   Copyright (C) 2013 Inge Wallin            <inge@lysator.liu.se>
+   Copyright (C) 2013-2014 Inge Wallin       <inge@lysator.liu.se>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -28,6 +28,8 @@
 // this library
 #include "koodfreader_export.h"
 #include "OdtReader.h"
+#include "OdfReaderBackend.h"
+#include "OdfReaderInternals.h"
 
 
 class QByteArray;
@@ -67,7 +69,7 @@ class OdfReaderContext;
  * inherit this class and only reimplement those functions that are
  * actually needed.
  */
-class KOODFREADER_EXPORT OdtReaderBackend
+class KOODFREADER_EXPORT OdtReaderBackend : public OdfReaderBackend
 {
  public:
     explicit OdtReaderBackend();
@@ -76,9 +78,7 @@ class KOODFREADER_EXPORT OdtReaderBackend
     // ----------------------------------------------------------------
     // ODT document level functions
 
-    virtual void elementOfficeDocumentcontent(KoXmlStreamReader &reader, \
                OdfReaderContext *context);
-    virtual void elementOfficeBody(KoXmlStreamReader &reader, OdfReaderContext \
                *context);
-    virtual void elementOfficeText(KoXmlStreamReader &reader, OdfReaderContext \
*context); +    DECLARE_BACKEND_FUNCTION(OfficeText);
 
  private:
     class Private;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic